linda-socket.io
Version:
Linda implementation on Socket.IO
100 lines (91 loc) • 2.97 kB
text/coffeescript
path = require 'path'
Tuple = require path.join(__dirname, 'tuple')
module.exports = class TupleSpace
constructor: (='noname') ->
= []
= []
'size', ->
return .length
write: (tuple, options={expire: Tuple.DEFAULT.expire}) ->
return if !Tuple.isHash(tuple) and !(tuple instanceof Tuple)
tuple = new Tuple(tuple) unless tuple instanceof Tuple
tuple.expire =
if typeof options.expire == 'number' and options.expire > 0
options.expire
else
Tuple.DEFAULT.expire
tuple.from = options.from
called = []
taked = false
for i in [0....length]
c = [i]
if c.tuple.match tuple
called.push i if c.type == 'take' or c.type == 'read'
do (c) ->
setImmediate -> c.callback(null, tuple)
if c.type == 'take'
taked = true
break
for i in called by -1
.splice i, 1
.push tuple unless taked
create_callback_id: ->
return Date.now() - Math.random()
read: (tuple, callback) ->
return unless typeof callback == 'function'
if !Tuple.isHash(tuple) and !(tuple instanceof Tuple)
setImmediate -> callback('argument_error')
return null
tuple = new Tuple(tuple) unless tuple instanceof Tuple
for i in [-1..0]
t = [i]
if tuple.match t
setImmediate -> callback(null, t)
return
id =
.push {type: 'read', callback: callback, tuple: tuple, id: id}
return id
take: (tuple, callback) ->
return unless typeof callback == 'function'
if !Tuple.isHash(tuple) and !(tuple instanceof Tuple)
setImmediate -> callback('argument_error')
return null
tuple = new Tuple(tuple) unless tuple instanceof Tuple
for i in [-1..0]
t = [i]
if tuple.match t
setImmediate -> callback(null, t)
.splice i, 1
return
id =
.push {type: 'take', callback: callback, tuple: tuple, id: id}
return id
watch: (tuple, callback) ->
return unless typeof callback == 'function'
if !Tuple.isHash(tuple) and !(tuple instance Tuple)
setImmediate -> callback('argument_error')
return
tuple = new Tuple(tuple) unless tuple instanceof Tuple
id =
.unshift
id: id
type: 'watch'
tuple: tuple
callback: callback
return id
cancel: (id) ->
return unless id?
for i in [0....length]
c = [i]
if id == c.id
setImmediate -> c.callback('cancel', null)
.splice i, 1
return
check_expire: ->
expires = []
for i in [0....length]
if [i].expire_at < Date.now() / 1000
expires.push i
for i in expires by -1
.splice i, 1
return expires.length