sunspot_index_queue 1.1.3 → 1.1.4
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGE_LOG.txt +5 -0
- data/README.rdoc +4 -0
- data/Rakefile +1 -0
- data/VERSION +1 -1
- data/lib/sunspot/index_queue/entry.rb +13 -6
- data/lib/sunspot/index_queue/entry/active_record_impl.rb +1 -1
- data/lib/sunspot/index_queue/entry/redis_impl.rb +216 -0
- data/spec/entry_spec.rb +37 -14
- data/spec/redis_impl_spec.rb +36 -0
- data/sunspot_index_queue.gemspec +13 -8
- metadata +112 -158
data/CHANGE_LOG.txt
CHANGED
data/README.rdoc
CHANGED
@@ -57,6 +57,9 @@ The queue component is designed to be modular so that you can plugin a datastore
|
|
57
57
|
# Queue implementation backed by MongoDB
|
58
58
|
Sunspot::IndexQueue::Entry.implementation = :mongo
|
59
59
|
|
60
|
+
# Queue implementation backed by Redis
|
61
|
+
Sunspot::IndexQueue::Entry.implementation = :redis
|
62
|
+
|
60
63
|
# You can also provide your own queue implementation
|
61
64
|
Sunspot::IndexQueue::Entry.implementation = MyQueueImplementation
|
62
65
|
|
@@ -65,6 +68,7 @@ You'll need to make sure you have the data structures set up properly for the im
|
|
65
68
|
* Sunspot::IndexQueue::Entry::ActiveRecordImpl
|
66
69
|
* Sunspot::IndexQueue::Entry::DataMapperImpl
|
67
70
|
* Sunspot::IndexQueue::Entry::MongoImpl
|
71
|
+
* Sunspot::IndexQueue::Entry::RedisImpl
|
68
72
|
|
69
73
|
Note that as of version 1.1.0 the data structure for the ActiveRecord and the DataMapper implementations assumes the primary key on the indexed records is an integer. This is done since it is the usual case and far more efficient that using a string index. If your records use a primary key that is not an integer, you'll need to add an additional migration to change the +record_id+ column type.
|
70
74
|
|
data/Rakefile
CHANGED
@@ -34,6 +34,7 @@ begin
|
|
34
34
|
gem.add_development_dependency('dm-migrations', '>=1.0.0')
|
35
35
|
gem.add_development_dependency('dm-sqlite-adapter', '>=1.0.0')
|
36
36
|
gem.add_development_dependency('mongo')
|
37
|
+
gem.add_development_dependency('redis')
|
37
38
|
gem.add_development_dependency('rspec', '>= 2.0.0')
|
38
39
|
gem.add_development_dependency('jeweler')
|
39
40
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.1.
|
1
|
+
1.1.4
|
@@ -9,7 +9,7 @@ module Sunspot
|
|
9
9
|
autoload :ActiveRecordImpl, File.expand_path('../entry/active_record_impl', __FILE__)
|
10
10
|
autoload :DataMapperImpl, File.expand_path('../entry/data_mapper_impl', __FILE__)
|
11
11
|
autoload :MongoImpl, File.expand_path('../entry/mongo_impl', __FILE__)
|
12
|
-
|
12
|
+
autoload :RedisImpl, File.expand_path('../entry/redis_impl', __FILE__)
|
13
13
|
attr_writer :processed
|
14
14
|
|
15
15
|
class << self
|
@@ -101,20 +101,27 @@ module Sunspot
|
|
101
101
|
# Load all records in an array of entries. This can be faster than calling load on each DataAccessor
|
102
102
|
# depending on the implementation
|
103
103
|
def load_all_records(entries)
|
104
|
-
classes
|
105
|
-
|
106
|
-
|
107
|
-
|
104
|
+
#First create maps for classes => ids and "Classname id" => entry
|
105
|
+
class_id_map = {}
|
106
|
+
entry_map = {}
|
107
|
+
entries.each do |entry|
|
108
|
+
classname = Sunspot::Util.full_const_get(entry.record_class_name)
|
109
|
+
class_id_map[classname] = [] if class_id_map[classname].nil?
|
110
|
+
class_id_map[classname] << entry.record_id
|
111
|
+
entry_map["#{classname} #{entry.record_id}"] = entry
|
112
|
+
end
|
113
|
+
class_id_map.each do |klass, ids|
|
108
114
|
adapter = Sunspot::Adapters::DataAccessor.create(klass)
|
109
115
|
if klass.respond_to?(:sunspot_options) && klass.sunspot_options && klass.sunspot_options[:include] && adapter.respond_to?(:include=)
|
110
116
|
adapter.include = klass.sunspot_options[:include]
|
111
117
|
end
|
112
118
|
adapter.load_all(ids).each do |record|
|
113
|
-
entry =
|
119
|
+
entry = entry_map["#{klass} #{Sunspot::Adapters::InstanceAdapter.adapt(record).id}"]
|
114
120
|
entry.instance_variable_set(:@record, record) if entry
|
115
121
|
end
|
116
122
|
end
|
117
123
|
end
|
124
|
+
|
118
125
|
end
|
119
126
|
|
120
127
|
def processed?
|
@@ -0,0 +1,216 @@
|
|
1
|
+
require 'redis'
|
2
|
+
begin
|
3
|
+
require 'yajl/json_gem'
|
4
|
+
rescue LoadError
|
5
|
+
require 'json'
|
6
|
+
end
|
7
|
+
|
8
|
+
module Sunspot
|
9
|
+
class IndexQueue
|
10
|
+
module Entry
|
11
|
+
class RedisImpl
|
12
|
+
include Entry
|
13
|
+
|
14
|
+
attr_accessor :record_id, :record_class_name, :is_delete, :run_at, :priority, :error, :attempts, :is_locked, :duplicate
|
15
|
+
|
16
|
+
class << self
|
17
|
+
def connection= (*args)
|
18
|
+
host, port = *args
|
19
|
+
host ||= 'localhost'
|
20
|
+
port ||= 6379
|
21
|
+
@connection = Redis.new(:host => host, :port => port)
|
22
|
+
end
|
23
|
+
|
24
|
+
def connection
|
25
|
+
@connection
|
26
|
+
end
|
27
|
+
|
28
|
+
def logger
|
29
|
+
@logger
|
30
|
+
end
|
31
|
+
|
32
|
+
def logger= (logger)
|
33
|
+
@logger = logger
|
34
|
+
end
|
35
|
+
|
36
|
+
def datastore_name= (name)
|
37
|
+
@datastore_name = name
|
38
|
+
end
|
39
|
+
|
40
|
+
def datastore_name
|
41
|
+
@datastore_name
|
42
|
+
end
|
43
|
+
|
44
|
+
def collection
|
45
|
+
object_array = []
|
46
|
+
@connection.hvals(@datastore_name).each {|value| object_array << self.new(JSON.parse(value))}
|
47
|
+
object_array.sort
|
48
|
+
end
|
49
|
+
|
50
|
+
def total_count(queue)
|
51
|
+
if queue.class_names.empty?
|
52
|
+
@connection.hlen @datastore_name
|
53
|
+
else
|
54
|
+
collection.select{|object| queue.class_names.include?(object.record_class_name)}.size
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def ready_count(queue)
|
59
|
+
present_time = Time.now.utc
|
60
|
+
if queue.class_names.empty?
|
61
|
+
collection.select{|object| Time.parse(object.run_at) < present_time}.size
|
62
|
+
else
|
63
|
+
collection.select{|object| (Time.parse(object.run_at) < present_time) && queue.class_names.include?(object.record_class_name)}.size
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def error_count(queue)
|
68
|
+
if queue.class_names.empty?
|
69
|
+
collection.select{|object| object.error != nil}.size
|
70
|
+
else
|
71
|
+
collection.select{|object| (object.error != nil) && queue.class_names.include?(object.record_class_name)}.size
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def errors(queue, limit, offset)
|
76
|
+
if queue.class_names.empty?
|
77
|
+
collection.select{|object| object.error != nil}.slice(offset..limit)
|
78
|
+
else
|
79
|
+
collection.select{|object| (object.error != nil) && queue.class_names.include?(object.record_class_name)}.slice(offset..limit)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def reset!(queue)
|
84
|
+
collection_to_reset =
|
85
|
+
if queue.class_names.empty?
|
86
|
+
collection
|
87
|
+
else
|
88
|
+
collection.select{|object| queue.class_names.include?(object.record_class_name)}
|
89
|
+
end
|
90
|
+
collection_to_reset.each do |object|
|
91
|
+
object.run_at = Time.now.utc
|
92
|
+
object.attempts = 0
|
93
|
+
object.error = nil
|
94
|
+
object.is_locked = false
|
95
|
+
@connection.hset(@datastore_name, "#{object.record_class_name}_#{object.record_id}", object.json_formatted)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def next_batch! (queue)
|
100
|
+
object_array = []
|
101
|
+
collection_to_process =
|
102
|
+
if queue.class_names.empty?
|
103
|
+
collection
|
104
|
+
else
|
105
|
+
collection.select{|object| queue.class_names.include?(object.record_class_name)}
|
106
|
+
end
|
107
|
+
collection_to_process.each do |object|
|
108
|
+
object_array << object if (Time.parse(object.run_at) <= Time.now.utc) && !object.is_locked
|
109
|
+
end
|
110
|
+
sliced_object_array = object_array.slice!(0..(queue.batch_size - 1))
|
111
|
+
sliced_object_array = sliced_object_array.nil? ? [] : sliced_object_array
|
112
|
+
sliced_object_array.each do |object|
|
113
|
+
object.is_locked = true
|
114
|
+
@connection.hset @datastore_name, "#{object.record_class_name}_#{object.record_id}", object.json_formatted
|
115
|
+
end
|
116
|
+
sliced_object_array
|
117
|
+
end
|
118
|
+
|
119
|
+
def add(klass, id, delete, priority)
|
120
|
+
redis_object = if @connection.hexists(@datastore_name, "#{klass.name}_#{id}") && !find_entry("#{klass.name}_#{id}").is_locked
|
121
|
+
find_entry("#{klass.name}_#{id}")
|
122
|
+
else
|
123
|
+
if @connection.hexists(@datastore_name, "#{klass.name}_#{id}_dup") && !find_entry("#{klass.name}_#{id}_dup").is_locked
|
124
|
+
find_entry("#{klass.name}_#{id}_dup")
|
125
|
+
else
|
126
|
+
new(:priority => priority, :record_class_name => klass.name, :record_id => id)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
redis_object.is_delete = delete
|
130
|
+
redis_object.priority = priority if priority > redis_object.priority
|
131
|
+
redis_object.run_at = Time.now.utc
|
132
|
+
redis_key = (@connection.hexists(@datastore_name, "#{klass.name}_#{id}") && find_entry("#{klass.name}_#{id}").is_locked) ?
|
133
|
+
"#{klass.name}_#{id}_dup" :
|
134
|
+
"#{klass.name}_#{id}"
|
135
|
+
redis_object.duplicate = @connection.hexists(@datastore_name, "#{klass.name}_#{id}") && find_entry("#{klass.name}_#{id}").is_locked
|
136
|
+
@connection.hset(@datastore_name, redis_key, redis_object.json_formatted)
|
137
|
+
end
|
138
|
+
|
139
|
+
def create(attributes)
|
140
|
+
redis_object = new(attributes)
|
141
|
+
@connection.hset(@datastore_name, "#{redis_object.record_class_name}_#{redis_object.record_id}", redis_object.json_formatted)
|
142
|
+
redis_object
|
143
|
+
end
|
144
|
+
|
145
|
+
def delete_entries (records)
|
146
|
+
records.each do |record|
|
147
|
+
redis_key = "#{record.record_class_name}_#{record.record_id}"
|
148
|
+
redis_key << "_dup" if record.duplicate
|
149
|
+
@connection.hdel @datastore_name, redis_key
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def find_entry(id)
|
154
|
+
@connection.hexists(@datastore_name, id) ?
|
155
|
+
new(JSON.parse(@connection.hget(@datastore_name, id))) : nil
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def initialize(options = {})
|
160
|
+
[:record_id, :record_class_name, :is_delete, :run_at, :priority, :error, :attempts, :is_locked, :duplicate].each do |attribute|
|
161
|
+
instance_variable_set("@#{attribute.to_s}", options[attribute] || options[attribute.to_s])
|
162
|
+
@attempts ||= 0
|
163
|
+
@priority ||= 0
|
164
|
+
@is_delete ||= false
|
165
|
+
@is_locked ||= false
|
166
|
+
@duplicate ||= false
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
def json_formatted
|
171
|
+
JSON.dump("record_id" => self.record_id, "record_class_name" => self.record_class_name, "is_delete" => self.is_delete, "duplicate" => self.duplicate,
|
172
|
+
"run_at" => self.run_at, "priority" => self.priority, "error" => self.error, "attempts" => self.attempts, "is_locked" => self.is_locked)
|
173
|
+
end
|
174
|
+
|
175
|
+
def set_error! (error, retry_interval = nil)
|
176
|
+
self.attempts += 1
|
177
|
+
self.run_at = Time.now.utc + (retry_interval * attempts) if retry_interval
|
178
|
+
self.error = "#{error.class.name}: #{error.message}\n#{error.backtrace.join("\n")[0, 4000]}"
|
179
|
+
begin
|
180
|
+
self.class.connection.hset(self.class.datastore_name, "#{self.record_class_name}_#{self.record_id}", self.json_formatted)
|
181
|
+
rescue => e
|
182
|
+
if logger = self.class.logger
|
183
|
+
logger.warn(error)
|
184
|
+
logger.warn(e)
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
def reset!
|
190
|
+
begin
|
191
|
+
self.run_at = Time.now.utc
|
192
|
+
self.attempts = 0
|
193
|
+
self.error = nil
|
194
|
+
self.class.connection.hset(self.class.datastore_name, "#{self.record_class_name}_#{self.record_id}", self.json_formatted)
|
195
|
+
rescue => e
|
196
|
+
if logger = self.class.logger
|
197
|
+
logger.warn(e)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
def id
|
203
|
+
"#{record_class_name}_#{record_id}"
|
204
|
+
end
|
205
|
+
|
206
|
+
def is_delete?
|
207
|
+
is_delete
|
208
|
+
end
|
209
|
+
|
210
|
+
def <=> (redis_object)
|
211
|
+
priority.nil? ? (redis_object.run_at <=> self.run_at) : (redis_object.priority <=> self.priority)
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
data/spec/entry_spec.rb
CHANGED
@@ -111,21 +111,44 @@ describe Sunspot::IndexQueue::Entry do
|
|
111
111
|
lambda{ Sunspot::IndexQueue::Entry.enqueue(queue, Object, 1, false) }.should raise_error(ArgumentError)
|
112
112
|
end
|
113
113
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
114
|
+
context "load all records" do
|
115
|
+
it "should load all records for an array of entries at once" do
|
116
|
+
entry_1 = Sunspot::IndexQueue::Entry.implementation.new(:record_class_name => "Sunspot::IndexQueue::Test::Searchable", :record_id => 1)
|
117
|
+
entry_2 = Sunspot::IndexQueue::Entry.implementation.new(:record_class_name => "Sunspot::IndexQueue::Test::Searchable", :record_id => 2)
|
118
|
+
entry_3 = Sunspot::IndexQueue::Entry.implementation.new(:record_class_name => "Sunspot::IndexQueue::Test::Searchable::Subclass", :record_id => 3)
|
119
|
+
Sunspot::IndexQueue::Entry.load_all_records([entry_1, entry_2, entry_3])
|
120
|
+
record_1 = entry_1.instance_variable_get(:@record)
|
121
|
+
record_1.should == Sunspot::IndexQueue::Test::Searchable.new(1)
|
122
|
+
entry_1.record.object_id.should == record_1.object_id
|
123
|
+
record_2 = entry_2.instance_variable_get(:@record)
|
124
|
+
record_2.should == Sunspot::IndexQueue::Test::Searchable.new(2)
|
125
|
+
entry_2.record.object_id.should == record_2.object_id
|
126
|
+
record_3 = entry_3.instance_variable_get(:@record)
|
127
|
+
record_3.should == Sunspot::IndexQueue::Test::Searchable::Subclass.new(3)
|
128
|
+
entry_3.record.object_id.should == record_3.object_id
|
129
|
+
end
|
130
|
+
|
131
|
+
it "should load all records for an array of entries at once even if ids clash between record class names" do
|
132
|
+
entry_1 = Sunspot::IndexQueue::Entry.implementation.new(:record_class_name => "Sunspot::IndexQueue::Test::Searchable", :record_id => 1)
|
133
|
+
entry_2 = Sunspot::IndexQueue::Entry.implementation.new(:record_class_name => "Sunspot::IndexQueue::Test::Searchable", :record_id => 2)
|
134
|
+
entry_3 = Sunspot::IndexQueue::Entry.implementation.new(:record_class_name => "Sunspot::IndexQueue::Test::Searchable::Subclass", :record_id => 1)
|
135
|
+
entry_4 = Sunspot::IndexQueue::Entry.implementation.new(:record_class_name => "Sunspot::IndexQueue::Test::Searchable::Subclass", :record_id => 2)
|
136
|
+
Sunspot::IndexQueue::Entry.load_all_records([entry_1, entry_2, entry_3, entry_4])
|
137
|
+
record_1 = entry_1.instance_variable_get(:@record)
|
138
|
+
record_1.should == Sunspot::IndexQueue::Test::Searchable.new(1)
|
139
|
+
entry_1.record.object_id.should == record_1.object_id
|
140
|
+
record_2 = entry_2.instance_variable_get(:@record)
|
141
|
+
record_2.should == Sunspot::IndexQueue::Test::Searchable.new(2)
|
142
|
+
entry_2.record.object_id.should == record_2.object_id
|
143
|
+
record_3 = entry_3.instance_variable_get(:@record)
|
144
|
+
record_3.should == Sunspot::IndexQueue::Test::Searchable::Subclass.new(1)
|
145
|
+
entry_3.record.object_id.should == record_3.object_id
|
146
|
+
record_4 = entry_4.instance_variable_get(:@record)
|
147
|
+
record_4.should == Sunspot::IndexQueue::Test::Searchable::Subclass.new(2)
|
148
|
+
entry_4.record.object_id.should == record_4.object_id
|
149
|
+
end
|
128
150
|
end
|
151
|
+
|
129
152
|
end
|
130
153
|
|
131
154
|
context "instance methods" do
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require File.expand_path('../spec_helper', __FILE__)
|
2
|
+
require File.expand_path('../entry_impl_examples', __FILE__)
|
3
|
+
|
4
|
+
describe Sunspot::IndexQueue::Entry::RedisImpl do
|
5
|
+
|
6
|
+
before :all do
|
7
|
+
Sunspot::IndexQueue::Entry.implementation = :redis
|
8
|
+
Sunspot::IndexQueue::Entry::RedisImpl.connection = 'localhost'
|
9
|
+
Sunspot::IndexQueue::Entry::RedisImpl.datastore_name = "sunspot_index_queue_test"
|
10
|
+
end
|
11
|
+
|
12
|
+
after :all do
|
13
|
+
Sunspot::IndexQueue::Entry.implementation = nil
|
14
|
+
end
|
15
|
+
|
16
|
+
let(:factory) do
|
17
|
+
factory = Object.new
|
18
|
+
def factory.create (attributes)
|
19
|
+
Sunspot::IndexQueue::Entry::RedisImpl.create(attributes)
|
20
|
+
end
|
21
|
+
|
22
|
+
def factory.delete_all
|
23
|
+
collection = Sunspot::IndexQueue::Entry::RedisImpl.collection
|
24
|
+
Sunspot::IndexQueue::Entry::RedisImpl.delete_entries(collection)
|
25
|
+
end
|
26
|
+
|
27
|
+
def factory.find (id)
|
28
|
+
Sunspot::IndexQueue::Entry::RedisImpl.find_entry(id)
|
29
|
+
end
|
30
|
+
|
31
|
+
factory
|
32
|
+
end
|
33
|
+
|
34
|
+
it_should_behave_like "Entry implementation"
|
35
|
+
|
36
|
+
end
|
data/sunspot_index_queue.gemspec
CHANGED
@@ -4,14 +4,14 @@
|
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
|
-
s.name =
|
8
|
-
s.version = "1.1.
|
7
|
+
s.name = "sunspot_index_queue"
|
8
|
+
s.version = "1.1.4"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Brian Durand"]
|
12
|
-
s.date =
|
13
|
-
s.description =
|
14
|
-
s.email =
|
12
|
+
s.date = "2012-06-19"
|
13
|
+
s.description = "This gem provides asynchronous indexing to Solr for the sunspot gem. It uses a pluggable model for the backing queue and provides support for ActiveRecord, DataMapper, and MongoDB out of the box."
|
14
|
+
s.email = "brian@embellishedvisions.com"
|
15
15
|
s.extra_rdoc_files = [
|
16
16
|
"README.rdoc"
|
17
17
|
]
|
@@ -28,6 +28,7 @@ Gem::Specification.new do |s|
|
|
28
28
|
"lib/sunspot/index_queue/entry/active_record_impl.rb",
|
29
29
|
"lib/sunspot/index_queue/entry/data_mapper_impl.rb",
|
30
30
|
"lib/sunspot/index_queue/entry/mongo_impl.rb",
|
31
|
+
"lib/sunspot/index_queue/entry/redis_impl.rb",
|
31
32
|
"lib/sunspot/index_queue/session_proxy.rb",
|
32
33
|
"lib/sunspot_index_queue.rb",
|
33
34
|
"spec/active_record_impl_spec.rb",
|
@@ -38,15 +39,16 @@ Gem::Specification.new do |s|
|
|
38
39
|
"spec/index_queue_spec.rb",
|
39
40
|
"spec/integration_spec.rb",
|
40
41
|
"spec/mongo_impl_spec.rb",
|
42
|
+
"spec/redis_impl_spec.rb",
|
41
43
|
"spec/session_proxy_spec.rb",
|
42
44
|
"spec/spec_helper.rb",
|
43
45
|
"sunspot_index_queue.gemspec"
|
44
46
|
]
|
45
|
-
s.homepage =
|
47
|
+
s.homepage = "http://github.com/bdurand/sunspot_index_queue"
|
46
48
|
s.rdoc_options = ["--charset=UTF-8", "--main", "README.rdoc", "MIT_LICENSE"]
|
47
49
|
s.require_paths = ["lib"]
|
48
|
-
s.rubygems_version =
|
49
|
-
s.summary =
|
50
|
+
s.rubygems_version = "1.8.11"
|
51
|
+
s.summary = "Asynchronous Solr indexing support for the sunspot gem with an emphasis on reliablity and throughput."
|
50
52
|
|
51
53
|
if s.respond_to? :specification_version then
|
52
54
|
s.specification_version = 3
|
@@ -60,6 +62,7 @@ Gem::Specification.new do |s|
|
|
60
62
|
s.add_development_dependency(%q<dm-migrations>, [">= 1.0.0"])
|
61
63
|
s.add_development_dependency(%q<dm-sqlite-adapter>, [">= 1.0.0"])
|
62
64
|
s.add_development_dependency(%q<mongo>, [">= 0"])
|
65
|
+
s.add_development_dependency(%q<redis>, [">= 0"])
|
63
66
|
s.add_development_dependency(%q<rspec>, [">= 2.0.0"])
|
64
67
|
s.add_development_dependency(%q<jeweler>, [">= 0"])
|
65
68
|
else
|
@@ -71,6 +74,7 @@ Gem::Specification.new do |s|
|
|
71
74
|
s.add_dependency(%q<dm-migrations>, [">= 1.0.0"])
|
72
75
|
s.add_dependency(%q<dm-sqlite-adapter>, [">= 1.0.0"])
|
73
76
|
s.add_dependency(%q<mongo>, [">= 0"])
|
77
|
+
s.add_dependency(%q<redis>, [">= 0"])
|
74
78
|
s.add_dependency(%q<rspec>, [">= 2.0.0"])
|
75
79
|
s.add_dependency(%q<jeweler>, [">= 0"])
|
76
80
|
end
|
@@ -83,6 +87,7 @@ Gem::Specification.new do |s|
|
|
83
87
|
s.add_dependency(%q<dm-migrations>, [">= 1.0.0"])
|
84
88
|
s.add_dependency(%q<dm-sqlite-adapter>, [">= 1.0.0"])
|
85
89
|
s.add_dependency(%q<mongo>, [">= 0"])
|
90
|
+
s.add_dependency(%q<redis>, [">= 0"])
|
86
91
|
s.add_dependency(%q<rspec>, [">= 2.0.0"])
|
87
92
|
s.add_dependency(%q<jeweler>, [">= 0"])
|
88
93
|
end
|
metadata
CHANGED
@@ -1,185 +1,146 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: sunspot_index_queue
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.1.4
|
5
5
|
prerelease:
|
6
|
-
segments:
|
7
|
-
- 1
|
8
|
-
- 1
|
9
|
-
- 3
|
10
|
-
version: 1.1.3
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Brian Durand
|
14
9
|
autorequire:
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
dependencies:
|
21
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2012-06-19 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
22
15
|
name: sunspot
|
23
|
-
|
24
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
16
|
+
requirement: &70150273685320 !ruby/object:Gem::Requirement
|
25
17
|
none: false
|
26
|
-
requirements:
|
27
|
-
- -
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
hash: 19
|
30
|
-
segments:
|
31
|
-
- 1
|
32
|
-
- 1
|
33
|
-
- 0
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
34
21
|
version: 1.1.0
|
35
22
|
type: :runtime
|
36
|
-
version_requirements: *id001
|
37
|
-
- !ruby/object:Gem::Dependency
|
38
|
-
name: sqlite3
|
39
23
|
prerelease: false
|
40
|
-
|
24
|
+
version_requirements: *70150273685320
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: sqlite3
|
27
|
+
requirement: &70150273684740 !ruby/object:Gem::Requirement
|
41
28
|
none: false
|
42
|
-
requirements:
|
43
|
-
- -
|
44
|
-
- !ruby/object:Gem::Version
|
45
|
-
|
46
|
-
segments:
|
47
|
-
- 0
|
48
|
-
version: "0"
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
49
33
|
type: :development
|
50
|
-
version_requirements: *id002
|
51
|
-
- !ruby/object:Gem::Dependency
|
52
|
-
name: activerecord
|
53
34
|
prerelease: false
|
54
|
-
|
35
|
+
version_requirements: *70150273684740
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: activerecord
|
38
|
+
requirement: &70150273684220 !ruby/object:Gem::Requirement
|
55
39
|
none: false
|
56
|
-
requirements:
|
57
|
-
- -
|
58
|
-
- !ruby/object:Gem::Version
|
59
|
-
|
60
|
-
segments:
|
61
|
-
- 2
|
62
|
-
- 2
|
63
|
-
version: "2.2"
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '2.2'
|
64
44
|
type: :development
|
65
|
-
version_requirements: *id003
|
66
|
-
- !ruby/object:Gem::Dependency
|
67
|
-
name: dm-core
|
68
45
|
prerelease: false
|
69
|
-
|
46
|
+
version_requirements: *70150273684220
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: dm-core
|
49
|
+
requirement: &70150273683660 !ruby/object:Gem::Requirement
|
70
50
|
none: false
|
71
|
-
requirements:
|
72
|
-
- -
|
73
|
-
- !ruby/object:Gem::Version
|
74
|
-
hash: 23
|
75
|
-
segments:
|
76
|
-
- 1
|
77
|
-
- 0
|
78
|
-
- 0
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
79
54
|
version: 1.0.0
|
80
55
|
type: :development
|
81
|
-
version_requirements: *id004
|
82
|
-
- !ruby/object:Gem::Dependency
|
83
|
-
name: dm-aggregates
|
84
56
|
prerelease: false
|
85
|
-
|
57
|
+
version_requirements: *70150273683660
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: dm-aggregates
|
60
|
+
requirement: &70150273682620 !ruby/object:Gem::Requirement
|
86
61
|
none: false
|
87
|
-
requirements:
|
88
|
-
- -
|
89
|
-
- !ruby/object:Gem::Version
|
90
|
-
hash: 23
|
91
|
-
segments:
|
92
|
-
- 1
|
93
|
-
- 0
|
94
|
-
- 0
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
95
65
|
version: 1.0.0
|
96
66
|
type: :development
|
97
|
-
version_requirements: *id005
|
98
|
-
- !ruby/object:Gem::Dependency
|
99
|
-
name: dm-migrations
|
100
67
|
prerelease: false
|
101
|
-
|
68
|
+
version_requirements: *70150273682620
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: dm-migrations
|
71
|
+
requirement: &70150273681400 !ruby/object:Gem::Requirement
|
102
72
|
none: false
|
103
|
-
requirements:
|
104
|
-
- -
|
105
|
-
- !ruby/object:Gem::Version
|
106
|
-
hash: 23
|
107
|
-
segments:
|
108
|
-
- 1
|
109
|
-
- 0
|
110
|
-
- 0
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
111
76
|
version: 1.0.0
|
112
77
|
type: :development
|
113
|
-
version_requirements: *id006
|
114
|
-
- !ruby/object:Gem::Dependency
|
115
|
-
name: dm-sqlite-adapter
|
116
78
|
prerelease: false
|
117
|
-
|
79
|
+
version_requirements: *70150273681400
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: dm-sqlite-adapter
|
82
|
+
requirement: &70150273679860 !ruby/object:Gem::Requirement
|
118
83
|
none: false
|
119
|
-
requirements:
|
120
|
-
- -
|
121
|
-
- !ruby/object:Gem::Version
|
122
|
-
hash: 23
|
123
|
-
segments:
|
124
|
-
- 1
|
125
|
-
- 0
|
126
|
-
- 0
|
84
|
+
requirements:
|
85
|
+
- - ! '>='
|
86
|
+
- !ruby/object:Gem::Version
|
127
87
|
version: 1.0.0
|
128
88
|
type: :development
|
129
|
-
|
130
|
-
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: *70150273679860
|
91
|
+
- !ruby/object:Gem::Dependency
|
131
92
|
name: mongo
|
93
|
+
requirement: &70150273678380 !ruby/object:Gem::Requirement
|
94
|
+
none: false
|
95
|
+
requirements:
|
96
|
+
- - ! '>='
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
type: :development
|
132
100
|
prerelease: false
|
133
|
-
|
101
|
+
version_requirements: *70150273678380
|
102
|
+
- !ruby/object:Gem::Dependency
|
103
|
+
name: redis
|
104
|
+
requirement: &70150273693640 !ruby/object:Gem::Requirement
|
134
105
|
none: false
|
135
|
-
requirements:
|
136
|
-
- -
|
137
|
-
- !ruby/object:Gem::Version
|
138
|
-
|
139
|
-
segments:
|
140
|
-
- 0
|
141
|
-
version: "0"
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
142
110
|
type: :development
|
143
|
-
version_requirements: *id008
|
144
|
-
- !ruby/object:Gem::Dependency
|
145
|
-
name: rspec
|
146
111
|
prerelease: false
|
147
|
-
|
112
|
+
version_requirements: *70150273693640
|
113
|
+
- !ruby/object:Gem::Dependency
|
114
|
+
name: rspec
|
115
|
+
requirement: &70150273691420 !ruby/object:Gem::Requirement
|
148
116
|
none: false
|
149
|
-
requirements:
|
150
|
-
- -
|
151
|
-
- !ruby/object:Gem::Version
|
152
|
-
hash: 15
|
153
|
-
segments:
|
154
|
-
- 2
|
155
|
-
- 0
|
156
|
-
- 0
|
117
|
+
requirements:
|
118
|
+
- - ! '>='
|
119
|
+
- !ruby/object:Gem::Version
|
157
120
|
version: 2.0.0
|
158
121
|
type: :development
|
159
|
-
version_requirements: *id009
|
160
|
-
- !ruby/object:Gem::Dependency
|
161
|
-
name: jeweler
|
162
122
|
prerelease: false
|
163
|
-
|
123
|
+
version_requirements: *70150273691420
|
124
|
+
- !ruby/object:Gem::Dependency
|
125
|
+
name: jeweler
|
126
|
+
requirement: &70150273689740 !ruby/object:Gem::Requirement
|
164
127
|
none: false
|
165
|
-
requirements:
|
166
|
-
- -
|
167
|
-
- !ruby/object:Gem::Version
|
168
|
-
|
169
|
-
segments:
|
170
|
-
- 0
|
171
|
-
version: "0"
|
128
|
+
requirements:
|
129
|
+
- - ! '>='
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
172
132
|
type: :development
|
173
|
-
|
174
|
-
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: *70150273689740
|
135
|
+
description: This gem provides asynchronous indexing to Solr for the sunspot gem.
|
136
|
+
It uses a pluggable model for the backing queue and provides support for ActiveRecord,
|
137
|
+
DataMapper, and MongoDB out of the box.
|
175
138
|
email: brian@embellishedvisions.com
|
176
139
|
executables: []
|
177
|
-
|
178
140
|
extensions: []
|
179
|
-
|
180
|
-
extra_rdoc_files:
|
141
|
+
extra_rdoc_files:
|
181
142
|
- README.rdoc
|
182
|
-
files:
|
143
|
+
files:
|
183
144
|
- .travis.yml
|
184
145
|
- CHANGE_LOG.txt
|
185
146
|
- MIT_LICENSE
|
@@ -192,6 +153,7 @@ files:
|
|
192
153
|
- lib/sunspot/index_queue/entry/active_record_impl.rb
|
193
154
|
- lib/sunspot/index_queue/entry/data_mapper_impl.rb
|
194
155
|
- lib/sunspot/index_queue/entry/mongo_impl.rb
|
156
|
+
- lib/sunspot/index_queue/entry/redis_impl.rb
|
195
157
|
- lib/sunspot/index_queue/session_proxy.rb
|
196
158
|
- lib/sunspot_index_queue.rb
|
197
159
|
- spec/active_record_impl_spec.rb
|
@@ -202,45 +164,37 @@ files:
|
|
202
164
|
- spec/index_queue_spec.rb
|
203
165
|
- spec/integration_spec.rb
|
204
166
|
- spec/mongo_impl_spec.rb
|
167
|
+
- spec/redis_impl_spec.rb
|
205
168
|
- spec/session_proxy_spec.rb
|
206
169
|
- spec/spec_helper.rb
|
207
170
|
- sunspot_index_queue.gemspec
|
208
|
-
has_rdoc: true
|
209
171
|
homepage: http://github.com/bdurand/sunspot_index_queue
|
210
172
|
licenses: []
|
211
|
-
|
212
173
|
post_install_message:
|
213
|
-
rdoc_options:
|
174
|
+
rdoc_options:
|
214
175
|
- --charset=UTF-8
|
215
176
|
- --main
|
216
177
|
- README.rdoc
|
217
178
|
- MIT_LICENSE
|
218
|
-
require_paths:
|
179
|
+
require_paths:
|
219
180
|
- lib
|
220
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
181
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
221
182
|
none: false
|
222
|
-
requirements:
|
223
|
-
- -
|
224
|
-
- !ruby/object:Gem::Version
|
225
|
-
|
226
|
-
|
227
|
-
- 0
|
228
|
-
version: "0"
|
229
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
183
|
+
requirements:
|
184
|
+
- - ! '>='
|
185
|
+
- !ruby/object:Gem::Version
|
186
|
+
version: '0'
|
187
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
230
188
|
none: false
|
231
|
-
requirements:
|
232
|
-
- -
|
233
|
-
- !ruby/object:Gem::Version
|
234
|
-
|
235
|
-
segments:
|
236
|
-
- 0
|
237
|
-
version: "0"
|
189
|
+
requirements:
|
190
|
+
- - ! '>='
|
191
|
+
- !ruby/object:Gem::Version
|
192
|
+
version: '0'
|
238
193
|
requirements: []
|
239
|
-
|
240
194
|
rubyforge_project:
|
241
|
-
rubygems_version: 1.
|
195
|
+
rubygems_version: 1.8.11
|
242
196
|
signing_key:
|
243
197
|
specification_version: 3
|
244
|
-
summary: Asynchronous Solr indexing support for the sunspot gem with an emphasis on
|
198
|
+
summary: Asynchronous Solr indexing support for the sunspot gem with an emphasis on
|
199
|
+
reliablity and throughput.
|
245
200
|
test_files: []
|
246
|
-
|