unified-queues 0.1.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.
@@ -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