sinatra-rocketio-linda 0.2.0 → 1.0.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: 0294f5d3a02665a4a387de3e3881901f5d7f6608
4
- data.tar.gz: c09d1bb3e75e86f21f3076970865596362be56f0
3
+ metadata.gz: 80ea427ebe1d5b5567614294e23521c21878ea81
4
+ data.tar.gz: 9939c563e0d718a87ad755187efd8c8eb3452b4c
5
5
  SHA512:
6
- metadata.gz: 11388a5aa10b0a23ee081d3ddc12d25bfa5744d2bbb274aba6f2b98aa4368fe0f3e5a3953da9ff145943203b1346b1d9d819527dde0e6cf3b8a5e4cd94fbac59
7
- data.tar.gz: 4b29d75a5a3c4b744f00671ca5e40ac7fad9a150a486177ffad010af44f03fdcbf3407e0a05a851df73aa590c47f510ecdf8bf1d1d4364223c32ebf4c260cde3
6
+ metadata.gz: 62affc882c4199c103f37c6788d277748d6517140dd1d9e8c696530899981e10f8f5a40c9b2e540a00defc90cc1f001a1858480ca370851a036fda89000c1f23
7
+ data.tar.gz: 31bfd9e8adb98c70eac4578d130455eda41bfd3486a3e80c6e9f34386492dd959cac334ac95063ecb238437ca3aace28bf0cc4017d03100a5f04a321d80ba683
data/History.txt CHANGED
@@ -1,3 +1,7 @@
1
+ === 1.0.0 2013-10-03
2
+
3
+ * !!! protocol was updated
4
+
1
5
  === 0.2.0 2013-06-10
2
6
 
3
7
  * changed linda-rocketio command options
data/README.md CHANGED
@@ -89,7 +89,7 @@ $("#btn_request").click(function(){
89
89
 
90
90
  // wait result
91
91
  var take_result = function(){
92
- ts.take(["calc_result"], function(tuple){
92
+ ts.take(["calc_result"], function(tuple, info){
93
93
  var result = tuple[1]; // from 'worker' side
94
94
  console.log(result);
95
95
  take_result(); // recursive call
@@ -106,7 +106,7 @@ var ts = new linda.TupleSpace("calc");
106
106
 
107
107
  // calculate
108
108
  var calc = function(){
109
- ts.take(["calc_request"], function(tuple){
109
+ ts.take(["calc_request"], function(tuple, info){
110
110
  var query = tuple[1]; // => "1-2+3*4"
111
111
  var result = eval(query);
112
112
  console.log(query+" = "+result); // => "1-2+3*4 = 11"
@@ -129,7 +129,7 @@ ts = linda.tuplespace["calc"]
129
129
 
130
130
  ## calculate
131
131
  calc = lambda{
132
- ts.take ["calc_request"] do |tuple|
132
+ ts.take ["calc_request"] do |tuple, info|
133
133
  query = tuple[1] ## => "1-2+3*4"
134
134
  result = eval(query)
135
135
  puts "calc: #{query} = #{result}" ## => "1-2+3*4 = 11"
data/Rakefile CHANGED
@@ -1,3 +1,4 @@
1
+ require "bundler/setup"
1
2
  require "bundler/gem_tasks"
2
3
  require "rake/testtask"
3
4
 
data/lib/js/linda.js CHANGED
@@ -25,21 +25,27 @@ var Linda = function(io, opts){
25
25
  if(tuple === null || typeof tuple !== "object") return;
26
26
  if(typeof callback !== "function") return;
27
27
  var callback_id = make_callback_id();
28
- self.io.once("__linda_read_callback_"+callback_id, callback);
28
+ self.io.once("__linda_read_callback_"+callback_id, function(data){
29
+ callback(data.tuple, data.info);
30
+ });
29
31
  self.io.push("__linda_read", [space.name, tuple, callback_id]);
30
32
  };
31
33
  this.take = function(tuple, callback){
32
34
  if(tuple === null || typeof tuple !== "object") return;
33
35
  if(typeof callback !== "function") return;
34
36
  var callback_id = make_callback_id();
35
- self.io.once("__linda_take_callback_"+callback_id, callback);
37
+ self.io.once("__linda_take_callback_"+callback_id, function(data){
38
+ callback(data.tuple, data.info);
39
+ });
36
40
  self.io.push("__linda_take", [space.name, tuple, callback_id]);
37
41
  };
38
42
  this.watch = function(tuple, callback){
39
43
  if(tuple === null || typeof tuple !== "object") return;
40
44
  if(typeof callback !== "function") return;
41
45
  var callback_id = make_callback_id();
42
- self.io.on("__linda_watch_callback_"+callback_id, callback);
46
+ self.io.on("__linda_watch_callback_"+callback_id, function(data){
47
+ callback(data.tuple, data.info);
48
+ });
43
49
  self.io.push("__linda_watch", [space.name, tuple, callback_id]);
44
50
  };
45
51
  };
@@ -48,7 +48,9 @@ Sinatra::RocketIO.on :__linda_write do |data, client|
48
48
  end
49
49
  opts = opts_
50
50
  end
51
- Sinatra::RocketIO::Linda[space].write tuple, opts
51
+ opts[:from] = client.address
52
+ _tuple = Sinatra::RocketIO::Linda::Tuple.new tuple, opts
53
+ Sinatra::RocketIO::Linda[space].write _tuple
52
54
  Sinatra::RocketIO::Linda.emit :write, Hashie::Mash.new(:space => space, :tuple => tuple), client
53
55
  end
54
56
 
@@ -65,7 +67,7 @@ end
65
67
  next
66
68
  end
67
69
  callback_id = Sinatra::RocketIO::Linda[space].__send__ func, tuple do |tuple|
68
- Sinatra::RocketIO.push "__linda_#{func}_callback_#{callback}", tuple, :to => client.session
70
+ Sinatra::RocketIO.push "__linda_#{func}_callback_#{callback}", {:tuple => tuple.data, :info => {:from => tuple.from}}, :to => client.session
69
71
  Sinatra::RocketIO::Linda.emit func, Hashie::Mash.new(:space => space, :tuple => tuple), client
70
72
  end
71
73
  Sinatra::RocketIO::Linda.callbacks[client.session].push(:space => space, :callback => callback_id)
@@ -5,6 +5,13 @@ module Sinatra
5
5
  module Linda
6
6
  # use linda gem (https://rubygems.org/gems/linda)
7
7
  class Tuple < ::Linda::Tuple
8
+
9
+ attr_reader :from
10
+ def initialize(data, opts={})
11
+ @from = opts[:from] if opts.kind_of? Hash
12
+ super data, opts
13
+ end
14
+
8
15
  end
9
16
  end
10
17
  end
@@ -1,11 +1,15 @@
1
1
  require File.expand_path 'version', File.dirname(__FILE__)
2
2
  require 'event_emitter'
3
+ require 'hashie'
3
4
  require 'sinatra/rocketio/client'
4
5
 
5
6
  module Sinatra
6
7
  module RocketIO
7
8
  module Linda
8
9
 
10
+ class TupleInfo < Hashie::Mash
11
+ end
12
+
9
13
  class Client
10
14
  attr_reader :io, :tuplespace
11
15
  def initialize(io_or_url)
@@ -46,8 +50,12 @@ module Sinatra
46
50
  unless [Hash, Array].include? tuple.class
47
51
  raise ArgumentError, "tuple must be Array or Hash"
48
52
  end
49
- callback_id = "#{Time.now.to_i}#{Time.now.usec}_#{(rand*1000000).to_i}"
50
- @linda.io.once "__linda_read_callback_#{callback_id}", &block
53
+ callback_id = create_callback_id
54
+ if block_given?
55
+ @linda.io.once "__linda_read_callback_#{callback_id}" do |data|
56
+ block.call(data['tuple'], TupleInfo.new(data['info']))
57
+ end
58
+ end
51
59
  @linda.io.push "__linda_read", [@name, tuple, callback_id]
52
60
  end
53
61
 
@@ -55,8 +63,12 @@ module Sinatra
55
63
  unless [Hash, Array].include? tuple.class
56
64
  raise ArgumentError, "tuple must be Array or Hash"
57
65
  end
58
- callback_id = "#{Time.now.to_i}#{Time.now.usec}_#{(rand*1000000).to_i}"
59
- @linda.io.once "__linda_take_callback_#{callback_id}", &block
66
+ callback_id = create_callback_id
67
+ if block_given?
68
+ @linda.io.once "__linda_take_callback_#{callback_id}" do |data|
69
+ block.call(data['tuple'], TupleInfo.new(data['info']))
70
+ end
71
+ end
60
72
  @linda.io.push "__linda_take", [@name, tuple, callback_id]
61
73
  end
62
74
 
@@ -64,11 +76,20 @@ module Sinatra
64
76
  unless [Hash, Array].include? tuple.class
65
77
  raise ArgumentError, "tuple must be Array or Hash"
66
78
  end
67
- callback_id = "#{Time.now.to_i}#{Time.now.usec}_#{(rand*1000000).to_i}"
68
- @linda.io.on "__linda_watch_callback_#{callback_id}", &block
79
+ callback_id = create_callback_id
80
+ if block_given?
81
+ @linda.io.on "__linda_watch_callback_#{callback_id}" do |data|
82
+ block.call(data['tuple'], TupleInfo.new(data['info']))
83
+ end
84
+ end
69
85
  @linda.io.push "__linda_watch", [@name, tuple, callback_id]
70
86
  end
71
87
 
88
+ private
89
+ def create_callback_id
90
+ "#{Time.now.to_i}#{Time.now.usec}_#{(rand*1000000).to_i}"
91
+ end
92
+
72
93
  end
73
94
 
74
95
  end
@@ -1,7 +1,7 @@
1
1
  module Sinatra
2
2
  module RocketIO
3
3
  module Linda
4
- VERSION = "0.2.0"
4
+ VERSION = "1.0.0"
5
5
  end
6
6
  end
7
7
  end
data/linda.js CHANGED
@@ -1,4 +1,4 @@
1
- // Linda.js v0.2.0 (rocketio v0.2.6)
1
+ // Linda.js v1.0.0 (rocketio v0.3.0)
2
2
  // https://github.com/shokai/sinatra-rocketio-linda
3
3
  // (c) 2013 Sho Hashimoto <hashimoto@shokai.org>
4
4
  // The MIT License
@@ -29,21 +29,27 @@ var Linda = function(io, opts){
29
29
  if(tuple === null || typeof tuple !== "object") return;
30
30
  if(typeof callback !== "function") return;
31
31
  var callback_id = make_callback_id();
32
- self.io.once("__linda_read_callback_"+callback_id, callback);
32
+ self.io.once("__linda_read_callback_"+callback_id, function(data){
33
+ callback(data.tuple, data.info);
34
+ });
33
35
  self.io.push("__linda_read", [space.name, tuple, callback_id]);
34
36
  };
35
37
  this.take = function(tuple, callback){
36
38
  if(tuple === null || typeof tuple !== "object") return;
37
39
  if(typeof callback !== "function") return;
38
40
  var callback_id = make_callback_id();
39
- self.io.once("__linda_take_callback_"+callback_id, callback);
41
+ self.io.once("__linda_take_callback_"+callback_id, function(data){
42
+ callback(data.tuple, data.info);
43
+ });
40
44
  self.io.push("__linda_take", [space.name, tuple, callback_id]);
41
45
  };
42
46
  this.watch = function(tuple, callback){
43
47
  if(tuple === null || typeof tuple !== "object") return;
44
48
  if(typeof callback !== "function") return;
45
49
  var callback_id = make_callback_id();
46
- self.io.on("__linda_watch_callback_"+callback_id, callback);
50
+ self.io.on("__linda_watch_callback_"+callback_id, function(data){
51
+ callback(data.tuple, data.info);
52
+ });
47
53
  self.io.push("__linda_watch", [space.name, tuple, callback_id]);
48
54
  };
49
55
  };
data/linda.min.js CHANGED
@@ -1,5 +1,5 @@
1
- // Linda.js v0.2.0 (rocketio v0.2.6)
1
+ // Linda.js v1.0.0 (rocketio v0.3.0)
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,callback);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,callback);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,callback);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])}}};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}
@@ -8,8 +8,8 @@ ts = linda.tuplespace["calc"]
8
8
 
9
9
  linda.io.on :connect do
10
10
  puts "connect #{io.session}"
11
- ts.watch [] do |tuple|
12
- puts "watch #{tuple}"
11
+ ts.watch [] do |tuple, info|
12
+ puts "watch #{tuple} (from:#{info.from})"
13
13
  end
14
14
  end
15
15
 
@@ -7,10 +7,10 @@ linda = Sinatra::RocketIO::Linda::Client.new 'http://localhost:5000'
7
7
  ts = linda.tuplespace["calc"]
8
8
 
9
9
  calc = lambda{
10
- ts.take ["calc_request"] do |tuple|
10
+ ts.take ["calc_request"] do |tuple, info|
11
11
  query = tuple[1]
12
12
  result = eval(query)
13
- puts "calc: #{query} = #{result}"
13
+ puts "calc: #{query} = #{result} (from:#{info.from})"
14
14
  ts.write ["calc_result", result]
15
15
  calc.call
16
16
  end
@@ -19,7 +19,8 @@ var take_result = function(){
19
19
 
20
20
  io.on("connect", take_result);
21
21
  io.on("connect", function(){
22
- ts.watch(["calc_request"], function(tuple){
22
+ ts.watch(["calc_request"], function(tuple, info){
23
23
  console.log(tuple);
24
+ console.log(info)
24
25
  });
25
26
  });
@@ -2,7 +2,7 @@ var linda = new Linda();
2
2
  var ts = new linda.TupleSpace("calc");
3
3
 
4
4
  var calc = function(){
5
- ts.take(["calc_request"], function(tuple){
5
+ ts.take(["calc_request"], function(tuple, info){
6
6
  var query = tuple[1];
7
7
  var result = eval(query);
8
8
  $("#log").prepend( $("<p>").text(query+" = "+result).prepend("calc: ") );
@@ -26,7 +26,7 @@ Gem::Specification.new do |spec|
26
26
 
27
27
  spec.add_dependency "linda", ">= 0.0.4"
28
28
  spec.add_dependency "hashie"
29
- spec.add_dependency "sinatra-rocketio"
29
+ spec.add_dependency "sinatra-rocketio", "~> 0.3"
30
30
  spec.add_dependency "event_emitter"
31
31
  spec.add_dependency "sinatra"
32
32
  spec.add_dependency "args_parser"
@@ -15,16 +15,16 @@ class TestClientDisconnect < MiniTest::Test
15
15
  client2.io.on :connect do
16
16
  ts1 = client1.tuplespace[ts_name]
17
17
  ts2 = client2.tuplespace[ts_name]
18
- ts1.read [1,2] do |tuple|
18
+ ts1.read [1,2] do |tuple, info|
19
19
  _tuple1 = tuple
20
20
  end
21
- ts1.take [1,2] do |tuple|
21
+ ts1.take [1,2] do |tuple, info|
22
22
  _tuple2 = tuple
23
23
  end
24
- ts1.watch [1,2] do |tuple|
24
+ ts1.watch [1,2] do |tuple, info|
25
25
  _tuple3 = tuple
26
26
  end
27
- ts2.take [1,2] do |tuple|
27
+ ts2.take [1,2] do |tuple, info|
28
28
  _tuple4 = tuple
29
29
  end
30
30
  client1.io.close
@@ -18,19 +18,19 @@ class TestRubyClient < MiniTest::Test
18
18
  ts.write ["rw",1,2,3]
19
19
  ts.write ["rw",1,2,"a"]
20
20
  ts.write ["rw",1,"a",2]
21
- ts.take ["rw",1,2] do |tuple|
21
+ ts.take ["rw",1,2] do |tuple, info|
22
22
  _tuple1 = tuple
23
23
  end
24
- ts.read ["rw",1,2] do |tuple|
24
+ ts.read ["rw",1,2] do |tuple, info|
25
25
  _tuple2 = tuple
26
26
  end
27
- ts.take ["rw",1,2] do |tuple|
27
+ ts.take ["rw",1,2] do |tuple, info|
28
28
  _tuple3 = tuple
29
29
  end
30
30
  client2 = Sinatra::RocketIO::Linda::Client.new App.url
31
31
  ts2 = client2.tuplespace[ts_name]
32
32
  client2.io.on :connect do
33
- ts2.take ["rw",1] do |tuple|
33
+ ts2.take ["rw",1] do |tuple, info|
34
34
  _tuple4 = tuple
35
35
  end
36
36
  end
@@ -51,13 +51,13 @@ class TestRubyClient < MiniTest::Test
51
51
  _tuple2 = nil
52
52
  ts = @client.tuplespace["ts_#{rand Time.now.to_i}"]
53
53
  @client.io.on :connect do
54
- ts.take ["watch",1,2] do |tuple|
54
+ ts.take ["watch",1,2] do |tuple, info|
55
55
  _tuple1 = tuple
56
56
  end
57
- ts.read ["watch",1,2] do |tuple|
57
+ ts.read ["watch",1,2] do |tuple, info|
58
58
  _tuple2 = tuple
59
59
  end
60
- ts.watch ["watch",1,2] do |tuple|
60
+ ts.watch ["watch",1,2] do |tuple, info|
61
61
  results.push tuple
62
62
  end
63
63
  ts.write ["watch",1,2,3]
@@ -81,10 +81,10 @@ class TestRubyClient < MiniTest::Test
81
81
  _tuple1 = nil
82
82
  _tuple2 = nil
83
83
  @client.io.on :connect do
84
- ts2.take ["a"] do |tuple|
84
+ ts2.take ["a"] do |tuple, info|
85
85
  _tuple2 = tuple
86
86
  end
87
- ts1.take [1] do |tuple|
87
+ ts1.take [1] do |tuple, info|
88
88
  _tuple1 = tuple
89
89
  end
90
90
  ts1.write [1,2,3]
@@ -106,12 +106,12 @@ class TestRubyClient < MiniTest::Test
106
106
  ts.write ["expire",1,2,999], :expire => false
107
107
  ts.write ["expire",1,2,3], :expire => 10
108
108
  ts.write ["expire",1,2,"a","b"], :expire => 2
109
- ts.read ["expire",1,2] do |tuple|
109
+ ts.read ["expire",1,2] do |tuple, info|
110
110
  _tuple1 = tuple
111
111
  end
112
112
  sleep 3
113
113
  push :check_expire, nil
114
- ts.read ["expire",1,2] do |tuple|
114
+ ts.read ["expire",1,2] do |tuple, info|
115
115
  _tuple2 = tuple
116
116
  end
117
117
  end
@@ -122,4 +122,39 @@ class TestRubyClient < MiniTest::Test
122
122
  assert_equal _tuple1, ["expire",1,2,"a","b"]
123
123
  assert_equal _tuple2, ["expire",1,2,3]
124
124
  end
125
+
126
+ def test_tuple_info
127
+ ts = @client.tuplespace["ts_#{rand Time.now.to_i}"]
128
+ _tuple1 = nil
129
+ _tuple2 = nil
130
+ _tuple3 = nil
131
+ _info1 = nil
132
+ _info2 = nil
133
+ _info3 = nil
134
+ @client.io.on :connect do
135
+ ts.read [1,2] do |tuple, info|
136
+ _tuple1 = tuple
137
+ _info1 = info
138
+ end
139
+ ts.watch [1] do |tuple, info|
140
+ _tuple2 = tuple
141
+ _info2 = info
142
+ end
143
+ ts.take [1,2,3] do |tuple, info|
144
+ _tuple3 = tuple
145
+ _info3 = info
146
+ end
147
+ ts.write [1,2,3]
148
+ end
149
+ 50.times do
150
+ sleep 0.1
151
+ break if _tuple3
152
+ end
153
+ assert_equal _tuple1, [1,2,3]
154
+ assert_equal _tuple2, [1,2,3]
155
+ assert_equal _tuple3, [1,2,3]
156
+ assert _info1.from =~ /^\d+\.\d+\.\d+\.\d+$/
157
+ assert _info2.from =~ /^\d+\.\d+\.\d+\.\d+$/
158
+ assert _info3.from =~ /^\d+\.\d+\.\d+\.\d+$/
159
+ end
125
160
  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: 0.2.0
4
+ version: 1.0.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-06-09 00:00:00.000000000 Z
11
+ date: 2013-10-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -112,16 +112,16 @@ dependencies:
112
112
  name: sinatra-rocketio
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
- - - '>='
115
+ - - ~>
116
116
  - !ruby/object:Gem::Version
117
- version: '0'
117
+ version: '0.3'
118
118
  type: :runtime
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
- - - '>='
122
+ - - ~>
123
123
  - !ruby/object:Gem::Version
124
- version: '0'
124
+ version: '0.3'
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: event_emitter
127
127
  requirement: !ruby/object:Gem::Requirement
@@ -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.0.3
234
+ rubygems_version: 2.1.5
235
235
  signing_key:
236
236
  specification_version: 4
237
237
  summary: Linda implementation on Sinatra RocketIO
@@ -244,4 +244,3 @@ test_files:
244
244
  - test/test_rubyclient.rb
245
245
  - test/test_tuple.rb
246
246
  - test/test_tuplespace.rb
247
- has_rdoc: