sinatra-rocketio-linda 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/History.txt +8 -0
- data/LICENSE.txt +22 -0
- data/README.md +117 -0
- data/Rakefile +8 -0
- data/lib/js/linda.js +36 -0
- data/lib/sinatra-rocketio-linda/application.rb +16 -0
- data/lib/sinatra-rocketio-linda/helper.rb +13 -0
- data/lib/sinatra-rocketio-linda/javascript.rb +18 -0
- data/lib/sinatra-rocketio-linda/linda.rb +76 -0
- data/lib/sinatra-rocketio-linda/options.rb +53 -0
- data/lib/sinatra-rocketio-linda/tuple.rb +41 -0
- data/lib/sinatra-rocketio-linda/tuplespace.rb +100 -0
- data/lib/sinatra/rocketio/linda.rb +16 -0
- data/lib/sinatra/rocketio/linda/client.rb +60 -0
- data/lib/sinatra/rocketio/linda/version.rb +7 -0
- data/sample/bin/cui_calc_worker.rb +29 -0
- data/sample/config.ru +14 -0
- data/sample/main.rb +26 -0
- data/sample/public/client.js +20 -0
- data/sample/public/worker.js +14 -0
- data/sample/views/client.haml +16 -0
- data/sample/views/index.haml +12 -0
- data/sample/views/worker.haml +13 -0
- data/sinatra-rocketio-linda.gemspec +30 -0
- data/test/test_helper.rb +3 -0
- data/test/test_tuple.rb +29 -0
- data/test/test_tuplespace.rb +110 -0
- metadata +188 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 523bf63e3fe852d759d5e75b62e82d8b5900ffa9
|
4
|
+
data.tar.gz: ca656ff542d98f73c942542ddeaf5654566f5b60
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6328614db8c10c14410d515d7aad2a0885335165e4aaeae081852fae8dd13cf45687cf4ae30e6caf571a8b2d5cca7b08434d8387b962bf30f350c3a83290792f
|
7
|
+
data.tar.gz: 0f41f574bbcace16a210b0f4e3a93f29d0aca235ae1dd3e9b85b52f1dd0ffe548a123e125f6cdd87c9d1d3590af7e723c7fe6a2de837c995847f50e1ef3b50c6
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/History.txt
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Sho Hashimoto
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
sinatra-rocketio-linda
|
2
|
+
======================
|
3
|
+
|
4
|
+
* Linda implementation on Sinatra::RocketIO
|
5
|
+
* https://github.com/shokai/sinatra-rocketio-linda
|
6
|
+
|
7
|
+
|
8
|
+
Linda
|
9
|
+
-----
|
10
|
+
|
11
|
+
* http://en.wikipedia.org/wiki/Linda_(coordination_language)
|
12
|
+
* http://ja.wikipedia.org/wiki/Linda
|
13
|
+
|
14
|
+
|
15
|
+
Installation
|
16
|
+
------------
|
17
|
+
|
18
|
+
% gem install sinatra-rocketio-linda
|
19
|
+
|
20
|
+
|
21
|
+
Requirements
|
22
|
+
------------
|
23
|
+
* Ruby 1.8.7 or 1.9.2 or 1.9.3 or 2.0.0
|
24
|
+
* Sinatra 1.3.0+
|
25
|
+
* [Sinatra RocketIO](https://github.com/shokai/sinatra-rocketio)
|
26
|
+
* [EventMachine](http://rubyeventmachine.com)
|
27
|
+
* [jQuery](http://jquery.com)
|
28
|
+
|
29
|
+
|
30
|
+
Usage
|
31
|
+
-----
|
32
|
+
|
33
|
+
### Setup
|
34
|
+
|
35
|
+
Server Side
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
require 'sinatra'
|
39
|
+
require 'sinatra/rocketio'
|
40
|
+
require 'sinatra/rocketio/linda'
|
41
|
+
set :linda, :check_expire => 60
|
42
|
+
|
43
|
+
run Sinatra::Application
|
44
|
+
```
|
45
|
+
|
46
|
+
Client Side
|
47
|
+
|
48
|
+
```html
|
49
|
+
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
|
50
|
+
<script src="<%= rocketio_js %>"></script>
|
51
|
+
<script src="<%= linda_js %>"></script>
|
52
|
+
```
|
53
|
+
|
54
|
+
```javascript
|
55
|
+
var io = new RocketIO().connect();
|
56
|
+
var linda = new Linda(io);
|
57
|
+
```
|
58
|
+
|
59
|
+
### client / worker
|
60
|
+
|
61
|
+
client side
|
62
|
+
|
63
|
+
```javascript
|
64
|
+
// create tuplespace
|
65
|
+
var ts = new linda.TupleSpace("calc");
|
66
|
+
|
67
|
+
// request
|
68
|
+
$("#btn_request").click(function(){
|
69
|
+
ts.write(["calc_request", "1-2+3*4"]);
|
70
|
+
});
|
71
|
+
|
72
|
+
// wait result
|
73
|
+
var take_result = function(){
|
74
|
+
ts.take(["calc_result"], function(tuple){
|
75
|
+
var result = tuple[1]; // from 'worker' side
|
76
|
+
console.log(result);
|
77
|
+
take_result(); // recursive call
|
78
|
+
});
|
79
|
+
};
|
80
|
+
io.on("connect", take_result); // RocketIO's "connect" event
|
81
|
+
```
|
82
|
+
|
83
|
+
worker side
|
84
|
+
|
85
|
+
```javascript
|
86
|
+
// create tuplespace
|
87
|
+
var ts = new linda.TupleSpace("calc");
|
88
|
+
|
89
|
+
// calculate
|
90
|
+
var calc = function(){
|
91
|
+
ts.take(["calc_request"], function(tuple){
|
92
|
+
var query = tuple[1]; // => "1-2+3*4"
|
93
|
+
var result = eval(query);
|
94
|
+
console.log(query+" = "+result); // => "1-2+3*4 = 11"
|
95
|
+
ts.write(["calc_result", result]); // return to 'client' side
|
96
|
+
calc(); // recursive call
|
97
|
+
});
|
98
|
+
};
|
99
|
+
io.on("connect", calc); // RocketIO's "connect" event
|
100
|
+
```
|
101
|
+
|
102
|
+
Test
|
103
|
+
----
|
104
|
+
|
105
|
+
% gem install bundler
|
106
|
+
% bundle install
|
107
|
+
% rake test
|
108
|
+
|
109
|
+
|
110
|
+
Contributing
|
111
|
+
------------
|
112
|
+
|
113
|
+
1. Fork it
|
114
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
115
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
116
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
117
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/lib/js/linda.js
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
var Linda = function(io, opts){
|
2
|
+
var self = this;
|
3
|
+
this.io = null;
|
4
|
+
if(io === null || typeof io === "undefined"){
|
5
|
+
this.io = new RocketIO().connect();
|
6
|
+
}
|
7
|
+
else{
|
8
|
+
this.io = io;
|
9
|
+
}
|
10
|
+
this.opts = opts || {};
|
11
|
+
this.TupleSpace = function(name){
|
12
|
+
if(name === null || typeof name !== "string") name = "__default__";
|
13
|
+
this.name = name;
|
14
|
+
this.linda = self;
|
15
|
+
var space = this;
|
16
|
+
this.write = function(tuple, opts){
|
17
|
+
if(tuple === null || typeof tuple !== "object") return;
|
18
|
+
if(opts === null || typeof opts === "undefined") opts = {};
|
19
|
+
self.io.push("__linda_write", [space.name, tuple, opts]);
|
20
|
+
};
|
21
|
+
this.read = function(tuple, callback){
|
22
|
+
if(tuple === null || typeof tuple !== "object") return;
|
23
|
+
if(typeof callback !== "function") return;
|
24
|
+
var callback_id = new Date()-0+"";
|
25
|
+
self.io.once("__linda_read_callback_"+callback_id, callback);
|
26
|
+
self.io.push("__linda_read", [space.name, tuple, callback_id]);
|
27
|
+
};
|
28
|
+
this.take = function(tuple, callback){
|
29
|
+
if(tuple === null || typeof tuple !== "object") return;
|
30
|
+
if(typeof callback !== "function") return;
|
31
|
+
var callback_id = new Date()-0+"";
|
32
|
+
self.io.once("__linda_take_callback_"+callback_id, callback);
|
33
|
+
self.io.push("__linda_take", [space.name, tuple, callback_id]);
|
34
|
+
};
|
35
|
+
};
|
36
|
+
};
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Sinatra
|
2
|
+
module RocketIO
|
3
|
+
module Linda
|
4
|
+
|
5
|
+
def self.registered(app)
|
6
|
+
app.helpers Sinatra::RocketIO::Linda::Helper
|
7
|
+
|
8
|
+
app.get '/rocketio/linda.js' do
|
9
|
+
content_type 'application/javascript'
|
10
|
+
@js ||= ERB.new(::Sinatra::RocketIO::Linda.javascript).result(binding)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Sinatra
|
2
|
+
module RocketIO
|
3
|
+
module Linda
|
4
|
+
|
5
|
+
def self.javascript(*js_file_names)
|
6
|
+
js_file_names = ['linda.js']
|
7
|
+
js = ''
|
8
|
+
js_file_names.each do |i|
|
9
|
+
File.open(File.expand_path "../js/#{i}", File.dirname(__FILE__)) do |f|
|
10
|
+
js += f.read+"\n"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
js
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module Sinatra
|
2
|
+
module RocketIO
|
3
|
+
module Linda
|
4
|
+
|
5
|
+
def self.tuplespaces
|
6
|
+
@@spaces ||= Hash.new{|h,k| h[k] = TupleSpace.new }
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.[](name)
|
10
|
+
self.tuplespaces[name]
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
Sinatra::RocketIO.on :start do
|
18
|
+
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
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
EventEmitter.apply Sinatra::RocketIO::Linda
|
26
|
+
|
27
|
+
Sinatra::RocketIO.on :__linda_write do |data, client|
|
28
|
+
space, tuple, opts = data
|
29
|
+
space = "__default__" if !space or !space.kind_of? String or space.empty?
|
30
|
+
unless [Hash, Array].include? tuple.class
|
31
|
+
Sinatra::RocketIO::Linda.emit :error, "received Tuple is not Hash or Array at :__linda_write"
|
32
|
+
next
|
33
|
+
end
|
34
|
+
unless opts.kind_of? Hash
|
35
|
+
opts = {}
|
36
|
+
else
|
37
|
+
opts_ = {}
|
38
|
+
opts.each do |k,v|
|
39
|
+
opts_[k.to_sym] = v
|
40
|
+
end
|
41
|
+
opts = opts_
|
42
|
+
end
|
43
|
+
Sinatra::RocketIO::Linda[space].write tuple, opts
|
44
|
+
end
|
45
|
+
|
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
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Sinatra
|
2
|
+
module RocketIO
|
3
|
+
module Linda
|
4
|
+
|
5
|
+
def linda=(options)
|
6
|
+
Linda.options = options
|
7
|
+
end
|
8
|
+
|
9
|
+
def linda
|
10
|
+
Linda.options
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.default_options
|
14
|
+
{
|
15
|
+
:expire_check => [60, lambda{|v| v.kind_of? Fixnum and v > 0 }]
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.options
|
20
|
+
@@options ||= (
|
21
|
+
opts = {}
|
22
|
+
default_options.each do |k,v|
|
23
|
+
opts[k] = v[0]
|
24
|
+
end
|
25
|
+
opts
|
26
|
+
)
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.options=(opts)
|
30
|
+
@@options = {}
|
31
|
+
opts.each do |k,v|
|
32
|
+
k = k.to_sym
|
33
|
+
unless default_options.include? k
|
34
|
+
STDERR.puts "!! Sinatra::RocketIO::Linda setting - \"#{k}\" is not valid key"
|
35
|
+
else
|
36
|
+
unless default_options[k][1].call(v)
|
37
|
+
default = default_options[k][0]
|
38
|
+
STDERR.puts "!! Sinatra::RocketIO::Linda setting - \"#{k} => #{v}\" is not valid. set default \"#{k} => #{default}\""
|
39
|
+
@@options[k] = default
|
40
|
+
else
|
41
|
+
@@options[k] = v
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
default_options.each do |k, v|
|
46
|
+
@@options[k] = v[0] unless @@options.include? k
|
47
|
+
end
|
48
|
+
@@options
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Sinatra
|
2
|
+
module RocketIO
|
3
|
+
module Linda
|
4
|
+
|
5
|
+
class Tuple
|
6
|
+
attr_reader :data, :type, :expire_at
|
7
|
+
def initialize(data, opts={})
|
8
|
+
unless [Array, Hash].include? data.class
|
9
|
+
raise ArgumentError, 'argument must be instance of Array or Hash'
|
10
|
+
end
|
11
|
+
@data = data
|
12
|
+
@type = data.class
|
13
|
+
@expire_at = Time.now+(opts[:expire] || 300)
|
14
|
+
end
|
15
|
+
|
16
|
+
def match?(target)
|
17
|
+
raise ArgumentError, 'argument must be instance of Tuple' unless target.kind_of? self.class
|
18
|
+
return false if @type != target.type
|
19
|
+
if @type == Array
|
20
|
+
return false if @data.length > target.data.length
|
21
|
+
@data.each_with_index do |v,i|
|
22
|
+
return false if target.data[i] != v
|
23
|
+
end
|
24
|
+
return true
|
25
|
+
elsif @type == Hash
|
26
|
+
@data.each do |k,v|
|
27
|
+
return false if target.data[k] != v
|
28
|
+
end
|
29
|
+
return true
|
30
|
+
end
|
31
|
+
false
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_s
|
35
|
+
@data.to_s
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
module Sinatra
|
2
|
+
module RocketIO
|
3
|
+
module Linda
|
4
|
+
|
5
|
+
class TupleSpace
|
6
|
+
include Enumerable
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@tuples = Array.new
|
10
|
+
@callbacks = Array.new
|
11
|
+
end
|
12
|
+
|
13
|
+
def each(&block)
|
14
|
+
@tuples.each do |tp|
|
15
|
+
yield tp
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def size
|
20
|
+
@tuples.size
|
21
|
+
end
|
22
|
+
|
23
|
+
DEFAULT_WRITE_OPTIONS = {
|
24
|
+
:expire => 300
|
25
|
+
}
|
26
|
+
|
27
|
+
def write(tuple, opts={})
|
28
|
+
raise ArgumentError, "options must be Hash" unless opts.kind_of? Hash
|
29
|
+
DEFAULT_WRITE_OPTIONS.each do |k,v|
|
30
|
+
opts[k] = v unless opts.include? k
|
31
|
+
end
|
32
|
+
tuple = Tuple.new tuple, opts unless tuple.kind_of? Tuple
|
33
|
+
calleds = []
|
34
|
+
taked = nil
|
35
|
+
@callbacks.each do |callback|
|
36
|
+
next unless callback[:tuple].match? tuple
|
37
|
+
callback[:callback].call tuple
|
38
|
+
calleds.push callback
|
39
|
+
if callback[:type] == :take
|
40
|
+
taked = tuple
|
41
|
+
break
|
42
|
+
end
|
43
|
+
end
|
44
|
+
calleds.each do |called|
|
45
|
+
@callbacks.delete called
|
46
|
+
end
|
47
|
+
@tuples.unshift tuple unless taked
|
48
|
+
tuple
|
49
|
+
end
|
50
|
+
|
51
|
+
def read(tuple, &block)
|
52
|
+
tuple = Tuple.new tuple unless tuple.kind_of? Tuple
|
53
|
+
@tuples.each do |t|
|
54
|
+
if tuple.match? t
|
55
|
+
if block_given?
|
56
|
+
block.call t
|
57
|
+
return
|
58
|
+
else
|
59
|
+
return t
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
@callbacks.push(:type => :read, :callback => block, :tuple => tuple) if block_given?
|
64
|
+
end
|
65
|
+
|
66
|
+
def take(tuple, &block)
|
67
|
+
tuple = Tuple.new tuple unless tuple.kind_of? Tuple
|
68
|
+
matched_tuple = nil
|
69
|
+
@tuples.each do |t|
|
70
|
+
if tuple.match? t
|
71
|
+
matched_tuple = t
|
72
|
+
break
|
73
|
+
end
|
74
|
+
end
|
75
|
+
if matched_tuple
|
76
|
+
@tuples.delete matched_tuple
|
77
|
+
if block_given?
|
78
|
+
block.call matched_tuple
|
79
|
+
else
|
80
|
+
return matched_tuple
|
81
|
+
end
|
82
|
+
else
|
83
|
+
@callbacks.push(:type => :take, :callback => block, :tuple => tuple) if block_given?
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def check_expire
|
88
|
+
expires = []
|
89
|
+
each do |tuple|
|
90
|
+
expires.push tuple unless tuple.expire_at > Time.now
|
91
|
+
end
|
92
|
+
expires.each do |tuple|
|
93
|
+
@tuples.delete tuple
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require "sinatra/rocketio/linda/version"
|
2
|
+
require "sinatra-rocketio-linda/helper"
|
3
|
+
require "sinatra-rocketio-linda/options"
|
4
|
+
require "sinatra-rocketio-linda/javascript"
|
5
|
+
require "sinatra-rocketio-linda/tuple"
|
6
|
+
require "sinatra-rocketio-linda/tuplespace"
|
7
|
+
require "sinatra-rocketio-linda/linda"
|
8
|
+
require "sinatra-rocketio-linda/application"
|
9
|
+
|
10
|
+
module Sinatra
|
11
|
+
module RocketIO
|
12
|
+
module Linda
|
13
|
+
end
|
14
|
+
end
|
15
|
+
register Sinatra::RocketIO::Linda
|
16
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'event_emitter'
|
2
|
+
require 'sinatra/rocketio/client'
|
3
|
+
|
4
|
+
module Sinatra
|
5
|
+
module RocketIO
|
6
|
+
module Linda
|
7
|
+
|
8
|
+
class Client
|
9
|
+
attr_reader :io, :tuplespace
|
10
|
+
def initialize(io)
|
11
|
+
if io.kind_of? String and io =~ /^https?:\/\/.+$/
|
12
|
+
@io = Sinatra::RocketIO::Client.new(io).connect
|
13
|
+
elsif io.kind_of? Sinatra::RocketIO::Client
|
14
|
+
@io = io
|
15
|
+
else
|
16
|
+
raise ArgumentError, "argument must be URL or RocketIO::Client"
|
17
|
+
end
|
18
|
+
@tuplespace = Hash.new{|h,k|
|
19
|
+
h[k] = Sinatra::RocketIO::Linda::Client::TupleSpace.new(k, self)
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
class TupleSpace
|
24
|
+
attr_reader :name, :linda
|
25
|
+
def initialize(name, linda)
|
26
|
+
@name = name
|
27
|
+
@linda = linda
|
28
|
+
end
|
29
|
+
|
30
|
+
def write(tuple, opts={})
|
31
|
+
unless [Hash, Array].include? tuple.class
|
32
|
+
raise ArgumentError, "tuple must be Array or Hash"
|
33
|
+
end
|
34
|
+
@linda.io.push "__linda_write", [@name, tuple, opts]
|
35
|
+
end
|
36
|
+
|
37
|
+
def read(tuple, &block)
|
38
|
+
unless [Hash, Array].include? tuple.class
|
39
|
+
raise ArgumentError, "tuple must be Array or Hash"
|
40
|
+
end
|
41
|
+
callback_id = "#{Time.now.to_i}#{Time.now.usec}"
|
42
|
+
@linda.io.once "__linda_read_callback_#{callback_id}", &block
|
43
|
+
@linda.io.push "__linda_read", [@name, tuple, callback_id]
|
44
|
+
end
|
45
|
+
|
46
|
+
def take(tuple, &block)
|
47
|
+
unless [Hash, Array].include? tuple.class
|
48
|
+
raise ArgumentError, "tuple must be Array or Hash"
|
49
|
+
end
|
50
|
+
callback_id = "#{Time.now.to_i}#{Time.now.usec}"
|
51
|
+
@linda.io.once "__linda_take_callback_#{callback_id}", &block
|
52
|
+
@linda.io.push "__linda_take", [@name, tuple, callback_id]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
$:.unshift File.expand_path '../../lib', File.dirname(__FILE__)
|
2
|
+
require 'rubygems'
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'sinatra/rocketio/linda/client'
|
5
|
+
|
6
|
+
linda = Sinatra::RocketIO::Linda::Client.new 'http://localhost:5000'
|
7
|
+
ts = linda.tuplespace["calc"]
|
8
|
+
|
9
|
+
calc = lambda{
|
10
|
+
ts.take ["calc_request"] do |tuple|
|
11
|
+
query = tuple[1]
|
12
|
+
result = eval(query)
|
13
|
+
puts "calc: #{query} = #{result}"
|
14
|
+
ts.write ["calc_result", result]
|
15
|
+
calc.call
|
16
|
+
end
|
17
|
+
}
|
18
|
+
|
19
|
+
linda.io.on :connect do
|
20
|
+
puts "connect #{io.session}"
|
21
|
+
calc.call
|
22
|
+
end
|
23
|
+
|
24
|
+
linda.io.on :disconnect do
|
25
|
+
puts "disconnect #{io.session}"
|
26
|
+
end
|
27
|
+
|
28
|
+
loop do
|
29
|
+
end
|
data/sample/config.ru
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
$:.unshift File.expand_path '../lib', File.dirname(__FILE__)
|
2
|
+
require 'rubygems'
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'thin'
|
5
|
+
require 'sinatra'
|
6
|
+
require 'sinatra/rocketio'
|
7
|
+
require 'sinatra/reloader' if development?
|
8
|
+
require 'sinatra/rocketio/linda'
|
9
|
+
require 'haml'
|
10
|
+
require File.expand_path 'main', File.dirname(__FILE__)
|
11
|
+
|
12
|
+
set :linda, :expire_check => 20
|
13
|
+
|
14
|
+
run Sinatra::Application
|
data/sample/main.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
io = Sinatra::RocketIO
|
2
|
+
linda = Sinatra::RocketIO::Linda
|
3
|
+
|
4
|
+
io.on :connect do |client|
|
5
|
+
puts "new client connect <#{client}>"
|
6
|
+
end
|
7
|
+
|
8
|
+
io.on :disconnect do |client|
|
9
|
+
puts "bye <#{client}>"
|
10
|
+
end
|
11
|
+
|
12
|
+
linda.on :error do |err|
|
13
|
+
STDERR.puts err
|
14
|
+
end
|
15
|
+
|
16
|
+
get '/' do
|
17
|
+
haml :index
|
18
|
+
end
|
19
|
+
|
20
|
+
get '/worker' do
|
21
|
+
haml :worker
|
22
|
+
end
|
23
|
+
|
24
|
+
get '/client' do
|
25
|
+
haml :client
|
26
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
var io = new RocketIO().connect();
|
2
|
+
var linda = new Linda(io);
|
3
|
+
var ts = new linda.TupleSpace("calc");
|
4
|
+
|
5
|
+
$(function(){
|
6
|
+
$("#btn_request").click(function(){
|
7
|
+
var query = $("#txt_request").val();
|
8
|
+
ts.write(["calc_request", query]);
|
9
|
+
});
|
10
|
+
});
|
11
|
+
|
12
|
+
var take_result = function(){
|
13
|
+
ts.take(["calc_result"], function(tuple){
|
14
|
+
var result = tuple[1];
|
15
|
+
$("#log").prepend( $("<p>").text(result) );
|
16
|
+
take_result();
|
17
|
+
});
|
18
|
+
};
|
19
|
+
|
20
|
+
io.on("connect", take_result);
|
@@ -0,0 +1,14 @@
|
|
1
|
+
var linda = new Linda();
|
2
|
+
var ts = new linda.TupleSpace("calc");
|
3
|
+
|
4
|
+
var calc = function(){
|
5
|
+
ts.take(["calc_request"], function(tuple){
|
6
|
+
var query = tuple[1];
|
7
|
+
var result = eval(query);
|
8
|
+
$("#log").prepend( $("<p>").text(query+" = "+result).prepend("calc: ") );
|
9
|
+
ts.write(["calc_result", result]);
|
10
|
+
calc();
|
11
|
+
});
|
12
|
+
};
|
13
|
+
|
14
|
+
linda.io.on("connect", calc);
|
@@ -0,0 +1,16 @@
|
|
1
|
+
!!!XHTML
|
2
|
+
%html
|
3
|
+
%head
|
4
|
+
%meta{'http-equiv' => 'Content-Type', :content => 'text/html', :charset => 'UTF-8'}
|
5
|
+
%title Linda Client on RocketIO
|
6
|
+
%script{:src => "//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"}
|
7
|
+
%script{:src => rocketio_js}
|
8
|
+
%script{:src => linda_js}
|
9
|
+
%script{:src => "/client.js"}
|
10
|
+
%body
|
11
|
+
%h1 Calc Client
|
12
|
+
%div#main
|
13
|
+
%div#calc
|
14
|
+
%input#txt_request{:type => :text, :value => "1+2*3*4-5"}
|
15
|
+
%input#btn_request{:type => :button, :value => "request!"}
|
16
|
+
%div#log
|
@@ -0,0 +1,12 @@
|
|
1
|
+
!!!XHTML
|
2
|
+
%html
|
3
|
+
%head
|
4
|
+
%meta{'http-equiv' => 'Content-Type', :content => 'text/html', :charset => 'UTF-8'}
|
5
|
+
%title Linda on RocketIO
|
6
|
+
%body
|
7
|
+
%h1 Linda on RocketIO
|
8
|
+
%ul
|
9
|
+
%li
|
10
|
+
%a{:href => "/worker"} calc worker
|
11
|
+
%li
|
12
|
+
%a{:href => "/client"} calc client
|
@@ -0,0 +1,13 @@
|
|
1
|
+
!!!XHTML
|
2
|
+
%html
|
3
|
+
%head
|
4
|
+
%meta{'http-equiv' => 'Content-Type', :content => 'text/html', :charset => 'UTF-8'}
|
5
|
+
%title Linda Worker on RocketIO
|
6
|
+
%script{:src => "//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"}
|
7
|
+
%script{:src => rocketio_js}
|
8
|
+
%script{:src => linda_js}
|
9
|
+
%script{:src => "/worker.js"}
|
10
|
+
%body
|
11
|
+
%h1 Calc Worker
|
12
|
+
%div#main
|
13
|
+
%div#log
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'sinatra/rocketio/linda/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "sinatra-rocketio-linda"
|
8
|
+
spec.version = Sinatra::RocketIO::Linda::VERSION
|
9
|
+
spec.authors = ["Sho Hashimoto"]
|
10
|
+
spec.email = ["hashimoto@shokai.org"]
|
11
|
+
spec.description = %q{Linda implementation on Sinatra RocketIO}
|
12
|
+
spec.summary = spec.description
|
13
|
+
spec.homepage = "https://github.com/shokai/sinatra-rocketio-linda"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/).reject{|i| i == "Gemfile.lock" }
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_development_dependency "minitest"
|
24
|
+
spec.add_development_dependency "thin"
|
25
|
+
spec.add_development_dependency "haml"
|
26
|
+
|
27
|
+
spec.add_dependency "sinatra-rocketio"
|
28
|
+
spec.add_dependency "event_emitter"
|
29
|
+
spec.add_dependency "sinatra"
|
30
|
+
end
|
data/test/test_helper.rb
ADDED
data/test/test_tuple.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require File.expand_path 'test_helper', File.dirname(__FILE__)
|
2
|
+
require 'sinatra-rocketio-linda/tuple'
|
3
|
+
|
4
|
+
class TestTuple < MiniTest::Test
|
5
|
+
def test_match_array
|
6
|
+
tuple = Sinatra::RocketIO::Linda::Tuple.new [1,2,3]
|
7
|
+
assert tuple.match? Sinatra::RocketIO::Linda::Tuple.new [1,2,3]
|
8
|
+
assert tuple.match? Sinatra::RocketIO::Linda::Tuple.new [1,2,3,4]
|
9
|
+
assert !tuple.match?(Sinatra::RocketIO::Linda::Tuple.new [1,2])
|
10
|
+
assert !tuple.match?(Sinatra::RocketIO::Linda::Tuple.new [1,"a",3])
|
11
|
+
assert !tuple.match?(Sinatra::RocketIO::Linda::Tuple.new :a => 1, :b => 2)
|
12
|
+
tuple = Sinatra::RocketIO::Linda::Tuple.new ["a","b","c"]
|
13
|
+
assert tuple.match? Sinatra::RocketIO::Linda::Tuple.new ["a","b","c"]
|
14
|
+
assert tuple.match? Sinatra::RocketIO::Linda::Tuple.new ["a","b","c","d","efg",123,"h"]
|
15
|
+
assert !tuple.match?(Sinatra::RocketIO::Linda::Tuple.new ["a","b"])
|
16
|
+
assert !tuple.match?(Sinatra::RocketIO::Linda::Tuple.new ["a","b",789])
|
17
|
+
assert !tuple.match?(Sinatra::RocketIO::Linda::Tuple.new :foo => 1, :bar => 2)
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_match_hash
|
21
|
+
tuple = Sinatra::RocketIO::Linda::Tuple.new :a => 1, :b => 2
|
22
|
+
assert tuple.match? Sinatra::RocketIO::Linda::Tuple.new :a => 1, :b => 2
|
23
|
+
assert tuple.match? Sinatra::RocketIO::Linda::Tuple.new :a => 1, :b => 2, :c => 3
|
24
|
+
assert tuple.match? Sinatra::RocketIO::Linda::Tuple.new :a => 1, :b => 2, :c => {:foo => "bar"}
|
25
|
+
assert !tuple.match?(Sinatra::RocketIO::Linda::Tuple.new :a => 0, :b => 2)
|
26
|
+
assert !tuple.match?(Sinatra::RocketIO::Linda::Tuple.new :b => 2, :c => 3)
|
27
|
+
assert !tuple.match?(Sinatra::RocketIO::Linda::Tuple.new [1,2,3])
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
require File.expand_path 'test_helper', File.dirname(__FILE__)
|
2
|
+
require 'sinatra-rocketio-linda/tuple'
|
3
|
+
require 'sinatra-rocketio-linda/tuplespace'
|
4
|
+
|
5
|
+
class TestTupleSpace < MiniTest::Test
|
6
|
+
|
7
|
+
def setup
|
8
|
+
@space = Sinatra::RocketIO::Linda::TupleSpace.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_write_read
|
12
|
+
assert_equal @space.size, 0
|
13
|
+
@space.write Sinatra::RocketIO::Linda::Tuple.new [1,2,3]
|
14
|
+
assert_equal @space.size, 1
|
15
|
+
assert_equal @space.read([1,2]).data, [1,2,3]
|
16
|
+
@space.write :a => 1, :b => 2, :c => 999
|
17
|
+
@space.write :a => 1, :b => 2, :c => 3
|
18
|
+
assert_equal @space.size, 3
|
19
|
+
assert_equal @space.read(:a => 1, :c => 999).data, {:a => 1, :b => 2, :c => 999}
|
20
|
+
assert_equal @space.read(:a => 1, :c => 999).data, {:a => 1, :b => 2, :c => 999}
|
21
|
+
assert_equal @space.read(:a => 1).data, {:a => 1, :b => 2, :c => 3}
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_write_read_callback
|
25
|
+
assert_equal @space.size, 0
|
26
|
+
_tuple1 = nil
|
27
|
+
@space.read [1,2] do |tuple|
|
28
|
+
_tuple1 = tuple
|
29
|
+
end
|
30
|
+
_tuple2 = nil
|
31
|
+
@space.read [1,"a"] do |tuple|
|
32
|
+
_tuple2 = tuple
|
33
|
+
end
|
34
|
+
_tuple3 = nil
|
35
|
+
@space.read [1,2,3] do |tuple|
|
36
|
+
_tuple3 = tuple
|
37
|
+
end
|
38
|
+
@space.write [1,2,3]
|
39
|
+
assert_equal _tuple1.data, [1,2,3]
|
40
|
+
assert_equal _tuple2, nil
|
41
|
+
assert_equal _tuple3.data, [1,2,3]
|
42
|
+
assert_equal @space.read([1]).data, [1,2,3]
|
43
|
+
assert_equal @space.size, 1
|
44
|
+
@space.write [1,2,4]
|
45
|
+
assert_equal _tuple1.data, [1,2,3]
|
46
|
+
assert_equal @space.size, 2
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_take
|
50
|
+
assert_equal @space.size, 0
|
51
|
+
1.upto(3) do |i|
|
52
|
+
@space.write [1,2,3,"a"*i]
|
53
|
+
end
|
54
|
+
assert_equal @space.size, 3
|
55
|
+
assert_equal @space.take([1,2,3]).data, [1,2,3,"aaa"]
|
56
|
+
assert_equal @space.size, 2
|
57
|
+
@space.write :a => 1, :b => 2, :c => 3
|
58
|
+
assert_equal @space.size, 3
|
59
|
+
assert_equal @space.take([1,3]), nil
|
60
|
+
assert_equal @space.take(:a => 1, :b => 2, :c => 4), nil
|
61
|
+
assert_equal @space.take([1,2,3]).data, [1,2,3,"aa"]
|
62
|
+
assert_equal @space.size, 2
|
63
|
+
assert_equal @space.take([1,2,3]).data, [1,2,3,"a"]
|
64
|
+
assert_equal @space.size, 1
|
65
|
+
assert_equal @space.take(:b => 2, :a => 1).data, {:a => 1, :b => 2, :c => 3}
|
66
|
+
assert_equal @space.size, 0
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_take_callback
|
70
|
+
assert_equal @space.size, 0
|
71
|
+
_tuple1 = nil
|
72
|
+
@space.take [1,2] do |tuple|
|
73
|
+
_tuple1 = tuple
|
74
|
+
end
|
75
|
+
_tuple2 = nil
|
76
|
+
@space.take [1,"a"] do |tuple|
|
77
|
+
_tuple2 = tuple
|
78
|
+
end
|
79
|
+
_tuple3 = nil
|
80
|
+
@space.read [1,2,3] do |tuple|
|
81
|
+
_tuple3 = tuple
|
82
|
+
end
|
83
|
+
_tuple4 = nil
|
84
|
+
@space.take [1,2,3] do |tuple|
|
85
|
+
_tuple4 = tuple
|
86
|
+
end
|
87
|
+
1.upto(3) do |i|
|
88
|
+
@space.write [1,2,3,"a"*i]
|
89
|
+
end
|
90
|
+
assert_equal @space.size, 1
|
91
|
+
assert_equal _tuple1.data, [1,2,3,"a"]
|
92
|
+
assert_equal _tuple2, nil
|
93
|
+
assert_equal _tuple3.data, [1,2,3,"aa"]
|
94
|
+
assert_equal _tuple4.data, [1,2,3,"aa"]
|
95
|
+
assert_equal @space.take([1]).data, [1,2,3,"aaa"]
|
96
|
+
assert_equal @space.size, 0
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_tuple_expire
|
100
|
+
@space.write [1,2,3], :expire => 3
|
101
|
+
@space.write [1,2,"a","b"], :expire => 2
|
102
|
+
assert_equal @space.size, 2
|
103
|
+
sleep 2
|
104
|
+
@space.check_expire
|
105
|
+
assert_equal @space.size, 1
|
106
|
+
assert_equal @space.take([1,2]).data, [1,2,3]
|
107
|
+
assert_equal @space.size, 0
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
metadata
ADDED
@@ -0,0 +1,188 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sinatra-rocketio-linda
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Sho Hashimoto
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-05-14 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: thin
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: haml
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: sinatra-rocketio
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: event_emitter
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - '>='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - '>='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: sinatra
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - '>='
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
description: Linda implementation on Sinatra RocketIO
|
126
|
+
email:
|
127
|
+
- hashimoto@shokai.org
|
128
|
+
executables: []
|
129
|
+
extensions: []
|
130
|
+
extra_rdoc_files: []
|
131
|
+
files:
|
132
|
+
- .gitignore
|
133
|
+
- Gemfile
|
134
|
+
- History.txt
|
135
|
+
- LICENSE.txt
|
136
|
+
- README.md
|
137
|
+
- Rakefile
|
138
|
+
- lib/js/linda.js
|
139
|
+
- lib/sinatra-rocketio-linda/application.rb
|
140
|
+
- lib/sinatra-rocketio-linda/helper.rb
|
141
|
+
- lib/sinatra-rocketio-linda/javascript.rb
|
142
|
+
- lib/sinatra-rocketio-linda/linda.rb
|
143
|
+
- lib/sinatra-rocketio-linda/options.rb
|
144
|
+
- lib/sinatra-rocketio-linda/tuple.rb
|
145
|
+
- lib/sinatra-rocketio-linda/tuplespace.rb
|
146
|
+
- lib/sinatra/rocketio/linda.rb
|
147
|
+
- lib/sinatra/rocketio/linda/client.rb
|
148
|
+
- lib/sinatra/rocketio/linda/version.rb
|
149
|
+
- sample/bin/cui_calc_worker.rb
|
150
|
+
- sample/config.ru
|
151
|
+
- sample/main.rb
|
152
|
+
- sample/public/client.js
|
153
|
+
- sample/public/worker.js
|
154
|
+
- sample/views/client.haml
|
155
|
+
- sample/views/index.haml
|
156
|
+
- sample/views/worker.haml
|
157
|
+
- sinatra-rocketio-linda.gemspec
|
158
|
+
- test/test_helper.rb
|
159
|
+
- test/test_tuple.rb
|
160
|
+
- test/test_tuplespace.rb
|
161
|
+
homepage: https://github.com/shokai/sinatra-rocketio-linda
|
162
|
+
licenses:
|
163
|
+
- MIT
|
164
|
+
metadata: {}
|
165
|
+
post_install_message:
|
166
|
+
rdoc_options: []
|
167
|
+
require_paths:
|
168
|
+
- lib
|
169
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - '>='
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
175
|
+
requirements:
|
176
|
+
- - '>='
|
177
|
+
- !ruby/object:Gem::Version
|
178
|
+
version: '0'
|
179
|
+
requirements: []
|
180
|
+
rubyforge_project:
|
181
|
+
rubygems_version: 2.0.3
|
182
|
+
signing_key:
|
183
|
+
specification_version: 4
|
184
|
+
summary: Linda implementation on Sinatra RocketIO
|
185
|
+
test_files:
|
186
|
+
- test/test_helper.rb
|
187
|
+
- test/test_tuple.rb
|
188
|
+
- test/test_tuplespace.rb
|