lark 0.0.1 → 0.0.2
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/README.markdown +10 -8
- data/VERSION +1 -1
- data/lib/lark.rb +88 -63
- data/spec/lark_spec.rb +9 -8
- metadata +3 -3
data/README.markdown
CHANGED
@@ -3,20 +3,22 @@
|
|
3
3
|
Lark is a simple system to store local cache in a cluster of redis servers, be
|
4
4
|
able to query state about other lark nodes, and notice when one goes offline.
|
5
5
|
|
6
|
-
Lark.
|
6
|
+
Lark.on_expired do |id|
|
7
7
|
Log.debug "Lost node #{id}"
|
8
8
|
end
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
Lark.configure :domain => "staging", :expire => 60
|
11
|
+
|
12
|
+
EM.run do
|
13
|
+
lark = Lark::Base.new "bottom_node.1", "group3", "ip" => "127.0.0.1", "role" => "worker node"
|
14
|
+
|
15
|
+
EM::PeriodicTimer.new(5) do
|
14
16
|
lark.set "load" => get_load, "mem_usage" => get_mem_usage
|
15
17
|
end
|
16
18
|
|
17
19
|
on_some_event do
|
18
|
-
|
19
|
-
check_on_node(
|
20
|
-
|
20
|
+
Lark.get(:group3).each do |n|
|
21
|
+
check_on_node(n)
|
22
|
+
end
|
21
23
|
end
|
22
24
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.2
|
data/lib/lark.rb
CHANGED
@@ -2,11 +2,27 @@ require 'redis'
|
|
2
2
|
|
3
3
|
class LarkDBOffline < Exception ; end
|
4
4
|
|
5
|
-
|
6
|
-
attr_accessor :id
|
5
|
+
module Lark
|
6
|
+
# attr_accessor :id
|
7
7
|
|
8
|
-
|
9
|
-
|
8
|
+
extend self;
|
9
|
+
|
10
|
+
def configure(options)
|
11
|
+
@domain = options[:domain]
|
12
|
+
@expire = options[:expire]
|
13
|
+
@urls = options[:urls]
|
14
|
+
end
|
15
|
+
|
16
|
+
def domain
|
17
|
+
@domain.to_s
|
18
|
+
end
|
19
|
+
|
20
|
+
def urls
|
21
|
+
if @urls
|
22
|
+
@urls
|
23
|
+
elsif @url
|
24
|
+
[ @url ]
|
25
|
+
elsif ENV['LARK_URLS']
|
10
26
|
ENV['LARK_URLS'].split(",")
|
11
27
|
elsif ENV['LARK_URL']
|
12
28
|
[ ENV['LARK_URL'] ]
|
@@ -15,20 +31,24 @@ class Lark
|
|
15
31
|
end
|
16
32
|
end
|
17
33
|
|
18
|
-
def
|
34
|
+
def dbs
|
19
35
|
@dbs ||= urls.map do |url|
|
20
36
|
puts "Connecting to #{url}";
|
21
37
|
Redis.connect(:url => url)
|
22
38
|
end
|
23
39
|
end
|
24
40
|
|
41
|
+
def index(group)
|
42
|
+
"#{domain}:#{group}:idx"
|
43
|
+
end
|
44
|
+
|
25
45
|
## all the black magic happens here
|
26
46
|
## pool runs the block against all the db's
|
27
47
|
## throws an error if non of them are online
|
28
48
|
## and returns an array of the block results
|
29
49
|
## from the ones who are online
|
30
50
|
|
31
|
-
def
|
51
|
+
def pool(&blk)
|
32
52
|
dbs.push dbs.shift
|
33
53
|
|
34
54
|
num_errors = 0
|
@@ -48,95 +68,100 @@ class Lark
|
|
48
68
|
results
|
49
69
|
end
|
50
70
|
|
51
|
-
def
|
71
|
+
def on_expired(&blk)
|
52
72
|
@expired = blk;
|
53
73
|
end
|
54
74
|
|
55
|
-
def
|
56
|
-
|
75
|
+
def index_search(group)
|
76
|
+
pool { |db| db.smembers(index(group)) }.flatten.uniq.sort
|
57
77
|
end
|
58
78
|
|
59
|
-
def
|
60
|
-
|
61
|
-
@options = options
|
62
|
-
@domain = options[:domain]
|
63
|
-
@expire = options[:expire]
|
79
|
+
def key(id, group)
|
80
|
+
"#{domain}:#{group}:key:#{id}"
|
64
81
|
end
|
65
82
|
|
66
|
-
def
|
67
|
-
## try each db - return when one works without an error
|
68
|
-
## throw an error if all are down
|
83
|
+
def destroy(id, group)
|
69
84
|
pool do |db|
|
70
|
-
|
71
|
-
|
85
|
+
db.multi do
|
86
|
+
db.del key(id, group)
|
87
|
+
db.srem index(group), id
|
88
|
+
end
|
72
89
|
end
|
73
|
-
|
90
|
+
@expired.call(id, group) if @expired
|
74
91
|
end
|
75
92
|
|
76
|
-
def
|
77
|
-
|
93
|
+
def clean(group)
|
94
|
+
index_search(group).reject { |i| load_data(i, group) }.each { |i| destroy(i, group) }
|
78
95
|
end
|
79
96
|
|
80
|
-
def
|
81
|
-
|
97
|
+
def get_all(group)
|
98
|
+
index_search(group).map { |i| load_data(i, group) }
|
82
99
|
end
|
83
100
|
|
84
|
-
def
|
85
|
-
|
86
|
-
|
101
|
+
def load_data(id, group)
|
102
|
+
key = key(id, group)
|
103
|
+
## try each db - return when one works without an error
|
104
|
+
## throw an error if all are down
|
105
|
+
pool do |db|
|
106
|
+
data = db.hgetall(key)
|
107
|
+
return data if not data.empty?
|
108
|
+
end
|
109
|
+
nil
|
87
110
|
end
|
88
111
|
|
89
|
-
def save_data
|
90
|
-
|
91
|
-
|
92
|
-
data[:updated_on] = Time.new.to_i
|
112
|
+
def save_data(id, group, data)
|
113
|
+
key = key(id,group)
|
114
|
+
|
93
115
|
pool do |db|
|
94
116
|
db.multi do
|
95
117
|
db.hmset *[ key, data.to_a ].flatten
|
96
118
|
db.expire key, @expire if @expire
|
97
|
-
db.sadd
|
119
|
+
db.sadd index(group), id
|
98
120
|
end
|
99
121
|
end
|
100
122
|
end
|
101
123
|
|
102
|
-
def
|
103
|
-
|
124
|
+
def get(group)
|
125
|
+
get_all(group).select { |i| i }
|
104
126
|
end
|
105
127
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
128
|
+
class Base
|
129
|
+
attr_accessor :id, :group
|
130
|
+
|
131
|
+
def initialize(_id, _group, _data = nil)
|
132
|
+
@id = _id
|
133
|
+
@group = _group
|
134
|
+
@data = _data
|
135
|
+
save_data if @data
|
112
136
|
end
|
113
|
-
self.class.expired.call(id, @domain);
|
114
|
-
end
|
115
137
|
|
116
|
-
|
117
|
-
|
118
|
-
|
138
|
+
def key
|
139
|
+
Lark.key(id, group)
|
140
|
+
end
|
119
141
|
|
120
|
-
|
121
|
-
|
122
|
-
|
142
|
+
def set(new_data)
|
143
|
+
data.merge!(new_data)
|
144
|
+
save_data
|
145
|
+
end
|
123
146
|
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
end
|
147
|
+
def save_data
|
148
|
+
data[:created_on] ||= Time.new.to_i
|
149
|
+
data[:updated_on] = Time.new.to_i
|
150
|
+
data[:id] = id
|
151
|
+
Lark.save_data(id, group, data)
|
152
|
+
end
|
131
153
|
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
result
|
136
|
-
end
|
154
|
+
def data
|
155
|
+
@data ||= (Lark.load_data(key) || {})
|
156
|
+
end
|
137
157
|
|
138
|
-
|
139
|
-
|
140
|
-
|
158
|
+
def destroy
|
159
|
+
Lark.destroy(id, group)
|
160
|
+
end
|
141
161
|
|
162
|
+
def pool(&blk)
|
163
|
+
self.class.pool(&blk)
|
164
|
+
end
|
165
|
+
|
166
|
+
end
|
142
167
|
end
|
data/spec/lark_spec.rb
CHANGED
@@ -2,26 +2,27 @@
|
|
2
2
|
require File.dirname(__FILE__) + "/init.rb"
|
3
3
|
|
4
4
|
describe 'Lark' do
|
5
|
+
|
5
6
|
before do
|
6
|
-
@
|
7
|
-
@db1
|
8
|
-
@db2
|
7
|
+
@group = :testgroup
|
8
|
+
@db1 = mock()
|
9
|
+
@db2 = mock()
|
9
10
|
Lark.stubs(:dbs).returns([@db1, @db2]);
|
10
11
|
end
|
11
12
|
|
12
13
|
it 'should locate the data even if the key and data are on different databases' do
|
13
|
-
@db1.expects(:smembers).returns([ "
|
14
|
-
@db1.expects(:hgetall).with("
|
14
|
+
@db1.expects(:smembers).returns([ "test123" ])
|
15
|
+
@db1.expects(:hgetall).with(":#{@group}:key:test123").returns({})
|
15
16
|
@db2.expects(:smembers).returns([ ])
|
16
|
-
@db2.expects(:hgetall).with("
|
17
|
+
@db2.expects(:hgetall).with(":#{@group}:key:test123").returns({"foo" => "bar"})
|
17
18
|
|
18
|
-
@
|
19
|
+
Lark.get(@group).should.equal([ {"foo" => "bar"} ])
|
19
20
|
end
|
20
21
|
|
21
22
|
it 'should get the union of the ids on each server' do
|
22
23
|
@db1.expects(:smembers).returns([ "a", "b" ])
|
23
24
|
@db2.expects(:smembers).returns([ "b", "c" ])
|
24
|
-
@
|
25
|
+
Lark.index_search(@group).should.equal ["a","b","c"]
|
25
26
|
end
|
26
27
|
|
27
28
|
# it 'should run delete on old objects'
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lark
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 27
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 2
|
10
|
+
version: 0.0.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Orion Henry
|