UNPKG

2.97 kBtext/coffeescriptView Raw
1path = require 'path'
2Tuple = require path.join(__dirname, 'tuple')
3
4module.exports = class TupleSpace
5 constructor: (@name='noname') ->
6 @tuples = []
7 @callbacks = []
8 @__defineGetter__ 'size', ->
9 return @tuples.length
10
11 write: (tuple, options={expire: Tuple.DEFAULT.expire}) ->
12 return if !Tuple.isHash(tuple) and !(tuple instanceof Tuple)
13 tuple = new Tuple(tuple) unless tuple instanceof Tuple
14 tuple.expire =
15 if typeof options.expire == 'number' and options.expire > 0
16 options.expire
17 else
18 Tuple.DEFAULT.expire
19 tuple.from = options.from
20 called = []
21 taked = false
22 for i in [0...@callbacks.length]
23 c = @callbacks[i]
24 if c.tuple.match tuple
25 called.push i if c.type == 'take' or c.type == 'read'
26 do (c) ->
27 setImmediate -> c.callback(null, tuple)
28 if c.type == 'take'
29 taked = true
30 break
31 for i in called by -1
32 @callbacks.splice i, 1
33 @tuples.push tuple unless taked
34
35 create_callback_id: ->
36 return Date.now() - Math.random()
37
38 read: (tuple, callback) ->
39 return unless typeof callback == 'function'
40 if !Tuple.isHash(tuple) and !(tuple instanceof Tuple)
41 setImmediate -> callback('argument_error')
42 return null
43 tuple = new Tuple(tuple) unless tuple instanceof Tuple
44 for i in [@size-1..0]
45 t = @tuples[i]
46 if tuple.match t
47 setImmediate -> callback(null, t)
48 return
49 id = @create_callback_id()
50 @callbacks.push {type: 'read', callback: callback, tuple: tuple, id: id}
51 return id
52
53 take: (tuple, callback) ->
54 return unless typeof callback == 'function'
55 if !Tuple.isHash(tuple) and !(tuple instanceof Tuple)
56 setImmediate -> callback('argument_error')
57 return null
58 tuple = new Tuple(tuple) unless tuple instanceof Tuple
59 for i in [@size-1..0]
60 t = @tuples[i]
61 if tuple.match t
62 setImmediate -> callback(null, t)
63 @tuples.splice i, 1
64 return
65 id = @create_callback_id()
66 @callbacks.push {type: 'take', callback: callback, tuple: tuple, id: id}
67 return id
68
69 watch: (tuple, callback) ->
70 return unless typeof callback == 'function'
71 if !Tuple.isHash(tuple) and !(tuple instance Tuple)
72 setImmediate -> callback('argument_error')
73 return
74 tuple = new Tuple(tuple) unless tuple instanceof Tuple
75 id = @create_callback_id()
76 @callbacks.unshift
77 id: id
78 type: 'watch'
79 tuple: tuple
80 callback: callback
81 return id
82
83 cancel: (id) ->
84 return unless id?
85 for i in [0...@callbacks.length]
86 c = @callbacks[i]
87 if id == c.id
88 setImmediate -> c.callback('cancel', null)
89 @callbacks.splice i, 1
90 return
91
92 check_expire: ->
93 expires = []
94 for i in [0...@tuples.length]
95 if @tuples[i].expire_at < Date.now() / 1000
96 expires.push i
97 for i in expires by -1
98 @tuples.splice i, 1
99 return expires.length