acts_as_hashish 0.3.0 → 0.4.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.
- data/lib/acts_as_hashish.rb +1 -0
- data/lib/acts_as_hashish/hashish.rb +18 -81
- data/lib/acts_as_hashish/private_class_methods.rb +85 -0
- data/lib/acts_as_hashish/version.rb +1 -1
- data/spec/hashish_spec.rb +111 -20
- data/spec/spec_helper.rb +1 -1
- metadata +10 -9
data/lib/acts_as_hashish.rb
CHANGED
@@ -9,68 +9,25 @@ module Hashish
|
|
9
9
|
|
10
10
|
@options = options
|
11
11
|
extend ClassMethods
|
12
|
+
extend PrivateClassMethods
|
12
13
|
end
|
13
14
|
|
14
15
|
module ClassMethods
|
15
|
-
|
16
|
-
private
|
17
|
-
def get_hashish_key(item)
|
18
|
-
key = @options[:key]
|
19
|
-
key_value = key.is_a?(Proc) ? key.call(item) : item[key]
|
20
|
-
end
|
21
16
|
|
22
|
-
def
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
Hashish.redis_connection.srem("#{prefix}#INDEXES", member) if Hashish.redis_connection.zcard(member) == 0
|
17
|
+
def hashish_rebuild(data = nil)
|
18
|
+
hashish_wait_on_lock do
|
19
|
+
data ||= hashish_list(:page_size => 0)
|
20
|
+
hashish_flush!
|
27
21
|
end
|
28
|
-
Hashish.redis_connection.smembers("#{prefix}#SORTERS").each do |member|
|
29
|
-
if member =~ /^#{prefix}\$[\w]+@#{key}$/
|
30
|
-
Hashish.redis_connection.del(member)
|
31
|
-
Hashish.redis_connection.srem("#{prefix}#SORTERS", member)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
def add_hashish_metadata(name, category)
|
37
|
-
prefix = @options[:key_prefix]
|
38
|
-
Hashish.redis_connection.sadd("#{prefix}##{category}", name)
|
39
|
-
end
|
40
|
-
|
41
|
-
def redis_keys
|
42
|
-
Hashish.redis_connection.keys("#{@options[:key_prefix]}*").inject({}){|h,x| h[x] = Hashish.redis_connection.type(x);h}
|
43
|
-
end
|
44
|
-
|
45
|
-
def wait_on_lock(timeout = 0)
|
46
|
-
lock_key = "#{@options[:key_prefix]}#MUTEX_LOCK"
|
47
22
|
begin
|
48
|
-
Timeout::timeout(timeout) do
|
49
|
-
while Hashish.redis_connection.incr(lock_key) != 1
|
50
|
-
sleep(1)
|
51
|
-
end
|
52
|
-
end
|
53
23
|
yield if block_given?
|
54
24
|
ensure
|
55
|
-
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
public
|
60
|
-
def hashish_rebuild
|
61
|
-
temp = nil
|
62
|
-
wait_on_lock do
|
63
|
-
temp = hashish_list(:page_size => 0)
|
64
|
-
hashish_flush!
|
65
|
-
end
|
66
|
-
yield if block_given?
|
67
|
-
temp.each do |item|
|
68
|
-
hashish_insert(item)
|
25
|
+
hashish_insert(data, Time.now.to_i)
|
69
26
|
end
|
70
27
|
end
|
71
28
|
|
72
29
|
def hashish_flush!
|
73
|
-
|
30
|
+
hashish_redis_keys.each{|x| Hashish.redis_connection.del(x)}
|
74
31
|
end
|
75
32
|
|
76
33
|
def hashish_length
|
@@ -78,43 +35,23 @@ module Hashish
|
|
78
35
|
end
|
79
36
|
|
80
37
|
def hashish_delete(key = nil)
|
81
|
-
key ||=
|
38
|
+
key ||= hashish_get_key(hashish_list.first)
|
82
39
|
prefix = @options[:key_prefix]
|
83
40
|
Hashish.redis_connection.zrem("#{prefix}*", "#{prefix}@#{key}")
|
84
|
-
|
41
|
+
hashish_remove_metadata("#{key}")
|
85
42
|
Hashish.redis_connection.del("#{prefix}@#{key}")
|
86
43
|
end
|
87
44
|
|
88
|
-
def hashish_insert(
|
89
|
-
|
90
|
-
data
|
91
|
-
|
92
|
-
key = get_hashish_key(o)
|
93
|
-
raise "Error: Computed data key as '#{key}'. Only alphanumeric characters allowed!" unless key.to_s =~ /^[\w]+$/
|
94
|
-
Hashish.redis_connection.multi do
|
95
|
-
Hashish.redis_connection.zadd("#{prefix}*", t , "#{prefix}@#{key}")
|
96
|
-
# Hashish.redis_connection.zremrangebyrank("#{prefix}:", 0, -(@options[:max_size] + 1)) if @options[:max_size]
|
97
|
-
@options[:indexes].each do |index_field, index|
|
98
|
-
index_value = index.is_a?(Proc) ? index.call(o) : o[index]
|
99
|
-
if index_value.is_a?(Array)
|
100
|
-
index_value.each do |i|
|
101
|
-
Hashish.redis_connection.zadd("#{prefix}!#{index_field}=#{i}", t, "#{prefix}@#{key}") if i.is_a?(String)
|
102
|
-
add_hashish_metadata("#{prefix}!#{index_field}=#{i}", 'INDEXES')
|
103
|
-
end
|
104
|
-
else
|
105
|
-
Hashish.redis_connection.zadd("#{prefix}!#{index_field}=#{index_value}", t, "#{prefix}@#{key}")
|
106
|
-
add_hashish_metadata("#{prefix}!#{index_field}=#{index_value}", 'INDEXES')
|
107
|
-
end
|
108
|
-
end
|
109
|
-
@options[:sorters].each do |sort_field, sort|
|
110
|
-
sort_value = sort.is_a?(Proc) ? sort.call(o) : o[sort]
|
111
|
-
Hashish.redis_connection.set("#{prefix}$#{sort_field}@#{key}", sort_value)
|
112
|
-
add_hashish_metadata("#{prefix}$#{sort_field}@#{key}", 'SORTERS')
|
113
|
-
end
|
114
|
-
Hashish.redis_connection.set("#{prefix}@#{key}", data)
|
45
|
+
def hashish_insert(data, t = Time.now.to_i)
|
46
|
+
if data.is_a?(Array)
|
47
|
+
data.each do |d|
|
48
|
+
hashish_single_insert(d, t)
|
115
49
|
end
|
50
|
+
elsif data.is_a?(Hash)
|
51
|
+
hashish_single_insert(data, t)
|
52
|
+
else
|
53
|
+
raise "Data must be of type Hash or Array of Hash"
|
116
54
|
end
|
117
|
-
true
|
118
55
|
end
|
119
56
|
|
120
57
|
def hashish_list(options = {})
|
@@ -178,7 +115,7 @@ module Hashish
|
|
178
115
|
result = nil
|
179
116
|
if sort_by
|
180
117
|
custom_sort_key = "#{@options[:key_prefix]}#CUSTOM_SORT##{seq}"
|
181
|
-
Hashish.redis_connection.sort(result_key, :by => "
|
118
|
+
Hashish.redis_connection.sort(result_key, :by => "*$#{sort_by}",:get => '*', :store => custom_sort_key, :order => sort_order)
|
182
119
|
Hashish.redis_connection.expire(custom_sort_key, Hashish.redis_search_keys_ttl * 60)
|
183
120
|
result = Hashish.redis_connection.lrange(custom_sort_key, offset, limit -1)
|
184
121
|
else
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module Hashish
|
2
|
+
module PrivateClassMethods
|
3
|
+
|
4
|
+
private
|
5
|
+
def hashish_get_key(item)
|
6
|
+
key = @options[:key]
|
7
|
+
key_value = key.is_a?(Proc) ? key.call(item) : item[key]
|
8
|
+
end
|
9
|
+
|
10
|
+
def hashish_remove_metadata(key)
|
11
|
+
prefix = @options[:key_prefix]
|
12
|
+
Hashish.redis_connection.smembers("#{prefix}#INDEXES").each do |member|
|
13
|
+
Hashish.redis_connection.zrem(member, "#{prefix}@#{key}")
|
14
|
+
Hashish.redis_connection.srem("#{prefix}#INDEXES", member) if Hashish.redis_connection.zcard(member) == 0
|
15
|
+
end
|
16
|
+
Hashish.redis_connection.smembers("#{prefix}#SORTERS").each do |member|
|
17
|
+
if member =~ /^#{prefix}@#{key}\$.+$/
|
18
|
+
Hashish.redis_connection.del(member)
|
19
|
+
Hashish.redis_connection.srem("#{prefix}#SORTERS", member)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def hashish_add_metadata(name, category)
|
25
|
+
prefix = @options[:key_prefix]
|
26
|
+
Hashish.redis_connection.sadd("#{prefix}##{category}", name)
|
27
|
+
end
|
28
|
+
|
29
|
+
def hashish_wait_on_lock(timeout = 0)
|
30
|
+
lock_key = "#{@options[:key_prefix]}#MUTEX_LOCK"
|
31
|
+
begin
|
32
|
+
Timeout::timeout(timeout) do
|
33
|
+
while Hashish.redis_connection.incr(lock_key) != 1
|
34
|
+
sleep(1)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
yield if block_given?
|
38
|
+
ensure
|
39
|
+
Hashish.redis_connection.del(lock_key)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def hashish_redis_keys
|
44
|
+
Hashish.redis_connection.keys("#{@options[:key_prefix]}*")
|
45
|
+
end
|
46
|
+
|
47
|
+
def hashish_single_insert(o, t)
|
48
|
+
raise "Data must be of type Hash or Array of Hash" unless o.is_a?(Hash)
|
49
|
+
hashish_wait_on_lock do
|
50
|
+
data = o.to_json
|
51
|
+
prefix = @options[:key_prefix]
|
52
|
+
key = hashish_get_key(o)
|
53
|
+
raise "Error: Computed data key as '#{key}'. Only alphanumeric characters and underscore allowed!" unless key.to_s =~ /^[\w_]+$/
|
54
|
+
Hashish.redis_connection.multi do
|
55
|
+
Hashish.redis_connection.zadd("#{prefix}*", t , "#{prefix}@#{key}")
|
56
|
+
# Hashish.redis_connection.zremrangebyrank("#{prefix}:", 0, -(@options[:max_size] + 1)) if @options[:max_size]
|
57
|
+
@options[:indexes].each do |index_field, index|
|
58
|
+
index_value = index.is_a?(Proc) ? index.call(o) : o[index]
|
59
|
+
if index_value.is_a?(Array)
|
60
|
+
index_value.each do |i|
|
61
|
+
if i.is_a?(String) and !i.empty?
|
62
|
+
Hashish.redis_connection.zadd("#{prefix}!#{index_field}=#{i}", t, "#{prefix}@#{key}")
|
63
|
+
hashish_add_metadata("#{prefix}!#{index_field}=#{i}", 'INDEXES')
|
64
|
+
end
|
65
|
+
end
|
66
|
+
elsif index_value.is_a?(String) and !index_value.empty?
|
67
|
+
Hashish.redis_connection.zadd("#{prefix}!#{index_field}=#{index_value}", t, "#{prefix}@#{key}")
|
68
|
+
hashish_add_metadata("#{prefix}!#{index_field}=#{index_value}", 'INDEXES')
|
69
|
+
end
|
70
|
+
end
|
71
|
+
@options[:sorters].each do |sort_field, sort|
|
72
|
+
sort_value = sort.is_a?(Proc) ? sort.call(o) : o[sort]
|
73
|
+
if sort_value # only if there is a sort_value
|
74
|
+
Hashish.redis_connection.set("#{prefix}@#{key}$#{sort_field}", sort_value)
|
75
|
+
hashish_add_metadata("#{prefix}@#{key}$#{sort_field}", 'SORTERS')
|
76
|
+
end
|
77
|
+
end
|
78
|
+
Hashish.redis_connection.set("#{prefix}@#{key}", data)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
true
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
end
|
data/spec/hashish_spec.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require 'set'
|
2
3
|
|
3
4
|
describe Hashish do
|
4
5
|
|
5
6
|
before :each do
|
6
|
-
@sample_data_1 = {'id' => 1, 'name' => 'Joe'}
|
7
|
-
@sample_data_2 = {'id' => 3, 'name' => 'Doe'}
|
8
|
-
@sample_data_3 = {'id' => 2, 'name' => 'Moe'}
|
9
|
-
@sample_data_4 = {'id' => 4, 'name' => 'Loe'}
|
7
|
+
@sample_data_1 = {'id' => 1, 'name' => 'Joe', 'location' => 'Lisbon'}
|
8
|
+
@sample_data_2 = {'id' => 3, 'name' => 'Doe', 'location' => 'London'}
|
9
|
+
@sample_data_3 = {'id' => 2, 'name' => 'Moe', 'location' => 'Mumbai'}
|
10
|
+
@sample_data_4 = {'id' => 4, 'name' => 'Loe', 'location' => 'Goa'}
|
10
11
|
|
11
12
|
@primary_key = 'id'
|
12
13
|
|
@@ -23,7 +24,7 @@ describe Hashish do
|
|
23
24
|
|
24
25
|
@options = SampleClass.instance_variable_get(:@options)
|
25
26
|
end
|
26
|
-
|
27
|
+
|
27
28
|
describe ".acts_as_hashish" do
|
28
29
|
it "should hashify the class" do
|
29
30
|
@options = SampleClass.instance_variable_get(:@options)
|
@@ -37,18 +38,18 @@ describe Hashish do
|
|
37
38
|
describe ".hashish_insert" do
|
38
39
|
it "should insert the data into the list" do
|
39
40
|
SampleClass.hashish_insert(@sample_data_1)
|
40
|
-
Hashish.redis_connection.zscore("#{@options[:key_prefix]}*", "#{@options[:key_prefix]}@#{SampleClass.send(:
|
41
|
+
Hashish.redis_connection.zscore("#{@options[:key_prefix]}*", "#{@options[:key_prefix]}@#{SampleClass.send(:hashish_get_key, @sample_data_1)}").should_not be_nil
|
41
42
|
end
|
42
43
|
|
43
44
|
it "should create appropriate indexes" do
|
44
45
|
SampleClass.hashish_insert(@sample_data_1)
|
45
|
-
Hashish.redis_connection.zscore("#{@options[:key_prefix]}!#{@index_name}=#{@sample_data_1[@index_value]}", "#{@options[:key_prefix]}@#{SampleClass.send(:
|
46
|
-
Hashish.redis_connection.zscore("#{@options[:key_prefix]}!#{@proc_index_name}=#{@proc_index_value.call(@sample_data_1)}", "#{@options[:key_prefix]}@#{SampleClass.send(:
|
46
|
+
Hashish.redis_connection.zscore("#{@options[:key_prefix]}!#{@index_name}=#{@sample_data_1[@index_value]}", "#{@options[:key_prefix]}@#{SampleClass.send(:hashish_get_key, @sample_data_1)}").should_not be_nil
|
47
|
+
Hashish.redis_connection.zscore("#{@options[:key_prefix]}!#{@proc_index_name}=#{@proc_index_value.call(@sample_data_1)}", "#{@options[:key_prefix]}@#{SampleClass.send(:hashish_get_key, @sample_data_1)}").should_not be_nil
|
47
48
|
end
|
48
49
|
|
49
50
|
it "should create appropriate sorters" do
|
50
51
|
SampleClass.hashish_insert(@sample_data_1)
|
51
|
-
Hashish.redis_connection.get("#{@options[:key_prefix]}
|
52
|
+
Hashish.redis_connection.get("#{@options[:key_prefix]}@#{SampleClass.send(:hashish_get_key, @sample_data_1)}$#{@sorter_name}").should == @sample_data_1[@sorter_value].to_s
|
52
53
|
end
|
53
54
|
end
|
54
55
|
|
@@ -56,19 +57,108 @@ describe Hashish do
|
|
56
57
|
it "should delete the data from the list" do
|
57
58
|
SampleClass.hashish_insert(@sample_data_1)
|
58
59
|
SampleClass.hashish_delete(@sample_data_1[@primary_key])
|
59
|
-
Hashish.redis_connection.zscore("#{@options[:key_prefix]}:", "#{@options[:key_prefix]}:#{SampleClass.send(:
|
60
|
-
Hashish.redis_connection.exists("#{@options[:key_prefix]}:#{SampleClass.send(:
|
60
|
+
Hashish.redis_connection.zscore("#{@options[:key_prefix]}:", "#{@options[:key_prefix]}:#{SampleClass.send(:hashish_get_key, @sample_data_1)}").should be_nil
|
61
|
+
Hashish.redis_connection.exists("#{@options[:key_prefix]}:#{SampleClass.send(:hashish_get_key, @sample_data_1)}").should be_false
|
61
62
|
end
|
62
63
|
|
63
64
|
it "should delete appropriate sorters and indexes" do
|
64
65
|
SampleClass.hashish_insert(@sample_data_1)
|
65
66
|
SampleClass.hashish_delete(@sample_data_1[@primary_key])
|
66
|
-
SampleClass.send(:
|
67
|
+
SampleClass.send(:hashish_redis_keys).should == []
|
67
68
|
end
|
68
69
|
end
|
69
70
|
|
70
71
|
describe ".hashish_list" do
|
71
|
-
it "should
|
72
|
+
it "should return all the items from the list" do
|
73
|
+
test_data = [@sample_data_2, @sample_data_1, @sample_data_3]
|
74
|
+
test_data.each do |data|
|
75
|
+
SampleClass.hashish_insert(data)
|
76
|
+
end
|
77
|
+
test_data.each do |data|
|
78
|
+
SampleClass.hashish_list.include?(data).should be_true
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should not return any items that are not from the list" do
|
83
|
+
test_data = [@sample_data_2, @sample_data_1, @sample_data_3]
|
84
|
+
test_data.each do |data|
|
85
|
+
SampleClass.hashish_insert(data)
|
86
|
+
end
|
87
|
+
SampleClass.hashish_list.include?(@sample_data_4).should be_false
|
88
|
+
end
|
89
|
+
|
90
|
+
context "when sort_by is not specified" do
|
91
|
+
it "should sort the items based on the insert time with no specified sorter" do
|
92
|
+
test_data = [@sample_data_2, @sample_data_1, @sample_data_3]
|
93
|
+
test_data.each do |data|
|
94
|
+
SampleClass.hashish_insert(data)
|
95
|
+
sleep(1) # avoid exact same time of insert (redis is quick!!!)
|
96
|
+
end
|
97
|
+
SampleClass.hashish_list.should == test_data
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
context "when sort_by is not specified and sort_order is DESC" do
|
102
|
+
it "should sort the items based on the insert time with no specified sorter" do
|
103
|
+
test_data = [@sample_data_2, @sample_data_1, @sample_data_3]
|
104
|
+
test_data.each do |data|
|
105
|
+
SampleClass.hashish_insert(data)
|
106
|
+
sleep(1) # avoid exact same time of insert (redis is quick!!!)
|
107
|
+
end
|
108
|
+
SampleClass.hashish_list(:sort_order => 'DESC').should == test_data.reverse
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
context "when sort_by is specified and sort_order is not specified" do
|
113
|
+
it "should sort the items based on the sorter with a specified sorter" do
|
114
|
+
test_data = [@sample_data_2, @sample_data_1, @sample_data_3]
|
115
|
+
test_data.each do |data|
|
116
|
+
SampleClass.hashish_insert(data)
|
117
|
+
end
|
118
|
+
SampleClass.hashish_list(:sort_by => @sorter_name).should == [@sample_data_1, @sample_data_3, @sample_data_2]
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
context "when sort_by is specified and sort_order is DESC" do
|
123
|
+
it "should sort the items based on the sorter with a specified sorter" do
|
124
|
+
test_data = [@sample_data_2, @sample_data_1, @sample_data_3]
|
125
|
+
test_data.each do |data|
|
126
|
+
SampleClass.hashish_insert(data)
|
127
|
+
end
|
128
|
+
SampleClass.hashish_list(:sort_by => @sorter_name, :sort_order => 'DESC').should == [@sample_data_1, @sample_data_3, @sample_data_2].reverse
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
context "when a filter is provided" do
|
133
|
+
it "should find items using indexes based on filters" do
|
134
|
+
test_data = [@sample_data_2, @sample_data_1, @sample_data_3]
|
135
|
+
test_data.each do |data|
|
136
|
+
SampleClass.hashish_insert(data)
|
137
|
+
end
|
138
|
+
SampleClass.hashish_list(:filters => {@index_name => 'Moe'}).should == [@sample_data_3]
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
context "when a multiple values for filter is provided (OR)" do
|
143
|
+
it "should find items using indexes based on multiple values for filters" do
|
144
|
+
test_data = [@sample_data_2, @sample_data_1, @sample_data_3]
|
145
|
+
test_data.each do |data|
|
146
|
+
SampleClass.hashish_insert(data)
|
147
|
+
end
|
148
|
+
SampleClass.hashish_list(:filters => {@index_name => ['Moe', 'Joe']}).should == [@sample_data_1, @sample_data_3]
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
context "when a multiple filters are provided (AND)" do
|
153
|
+
it "should find items using indexes based on multiple filters" do
|
154
|
+
test_data = [@sample_data_2, @sample_data_1, @sample_data_3]
|
155
|
+
test_data.each do |data|
|
156
|
+
SampleClass.hashish_insert(data)
|
157
|
+
end
|
158
|
+
SampleClass.hashish_list(:filters => {@index_name => 'Joe', @proc_index_name => ['1=>Joe']}).should == [@sample_data_1]
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
72
162
|
end
|
73
163
|
|
74
164
|
describe ".hashish_flush!" do
|
@@ -77,7 +167,7 @@ describe Hashish do
|
|
77
167
|
SampleClass.hashish_insert(@sample_data_2)
|
78
168
|
SampleClass.hashish_insert(@sample_data_3)
|
79
169
|
SampleClass.hashish_flush!
|
80
|
-
SampleClass.send(:
|
170
|
+
SampleClass.send(:hashish_redis_keys).should == []
|
81
171
|
end
|
82
172
|
end
|
83
173
|
|
@@ -90,24 +180,25 @@ describe Hashish do
|
|
90
180
|
end
|
91
181
|
|
92
182
|
describe ".hashish_rebuild" do
|
93
|
-
it "should
|
183
|
+
it "should build the list correctly" do
|
94
184
|
SampleClass.hashish_insert(@sample_data_1)
|
95
185
|
SampleClass.hashish_insert(@sample_data_2)
|
96
186
|
SampleClass.hashish_insert(@sample_data_3)
|
97
|
-
before = SampleClass.
|
187
|
+
before = SampleClass.hashish_list
|
98
188
|
SampleClass.hashish_rebuild
|
99
|
-
after = SampleClass.
|
189
|
+
after = SampleClass.hashish_list
|
100
190
|
before.should == after
|
101
191
|
end
|
192
|
+
|
102
193
|
end
|
103
194
|
|
104
|
-
describe ".
|
195
|
+
describe ".hashish_wait_on_lock" do
|
105
196
|
it "should avoid concurrency issues" do
|
106
197
|
x = 0
|
107
198
|
threads = []
|
108
199
|
(0..1).each do |i|
|
109
200
|
threads << Thread.new do
|
110
|
-
SampleClass.send(:
|
201
|
+
SampleClass.send(:hashish_wait_on_lock) do
|
111
202
|
a = x + 1
|
112
203
|
sleep(5)
|
113
204
|
x = a
|
@@ -118,6 +209,6 @@ describe Hashish do
|
|
118
209
|
x.should == 2
|
119
210
|
end
|
120
211
|
end
|
121
|
-
|
212
|
+
|
122
213
|
end
|
123
214
|
|
data/spec/spec_helper.rb
CHANGED
@@ -16,7 +16,7 @@ RSpec.configure do |config|
|
|
16
16
|
|
17
17
|
config.before(:all) do
|
18
18
|
Hashish.configure do |configuration|
|
19
|
-
configuration.redis_connection = Redis.new(:db => 15, :host => '
|
19
|
+
configuration.redis_connection = Redis.new(:db => 15, :host => '127.0.0.1')
|
20
20
|
configuration.redis_namespace = 'hashish_test_namspace'
|
21
21
|
end
|
22
22
|
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: acts_as_hashish
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.
|
5
|
+
version: 0.4.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Schubert Cardozo
|
@@ -18,9 +18,9 @@ dependencies:
|
|
18
18
|
requirement: &id001 !ruby/object:Gem::Requirement
|
19
19
|
none: false
|
20
20
|
requirements:
|
21
|
-
- -
|
21
|
+
- - ~>
|
22
22
|
- !ruby/object:Gem::Version
|
23
|
-
version:
|
23
|
+
version: 3.0.2
|
24
24
|
type: :runtime
|
25
25
|
version_requirements: *id001
|
26
26
|
- !ruby/object:Gem::Dependency
|
@@ -29,9 +29,9 @@ dependencies:
|
|
29
29
|
requirement: &id002 !ruby/object:Gem::Requirement
|
30
30
|
none: false
|
31
31
|
requirements:
|
32
|
-
- -
|
32
|
+
- - ~>
|
33
33
|
- !ruby/object:Gem::Version
|
34
|
-
version:
|
34
|
+
version: 1.6.6
|
35
35
|
type: :runtime
|
36
36
|
version_requirements: *id002
|
37
37
|
- !ruby/object:Gem::Dependency
|
@@ -42,7 +42,7 @@ dependencies:
|
|
42
42
|
requirements:
|
43
43
|
- - ">="
|
44
44
|
- !ruby/object:Gem::Version
|
45
|
-
version:
|
45
|
+
version: 10.0.3
|
46
46
|
type: :development
|
47
47
|
version_requirements: *id003
|
48
48
|
- !ruby/object:Gem::Dependency
|
@@ -53,7 +53,7 @@ dependencies:
|
|
53
53
|
requirements:
|
54
54
|
- - ">="
|
55
55
|
- !ruby/object:Gem::Version
|
56
|
-
version:
|
56
|
+
version: 2.11.0
|
57
57
|
type: :development
|
58
58
|
version_requirements: *id004
|
59
59
|
- !ruby/object:Gem::Dependency
|
@@ -64,10 +64,10 @@ dependencies:
|
|
64
64
|
requirements:
|
65
65
|
- - ">="
|
66
66
|
- !ruby/object:Gem::Version
|
67
|
-
version:
|
67
|
+
version: 0.12.7
|
68
68
|
type: :development
|
69
69
|
version_requirements: *id005
|
70
|
-
description: A sortable and searchable list backed by Redis
|
70
|
+
description: A sortable and searchable list backed by Redis. You can use it as a quick actionable workflow queue which you can search/sort and paginate thorough
|
71
71
|
email:
|
72
72
|
- cardozoschubert@gmail.com
|
73
73
|
executables: []
|
@@ -79,6 +79,7 @@ extra_rdoc_files: []
|
|
79
79
|
files:
|
80
80
|
- lib/acts_as_hashish/configuration.rb
|
81
81
|
- lib/acts_as_hashish/hashish.rb
|
82
|
+
- lib/acts_as_hashish/private_class_methods.rb
|
82
83
|
- lib/acts_as_hashish/version.rb
|
83
84
|
- lib/acts_as_hashish.rb
|
84
85
|
- spec/hashish_spec.rb
|