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.
Files changed (5) hide show
  1. data/README.markdown +10 -8
  2. data/VERSION +1 -1
  3. data/lib/lark.rb +88 -63
  4. data/spec/lark_spec.rb +9 -8
  5. metadata +3 -3
@@ -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.on_expire do |id|
6
+ Lark.on_expired do |id|
7
7
  Log.debug "Lost node #{id}"
8
8
  end
9
9
 
10
- EM.start do
11
- lark = Lark.new "bottom_node.1", :expire => 60
12
- lark.set "ip" => "127.0.0.1", "role" => "worker node"
13
- EM::PeriodicTimer(5) do
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
- lark.find(/^top_node/).each do |id, data|
19
- check_on_node(id, data)
20
- do
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
1
+ 0.0.2
@@ -2,11 +2,27 @@ require 'redis'
2
2
 
3
3
  class LarkDBOffline < Exception ; end
4
4
 
5
- class Lark
6
- attr_accessor :id
5
+ module Lark
6
+ # attr_accessor :id
7
7
 
8
- def self.urls
9
- if ENV['LARK_URLS']
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 self.dbs
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 self.pool(&blk)
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 self.on_expired(&blk)
71
+ def on_expired(&blk)
52
72
  @expired = blk;
53
73
  end
54
74
 
55
- def self.expired
56
- @expired
75
+ def index_search(group)
76
+ pool { |db| db.smembers(index(group)) }.flatten.uniq.sort
57
77
  end
58
78
 
59
- def initialize(_id, options = {})
60
- @id = _id
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 load_data
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
- data = db.hgetall(key)
71
- return data if not data.empty?
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 key
77
- "#{@domain}:#{@id}"
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 set_key
81
- "#{@domain}:lark:all"
97
+ def get_all(group)
98
+ index_search(group).map { |i| load_data(i, group) }
82
99
  end
83
100
 
84
- def set(new_data)
85
- data.merge!(new_data)
86
- save_data
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
- data[:created_on] ||= Time.new.to_i
91
- data[:domain] ||= @domain
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 set_key, @id
119
+ db.sadd index(group), id
98
120
  end
99
121
  end
100
122
  end
101
123
 
102
- def data
103
- @data ||= load_data
124
+ def get(group)
125
+ get_all(group).select { |i| i }
104
126
  end
105
127
 
106
- def destroy
107
- pool do |db|
108
- db.multi do
109
- db.del key
110
- db.srem set_key, id
111
- end
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
- def all_ids
117
- pool { |db| db.smembers(set_key) }.flatten.uniq.sort
118
- end
138
+ def key
139
+ Lark.key(id, group)
140
+ end
119
141
 
120
- def find_ids(match)
121
- all_ids.select { |_id| match.match(_id) }
122
- end
142
+ def set(new_data)
143
+ data.merge!(new_data)
144
+ save_data
145
+ end
123
146
 
124
- def find_valid(match)
125
- all = find_ids(match).map { |_id| Lark.new(_id, @options) }
126
- valid = all.reject { |l| l.data.empty? }
127
- invalid = all - valid
128
- invalid.each { |i| i.destroy }
129
- valid
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
- def find(match = //)
133
- result = {}
134
- find_valid(match).each { |v| result[v.id] = v.data }
135
- result
136
- end
154
+ def data
155
+ @data ||= (Lark.load_data(key) || {})
156
+ end
137
157
 
138
- def pool(&blk)
139
- self.class.pool(&blk)
140
- end
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
@@ -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
- @lark = Lark.new "lark", :domain => "domain"
7
- @db1 = mock()
8
- @db2 = mock()
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([ "key1" ])
14
- @db1.expects(:hgetall).with("domain:key1").returns({})
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("domain:key1").returns({"foo" => "bar"})
17
+ @db2.expects(:hgetall).with(":#{@group}:key:test123").returns({"foo" => "bar"})
17
18
 
18
- @lark.find.should.equal({ "key1" => {"foo" => "bar"} })
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
- @lark.all_ids.should.equal ["a","b","c"]
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: 29
4
+ hash: 27
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 1
10
- version: 0.0.1
9
+ - 2
10
+ version: 0.0.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Orion Henry