evented-queue 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
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+
5
+ gem "abstract", ">= 0"
6
+ gem "unified-queues", ">= 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
+ end
@@ -0,0 +1,29 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ abstract (1.0.0)
5
+ git (1.2.5)
6
+ hash-utils (1.0.0)
7
+ ruby-version
8
+ jeweler2 (2.0.9)
9
+ git (>= 1.2.5)
10
+ lookup-hash (0.2.0)
11
+ hash-utils (>= 0.11.0)
12
+ riot (0.12.5)
13
+ rr
14
+ rr (1.0.4)
15
+ ruby-version (0.3.1)
16
+ unified-queues (0.1.0)
17
+ abstract (>= 1.0.0)
18
+ hash-utils (>= 0.18.1)
19
+ lookup-hash
20
+
21
+ PLATFORMS
22
+ ruby
23
+
24
+ DEPENDENCIES
25
+ abstract
26
+ bundler (>= 1.0.0)
27
+ jeweler2 (>= 2.0.0)
28
+ riot (>= 0.12.3)
29
+ unified-queues
@@ -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,63 @@
1
+ Ruby Evented Queue
2
+ ==================
3
+
4
+ **evented-queue** simply wraps non-evented queue to an evented
5
+ interface. It directly uses the [Unified Queues][1] gem which means,
6
+ wide spectrum of queues can be converted to the evented queues.
7
+ Advantage of the evented queue is, they can be *recurring*, so
8
+ can serve as de-facto permanent provider of the events.
9
+
10
+ An example:
11
+
12
+ require "evented-queue"
13
+ require "depq" # will serve as example here
14
+
15
+ queue = EventedQueue::new(Depq)
16
+ queue.push(:foo)
17
+
18
+ queue.pop do |item|
19
+ item # will contain :foo
20
+ end
21
+
22
+ queue.push(:bar)
23
+
24
+ queue.pop do |item|
25
+ item # will contain :bar
26
+ end
27
+
28
+
29
+ And recurring queue example:
30
+
31
+ require "evented-queue/recurring"
32
+
33
+ queue = EventedQueue::Recurring::new(Array)
34
+ queue.push(:foo)
35
+
36
+ queue.pop do |item| # :foo will be written out now
37
+ p item
38
+ end
39
+
40
+ queue.push(:bar) # :bar will be written out now
41
+ queue.push(:delta) # :delta will be written out now
42
+
43
+
44
+ Contributing
45
+ ------------
46
+
47
+ 1. Fork it.
48
+ 2. Create a branch (`git checkout -b 20101220-my-change`).
49
+ 3. Commit your changes (`git commit -am "Added something"`).
50
+ 4. Push to the branch (`git push origin 20101220-my-change`).
51
+ 5. Create an [Issue][9] with a link to your branch.
52
+ 6. Enjoy a refreshing Diet Coke and wait.
53
+
54
+
55
+ Copyright
56
+ ---------
57
+
58
+ Copyright © 2011 - 2012 [Martin Kozák][10]. See `LICENSE.txt` for
59
+ further details.
60
+
61
+ [1]: http://github.com/martinkozak/unified-queues
62
+ [9]: http://github.com/martinkozak/evented-queue/issues
63
+ [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 = "evented-queue"
19
+ gem.homepage = "http://github.com/martinkozak/evented-queue"
20
+ gem.license = "MIT"
21
+ gem.summary = 'Provides queue driven by callbacks so suitable for asynchronous processing environments and its recurring variant for request distribution to more clients or emulating of server behaviour.'
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
@@ -0,0 +1,118 @@
1
+ # encoding: utf-8
2
+ # (c) 2011 Martin Kozák (martinkozak@martinkozak.net)
3
+
4
+ require "evented-queue/abstract"
5
+ require "unified-queues/single"
6
+
7
+ ##
8
+ # Non thread-safe queue working using callbacks
9
+ # usable especially for evented environments such as EventMachine
10
+ #
11
+
12
+ class EventedQueue < AbstractEventedQueue
13
+
14
+ ##
15
+ # Holds values stack.
16
+ # @return [UnifiedQueues::Single]
17
+ #
18
+
19
+ attr_accessor :stack
20
+ @stack
21
+
22
+ ##
23
+ # Holds callbacks waiting for value.
24
+ # @return [Array]
25
+ #
26
+
27
+ attr_accessor :callbacks
28
+ @callbacks
29
+
30
+ ##
31
+ # Constructor.
32
+ # @param [UnifiedQueues::Single] stak holder instance wrapped to unified queue
33
+ #
34
+
35
+ def initialize(stack = UnifiedQueues::Single::new(Array))
36
+ @stack = stack
37
+ @callbacks = [ ]
38
+ end
39
+
40
+ ##
41
+ # Pushes value into the queue. Priority isn't supported
42
+ # by default but can be obtained using the +stack+ argument
43
+ # of constructor by giving priority queue instance.
44
+ #
45
+ # @param [Object] value value to push
46
+ # @param [Object] key key fo priority purposes
47
+ # @yield [nil]
48
+ #
49
+
50
+ def push(value, key = value, &block)
51
+ @stack.push(value, key)
52
+ if not @callbacks.empty?
53
+ self.pop &@callbacks.shift
54
+ end
55
+
56
+ yield if not block.nil?
57
+ end
58
+
59
+ ##
60
+ # Pushes value out of the queue.
61
+ #
62
+ # @return [Object] value from the queue
63
+ # @yield [Object] value from the queue
64
+ #
65
+
66
+ def pop(&block)
67
+ if self.empty?
68
+ @callbacks << block
69
+ else
70
+ result = @stack.pop
71
+ yield result if not block.nil?
72
+ return result
73
+ end
74
+ end
75
+
76
+ alias :pop! :pop
77
+
78
+ ##
79
+ # Indicates length of the queue.
80
+ #
81
+ # @return [Integer] length of the queue
82
+ # @yield [Integer] length of the queue
83
+ #
84
+
85
+ def length(&block)
86
+ length = @stack.length
87
+ yield length if not block.nil?
88
+ return length
89
+ end
90
+
91
+ ##
92
+ # Indicates queue is empty.
93
+ #
94
+ # @return [Boolean] +true+ it it is, +false+ otherwise
95
+ # @yield [Boolean] +true+ it it is, +false+ otherwise
96
+ #
97
+
98
+ def empty?(&block)
99
+ empty = @stack.empty?
100
+ yield empty if not block.nil?
101
+ return empty
102
+ end
103
+
104
+ ##
105
+ # Clears the queue.
106
+ #
107
+
108
+ def clear(&block)
109
+ result = @stack.clear
110
+ yield result if not block.nil?
111
+ return result
112
+ end
113
+
114
+ alias :clear! :clear
115
+ end
116
+
117
+ require "evented-queue/recurring"
118
+
@@ -0,0 +1,72 @@
1
+ # encoding: utf-8
2
+ # (c) 2011 Martin Kozák (martinkozak@martinkozak.net)
3
+
4
+ require "abstract"
5
+
6
+ ##
7
+ # Abstract evented queue.
8
+ # @abstract
9
+ #
10
+
11
+ class AbstractEventedQueue
12
+
13
+ ##
14
+ # Pushes value into the queue.
15
+ #
16
+ # @param value [Object] object to push
17
+ # @abstract
18
+ #
19
+
20
+ def push(value, &block)
21
+ not_implemented
22
+ end
23
+
24
+ ##
25
+ # Pushes value out of the queue.
26
+ #
27
+ # @yield [Object] an object from the queue
28
+ # @abstract
29
+ #
30
+
31
+ def pop(&block)
32
+ not_implemented
33
+ end
34
+
35
+ ##
36
+ # Indicates length of the queue.
37
+ #
38
+ # @return [Integer] queue length
39
+ # @yield [Integer] queue length
40
+ # @abstract
41
+ #
42
+
43
+ def length(&block)
44
+ not_implemented
45
+ end
46
+
47
+ ##
48
+ # Indicates queue is empty.
49
+ #
50
+ # @return [Boolean] +true+ it it is, +false+ otherwise
51
+ # @yield [Boolean] +true+ it it is, +false+ otherwise
52
+ # @abstract
53
+ #
54
+
55
+ def empty?(&block)
56
+ not_implemented
57
+ end
58
+
59
+ ##
60
+ # Clears the queue.
61
+ #
62
+ # @yield [nil]
63
+ # @abstract
64
+ #
65
+
66
+ def clear(&block)
67
+ not_implemented
68
+ end
69
+
70
+ alias :clear! :clear
71
+
72
+ end
@@ -0,0 +1,53 @@
1
+ # encoding: utf-8
2
+ # (c) 2011 Martin Kozák (martinkozak@martinkozak.net)
3
+
4
+ require "evented-queue"
5
+
6
+ ##
7
+ # Recurring evented queue implementation.
8
+ #
9
+
10
+ class EventedQueue::Recurring < EventedQueue
11
+
12
+ ##
13
+ # Holds scheduling routine.
14
+ # @return [Proc]
15
+ #
16
+
17
+ attr_accessor :scheduler
18
+ @scheduler
19
+
20
+ ##
21
+ # Constructor.
22
+ # @param [Proc] &scheduler which indicates how to schedule recurring
23
+ #
24
+
25
+ def initialize(stack = UnifiedQueues::Single::new(Array), &scheduler)
26
+ super(stack)
27
+ @scheduler = scheduler
28
+ end
29
+
30
+ ##
31
+ # Pushes value out of the queue.
32
+ #
33
+ # @return [Object] value from the queue
34
+ # @yield [Object] value from the queue
35
+ #
36
+
37
+ def pop(&block)
38
+ if self.empty?
39
+ result = super(&block)
40
+ else
41
+ result = super(&block)
42
+
43
+ if @scheduler.nil?
44
+ self.pop(&block)
45
+ else
46
+ @scheduler.call(Proc::new { self.pop(&block) })
47
+ end
48
+ end
49
+
50
+ return result
51
+ end
52
+
53
+ end
data/test ADDED
@@ -0,0 +1,111 @@
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 "evented-queue"
9
+ require "riot"
10
+
11
+ context "EventedQueue" do
12
+ setup do
13
+ EventedQueue::new
14
+ end
15
+
16
+ asserts("#push") do
17
+ done = false
18
+ topic.push(:foo)
19
+ topic.pop do |v|
20
+ done = v == :foo
21
+ end
22
+ done
23
+ end
24
+ asserts("#pop") do
25
+ d1 = false
26
+ d2 = false
27
+
28
+ topic.push(:foo)
29
+ topic.pop do |v|
30
+ d1 = v == :foo
31
+ end
32
+ topic.pop do |v|
33
+ d2 = v == :bar
34
+ end
35
+ topic.push(:bar)
36
+
37
+ d1 and d2
38
+ end
39
+ asserts("#length") do
40
+ topic.push(:foo)
41
+ topic.pop
42
+ d1 = topic.length == 0
43
+ topic.push(:foo)
44
+ d2 = topic.length == 1
45
+
46
+ d1 and d2
47
+ end
48
+ asserts("#empty?") do
49
+ topic.clear!
50
+ topic.push(:foo)
51
+ d1 = not(topic.empty?)
52
+ topic.pop
53
+ d2 = topic.empty?
54
+
55
+ d1 and d2
56
+ end
57
+ asserts("#clear!") do
58
+ topic.push(:foo)
59
+ topic.clear!
60
+ topic.empty?
61
+ end
62
+ end
63
+
64
+ context "EventedQueue::Recurring" do
65
+ asserts("#push") do
66
+ topic = EventedQueue::Recurring::new
67
+ done = false
68
+ topic.push(:foo)
69
+ topic.pop do |v|
70
+ done = v == :foo
71
+ end
72
+ done
73
+ end
74
+ asserts("#pop") do
75
+ topic = EventedQueue::Recurring::new
76
+ result = [ ]
77
+ topic.push(:foo)
78
+ topic.pop do |v|
79
+ result << v
80
+ end
81
+ topic.push(:bar)
82
+ result == [:foo, :bar]
83
+ end
84
+ asserts("#length") do
85
+ topic = EventedQueue::Recurring::new
86
+ topic.push(:foo)
87
+ topic.pop
88
+ d1 = topic.length == 0
89
+ topic.push(:foo)
90
+ d2 = topic.length == 1
91
+
92
+ d1 and d2
93
+ end
94
+ asserts("#empty?") do
95
+ topic = EventedQueue::Recurring::new
96
+ topic.clear!
97
+ topic.push(:foo)
98
+ d1 = not(topic.empty?)
99
+ topic.pop
100
+ d2 = topic.empty?
101
+
102
+ d1 and d2
103
+ end
104
+ asserts("#clear!") do
105
+ topic = EventedQueue::Recurring::new
106
+ topic.push(:foo)
107
+ topic.clear!
108
+ topic.empty?
109
+ end
110
+ end
111
+
metadata ADDED
@@ -0,0 +1,143 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: evented-queue
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Martin Kozák
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-05-24 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: abstract
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: unified-queues
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: bundler
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: 1.0.0
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: 1.0.0
62
+ - !ruby/object:Gem::Dependency
63
+ name: jeweler2
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: 2.0.0
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: 2.0.0
78
+ - !ruby/object:Gem::Dependency
79
+ name: riot
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: 0.12.3
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: 0.12.3
94
+ description:
95
+ email: martinkozak@martinkozak.net
96
+ executables: []
97
+ extensions: []
98
+ extra_rdoc_files:
99
+ - LICENSE.txt
100
+ - README.md
101
+ files:
102
+ - .document
103
+ - Gemfile
104
+ - Gemfile.lock
105
+ - LICENSE.txt
106
+ - README.md
107
+ - Rakefile
108
+ - VERSION
109
+ - lib/evented-queue.rb
110
+ - lib/evented-queue/abstract.rb
111
+ - lib/evented-queue/recurring.rb
112
+ - test
113
+ homepage: http://github.com/martinkozak/evented-queue
114
+ licenses:
115
+ - MIT
116
+ post_install_message:
117
+ rdoc_options: []
118
+ require_paths:
119
+ - lib
120
+ required_ruby_version: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ segments:
127
+ - 0
128
+ hash: 4134528818554253317
129
+ required_rubygems_version: !ruby/object:Gem::Requirement
130
+ none: false
131
+ requirements:
132
+ - - ! '>='
133
+ - !ruby/object:Gem::Version
134
+ version: '0'
135
+ requirements: []
136
+ rubyforge_project:
137
+ rubygems_version: 1.8.24
138
+ signing_key:
139
+ specification_version: 3
140
+ summary: Provides queue driven by callbacks so suitable for asynchronous processing
141
+ environments and its recurring variant for request distribution to more clients
142
+ or emulating of server behaviour.
143
+ test_files: []