sinatra-rocketio-linda 1.0.1 → 1.1.0

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: 752b7b4286062e3c40cde9d2cb674913f92bf53e
4
- data.tar.gz: 16a0d15fc5000e97496e0a4c00f05e13cff15f7e
3
+ metadata.gz: 8b3e2b41086de9ae86e9cf3e01ea0f11f010cd3b
4
+ data.tar.gz: 5efc1e0cc59105bfeca9c10ce0d93369bbf184bc
5
5
  SHA512:
6
- metadata.gz: 72ad4d745e035bbcf001f55598a06e1daa0977df740d3ff5de6cda7a9042d6965dee4f25ea62a9caf36934872d0f4c40aa780306fec1b32ccb66cc01cfdc150e
7
- data.tar.gz: 71ad4cf606b6b3652ab572dd8474038bb9456237583094adc46368edff0474a866d16c561e8451293fd470aa6fa8558bbaa11684b2887610fbb06876dd88872b
6
+ metadata.gz: 603f3e6e6a7af503f587918d753d9884c899b5abdb9aabb75685e9f69b794cb39617b859b67c1a82ac7f6d34cd903b4748779733cae497e6a3ba863b337a769e
7
+ data.tar.gz: 15e28c9d82a3876c3067e15f230c31ed2630858ebfb028b1ce7a19e602070f4d9abfeafdec68e1351f3a000e336e1c7fb6818f0daf1fa86ba69a2c2f107f4ba0
@@ -1,3 +1,7 @@
1
+ === 1.1.0 2013-11-19
2
+
3
+ * add function Sinatra::RocketIO::Linda::TupleSpace#list
4
+
1
5
  === 1.0.1 2013-10-10
2
6
 
3
7
  * bugfix Sinatar::RocketIO::Linda::TupleSpace#write
@@ -48,5 +48,14 @@ var Linda = function(io, opts){
48
48
  });
49
49
  self.io.push("__linda_watch", [space.name, tuple, callback_id]);
50
50
  };
51
+ this.list = function(tuple, callback){
52
+ if(tuple === null || typeof tuple !== "object") return;
53
+ if(typeof callback !== "function") return;
54
+ var callback_id = make_callback_id();
55
+ self.io.on("__linda_list_callback_"+callback_id, function(list){
56
+ callback(list);
57
+ });
58
+ self.io.push("__linda_list", [space.name, tuple, callback_id]);
59
+ }
51
60
  };
52
61
  };
@@ -75,6 +75,17 @@ end
75
75
  end
76
76
  end
77
77
 
78
+ Sinatra::RocketIO.on :__linda_list 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_list"
83
+ next
84
+ end
85
+ list = Sinatra::RocketIO::Linda[space].list tuple
86
+ Sinatra::RocketIO.push "__linda_list_callback_#{callback}", list
87
+ end
88
+
78
89
  Sinatra::RocketIO.on :disconnect do |client|
79
90
  Sinatra::RocketIO::Linda.callbacks[client.session].each do |i|
80
91
  Sinatra::RocketIO::Linda[i[:space]].cancel i[:callback]
@@ -85,6 +85,19 @@ module Sinatra
85
85
  @linda.io.push "__linda_watch", [@name, tuple, callback_id]
86
86
  end
87
87
 
88
+ def list(tuple, &block)
89
+ unless [Hash, Array].include? tuple.class
90
+ raise ArgumentError, "tuple must be Array or Hash"
91
+ end
92
+ callback_id = create_callback_id
93
+ if block_given?
94
+ @linda.io.once "__linda_list_callback_#{callback_id}" do |data|
95
+ block.call data
96
+ end
97
+ @linda.io.push "__linda_list", [@name, tuple, callback_id]
98
+ end
99
+ end
100
+
88
101
  private
89
102
  def create_callback_id
90
103
  "#{Time.now.to_i}#{Time.now.usec}_#{(rand*1000000).to_i}"
@@ -1,7 +1,7 @@
1
1
  module Sinatra
2
2
  module RocketIO
3
3
  module Linda
4
- VERSION = "1.0.1"
4
+ VERSION = "1.1.0"
5
5
  end
6
6
  end
7
7
  end
data/linda.js CHANGED
@@ -1,4 +1,4 @@
1
- // Linda.js v1.0.1 (rocketio v0.3.3)
1
+ // Linda.js v1.1.0 (rocketio v0.3.3)
2
2
  // https://github.com/shokai/sinatra-rocketio-linda
3
3
  // (c) 2013 Sho Hashimoto <hashimoto@shokai.org>
4
4
  // The MIT License
@@ -52,6 +52,15 @@ var Linda = function(io, opts){
52
52
  });
53
53
  self.io.push("__linda_watch", [space.name, tuple, callback_id]);
54
54
  };
55
+ this.list = function(tuple, callback){
56
+ if(tuple === null || typeof tuple !== "object") return;
57
+ if(typeof callback !== "function") return;
58
+ var callback_id = make_callback_id();
59
+ self.io.on("__linda_list_callback_"+callback_id, function(list){
60
+ callback(list);
61
+ });
62
+ self.io.push("__linda_list", [space.name, tuple, callback_id]);
63
+ }
55
64
  };
56
65
  };
57
66
 
@@ -1,5 +1,5 @@
1
- // Linda.js v1.0.1 (rocketio v0.3.3)
1
+ // Linda.js v1.1.0 (rocketio v0.3.3)
2
2
  // https://github.com/shokai/sinatra-rocketio-linda
3
3
  // (c) 2013 Sho Hashimoto <hashimoto@shokai.org>
4
4
  // The MIT License
5
- var Linda=function(io,opts){var self=this;this.io=null;if(io===null||typeof io==="undefined"){this.io=(new RocketIO).connect()}else{this.io=io}this.opts=opts||{};this.TupleSpace=function(name){if(name===null||typeof name!=="string")name="__default__";this.name=name;this.linda=self;var space=this;var make_callback_id=function(){return new Date-0+"_"+Math.floor(Math.random()*1e6)};this.write=function(tuple,opts){if(tuple===null||typeof tuple!=="object")return;if(opts===null||typeof opts==="undefined")opts={};self.io.push("__linda_write",[space.name,tuple,opts])};this.read=function(tuple,callback){if(tuple===null||typeof tuple!=="object")return;if(typeof callback!=="function")return;var callback_id=make_callback_id();self.io.once("__linda_read_callback_"+callback_id,function(data){callback(data.tuple,data.info)});self.io.push("__linda_read",[space.name,tuple,callback_id])};this.take=function(tuple,callback){if(tuple===null||typeof tuple!=="object")return;if(typeof callback!=="function")return;var callback_id=make_callback_id();self.io.once("__linda_take_callback_"+callback_id,function(data){callback(data.tuple,data.info)});self.io.push("__linda_take",[space.name,tuple,callback_id])};this.watch=function(tuple,callback){if(tuple===null||typeof tuple!=="object")return;if(typeof callback!=="function")return;var callback_id=make_callback_id();self.io.on("__linda_watch_callback_"+callback_id,function(data){callback(data.tuple,data.info)});self.io.push("__linda_watch",[space.name,tuple,callback_id])}}};var RocketIO=function(opts){(new EventEmitter).apply(this);if(typeof opts==="undefined"||opts===null)opts={};this.type=opts.type||null;this.session=opts.session||null;this.channel=null;if(typeof opts.channel!=="undefined"&&opts.channel!==null){this.channel=""+opts.channel}var setting={};this.io=null;var self=this;var ws_close_timer=null;self.on("__connect",function(session_id){self.session=session_id;self.io.push("__channel_id",self.channel);self.emit("connect")});this.connect=function(url){if(typeof url==="string"){$.getJSON(url+"/rocketio/settings",function(res){setting=res;connect_io()});return self}else{return connect_io()}};var connect_io=function(){self.io=function(){if(self.type==="comet")return;if(typeof WebSocketIO!=="function")return;var io=new WebSocketIO;if(typeof setting.websocket==="string")io.url=setting.websocket;io.session=self.session;return io.connect()}()||function(){if(typeof CometIO!=="function")return;var io=new CometIO;if(typeof setting.comet==="string")io.url=setting.comet;io.session=self.session;return io.connect()}();if(typeof self.io==="undefined"){setTimeout(function(){self.emit("error","WebSocketIO and CometIO are not available")},100);return self}if(self.io.url.match(/^ws:\/\/.+/))self.type="websocket";else if(self.io.url.match(/cometio/))self.type="comet";else self.type="unknown";self.io.on("*",function(event_name,args){if(event_name==="connect")event_name="__connect";self.emit(event_name,args)});ws_close_timer=setTimeout(function(){self.close();self.type="comet";connect_io()},3e3);self.once("connect",function(){if(ws_close_timer)clearTimeout(ws_close_timer);ws_close_timer=null});return self};this.close=function(){self.io.close()};this.push=function(type,data){self.io.push(type,data)}};var CometIO=function(url,opts){(new EventEmitter).apply(this);if(typeof opts==="undefined"||opts===null)opts={};this.url=url||"";this.session=opts.session||null;var running=false;var self=this;var post_queue=[];var flush=function(){if(!running||post_queue.length<1)return;var post_data={json:JSON.stringify({session:self.session,events:post_queue})};$.ajax({url:self.url,data:post_data,success:function(data){},error:function(req,stat,e){self.emit("error","CometIO push error")},complete:function(e){},type:"POST",dataType:"json",timeout:1e4});post_queue=[]};setInterval(flush,1e3);this.push=function(type,data){if(!running||!self.session){self.emit("error","CometIO not connected");return}post_queue.push({type:type,data:data})};this.connect=function(){if(running)return self;self.on("__session_id",function(session){self.session=session;self.emit("connect",self.session)});running=true;get();return self};this.close=function(){running=false;self.removeListener("__session_id")};var get=function(){if(!running)return;$.ajax({url:self.url+"?"+(new Date-0),data:{session:self.session},success:function(data_arr){if(data_arr!==null&&typeof data_arr=="object"&&!!data_arr.length){for(var i=0;i<data_arr.length;i++){var data=data_arr[i];if(data)self.emit(data.type,data.data)}}get()},error:function(req,stat,e){self.emit("error","CometIO get error");setTimeout(get,1e4)},complete:function(e){},type:"GET",dataType:"json",timeout:13e4})}};var WebSocketIO=function(url,opts){(new EventEmitter).apply(this);if(typeof opts==="undefined"||opts===null)opts={};this.url=url||"";this.session=opts.session||null;this.websocket=null;this.connecting=false;var reconnect_timer_id=null;var running=false;var self=this;self.on("__session_id",function(session_id){self.session=session_id;self.emit("connect",self.session)});this.connect=function(){if(typeof WebSocket==="undefined"){self.emit("error","websocket not exists in this browser");return null}self.running=true;var url=self.session?self.url+"/session="+self.session:self.url;self.websocket=new WebSocket(url);self.websocket.onmessage=function(e){var data_=null;try{data_=JSON.parse(e.data)}catch(e){self.emit("error","WebSocketIO data parse error")}if(!!data_)self.emit(data_.type,data_.data)};self.websocket.onclose=function(){if(self.connecting){self.connecting=false;self.emit("disconnect")}if(self.running){reconnect_timer_id=setTimeout(self.connect,1e4)}};self.websocket.onopen=function(){self.connecting=true};return self};this.close=function(){clearTimeout(reconnect_timer_id);self.running=false;self.websocket.close()};this.push=function(type,data){if(!self.connecting){self.emit("error","websocket not connected");return}self.websocket.send(JSON.stringify({type:type,data:data,session:self.session}))}};var EventEmitter=function(){var self=this;this.apply=function(target,prefix){if(!prefix)prefix="";for(var func in self){if(self.hasOwnProperty(func)&&func!=="apply"){target[prefix+func]=this[func]}}};this.__events=new Array;this.on=function(type,listener,opts){if(typeof listener!=="function")return;var event_id=self.__events.length>0?1+self.__events[self.__events.length-1].id:0;var params={id:event_id,type:type,listener:listener};for(i in opts){if(!params[i])params[i]=opts[i]}self.__events.push(params);return event_id};this.once=function(type,listener){self.on(type,listener,{once:true})};this.emit=function(type,data){for(var i=0;i<self.__events.length;i++){var e=self.__events[i];switch(e.type){case type:e.listener(data);if(e.once)e.type=null;break;case"*":e.listener(type,data);if(e.once)e.type=null;break}}self.removeListener()};this.removeListener=function(id_or_type){for(var i=self.__events.length-1;i>=0;i--){var e=self.__events[i];switch(typeof id_or_type){case"number":if(e.id===id_or_type)self.__events.splice(i,1);break;case"string":case"object":if(e.type===id_or_type)self.__events.splice(i,1);break}}}};if(typeof module!=="undefined"&&typeof module.exports!=="undefined"){module.exports=EventEmitter}
5
+ var Linda=function(io,opts){var self=this;this.io=null;if(io===null||typeof io==="undefined"){this.io=(new RocketIO).connect()}else{this.io=io}this.opts=opts||{};this.TupleSpace=function(name){if(name===null||typeof name!=="string")name="__default__";this.name=name;this.linda=self;var space=this;var make_callback_id=function(){return new Date-0+"_"+Math.floor(Math.random()*1e6)};this.write=function(tuple,opts){if(tuple===null||typeof tuple!=="object")return;if(opts===null||typeof opts==="undefined")opts={};self.io.push("__linda_write",[space.name,tuple,opts])};this.read=function(tuple,callback){if(tuple===null||typeof tuple!=="object")return;if(typeof callback!=="function")return;var callback_id=make_callback_id();self.io.once("__linda_read_callback_"+callback_id,function(data){callback(data.tuple,data.info)});self.io.push("__linda_read",[space.name,tuple,callback_id])};this.take=function(tuple,callback){if(tuple===null||typeof tuple!=="object")return;if(typeof callback!=="function")return;var callback_id=make_callback_id();self.io.once("__linda_take_callback_"+callback_id,function(data){callback(data.tuple,data.info)});self.io.push("__linda_take",[space.name,tuple,callback_id])};this.watch=function(tuple,callback){if(tuple===null||typeof tuple!=="object")return;if(typeof callback!=="function")return;var callback_id=make_callback_id();self.io.on("__linda_watch_callback_"+callback_id,function(data){callback(data.tuple,data.info)});self.io.push("__linda_watch",[space.name,tuple,callback_id])};this.list=function(tuple,callback){if(tuple===null||typeof tuple!=="object")return;if(typeof callback!=="function")return;var callback_id=make_callback_id();self.io.on("__linda_list_callback_"+callback_id,function(list){callback(list)});self.io.push("__linda_list",[space.name,tuple,callback_id])}}};var RocketIO=function(opts){(new EventEmitter).apply(this);if(typeof opts==="undefined"||opts===null)opts={};this.type=opts.type||null;this.session=opts.session||null;this.channel=null;if(typeof opts.channel!=="undefined"&&opts.channel!==null){this.channel=""+opts.channel}var setting={};this.io=null;var self=this;var ws_close_timer=null;self.on("__connect",function(session_id){self.session=session_id;self.io.push("__channel_id",self.channel);self.emit("connect")});this.connect=function(url){if(typeof url==="string"){$.getJSON(url+"/rocketio/settings",function(res){setting=res;connect_io()});return self}else{return connect_io()}};var connect_io=function(){self.io=function(){if(self.type==="comet")return;if(typeof WebSocketIO!=="function")return;var io=new WebSocketIO;if(typeof setting.websocket==="string")io.url=setting.websocket;io.session=self.session;return io.connect()}()||function(){if(typeof CometIO!=="function")return;var io=new CometIO;if(typeof setting.comet==="string")io.url=setting.comet;io.session=self.session;return io.connect()}();if(typeof self.io==="undefined"){setTimeout(function(){self.emit("error","WebSocketIO and CometIO are not available")},100);return self}if(self.io.url.match(/^ws:\/\/.+/))self.type="websocket";else if(self.io.url.match(/cometio/))self.type="comet";else self.type="unknown";self.io.on("*",function(event_name,args){if(event_name==="connect")event_name="__connect";self.emit(event_name,args)});ws_close_timer=setTimeout(function(){self.close();self.type="comet";connect_io()},3e3);self.once("connect",function(){if(ws_close_timer)clearTimeout(ws_close_timer);ws_close_timer=null});return self};this.close=function(){self.io.close()};this.push=function(type,data){self.io.push(type,data)}};var CometIO=function(url,opts){(new EventEmitter).apply(this);if(typeof opts==="undefined"||opts===null)opts={};this.url=url||"";this.session=opts.session||null;var running=false;var self=this;var post_queue=[];var flush=function(){if(!running||post_queue.length<1)return;var post_data={json:JSON.stringify({session:self.session,events:post_queue})};$.ajax({url:self.url,data:post_data,success:function(data){},error:function(req,stat,e){self.emit("error","CometIO push error")},complete:function(e){},type:"POST",dataType:"json",timeout:1e4});post_queue=[]};setInterval(flush,1e3);this.push=function(type,data){if(!running||!self.session){self.emit("error","CometIO not connected");return}post_queue.push({type:type,data:data})};this.connect=function(){if(running)return self;self.on("__session_id",function(session){self.session=session;self.emit("connect",self.session)});running=true;get();return self};this.close=function(){running=false;self.removeListener("__session_id")};var get=function(){if(!running)return;$.ajax({url:self.url+"?"+(new Date-0),data:{session:self.session},success:function(data_arr){if(data_arr!==null&&typeof data_arr=="object"&&!!data_arr.length){for(var i=0;i<data_arr.length;i++){var data=data_arr[i];if(data)self.emit(data.type,data.data)}}get()},error:function(req,stat,e){self.emit("error","CometIO get error");setTimeout(get,1e4)},complete:function(e){},type:"GET",dataType:"json",timeout:13e4})}};var WebSocketIO=function(url,opts){(new EventEmitter).apply(this);if(typeof opts==="undefined"||opts===null)opts={};this.url=url||"";this.session=opts.session||null;this.websocket=null;this.connecting=false;var reconnect_timer_id=null;var running=false;var self=this;self.on("__session_id",function(session_id){self.session=session_id;self.emit("connect",self.session)});this.connect=function(){if(typeof WebSocket==="undefined"){self.emit("error","websocket not exists in this browser");return null}self.running=true;var url=self.session?self.url+"/session="+self.session:self.url;self.websocket=new WebSocket(url);self.websocket.onmessage=function(e){var data_=null;try{data_=JSON.parse(e.data)}catch(e){self.emit("error","WebSocketIO data parse error")}if(!!data_)self.emit(data_.type,data_.data)};self.websocket.onclose=function(){if(self.connecting){self.connecting=false;self.emit("disconnect")}if(self.running){reconnect_timer_id=setTimeout(self.connect,1e4)}};self.websocket.onopen=function(){self.connecting=true};return self};this.close=function(){clearTimeout(reconnect_timer_id);self.running=false;self.websocket.close()};this.push=function(type,data){if(!self.connecting){self.emit("error","websocket not connected");return}self.websocket.send(JSON.stringify({type:type,data:data,session:self.session}))}};var EventEmitter=function(){var self=this;this.apply=function(target,prefix){if(!prefix)prefix="";for(var func in self){if(self.hasOwnProperty(func)&&func!=="apply"){target[prefix+func]=this[func]}}};this.__events=new Array;this.on=function(type,listener,opts){if(typeof listener!=="function")return;var event_id=self.__events.length>0?1+self.__events[self.__events.length-1].id:0;var params={id:event_id,type:type,listener:listener};for(i in opts){if(!params[i])params[i]=opts[i]}self.__events.push(params);return event_id};this.once=function(type,listener){self.on(type,listener,{once:true})};this.emit=function(type,data){for(var i=0;i<self.__events.length;i++){var e=self.__events[i];switch(e.type){case type:e.listener(data);if(e.once)e.type=null;break;case"*":e.listener(type,data);if(e.once)e.type=null;break}}self.removeListener()};this.removeListener=function(id_or_type){for(var i=self.__events.length-1;i>=0;i--){var e=self.__events[i];switch(typeof id_or_type){case"number":if(e.id===id_or_type)self.__events.splice(i,1);break;case"string":case"object":if(e.type===id_or_type)self.__events.splice(i,1);break}}}};if(typeof module!=="undefined"&&typeof module.exports!=="undefined"){module.exports=EventEmitter}
@@ -17,6 +17,14 @@ get '/' do
17
17
  haml :index
18
18
  end
19
19
 
20
+ get '/list/*' do
21
+ tuple = params[:splat][0].split('/')
22
+ puts "list #{tuple}"
23
+ linda.tuplespaces["calc"].list(tuple).map{ |t|
24
+ t.data
25
+ }.to_json
26
+ end
27
+
20
28
  get '/worker' do
21
29
  haml :worker
22
30
  end
@@ -8,5 +8,11 @@
8
8
  %ul
9
9
  %li
10
10
  %a{:href => "/worker"} calc worker
11
+ %div write a Tuple ["calc_request", "code"]
11
12
  %li
12
13
  %a{:href => "/client"} calc client
14
+ %div read ["calc_request"] and write ["calc_result", result]
15
+ %li
16
+ %a{:href => "/list/calc_request"} list of Tuples matches ["calc_request"]
17
+ %li
18
+ %a{:href => "/list/calc_result"} list of Tuples matches ["calc_result"]
@@ -157,4 +157,32 @@ class TestRubyClient < MiniTest::Test
157
157
  assert _info2.from =~ /^\d+\.\d+\.\d+\.\d+$/
158
158
  assert _info3.from =~ /^\d+\.\d+\.\d+\.\d+$/
159
159
  end
160
+
161
+ def test_tuples_list
162
+ ts = @client.tuplespace["ts_#{rand Time.now.to_i}"]
163
+ _tuple1 = ["a", "b", "c"]
164
+ _tuple2 = ["a", "b"]
165
+ _tuple3 = ["a", "b", "c", 123]
166
+ _result1 = nil
167
+ _result2 = nil
168
+ @client.io.on :connect do
169
+ ts.write _tuple1
170
+ ts.write _tuple2
171
+ ts.write _tuple3
172
+
173
+ ts.list ["a", "b", "c"] do |tuples|
174
+ _result1 = tuples
175
+ end
176
+
177
+ ts.list ["a", "b"] do |tuples|
178
+ _result2 = tuples
179
+ end
180
+ end
181
+ 50.times do
182
+ sleep 0.1
183
+ break if _result2
184
+ end
185
+ assert_equal _result1, [_tuple3, _tuple1]
186
+ assert_equal _result2, [_tuple3, _tuple2, _tuple1]
187
+ end
160
188
  end
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: 1.0.1
4
+ version: 1.1.0
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-10-10 00:00:00.000000000 Z
11
+ date: 2013-11-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -231,7 +231,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
231
231
  version: '0'
232
232
  requirements: []
233
233
  rubyforge_project:
234
- rubygems_version: 2.1.5
234
+ rubygems_version: 2.0.3
235
235
  signing_key:
236
236
  specification_version: 4
237
237
  summary: Linda implementation on Sinatra RocketIO