unified-queues 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,176 @@
1
+ # encoding: utf-8
2
+ # (c) 2011 Martin Kozák (martinkozak@martinkozak.net)
3
+
4
+ require "abstract"
5
+
6
+
7
+ ##
8
+ # Base +Unified Queues+ module.
9
+ #
10
+
11
+ module UnifiedQueues
12
+
13
+ ##
14
+ # More queues single interface.
15
+ #
16
+
17
+ class Multi
18
+
19
+ ##
20
+ # Abstract multi driver class.
21
+ # @abstract
22
+ #
23
+
24
+ class Driver
25
+
26
+ ##
27
+ # Holds native object.
28
+ # @return [Object]
29
+ #
30
+
31
+ attr_accessor :native
32
+ @native
33
+
34
+ ##
35
+ # Constructor.
36
+ #
37
+
38
+ def initialize(cls, *args, &block)
39
+ if self.instance_of? UniversalQueues::Multi::Driver
40
+ not_implemented
41
+ end
42
+
43
+ if cls.kind_of? Class
44
+ @native = cls::new(*args, &block)
45
+ else
46
+ @native = cls
47
+ end
48
+ end
49
+
50
+ ##
51
+ # Pushes value to the currently used queue.
52
+ #
53
+ # @param [Object] value
54
+ # @abstract
55
+ #
56
+
57
+ def push(value, &block)
58
+ not_implemented
59
+ end
60
+
61
+ ##
62
+ # Pops value from the queue. In contrast to default Queue library,
63
+ # blocks or returns +nil+ if empty.
64
+ #
65
+ # @param [Boolean|Integer] blocking +true+ or timeout if it should block, +false+ otherwise
66
+ # @return [Object|nil]
67
+ # @abstract
68
+ #
69
+
70
+ def pop(blocking = false, &block)
71
+ not_implemented
72
+ end
73
+
74
+ ##
75
+ # Sets queue with given name as used. So marks it as target
76
+ # for {#push}.
77
+ #
78
+ # @param [Object] name name of the required queue
79
+ # @abstract
80
+ #
81
+
82
+ def use(name, &block)
83
+ not_implemented
84
+ end
85
+
86
+ ##
87
+ # Subscribes to the queue. So marks it as target for {#pop}.
88
+ # Note, than only single queue can be subscribed at one time.
89
+ #
90
+ # @param [Object] name name of the required queue
91
+ # @abstract
92
+ #
93
+
94
+ def subscribe(name, &block)
95
+ not_implemented
96
+ end
97
+
98
+ ##
99
+ # Unsubscribes from the queue.
100
+ #
101
+ # @param [Object] name name of the required queue\
102
+ # @abstract
103
+ #
104
+
105
+ def unsubscribe(name, &block)
106
+ not_implemented
107
+ end
108
+
109
+ ##
110
+ # Currently used queue.
111
+ #
112
+ # @return [Queue]
113
+ # @abstract
114
+ #
115
+
116
+ def used(&block)
117
+ not_implemented
118
+ end
119
+
120
+ ##
121
+ # Currently subscribed queue.
122
+ #
123
+ # @return [UniversalQueues::Single]
124
+ # @abstract
125
+ #
126
+
127
+ def subscribed(&block)
128
+ not_implemented
129
+ end
130
+
131
+ ##
132
+ # Lists names of all available queues.
133
+ #
134
+ # @return [Array]
135
+ # @abstract
136
+ #
137
+
138
+ def list(&block)
139
+ not_implemented
140
+ end
141
+
142
+ ##
143
+ # Lists all used queues.
144
+ #
145
+ # @return [Array]
146
+ # @abstract
147
+ #
148
+
149
+ def list_used(&block)
150
+ not_implemented
151
+ end
152
+
153
+ ##
154
+ # Lists all subscribed queues.
155
+ #
156
+ # @return [Array]
157
+ # @abstract
158
+ #
159
+
160
+ def list_subscribed(&block)
161
+ not_implemented
162
+ end
163
+
164
+ ##
165
+ # Closes the session.
166
+ #
167
+
168
+ def close(&block)
169
+ yield if not block.nil?
170
+ end
171
+
172
+ alias :close! :close
173
+
174
+ end
175
+ end
176
+ end
@@ -0,0 +1,200 @@
1
+ # encoding: utf-8
2
+ # (c) 2011 Martin Kozák (martinkozak@martinkozak.net)
3
+
4
+ require "hash-utils/array"
5
+ require "hash-utils/object"
6
+ require "lookup-hash"
7
+
8
+ ##
9
+ # Base +Unified Queues+ module.
10
+ #
11
+
12
+ module UnifiedQueues
13
+
14
+ ##
15
+ # Universal multi queue interface.
16
+ #
17
+
18
+ class Multi
19
+
20
+ ##
21
+ # Abstract multi driver class.
22
+ # @abstract
23
+ #
24
+
25
+ class Driver
26
+
27
+ ##
28
+ # Wraper according to +UnifiedQueues::Single+ internal structure.
29
+ #
30
+
31
+ module EMJackDriver
32
+
33
+ ##
34
+ # Multi queue driver for unified queues single queue interface.
35
+ #
36
+
37
+ class Connection < Driver
38
+
39
+ ##
40
+ # Holds native connection object.
41
+ # @return EMJack::Connection
42
+ #
43
+
44
+ @native
45
+
46
+ ##
47
+ # Tracks currently used queue name.
48
+ # @return Object
49
+ #
50
+
51
+ @used_name
52
+
53
+ ##
54
+ # Tracks currently subscribed queue names.
55
+ # @return [LookupHash]
56
+ #
57
+
58
+ @subscribed_names
59
+
60
+ ##
61
+ # Constructor.
62
+ #
63
+
64
+ def initialize(cls, *args, &block)
65
+ @native = cls::new(*args, &block)
66
+ @subscribed_names = LookupHash["default"]
67
+ @used_name = "default"
68
+ end
69
+
70
+ ##
71
+ # Pushes value to the currently used queue.
72
+ #
73
+ # @param [Object] value
74
+ # @param [Integer] key key for priority queues
75
+ #
76
+
77
+ def push(value, key = value, &block)
78
+ @native.put(value, :priority => key, &block)
79
+ end
80
+
81
+ ##
82
+ # Pops value from the queue. Callback is recurring, so it will
83
+ # keep callback active after +#pop+.
84
+ #
85
+ # @param [Boolean] blocking indicates, it should block or not
86
+ # @return [Object, nil]
87
+ #
88
+
89
+ def pop(blocking = false, &block)
90
+ timeout = blocking ? nil : 0
91
+ @native.each_job(timeout) do |job|
92
+ result = job.body
93
+ job.delete do
94
+ yield result
95
+ end
96
+ end
97
+ end
98
+
99
+ ##
100
+ # Sets queue with given name as used. So marks it as target
101
+ # for {#push}.
102
+ #
103
+ # @param [Object] name name of the required queue
104
+ #
105
+
106
+ def use(name, &block)
107
+ if name != @used_name
108
+ @used_name = name
109
+ @native.use(name, &block)
110
+ elsif not block.nil?
111
+ EM::next_tick do
112
+ yield
113
+ end
114
+ end
115
+ end
116
+
117
+ ##
118
+ # Subscribes to the queue. So marks it as target for {#pop}.
119
+ # Note, than only single queue can be subscribed at one time.
120
+ #
121
+ # @param [Object] name name of the required queue
122
+ #
123
+
124
+ def subscribe(name, &block)
125
+ if not name.in? @subscribed_names
126
+ @subscribed_names << name
127
+ @native.watch(name, &block)
128
+ elsif not block.nil?
129
+ EM::next_tick do
130
+ yield
131
+ end
132
+ end
133
+ end
134
+
135
+ ##
136
+ # Unsubscribes from the queue.
137
+ # @param [Object] name name of the required queue\
138
+ #
139
+
140
+ def unsubscribe(name, &block)
141
+ if name.in? @subscribed_names
142
+ @subscribed_names.delete name
143
+ @native.ignore(name, &block)
144
+ elsif not block.nil?
145
+ EM::next_tick do
146
+ yield
147
+ end
148
+ end
149
+ end
150
+
151
+ ##
152
+ # Currently used queue.
153
+ # @return [Queue]
154
+ #
155
+
156
+ def used
157
+ yield self
158
+ end
159
+
160
+ ##
161
+ # Currently subscribed queue.
162
+ # @return [Queue]
163
+ #
164
+
165
+ def subscribed
166
+ yield self
167
+ end
168
+
169
+ ##
170
+ # Lists names of all available queues.
171
+ # @return [Array]
172
+ #
173
+
174
+ def list(&block)
175
+ @native.list(&block)
176
+ end
177
+
178
+ ##
179
+ # Lists all used queues.
180
+ # @return [Array]
181
+ #
182
+
183
+ def list_used(&block)
184
+ @native.list(:used, &block)
185
+ end
186
+
187
+ ##
188
+ # Lists all subscribed queues.
189
+ # @return [Array]
190
+ #
191
+
192
+ def list_subscribed(&block)
193
+ @native.list(:watched, &block)
194
+ end
195
+
196
+ end
197
+ end
198
+ end
199
+ end
200
+ end
@@ -0,0 +1,227 @@
1
+ # encoding: utf-8
2
+ # (c) 2011 Martin Kozák (martinkozak@martinkozak.net)
3
+
4
+ require "hash-utils/array"
5
+ require "hash-utils/object"
6
+
7
+ ##
8
+ # Base +Unified Queues+ module.
9
+ #
10
+
11
+ module UnifiedQueues
12
+
13
+ ##
14
+ # Universal multi queue interface.
15
+ #
16
+
17
+ class Multi
18
+
19
+ ##
20
+ # Abstract multi driver class.
21
+ # @abstract
22
+ #
23
+
24
+ class Driver
25
+
26
+ ##
27
+ # Wraper according to +UnifiedQueues::Single+ internal structure.
28
+ #
29
+
30
+ module UnifiedQueuesDriver
31
+
32
+ ##
33
+ # Multi queue driver for unified queues single queue interface.
34
+ #
35
+
36
+ class Single < Driver
37
+
38
+ ##
39
+ # Holds available queues.
40
+ # @return Hash
41
+ #
42
+
43
+ @queues
44
+
45
+ ##
46
+ # Holds default queue class.
47
+ # @return [Class]
48
+ #
49
+
50
+ @class
51
+
52
+ ##
53
+ # Contains currently used queue specification.
54
+ # @return Array
55
+ #
56
+
57
+ @used
58
+
59
+ ##
60
+ # Contains currently subscribed queue specification.
61
+ # @return Array
62
+ #
63
+
64
+ @subscribed
65
+
66
+ ##
67
+ # Constructor.
68
+ #
69
+
70
+ def initialize(cls, *args, &block)
71
+ @queues = { }
72
+ @class = [cls, args, block]
73
+ end
74
+
75
+ ##
76
+ # Pushes value to the currently used queue.
77
+ #
78
+ # @param [Object] value
79
+ # @param [Object] key key for priority queues
80
+ #
81
+
82
+ def push(value, key = value, &block)
83
+ self.used.push(value, key, &block)
84
+ end
85
+
86
+ ##
87
+ # Pops value from the queue. In contrast to default Queue library,
88
+ # blocks or returns +nil+ if empty.
89
+ #
90
+ # @param [Boolean|Integer] blocking +true+ or timeout if it should block, +false+ otherwise
91
+ # @return [Object|nil]
92
+ #
93
+
94
+ def pop(blocking = false, &block)
95
+ self.subscribed.pop(blocking, &block)
96
+ end
97
+
98
+ ##
99
+ # Creates new queue under given name.
100
+ #
101
+ # @param [Object] name identification
102
+ # @return [Queue] new queue
103
+ #
104
+
105
+ def create(name, cls = @class)
106
+ if not name.in? @queues
107
+ self[name] = cls.first::new(*cls.second, &cls.third)
108
+ else
109
+ self[name]
110
+ end
111
+ end
112
+
113
+ ##
114
+ # Inserts queue instance to queues.
115
+ #
116
+ # @param [Object] name identification
117
+ # @param [Containers::Heap] queue heap instance
118
+ #
119
+
120
+ def insert(name, queue)
121
+ @queues[name] = queue
122
+ end
123
+
124
+ alias :[]= :insert
125
+
126
+ ##
127
+ # Returns named queue from instance.
128
+ # @param [Object] name queue name
129
+ #
130
+
131
+ def get(name)
132
+ @queues[name]
133
+ end
134
+
135
+ alias :[] :get
136
+
137
+ ##
138
+ # Sets queue with given name as used. So marks it as target
139
+ # for {#push}.
140
+ #
141
+ # @param [Object] name name of the required queue
142
+ #
143
+
144
+ def use(name, &block)
145
+ self.create(name)
146
+ @used = [name, self[name]]
147
+ yield if not block.nil?
148
+ end
149
+
150
+ ##
151
+ # Subscribes to the queue. So marks it as target for {#pop}.
152
+ # Note, than only single queue can be subscribed at one time.
153
+ #
154
+ # @param [Object] name name of the required queue
155
+ #
156
+
157
+ def subscribe(name, &block)
158
+ self.create(name)
159
+ @subscribed = [name, self[name]]
160
+ yield if not block.nil?
161
+ end
162
+
163
+ ##
164
+ # Unsubscribes from the queue.
165
+ # @param [Object] name name of the required queue\
166
+ #
167
+
168
+ def unsubscribe(name, &block)
169
+ if not @subscribed.nil? and (@subscribed.first == name)
170
+ @subscribed = nil
171
+ end
172
+
173
+ yield if not block.nil?
174
+ end
175
+
176
+ ##
177
+ # Currently used queue.
178
+ # @return [Queue]
179
+ #
180
+
181
+ def used(&block)
182
+ yield @used.second if not block.nil?
183
+ return @used.second
184
+ end
185
+
186
+ ##
187
+ # Currently subscribed queue.
188
+ # @return [Queue]
189
+ #
190
+
191
+ def subscribed(&block)
192
+ yield @subscribed.second if not block.nil?
193
+ return @subscribed.second
194
+ end
195
+
196
+ ##
197
+ # Lists names of all available queues.
198
+ # @return [Array]
199
+ #
200
+
201
+ def list
202
+ @queues.keys
203
+ end
204
+
205
+ ##
206
+ # Lists all used queues.
207
+ # @return [Array]
208
+ #
209
+
210
+ def list_used
211
+ [@used.first]
212
+ end
213
+
214
+ ##
215
+ # Lists all subscribed queues.
216
+ # @return [Array]
217
+ #
218
+
219
+ def list_subscribed
220
+ [@subscribed.first]
221
+ end
222
+
223
+ end
224
+ end
225
+ end
226
+ end
227
+ end