cassandra-queue 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,2 @@
1
+ *.gem
2
+ Gemfile.lock
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in your gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2011 Ooyala, Inc.
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1 @@
1
+ WRITE ME
data/Rakefile ADDED
@@ -0,0 +1,20 @@
1
+ require "bundler"
2
+ require "rake/testtask"
3
+
4
+ require File.join(File.dirname(__FILE__), "lib", "cassandra-queue", "version")
5
+
6
+ Rake::TestTask.new do |t|
7
+ t.libs << "test"
8
+ t.test_files = Dir.glob("test/**/*test.rb")
9
+ t.verbose = true
10
+ end
11
+
12
+ desc 'Builds the gem'
13
+ task :build do
14
+ sh "gem build cassandra-queue.gemspec"
15
+ end
16
+
17
+ desc 'Builds and installs the gem'
18
+ task :install => :build do
19
+ sh "gem install cassandra-queue-#{CassandraQueue::VERSION}"
20
+ end
data/TODO ADDED
@@ -0,0 +1 @@
1
+ WRITE ME
@@ -0,0 +1,43 @@
1
+ create keyspace CassandraQueueInfo
2
+ with placement_strategy = LocalStrategy
3
+ and strategy_options = [{replication_factor : 1}];
4
+
5
+ use CassandraQueueInfo;
6
+
7
+ create column family StringQueue
8
+ with column_type = Standard
9
+ and comparator = TimeUUIDType
10
+ and default_validation_class = UTF8Type
11
+ and key_validation_class = UTF8Type
12
+ and memtable_operations = 0.0328125
13
+ and memtable_throughput = 7
14
+ and memtable_flush_after = 1440
15
+ and rows_cached = 0.0
16
+ and row_cache_save_period = 0
17
+ and keys_cached = 200000.0
18
+ and key_cache_save_period = 14400
19
+ and read_repair_chance = 1.0
20
+ and gc_grace = 864000
21
+ and min_compaction_threshold = 4
22
+ and max_compaction_threshold = 32
23
+ and replicate_on_write = true
24
+ and row_cache_provider = 'ConcurrentLinkedHashCacheProvider';
25
+
26
+ create column family BytesQueue
27
+ with column_type = Standard
28
+ and comparator = TimeUUIDType
29
+ and default_validation_class = BytesType
30
+ and key_validation_class = UTF8Type
31
+ and memtable_operations = 0.0328125
32
+ and memtable_throughput = 7
33
+ and memtable_flush_after = 1440
34
+ and rows_cached = 0.0
35
+ and row_cache_save_period = 0
36
+ and keys_cached = 200000.0
37
+ and key_cache_save_period = 14400
38
+ and read_repair_chance = 1.0
39
+ and gc_grace = 864000
40
+ and min_compaction_threshold = 4
41
+ and max_compaction_threshold = 32
42
+ and replicate_on_write = true
43
+ and row_cache_provider = 'ConcurrentLinkedHashCacheProvider';
@@ -0,0 +1,34 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+
4
+ require "cassandra-queue/version"
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "cassandra-queue"
8
+ s.version = CassandraQueue::VERSION
9
+ s.platform = Gem::Platform::RUBY
10
+ s.authors = ["Jay Bhat"]
11
+ s.email = ["jbhat@ooyala.com"]
12
+ s.homepage = "http://www.ooyala.com"
13
+ s.summary = %q{Cassandra-backed general queue}
14
+ s.description = <<EOS
15
+ Cassandra Queue is a queue that uses cassandra as a backend, that can hopefully be used
16
+ as either a Job Queue, or a Message queue.
17
+ EOS
18
+
19
+ s.rubyforge_project = "cassandra-queue"
20
+
21
+ ignores = File.readlines(".gitignore").grep(/\S+/).map {|pattern| pattern.chomp }
22
+ dotfiles = Dir[".*"]
23
+ s.files = Dir["**/*"].reject {|f| File.directory?(f) || ignores.any? {|i| File.fnmatch(i, f) } } + dotfiles
24
+ s.test_files = s.files.grep(/^test\//)
25
+
26
+ s.require_paths = ["lib"]
27
+
28
+ s.add_dependency "cassandra"
29
+
30
+ s.add_development_dependency "bundler", "~> 1.1"
31
+ s.add_development_dependency "scope", "~> 0.2.1"
32
+ s.add_development_dependency "mocha"
33
+ s.add_development_dependency "rake"
34
+ end
@@ -0,0 +1,118 @@
1
+ #!/usr/bin/env ruby
2
+ # queue = CassandraQueue::Queue.get_queue("myqueue", :keyspace => "KeyspaceName", :servers => "localhost:9160")
3
+
4
+ require "cassandra"
5
+ include SimpleUUID
6
+
7
+ DEFAULT_KEYSPACE = "CassandraQueueInfo"
8
+ DEFAULT_SERVERS = ["127.0.0.1:9160"]
9
+ DEFAULT_STRING_QUEUE = :StringQueue
10
+ DEFAULT_BYTES_QUEUE = :BytesQueue
11
+ # Note(jbhat): Since almost all column names will be different, compression doesn't help for these CFs
12
+ module CassandraQueue
13
+ # Singleton class that manages our cassandra queues
14
+ class QueueManager
15
+ def self.queues
16
+ @queues ||= {}
17
+ end
18
+
19
+ def self.queue(qid, string_queue, keyspace, servers)
20
+ key = :"#{qid}_#{string_queue}_#{keyspace}_#{servers.flatten.join(',')}"
21
+ queues[key] ||= Queue.send(:new, qid, string_queue, keyspace, servers)
22
+ end
23
+ end
24
+
25
+ class Queue
26
+ # Entry point for using a queue. Class method which will return you a queue object for that UUID
27
+ def self.retrieve(qid, opts = {})
28
+ string_queue = opts[:string_queue] || false
29
+ keyspace = opts[:keyspace] || DEFAULT_KEYSPACE
30
+ servers = opts[:servers] || DEFAULT_SERVERS
31
+ QueueManager.queue(qid, string_queue, keyspace, servers)
32
+ end
33
+
34
+ class << self
35
+ alias :get_queue :retrieve
36
+ alias :get :retrieve
37
+ end
38
+ # Takes a payload, throws it on the queue, and returns the TimeUUID that was created for it
39
+ def insert(payload, time = Time.now, options = {})
40
+ timeUUID = UUID.new(time)
41
+ @client.insert(@queue_cf, @key, { timeUUID => payload }, options)
42
+ timeUUID
43
+ end
44
+
45
+ alias :add :insert
46
+
47
+ def push(payload, options = {})
48
+ insert(payload, Time.now, options)
49
+ end
50
+
51
+ alias :enqueue :push
52
+
53
+ # Removes a TimeUUID, and it's payload, from the queue
54
+ def remove(timeUUID, options = {})
55
+ @client.remove(@queue_cf, @key, timeUUID, options)
56
+ end
57
+
58
+ alias :delete :remove
59
+
60
+ # Show the first 100 elements of the queue by default, for things such as failure recovery
61
+ def list(get_times = false, options = {})
62
+ list = @client.get(@queue_cf, @key, options)
63
+ get_times ? list : list.values
64
+ end
65
+
66
+ alias :list_queue :list
67
+ alias :queue :list
68
+
69
+ def payloads(options = {})
70
+ list(false, options)
71
+ end
72
+
73
+ alias :messages :payloads
74
+ alias :values :payloads
75
+
76
+ def empty?(options = {})
77
+ list(true, options).empty?
78
+ end
79
+
80
+ # Show the first (oldest) element in the queue
81
+ # Returns payload [TimeUUID, payload] as a two element array
82
+ def peek(get_time = false, options = {})
83
+ options.merge(:count => 1)
84
+ payload = @client.get(@queue_cf, @key, options).first
85
+ payload && !get_time ? payload.last : payload
86
+ end
87
+
88
+ alias :front :peek
89
+ alias :get_first :peek
90
+
91
+ def pop(get_time = false, options = {})
92
+ item = peek(true, options)
93
+ return nil if item.nil?
94
+ remove(item.first, options)
95
+ get_time ? item : item.last
96
+ end
97
+
98
+ alias :dequeue :pop
99
+
100
+ private_class_method :new
101
+
102
+ private
103
+ def initialize(qid, string_queue, keyspace, servers)
104
+ @key = qid_to_rowkey qid
105
+ # Set cassandra client if it has not already been set
106
+ @client = create_client(keyspace, servers)
107
+ @queue_cf = string_queue ? DEFAULT_STRING_QUEUE : DEFAULT_BYTES_QUEUE
108
+ end
109
+
110
+ def qid_to_rowkey(qid)
111
+ qid
112
+ end
113
+
114
+ def create_client(keyspace, servers)
115
+ ::Cassandra.new(keyspace, [servers].flatten)
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,3 @@
1
+ module CassandraQueue
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,26 @@
1
+ require_relative "test_helper"
2
+
3
+ class QueueTest < Scope::TestCase
4
+ context "with cassandra queue" do
5
+ setup do
6
+ @cassandra = mock("Cassandra")
7
+ ::Cassandra.stubs(:new).returns @cassandra
8
+ @qid = mock "qid"
9
+ @queue = CassandraQueue::Queue.get_queue(@qid)
10
+ @cf = :BytesQueue
11
+ @tid = mock "tuuid"
12
+ SimpleUUID::UUID.stubs(:new).returns(@tid)
13
+ @message = mock "message"
14
+ end
15
+
16
+ should "insert into cassandra when asked to" do
17
+ @cassandra.expects(:insert).with(@cf, @qid, {@tid => @message}, {})
18
+ @queue.push(@message)
19
+ end
20
+
21
+ should "remove from cassandra when asked to" do
22
+ @cassandra.expects(:remove).with(@cf, @qid, @tid, {})
23
+ @queue.remove(@tid)
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,9 @@
1
+ require "rubygems"
2
+ require "bundler"
3
+ Bundler.require(:default, :development)
4
+ require "minitest/autorun"
5
+
6
+ # For testing cassandra-queue itself, use the local version *first*.
7
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), "..", "lib")
8
+
9
+ require "cassandra-queue"
metadata ADDED
@@ -0,0 +1,144 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cassandra-queue
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Jay Bhat
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-04-25 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: cassandra
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: bundler
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '1.1'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '1.1'
46
+ - !ruby/object:Gem::Dependency
47
+ name: scope
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 0.2.1
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: 0.2.1
62
+ - !ruby/object:Gem::Dependency
63
+ name: mocha
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '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: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: rake
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
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'
94
+ description: ! 'Cassandra Queue is a queue that uses cassandra as a backend, that
95
+ can hopefully be used
96
+
97
+ as either a Job Queue, or a Message queue.
98
+
99
+ '
100
+ email:
101
+ - jbhat@ooyala.com
102
+ executables: []
103
+ extensions: []
104
+ extra_rdoc_files: []
105
+ files:
106
+ - cassandra-cli.cass
107
+ - cassandra-queue.gemspec
108
+ - Gemfile
109
+ - lib/cassandra-queue/version.rb
110
+ - lib/cassandra-queue.rb
111
+ - LICENSE
112
+ - Rakefile
113
+ - README.md
114
+ - test/queue_test.rb
115
+ - test/test_helper.rb
116
+ - TODO
117
+ - .gitignore
118
+ homepage: http://www.ooyala.com
119
+ licenses: []
120
+ post_install_message:
121
+ rdoc_options: []
122
+ require_paths:
123
+ - lib
124
+ required_ruby_version: !ruby/object:Gem::Requirement
125
+ none: false
126
+ requirements:
127
+ - - ! '>='
128
+ - !ruby/object:Gem::Version
129
+ version: '0'
130
+ required_rubygems_version: !ruby/object:Gem::Requirement
131
+ none: false
132
+ requirements:
133
+ - - ! '>='
134
+ - !ruby/object:Gem::Version
135
+ version: '0'
136
+ requirements: []
137
+ rubyforge_project: cassandra-queue
138
+ rubygems_version: 1.8.22
139
+ signing_key:
140
+ specification_version: 3
141
+ summary: Cassandra-backed general queue
142
+ test_files:
143
+ - test/queue_test.rb
144
+ - test/test_helper.rb