turnpike 0.0.1

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.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm --create use 1.9.2@turnpike
data/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
1
+ # CHANGELOG
2
+
3
+ See [here](http://code.papercavalier.com/turnpike).
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in turnpike.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,32 @@
1
+ # Turnpike
2
+
3
+ Turnpike is a Redis-backed processing queue.
4
+
5
+ # Usage
6
+
7
+ Set up:
8
+
9
+ ```ruby
10
+ require "turnpike"
11
+
12
+ queue = Turnpike.new(:processing_queue)
13
+ ```
14
+
15
+ Queue:
16
+
17
+ ```ruby
18
+ queue << "unit of work"
19
+ ```
20
+
21
+ Process:
22
+
23
+ ```ruby
24
+ queue.each do |work|
25
+ # create value
26
+ end
27
+
28
+ # alternatively
29
+ queue.each_slice(10) do |slice)
30
+ # create value
31
+ end
32
+ ```
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ require 'rake/testtask'
4
+
5
+ task :default => :test
6
+
7
+ Rake::TestTask.new do |test|
8
+ test.libs << 'test'
9
+ test.test_files = FileList['test/**/*_test.rb']
10
+ end
data/lib/turnpike.rb ADDED
@@ -0,0 +1,121 @@
1
+ require 'redis'
2
+
3
+ # A Redis-backed queue.
4
+ class Turnpike
5
+ REDIS_VERSION = Redis.current.info['redis_version']
6
+ TIMEOUT = ENV['TURNPIKE_TIMEOUT'] || 2
7
+ VERSION = '0.0.1'
8
+
9
+ # The name of the queue.
10
+ attr :name
11
+
12
+ # Creates a new queue.
13
+ #
14
+ # Takes an optional name.
15
+ def initialize(name = 'default')
16
+ @name = "turnpike:#{name}"
17
+ end
18
+
19
+ # Removes all queued items.
20
+ def clear
21
+ redis.del(name)
22
+ end
23
+
24
+ # Calls block once for each queued item.
25
+ #
26
+ # Takes an optional boolean argument to specify if the command should block
27
+ # the connection when the queue is empty. This argument defaults to false.
28
+ def each(blocking = false, &block)
29
+ while item = shift(blocking)
30
+ block.call(item)
31
+ end
32
+ end
33
+
34
+ # Iterates the given block for each slice of `n` queued items.
35
+ def each_slice(n, blocking = false, &block)
36
+ slice = []
37
+
38
+ each(blocking) do |item|
39
+ slice << item
40
+ if slice.size == n
41
+ yield slice
42
+ slice = []
43
+ end
44
+ end
45
+
46
+ yield slice unless slice.empty?
47
+ end
48
+
49
+ # Returns `true` if the queue is empty.
50
+ def empty?
51
+ length == 0
52
+ end
53
+
54
+ # Returns the length of the queue.
55
+ def length
56
+ redis.llen(name)
57
+ end
58
+ alias size length
59
+
60
+ # Returns an array of items currently queued.
61
+ #
62
+ # `start` is an integer and indicates the start offset, 0 being the first
63
+ # queued item. If negative, it indicates the offset from the end, -1 being
64
+ # the last queued item.
65
+ #
66
+ # `count` is also an integer and indicates the number of items to return.
67
+ def peek(start, count)
68
+ redis.lrange(name, start, count)
69
+ end
70
+
71
+ # Retrieves the last queued item.
72
+ #
73
+ # Takes an optional boolean argument to specify if the command should block
74
+ # the connection when the queue is empty. This argument defaults to false.
75
+ def pop(blocking = false)
76
+ if blocking
77
+ redis.brpop(name, TIMEOUT)[1] rescue nil
78
+ else
79
+ redis.rpop(name)
80
+ end
81
+ end
82
+
83
+ # Pushes items to the end of the queue.
84
+ def push(*items)
85
+ # Up until Redis 2.3, `rpush` accepts a single value.
86
+ if REDIS_VERSION < '2.3'
87
+ items.each { |item| redis.rpush(name, item) }
88
+ else
89
+ redis.rpush(name, items)
90
+ end
91
+ end
92
+ alias << push
93
+
94
+ # Retrieves the first queued item.
95
+ #
96
+ # Takes an optional boolean argument to specify if the command should block
97
+ # the connection when the queue is empty. This argument defaults to false.
98
+ def shift(blocking = false)
99
+ if blocking
100
+ redis.blpop(name, TIMEOUT)[1] rescue nil
101
+ else
102
+ redis.lpop(name)
103
+ end
104
+ end
105
+
106
+ # Pushes items to the front of the queue.
107
+ def unshift(*items)
108
+ # Up until Redis 2.3, `rpush` accepts a single value.
109
+ if REDIS_VERSION < '2.3'
110
+ items.each { |item| redis.lpush(name, item) }
111
+ else
112
+ redis.lpush(name, items)
113
+ end
114
+ end
115
+
116
+ private
117
+
118
+ def redis
119
+ Redis.current
120
+ end
121
+ end
@@ -0,0 +1,131 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ require 'test/unit'
5
+
6
+ require File.expand_path('../lib/turnpike', File.dirname(__FILE__))
7
+
8
+ class TestTurnpike < Test::Unit::TestCase
9
+ def setup
10
+ Redis.current.flushall
11
+ end
12
+
13
+ def test_emptiness
14
+ queue = Turnpike.new
15
+ assert(queue.empty?)
16
+
17
+ queue << 1
18
+ assert(!queue.empty?)
19
+
20
+ queue.clear
21
+ assert(queue.empty?)
22
+ end
23
+
24
+ def test_pushing_items
25
+ queue = Turnpike.new
26
+ queue.push(1)
27
+ assert_equal(1, queue.length)
28
+
29
+ queue.push(2, 3)
30
+ assert_equal(3, queue.length)
31
+ assert_equal(['1', '2', '3'], queue.peek(0, 3))
32
+ end
33
+
34
+ def test_unshifting_items
35
+ queue = Turnpike.new
36
+ queue.unshift(1)
37
+ assert_equal(1, queue.length)
38
+
39
+ queue.unshift(2, 3)
40
+ assert_equal(3, queue.length)
41
+ assert_equal(['3', '2', '1'], queue.peek(0, 3))
42
+ end
43
+
44
+ def test_popping_items
45
+ queue = Turnpike.new
46
+ queue.push(1, 2)
47
+ assert_equal('2', queue.pop)
48
+ assert_equal('1', queue.pop)
49
+ assert_equal(nil, queue.pop)
50
+ end
51
+
52
+ def test_shifting_items
53
+ queue = Turnpike.new
54
+ queue.push(1, 2)
55
+ assert_equal('1', queue.shift)
56
+ assert_equal('2', queue.shift)
57
+ assert_equal(nil, queue.shift)
58
+ end
59
+
60
+ def test_enumeration
61
+ queue = Turnpike.new
62
+ queue.push(1, 2)
63
+ items = []
64
+ queue.each { |item| items << item }
65
+ assert_equal(['1', '2'], items)
66
+
67
+ queue.push(1, 2, 3, 4)
68
+ slices = []
69
+ queue.each_slice(3) { |slice| slices << slice }
70
+ assert_equal([['1', '2', '3'], ['4']], slices)
71
+
72
+ queue.push(1, 2)
73
+ slices = []
74
+ queue.each_slice(2) { |slice| slices << slice }
75
+ assert_equal([['1', '2']], slices)
76
+ end
77
+
78
+ def test_aliases
79
+ queue = Turnpike.new
80
+ queue << 1
81
+ assert_equal(1, queue.size)
82
+ end
83
+
84
+ def test_multiple_queues
85
+ queue1 = Turnpike.new("foo")
86
+ queue2 = Turnpike.new("bar")
87
+
88
+ queue1.push(1)
89
+ queue2.push(2, 3)
90
+
91
+ assert_equal(1, queue1.length)
92
+ assert_equal(2, queue2.length)
93
+ end
94
+
95
+ def test_blocking_pop
96
+ queue = Turnpike.new
97
+ started_at = Time.now.to_i
98
+ Thread.new do
99
+ sleep(1)
100
+ queue.push(1)
101
+ end
102
+ assert_equal(0, queue.length)
103
+ assert_equal('1', queue.pop(true))
104
+ assert_equal(1, Time.now.to_i - started_at)
105
+ end
106
+
107
+ def test_blocking_shift
108
+ queue = Turnpike.new
109
+ started_at = Time.now.to_i
110
+ Thread.new do
111
+ sleep(1)
112
+ queue.push(1)
113
+ end
114
+ assert_equal(0, queue.length)
115
+ assert_equal('1', queue.shift(true))
116
+ assert_equal(1, Time.now.to_i - started_at)
117
+ end
118
+
119
+ def test_timeout
120
+ queue = Turnpike.new
121
+ thread = Thread.new do
122
+ sleep(3)
123
+ queue.push(1)
124
+ end
125
+ assert_equal(0, queue.length)
126
+ assert_equal(nil, queue.shift(true))
127
+
128
+ thread.join
129
+ assert_equal(1, queue.length)
130
+ end
131
+ end
data/turnpike.gemspec ADDED
@@ -0,0 +1,31 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require "./lib/turnpike"
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "turnpike"
6
+ s.version = Turnpike::VERSION
7
+ s.authors = ["Paper Cavalier"]
8
+ s.email = ["code@papercavalier.com"]
9
+ s.homepage = ""
10
+ s.summary = %q{Turnpike is a Redis-backed processing queue.}
11
+ s.description = %q{Turnpike is a Redis-backed processing queue.}
12
+
13
+ s.rubyforge_project = "turnpike"
14
+
15
+ s.files = `git ls-files`.split("\n")
16
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
+ s.require_paths = ["lib"]
19
+
20
+ {
21
+ 'redis' => '~> 2.2'
22
+ }.each do |lib, version|
23
+ s.add_runtime_dependency lib, version
24
+ end
25
+
26
+ {
27
+ 'rake' => '~> 0.9'
28
+ }.each do |lib, version|
29
+ s.add_development_dependency lib, version
30
+ end
31
+ end
metadata ADDED
@@ -0,0 +1,102 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: turnpike
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ version: 0.0.1
10
+ platform: ruby
11
+ authors:
12
+ - Paper Cavalier
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-07-15 00:00:00 +01:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: redis
22
+ requirement: &id001 !ruby/object:Gem::Requirement
23
+ none: false
24
+ requirements:
25
+ - - ~>
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 2
29
+ - 2
30
+ version: "2.2"
31
+ type: :runtime
32
+ prerelease: false
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: rake
36
+ requirement: &id002 !ruby/object:Gem::Requirement
37
+ none: false
38
+ requirements:
39
+ - - ~>
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 0
43
+ - 9
44
+ version: "0.9"
45
+ type: :development
46
+ prerelease: false
47
+ version_requirements: *id002
48
+ description: Turnpike is a Redis-backed processing queue.
49
+ email:
50
+ - code@papercavalier.com
51
+ executables: []
52
+
53
+ extensions: []
54
+
55
+ extra_rdoc_files: []
56
+
57
+ files:
58
+ - .gitignore
59
+ - .rvmrc
60
+ - CHANGELOG.md
61
+ - Gemfile
62
+ - README.md
63
+ - Rakefile
64
+ - lib/turnpike.rb
65
+ - test/turnpike_test.rb
66
+ - turnpike.gemspec
67
+ has_rdoc: true
68
+ homepage: ""
69
+ licenses: []
70
+
71
+ post_install_message:
72
+ rdoc_options: []
73
+
74
+ require_paths:
75
+ - lib
76
+ required_ruby_version: !ruby/object:Gem::Requirement
77
+ none: false
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ hash: -65682769668407542
82
+ segments:
83
+ - 0
84
+ version: "0"
85
+ required_rubygems_version: !ruby/object:Gem::Requirement
86
+ none: false
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ hash: -65682769668407542
91
+ segments:
92
+ - 0
93
+ version: "0"
94
+ requirements: []
95
+
96
+ rubyforge_project: turnpike
97
+ rubygems_version: 1.3.7
98
+ signing_key:
99
+ specification_version: 3
100
+ summary: Turnpike is a Redis-backed processing queue.
101
+ test_files:
102
+ - test/turnpike_test.rb