sinatra-rocketio-linda 0.2.0 → 1.0.0

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 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: