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,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
@@ -0,0 +1,3 @@
1
+
2
+ 0.1.0 (2011-09-23)
3
+ * initial version
data/Gemfile ADDED
@@ -0,0 +1,17 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ gem "abstract", ">= 1.0.0"
5
+ gem "hash-utils", ">= 0.18.1"
6
+ gem "lookup-hash", ">= 0"
7
+
8
+ # Add dependencies to develop your gem here.
9
+ # Include everything needed to run rake, tests, features, etc.
10
+ group :development do
11
+ gem "bundler", ">= 1.0.0"
12
+ gem "jeweler2", ">= 2.0.0"
13
+ gem "riot", ">= 0.12.3"
14
+ gem "PriorityQueue", ">= 0"
15
+ gem "algorithms", ">= 0"
16
+ gem "depq", ">= 0"
17
+ end
@@ -0,0 +1,32 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ PriorityQueue (0.1.2)
5
+ abstract (1.0.0)
6
+ algorithms (0.3.0)
7
+ depq (0.6)
8
+ git (1.2.5)
9
+ hash-utils (1.0.0)
10
+ ruby-version
11
+ jeweler2 (2.0.9)
12
+ git (>= 1.2.5)
13
+ lookup-hash (0.2.0)
14
+ hash-utils (>= 0.11.0)
15
+ riot (0.12.5)
16
+ rr
17
+ rr (1.0.4)
18
+ ruby-version (0.3.1)
19
+
20
+ PLATFORMS
21
+ ruby
22
+
23
+ DEPENDENCIES
24
+ PriorityQueue
25
+ abstract (>= 1.0.0)
26
+ algorithms
27
+ bundler (>= 1.0.0)
28
+ depq
29
+ hash-utils (>= 0.18.1)
30
+ jeweler2 (>= 2.0.0)
31
+ lookup-hash
32
+ riot (>= 0.12.3)
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 - 2012 Martin Kozák (martinkozak@martinkozak.net)
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,88 @@
1
+ Ruby Unified Queues
2
+ ===================
3
+
4
+ **unified-queues** is an unified queue interface which unifies
5
+ several both normal and priority queue implementations to the single
6
+ queue API. Usage is simple:
7
+
8
+ require "unified-queues"
9
+
10
+ # Depq
11
+ require "depq"
12
+ depq_queue = UnifiedQueues::Single::new(Depq)
13
+
14
+ # Ruby Array
15
+ array_queue = UnifiedQueues::Single::new(Array)
16
+
17
+ # ...the same API!
18
+ depq_queue.push(:foo)
19
+ depq_queue.pop! # will return :foo
20
+
21
+ array_queue.push(:foo)
22
+ array_queue.pop! # will return :foo
23
+
24
+ Evented queues are also supported by transparent way; simply provide
25
+ blocks to calls instead of expecting return values. Currently, the
26
+ following classes are supported:
27
+
28
+ * `Queue` and `Array` (from Ruby),
29
+ * `Depq` (from `depq` gem),
30
+ * `Containers::Heap` (from `algorithms` gem),
31
+ * `CPriorityQueue`, `PoorPriorityQueue` and `RubyPriorityQueue` (from `priority_queue` gem),
32
+ * `EventedQueue` (from `evented-queue` gem).
33
+
34
+ And for multiqueues:
35
+
36
+ * `UnifiedQueues::Single` (from `unified-queues` gem),
37
+ * `EMJack::Connection` (from `em-jack` beanstalk gem)
38
+
39
+ ### Multiqueue Support
40
+
41
+ *Multiqueue* is a queue which is composed of more queues and single
42
+ queue can be selected for writing into or reading from. An example
43
+ of this type of queues are for example some queue servers which
44
+ typically contain more than one queue. By this way, an unified queue
45
+ interface can be implemented for more queue servers too.
46
+
47
+ Reasonable example isn't available, but see the [QRPC][1] project
48
+ where unified multiqueues are implemented.
49
+
50
+ Multiqueue driver for single unified queue interface is also
51
+ implemented, so it's possible to build a multiqueue interface from
52
+ the common datatypes or Ruby priority queues implementations by
53
+ an universal and transparent way.
54
+
55
+ ##### Hardcore example
56
+
57
+ Hardcore example can by for example following (bonus points for
58
+ decoding what it does):
59
+
60
+ UnifiedQueues::Multi::new UnifiedQueues::Single, ::EM::Wrapper::new(REUQ), UnifiedQueues::Single, CPriorityQueue
61
+
62
+ Well, it creates an unified queue interface from the `CPriorityQueue`
63
+ library, wraps it to an evented interface (converts standard
64
+ interface to the evented one), converts it to the evented unified
65
+ queue interface again and creates a multiqueue interface from it. It
66
+ may sounds difficulty, but it simply *creates an evented unified
67
+ multiqueue interface from non-evented proprietary library*. Cool.
68
+
69
+ Contributing
70
+ ------------
71
+
72
+ 1. Fork it.
73
+ 2. Create a branch (`git checkout -b 20101220-my-change`).
74
+ 3. Commit your changes (`git commit -am "Added something"`).
75
+ 4. Push to the branch (`git push origin 20101220-my-change`).
76
+ 5. Create an [Issue][9] with a link to your branch.
77
+ 6. Enjoy a refreshing Diet Coke and wait.
78
+
79
+
80
+ Copyright
81
+ ---------
82
+
83
+ Copyright © 2011 - 2012 [Martin Kozák][10]. See `LICENSE.txt` for
84
+ further details.
85
+
86
+ [1]: http://github.com/martinkozak/qrpc
87
+ [9]: http://github.com/martinkozak/unified-queues/issues
88
+ [10]: http://www.martinkozak.net/
@@ -0,0 +1,29 @@
1
+ # encoding: utf-8
2
+ require 'rubygems'
3
+ require 'bundler'
4
+
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+
13
+ require 'rake'
14
+ require 'jeweler2'
15
+
16
+ Jeweler::Tasks.new do |gem|
17
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
18
+ gem.name = "unified-queues"
19
+ gem.homepage = "http://github.com/martinkozak/unified-queue"
20
+ gem.license = "MIT"
21
+ gem.summary = 'Unifies many queue implementations under the single interface. Includes both single queue libraries and multiple queue libraries.'
22
+ gem.email = "martinkozak@martinkozak.net"
23
+ gem.authors = ["Martin Kozák"]
24
+ # Include your dependencies below. Runtime dependencies are required when using your gem,
25
+ # and development dependencies are only needed for development (ie running rake tasks, tests, etc)
26
+ # gem.add_runtime_dependency 'jabber4r', '> 0.1'
27
+ # gem.add_development_dependency 'rspec', '> 1.2.3'
28
+ end
29
+ Jeweler::RubygemsDotOrgTasks.new
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
data/debug ADDED
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/ruby
2
+ # encoding: utf-8
3
+ # (c) 2011 Martin Kozák (martinkozak@martinkozak.net)
4
+
5
+ $:.push("./lib")
6
+ $:.unshift("./lib")
7
+
8
+ require "em-jack"
9
+ require "unified-queues"
10
+ require "em-batch"
11
+
12
+ EM::run do
13
+ q = UnifiedQueues::Multi::new(EMJack::Connection)
14
+
15
+ queue = EM::Sequencer::new(q)
16
+ queue.use(:xxx)
17
+ queue.push("x", 2)
18
+ queue.push("y", 1)
19
+ queue.subscribe(:xxx)
20
+
21
+ queue.execute do
22
+ queue = EM::Sequencer::new(q)
23
+ queue.pop
24
+ queue.pop
25
+ queue.pop
26
+
27
+ queue.execute do
28
+ p queue.results
29
+
30
+ #q.pop
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,5 @@
1
+ # encoding: utf-8
2
+ # (c) 2011 Martin Kozák (martinkozak@martinkozak.net)
3
+
4
+ require "unified-queues/single"
5
+ require "unified-queues/multi"
@@ -0,0 +1,209 @@
1
+ # encoding: utf-8
2
+ # (c) 2011 Martin Kozák (martinkozak@martinkozak.net)
3
+
4
+ require "unified-queues/multi/driver"
5
+ require "hash-utils/module"
6
+
7
+ ##
8
+ # Base 9Unified Queues+ module.
9
+ #
10
+
11
+ module UnifiedQueues
12
+
13
+ ##
14
+ # More queues single interface.
15
+ #
16
+
17
+ class Multi
18
+
19
+ ##
20
+ # Contains assignment of classnames to drivers.
21
+ # @return [Hash]
22
+ #
23
+
24
+ DRIVERS = Hash[
25
+ :"UnifiedQueues::Single" => "unified-queues.rb",
26
+ :"EMJack::Connection" => "em-jack.rb"
27
+ ]
28
+
29
+ ##
30
+ # Contains driver for specific class instance.
31
+ # @return [UnifiedQueues::Multi::Driver] driver instance
32
+ #
33
+
34
+ attr_accessor :driver
35
+ @driver
36
+
37
+ ##
38
+ # Constructor.
39
+ #
40
+ # @param [Class|UnifiedQueues::Multi::Driver] cls required class object or driver instance
41
+ # @param [Array] *args array of arguments for the queue constructor
42
+ # @param [Proc] &block block for the queue constructor
43
+ #
44
+
45
+ def initialize(cls, *args, &block)
46
+ if cls.kind_of? UnifiedQueues::Multi::Driver
47
+ @driver = cls
48
+ else
49
+ self.assign_driver(cls, args, block)
50
+ end
51
+ end
52
+
53
+ ##
54
+ # Assigns driver to interface according to given class name.
55
+ #
56
+ # @param [Class] cls required class
57
+ # @param [Array] args array of arguments for the queue constructor
58
+ # @param [Proc] block block for the queue constructor
59
+ # @return [UnifiedQueues::Multi::Driver] new driver instance
60
+ #
61
+
62
+ def assign_driver(cls, args, block)
63
+ _cls = cls
64
+ if not _cls.kind_of? Class
65
+ _cls = cls.class
66
+ end
67
+
68
+ driver = nil
69
+ name = nil
70
+
71
+ self.class::DRIVERS.each_pair do |_name, _driver|
72
+ begin
73
+ _module = Module::get_module(_name.to_s)
74
+ rescue NameError
75
+ next
76
+ end
77
+
78
+ if _cls <= _module
79
+ driver = _driver
80
+ name = _name
81
+ break
82
+ end
83
+ end
84
+
85
+ ###
86
+
87
+ require "unified-queues/multi/driver/" << driver
88
+
89
+ path = name.to_s.split("::")
90
+ classname = path.shift << 'Driver::' << path.join('::')
91
+ _module = Module::get_module("UnifiedQueues::Multi::Driver::" << classname)
92
+
93
+ args = [cls] + args
94
+ @driver = _module::new(*args, &block)
95
+ return @driver
96
+ end
97
+
98
+ ##
99
+ # Pushes value to the currently used queue.
100
+ #
101
+ # @param [Object] value
102
+ # @param [Object] key key for priority purposes
103
+ #
104
+
105
+ def push(value, key = value, &block)
106
+ @driver.push(value, key, &block)
107
+ end
108
+
109
+ ##
110
+ # Pops value from the queue. In contrast to default Queue library,
111
+ # blocks or returns +nil+ if empty.
112
+ #
113
+ # @param [Boolean|Integer] blocking +true+ or timeout if it should block, +false+ otherwise
114
+ # @return [Object|nil]
115
+ #
116
+
117
+ def pop(blocking = false, &block)
118
+ @driver.pop(blocking, &block)
119
+ end
120
+
121
+ ##
122
+ # Sets queue with given name as used. So marks it as target
123
+ # for {#push}.
124
+ #
125
+ # @param [Object] name name of the required queue
126
+ #
127
+
128
+ def use(name, &block)
129
+ @driver.use(name, &block)
130
+ end
131
+
132
+ ##
133
+ # Subscribes to the queue. So marks it as target for {#pop}.
134
+ # Note, than only single queue usally can be subscribed at
135
+ # one time.
136
+ #
137
+ # @param [Object] name name of the required queue
138
+ #
139
+
140
+ def subscribe(name, &block)
141
+ @driver.subscribe(name, &block)
142
+ end
143
+
144
+ ##
145
+ # Unsubscribes from the queue.
146
+ # @param [Object] name name of the required queue
147
+ #
148
+
149
+ def unsubscribe(name, &block)
150
+ @driver.unsubscribe(name, &block)
151
+ end
152
+
153
+ ##
154
+ # Currently used queue.
155
+ # @return [Queue]
156
+ #
157
+
158
+ def used(&block)
159
+ @driver.used(&block)
160
+ end
161
+
162
+ ##
163
+ # Currently subscribed queue.
164
+ # @return [Queue]
165
+ #
166
+
167
+ def subscribed(&block)
168
+ @driver.subscribed(&block)
169
+ end
170
+
171
+ ##
172
+ # Lists names of all available queues.
173
+ # @return [Array]
174
+ #
175
+
176
+ def list(&block)
177
+ @driver.list(&block)
178
+ end
179
+
180
+ ##
181
+ # Lists all used queues.
182
+ # @return [Array]
183
+ #
184
+
185
+ def list_used(&block)
186
+ @driver.list_used(&block)
187
+ end
188
+
189
+ ##
190
+ # Lists all subscribed queues.
191
+ # @return [Array]
192
+ #
193
+
194
+ def list_subscribed(&block)
195
+ @driver.list_subscribed(&block)
196
+ end
197
+
198
+ ##
199
+ # Closes the session.
200
+ #
201
+
202
+ def close(&block)
203
+ @driver.close(&block)
204
+ end
205
+
206
+ alias :close! :close
207
+
208
+ end
209
+ end