sinatra-rocketio-linda 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ebfcd893b6fd6ef33fa0c366cb796c70896b76f2
4
- data.tar.gz: 85c84d5d7b420570cf6ed9a806dd2c94e2ea42ab
3
+ metadata.gz: 22a5549a8d89eeae678b0f22d44dae2afad0473f
4
+ data.tar.gz: aa42150b15eb7393de375740260e094c60e8ce00
5
5
  SHA512:
6
- metadata.gz: d2f78eeef9f0237a405a87684b7d832a986dcafa6b3aad4194036190efeef7859af3b811c72783820294d1bccd7826e13b9f6d0b9df2a0c78b8f833a66c9b47b
7
- data.tar.gz: a73311f2263b81720aa7c6963af7ea7e8eaf1b590637dfd43184da1409c7486dd613ec835d0bbec666d8ed65feb222154f418518985ae50262087ecaf588f2ff
6
+ metadata.gz: 5ce242560eb393dd968e79199708a6a7c5f1cce9a8593015d1f89b88286ee26ecb9f3d7f4aea5efc9856386ca5cdf39c255b2fe3f0a00793ca6940a369259111
7
+ data.tar.gz: 8f71b0aefc032cd9b2020a365b6633a95e7307817417ba4df96d2304a70a4b120d75544e43293f0e5a6fedd1418e5c646e16c655d6b1fa286088933665f6cab5
@@ -1,8 +1,16 @@
1
+ === 0.0.3 2013-05-16
2
+
3
+ * remove read/take/watch listener on client disconnect
4
+ * {expire => false} option on tuple write
5
+ * add ruby client's test
6
+
1
7
  === 0.0.2 2013-05-15
8
+
2
9
  * update README
3
10
  * TupleSpace#watch(tuple, callback(tuple))
4
11
 
5
12
  === 0.0.1 2013-05-15
13
+
6
14
  * JavaScript Linda Client for WebBrowser
7
15
  * Ruby Linda Client
8
16
  * TupleSpace#write(tuple)
data/README.md CHANGED
@@ -54,7 +54,7 @@ Server Side
54
54
  require 'sinatra'
55
55
  require 'sinatra/rocketio'
56
56
  require 'sinatra/rocketio/linda'
57
- set :linda, :check_expire => 60
57
+ set :linda, :expire_check => 60
58
58
 
59
59
  run Sinatra::Application
60
60
  ```
@@ -151,6 +151,13 @@ Test
151
151
 
152
152
  % gem install bundler
153
153
  % bundle install
154
+
155
+ start server
156
+
157
+ % rake test_server
158
+
159
+ run test
160
+
154
161
  % rake test
155
162
 
156
163
 
data/Rakefile CHANGED
@@ -5,4 +5,10 @@ Rake::TestTask.new do |t|
5
5
  t.pattern = "test/test_*.rb"
6
6
  end
7
7
 
8
+ desc "Start test server"
9
+ task :test_server do
10
+ require File.expand_path 'test/app', File.dirname(__FILE__)
11
+ App.start
12
+ end
13
+
8
14
  task :default => :test
@@ -3,22 +3,26 @@ module Sinatra
3
3
  module Linda
4
4
 
5
5
  def self.tuplespaces
6
- @@spaces ||= Hash.new{|h,k| h[k] = TupleSpace.new }
6
+ @@spaces ||= Hash.new{|h,k| h[k] = TupleSpace.new(k) }
7
7
  end
8
8
 
9
9
  def self.[](name)
10
10
  self.tuplespaces[name]
11
11
  end
12
12
 
13
+ def self.check_expire
14
+ tuplespaces.values.each do |ts|
15
+ ts.check_expire
16
+ end
17
+ end
18
+
13
19
  end
14
20
  end
15
21
  end
16
22
 
17
23
  Sinatra::RocketIO.on :start do
18
24
  EM::add_periodic_timer Sinatra::RocketIO::Linda.options[:expire_check] do
19
- Sinatra::RocketIO::Linda::tuplespaces.values.each do |ts|
20
- ts.check_expire
21
- end
25
+ Sinatra::RocketIO::Linda.check_expire
22
26
  end
23
27
  end
24
28
 
@@ -43,50 +47,23 @@ Sinatra::RocketIO.on :__linda_write do |data, client|
43
47
  Sinatra::RocketIO::Linda[space].write tuple, opts
44
48
  end
45
49
 
46
- Sinatra::RocketIO.on :__linda_read do |data, client|
47
- space, tuple, callback = data
48
- space = "__default__" if !space or !space.kind_of? String or space.empty?
49
- unless [Hash, Array].include? tuple.class
50
- Sinatra::RocketIO::Linda.emit :error, "received Tuple is not Hash or Array at :__linda_read"
51
- next
52
- end
53
- if !callback or !callback.kind_of? String or callback.empty?
54
- Sinatra::RocketIO::Linda.emit :error, "received Callback ID is not valid at :__linda_read"
55
- next
56
- end
57
- Sinatra::RocketIO::Linda[space].read tuple do |tuple|
58
- Sinatra::RocketIO.push "__linda_read_callback_#{callback}", tuple.data, :to => client.session
59
- end
60
- end
61
-
62
- Sinatra::RocketIO.on :__linda_take do |data, client|
63
- space, tuple, callback = data
64
- space = "__default__" if !space or !space.kind_of? String or space.empty?
65
- unless [Hash, Array].include? tuple.class
66
- Sinatra::RocketIO::Linda.emit :error, "received Tuple is not Hash or Array at :__linda_take"
67
- next
68
- end
69
- if !callback or !callback.kind_of? String or callback.empty?
70
- Sinatra::RocketIO::Linda.emit :error, "received Callback ID is not valid at :__linda_take"
71
- next
72
- end
73
- Sinatra::RocketIO::Linda[space].take tuple do |tuple|
74
- Sinatra::RocketIO.push "__linda_take_callback_#{callback}", tuple.data, :to => client.session
75
- end
76
- end
77
-
78
- Sinatra::RocketIO.on :__linda_watch do |data, client|
79
- space, tuple, callback = data
80
- space = "__default__" if !space or !space.kind_of? String or space.empty?
81
- unless [Hash, Array].include? tuple.class
82
- Sinatra::RocketIO::Linda.emit :error, "received Tuple is not Hash or Array at :__linda_watch"
83
- next
84
- end
85
- if !callback or !callback.kind_of? String or callback.empty?
86
- Sinatra::RocketIO::Linda.emit :error, "received Callback ID is not valid at :__linda_watch"
87
- next
88
- end
89
- Sinatra::RocketIO::Linda[space].watch tuple do |tuple|
90
- Sinatra::RocketIO.push "__linda_watch_callback_#{callback}", tuple.data, :to => client.session
50
+ [:read, :take, :watch].each do |func|
51
+ Sinatra::RocketIO.on "__linda_#{func}" do |data, client|
52
+ space, tuple, callback = data
53
+ space = "__default__" if !space or !space.kind_of? String or space.empty?
54
+ unless [Hash, Array].include? tuple.class
55
+ Sinatra::RocketIO::Linda.emit :error, "received Tuple is not Hash or Array at :__linda_#{func}"
56
+ next
57
+ end
58
+ if !callback or !callback.kind_of? String or callback.empty?
59
+ Sinatra::RocketIO::Linda.emit :error, "received Callback ID is not valid at :__linda_#{func}"
60
+ next
61
+ end
62
+ eid = Sinatra::RocketIO::Linda[space].__send__ func, tuple do |tuple|
63
+ Sinatra::RocketIO.push "__linda_#{func}_callback_#{callback}", tuple.data, :to => client.session
64
+ end
65
+ Sinatra::RocketIO.on :disconnect do |_client|
66
+ Sinatra::RocketIO::Linda[space].remove_callback eid if client.session == _client.session
67
+ end
91
68
  end
92
69
  end
@@ -10,7 +10,9 @@ module Sinatra
10
10
  end
11
11
  @data = data
12
12
  @type = data.class
13
- @expire_at = Time.now+(opts[:expire] || 300)
13
+ if opts[:expire].class == Fixnum and opts[:expire] > 0
14
+ @expire_at = Time.now + opts[:expire]
15
+ end
14
16
  end
15
17
 
16
18
  def match?(target)
@@ -4,8 +4,10 @@ module Sinatra
4
4
 
5
5
  class TupleSpace
6
6
  include Enumerable
7
+ attr_reader :name
7
8
 
8
- def initialize
9
+ def initialize(name="__default__")
10
+ @name = name
9
11
  @tuples = Array.new
10
12
  @callbacks = Array.new
11
13
  end
@@ -16,6 +18,10 @@ module Sinatra
16
18
  end
17
19
  end
18
20
 
21
+ def remove_callback(callback)
22
+ @callbacks.delete callback
23
+ end
24
+
19
25
  def size
20
26
  @tuples.size
21
27
  end
@@ -60,7 +66,11 @@ module Sinatra
60
66
  end
61
67
  end
62
68
  end
63
- @callbacks.push(:type => :read, :callback => block, :tuple => tuple) if block_given?
69
+ if block_given?
70
+ callback = {:type => :read, :callback => block, :tuple => tuple}
71
+ @callbacks.push callback
72
+ return callback
73
+ end
64
74
  end
65
75
 
66
76
  def take(tuple, &block)
@@ -80,20 +90,26 @@ module Sinatra
80
90
  return matched_tuple
81
91
  end
82
92
  else
83
- @callbacks.push(:type => :take, :callback => block, :tuple => tuple) if block_given?
93
+ if block_given?
94
+ callback = {:type => :take, :callback => block, :tuple => tuple}
95
+ @callbacks.push callback
96
+ return callback
97
+ end
84
98
  end
85
99
  end
86
100
 
87
101
  def watch(tuple, &block)
88
102
  raise ArgumentError, "block not given" unless block_given?
89
103
  tuple = Tuple.new tuple unless tuple.kind_of? Tuple
90
- @callbacks.unshift(:type => :watch, :callback => block, :tuple => tuple)
104
+ callback = {:type => :watch, :callback => block, :tuple => tuple}
105
+ @callbacks.unshift callback
106
+ callback
91
107
  end
92
108
 
93
109
  def check_expire
94
110
  expires = []
95
- each do |tuple|
96
- expires.push tuple unless tuple.expire_at > Time.now
111
+ self.each do |tuple|
112
+ expires.push(tuple) if tuple.expire_at and tuple.expire_at < Time.now
97
113
  end
98
114
  expires.each do |tuple|
99
115
  @tuples.delete tuple
@@ -1,7 +1,7 @@
1
1
  module Sinatra
2
2
  module RocketIO
3
3
  module Linda
4
- VERSION = "0.0.2"
4
+ VERSION = "0.0.3"
5
5
  end
6
6
  end
7
7
  end
@@ -0,0 +1,38 @@
1
+ class App
2
+
3
+ def self.running
4
+ @running ? true : false
5
+ end
6
+
7
+ def self.port
8
+ ENV['PORT'] || 5000
9
+ end
10
+
11
+ def self.ws_port
12
+ ENV['WS_PORT'] || 5001
13
+ end
14
+
15
+ def self.url
16
+ "http://localhost:#{port}"
17
+ end
18
+
19
+ def self.websocketio_url
20
+ "ws://localhost:#{ws_port}"
21
+ end
22
+
23
+ def self.cometio_url
24
+ "http://localhost:#{port}/cometio/io"
25
+ end
26
+
27
+ def self.app_dir
28
+ File.expand_path 'app', File.dirname(__FILE__)
29
+ end
30
+
31
+ def self.start
32
+ return if running
33
+ @running = true
34
+ cmd = "cd #{app_dir} && WS_PORT=#{ws_port} rackup config.ru -p #{port}"
35
+ system cmd
36
+ end
37
+
38
+ end
@@ -0,0 +1,14 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'sinatra'
4
+ require 'sinatra/base'
5
+ $stdout.sync = true
6
+ $:.unshift File.expand_path '../../lib', File.dirname(__FILE__)
7
+ require 'sinatra/rocketio'
8
+ require 'sinatra/rocketio/linda'
9
+ require File.dirname(__FILE__)+'/main'
10
+
11
+ set :linda, :expire_check => 30
12
+ set :websocketio, :port => ENV['WS_PORT'].to_i
13
+
14
+ run TestApp
@@ -0,0 +1,28 @@
1
+ class TestApp < Sinatra::Base
2
+ register Sinatra::RocketIO
3
+ io = Sinatra::RocketIO
4
+ register Sinatra::RocketIO::Linda
5
+ linda = Sinatra::RocketIO::Linda
6
+
7
+ get '/' do
8
+ "sinatra-rocketio-linda v#{Sinatra::RocketIO::Linda::VERSION}"
9
+ end
10
+
11
+ io.on :connect do |client|
12
+ puts "new client <session:#{client.session}> <type:#{client.type}>"
13
+ end
14
+
15
+ io.on :disconnect do |client|
16
+ puts "disconnect client <session:#{client.session}> <type:#{client.type}>"
17
+ end
18
+
19
+ io.on :check_expire do |data, client|
20
+ puts "check_expire"
21
+ linda.check_expire
22
+ end
23
+
24
+ io.on :* do |event, data, client|
25
+ next unless event.to_s =~ /linda/
26
+ puts "#{event} - #{data} from #{client}"
27
+ end
28
+ end
@@ -0,0 +1,46 @@
1
+ require File.expand_path 'test_helper', File.dirname(__FILE__)
2
+ require 'sinatra/rocketio/linda/client'
3
+
4
+ class TestClientDisconnect < MiniTest::Test
5
+
6
+ def test_client_disconnect
7
+ ts_name = "ts_#{Time.now.to_i}_#{Time.now.usec}"
8
+ client1 = Sinatra::RocketIO::Linda::Client.new App.url
9
+ _tuple1 = nil
10
+ _tuple2 = nil
11
+ _tuple3 = nil
12
+ _tuple4 = nil
13
+ client1.io.on :connect do
14
+ client2 = Sinatra::RocketIO::Linda::Client.new App.url
15
+ client2.io.on :connect do
16
+ ts1 = client1.tuplespace[ts_name]
17
+ ts2 = client2.tuplespace[ts_name]
18
+ ts1.read [1,2] do |tuple|
19
+ _tuple1 = tuple
20
+ end
21
+ ts1.take [1,2] do |tuple|
22
+ _tuple2 = tuple
23
+ end
24
+ ts1.watch [1,2] do |tuple|
25
+ _tuple3 = tuple
26
+ end
27
+ ts2.take [1,2] do |tuple|
28
+ _tuple4 = tuple
29
+ end
30
+ client1.io.close
31
+ sleep 3
32
+ ts2.write [1,2,3]
33
+ ts2.write [1,2,3,4]
34
+ end
35
+ end
36
+ 50.times do
37
+ sleep 0.1
38
+ break if _tuple4
39
+ end
40
+ assert_equal _tuple1, nil
41
+ assert_equal _tuple2, nil
42
+ assert_equal _tuple3, nil
43
+ assert_equal _tuple4, [1,2,3]
44
+ end
45
+
46
+ end
@@ -1,3 +1,5 @@
1
1
  require 'rubygems'
2
+ require 'bundler/setup'
2
3
  require 'minitest/autorun'
4
+ require File.expand_path 'app', File.dirname(__FILE__)
3
5
  $:.unshift File.expand_path '../lib', File.dirname(__FILE__)
@@ -0,0 +1,125 @@
1
+ require File.expand_path 'test_helper', File.dirname(__FILE__)
2
+ require 'sinatra/rocketio/linda/client'
3
+
4
+ class TestRubyClient < MiniTest::Test
5
+
6
+ def setup
7
+ @client = Sinatra::RocketIO::Linda::Client.new App.url
8
+ end
9
+
10
+ def test_write_read_take
11
+ ts_name = "ts_#{rand Time.now.to_i}"
12
+ ts = @client.tuplespace[ts_name]
13
+ _tuple1 = nil
14
+ _tuple2 = nil
15
+ _tuple3 = nil
16
+ _tuple4 = nil
17
+ @client.io.on :connect do
18
+ ts.write ["rw",1,2,3]
19
+ ts.write ["rw",1,2,"a"]
20
+ ts.write ["rw",1,"a",2]
21
+ ts.take ["rw",1,2] do |tuple|
22
+ _tuple1 = tuple
23
+ end
24
+ ts.read ["rw",1,2] do |tuple|
25
+ _tuple2 = tuple
26
+ end
27
+ ts.take ["rw",1,2] do |tuple|
28
+ _tuple3 = tuple
29
+ end
30
+ client2 = Sinatra::RocketIO::Linda::Client.new App.url
31
+ ts2 = client2.tuplespace[ts_name]
32
+ client2.io.on :connect do
33
+ ts2.take ["rw",1] do |tuple|
34
+ _tuple4 = tuple
35
+ end
36
+ end
37
+ end
38
+ 50.times do
39
+ sleep 0.1
40
+ break if _tuple4
41
+ end
42
+ assert_equal _tuple1, ["rw",1,2,"a"] # take
43
+ assert_equal _tuple2, ["rw",1,2,3] # read
44
+ assert_equal _tuple3, ["rw",1,2,3] # take
45
+ assert_equal _tuple4, ["rw",1,"a",2]
46
+ end
47
+
48
+ def test_watch
49
+ results = []
50
+ _tuple1 = nil
51
+ _tuple2 = nil
52
+ ts = @client.tuplespace["ts_#{rand Time.now.to_i}"]
53
+ @client.io.on :connect do
54
+ ts.take ["watch",1,2] do |tuple|
55
+ _tuple1 = tuple
56
+ end
57
+ ts.read ["watch",1,2] do |tuple|
58
+ _tuple2 = tuple
59
+ end
60
+ ts.watch ["watch",1,2] do |tuple|
61
+ results.push tuple
62
+ end
63
+ ts.write ["watch",1,2,3]
64
+ ts.write ["watch",1,"a",2]
65
+ ts.write ["watch",1,2,3,4]
66
+ end
67
+ 50.times do
68
+ sleep 0.1
69
+ break if _tuple1 != nil and _tuple2 != nil
70
+ end
71
+ assert_equal _tuple1, ["watch",1,2,3]
72
+ assert_equal _tuple2, ["watch",1,2,3,4]
73
+ assert_equal results.size, 2
74
+ assert_equal results[0], ["watch",1,2,3]
75
+ assert_equal results[1], ["watch",1,2,3,4]
76
+ end
77
+
78
+ def test_tuplespaces
79
+ ts1 = @client.tuplespace["ts1_#{rand Time.now.to_i}"]
80
+ ts2 = @client.tuplespace["ts2_#{rand Time.now.to_i}"]
81
+ _tuple1 = nil
82
+ _tuple2 = nil
83
+ @client.io.on :connect do
84
+ ts2.take ["a"] do |tuple|
85
+ _tuple2 = tuple
86
+ end
87
+ ts1.take [1] do |tuple|
88
+ _tuple1 = tuple
89
+ end
90
+ ts1.write [1,2,3]
91
+ ts2.write ["a","b","c"]
92
+ end
93
+ 50.times do
94
+ sleep 0.1
95
+ break if _tuple1
96
+ end
97
+ assert_equal _tuple1, [1,2,3]
98
+ assert_equal _tuple2, ["a","b","c"]
99
+ end
100
+
101
+ def test_tuple_expire
102
+ ts = @client.tuplespace["ts_#{rand Time.now.to_i}"]
103
+ _tuple1 = nil
104
+ _tuple2 = nil
105
+ @client.io.on :connect do
106
+ ts.write ["expire",1,2,999], :expire => false
107
+ ts.write ["expire",1,2,3], :expire => 10
108
+ ts.write ["expire",1,2,"a","b"], :expire => 2
109
+ ts.read ["expire",1,2] do |tuple|
110
+ _tuple1 = tuple
111
+ end
112
+ sleep 3
113
+ @client.io.push :check_expire, []
114
+ ts.read ["expire",1,2] do |tuple|
115
+ _tuple2 = tuple
116
+ end
117
+ end
118
+ 50.times do
119
+ sleep 0.1
120
+ break if _tuple2
121
+ end
122
+ assert_equal _tuple1, ["expire",1,2,"a","b"]
123
+ assert_equal _tuple2, ["expire",1,2,3]
124
+ end
125
+ end
@@ -117,13 +117,17 @@ class TestTupleSpace < MiniTest::Test
117
117
  end
118
118
 
119
119
  def test_tuple_expire
120
+ @space.write [1,2,999], :expire => false
120
121
  @space.write [1,2,3], :expire => 3
121
122
  @space.write [1,2,"a","b"], :expire => 2
122
- assert_equal @space.size, 2
123
+ assert_equal @space.size, 3
123
124
  sleep 2
124
125
  @space.check_expire
125
- assert_equal @space.size, 1
126
+ assert_equal @space.size, 2
126
127
  assert_equal @space.take([1,2]).data, [1,2,3]
128
+ assert_equal @space.size, 1
129
+ sleep 1
130
+ assert_equal @space.take([1,2]).data, [1,2,999]
127
131
  assert_equal @space.size, 0
128
132
  end
129
133
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sinatra-rocketio-linda
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sho Hashimoto
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-05-15 00:00:00.000000000 Z
11
+ date: 2013-05-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -156,7 +156,12 @@ files:
156
156
  - sample/views/index.haml
157
157
  - sample/views/worker.haml
158
158
  - sinatra-rocketio-linda.gemspec
159
+ - test/app.rb
160
+ - test/app/config.ru
161
+ - test/app/main.rb
162
+ - test/test_client_disconnect.rb
159
163
  - test/test_helper.rb
164
+ - test/test_rubyclient.rb
160
165
  - test/test_tuple.rb
161
166
  - test/test_tuplespace.rb
162
167
  homepage: https://github.com/shokai/sinatra-rocketio-linda
@@ -184,6 +189,11 @@ signing_key:
184
189
  specification_version: 4
185
190
  summary: Linda implementation on Sinatra RocketIO
186
191
  test_files:
192
+ - test/app.rb
193
+ - test/app/config.ru
194
+ - test/app/main.rb
195
+ - test/test_client_disconnect.rb
187
196
  - test/test_helper.rb
197
+ - test/test_rubyclient.rb
188
198
  - test/test_tuple.rb
189
199
  - test/test_tuplespace.rb