jsvd-blackboard 0.2.3 → 0.2.4
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/ChangeLog +4 -0
- data/README +1 -2
- data/blackboard.gemspec +1 -1
- data/lib/blackboard.rb +55 -60
- data/spec/blackboard_spec.rb +30 -30
- metadata +1 -1
data/ChangeLog
CHANGED
data/README
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
|
7
7
|
BlackBoard provides a folder-layer to memcache-client. A BlackBoard is created with a static structure of folders and items.
|
8
8
|
|
9
|
-
bb =
|
9
|
+
bb = BlackBoard.new :ttl => 2 do
|
10
10
|
folder :folder1, [:name1] do
|
11
11
|
folder :folder1, [:name1, :name2]
|
12
12
|
folder :folder2, [:name2]
|
@@ -49,7 +49,6 @@ obj = items[:folder1][:name1]
|
|
49
49
|
|
50
50
|
== Features/Problems
|
51
51
|
|
52
|
-
Must include Pulso module to use.
|
53
52
|
Fully specced.
|
54
53
|
|
55
54
|
== Synopsis
|
data/blackboard.gemspec
CHANGED
data/lib/blackboard.rb
CHANGED
@@ -1,6 +1,51 @@
|
|
1
1
|
# vim: expandtab : tabstop=2 : shiftwidth=2 : softtabstop=2
|
2
2
|
|
3
|
-
|
3
|
+
class BlackBoard
|
4
|
+
|
5
|
+
require 'rubygems'
|
6
|
+
require 'memcache'
|
7
|
+
|
8
|
+
@cache = nil
|
9
|
+
|
10
|
+
attr_reader :folders
|
11
|
+
|
12
|
+
def initialize opts = {}, &block
|
13
|
+
@folders = {}
|
14
|
+
@ttl = opts[:ttl] || 60
|
15
|
+
raise ArgumentError, "BlackBoard.new should not receive ttl bigger than #seconds in 30 days" if @ttl > 2592000
|
16
|
+
@servers = opts[:servers]
|
17
|
+
@servers ||= "127.0.0.1:11411"
|
18
|
+
@cache = MemCache.new(@servers, :namespace => 'blackboard')
|
19
|
+
instance_eval(&block) unless block.nil?
|
20
|
+
end
|
21
|
+
|
22
|
+
def active?
|
23
|
+
@cache.active?
|
24
|
+
end
|
25
|
+
|
26
|
+
def has_folders?
|
27
|
+
!@folders.empty?
|
28
|
+
end
|
29
|
+
|
30
|
+
def empty?
|
31
|
+
@cache.stats.inject(0) {|sum, server| sum + server.last["curr_items"]} == 0
|
32
|
+
end
|
33
|
+
|
34
|
+
def folder name, keys, args = {}, &block
|
35
|
+
raise BlackBoardError, "Folder #{name} already exists" if @folders.has_key?(name)
|
36
|
+
ttl = args[:ttl]
|
37
|
+
ttl ||= @ttl
|
38
|
+
instance_eval %Q{def #{name}; @folders[:#{name}]._update; @folders[:#{name}]; end}
|
39
|
+
@folders[name] = Folder.new name, keys, :cache => @cache, :ttl => ttl, &block
|
40
|
+
end
|
41
|
+
|
42
|
+
def clean
|
43
|
+
@cache.flush_all
|
44
|
+
end
|
45
|
+
|
46
|
+
def method_missing folder
|
47
|
+
raise BlackBoardError, "Folder #{folder} not found"
|
48
|
+
end
|
4
49
|
|
5
50
|
class Folder < Hash
|
6
51
|
|
@@ -14,11 +59,11 @@ module Pulso
|
|
14
59
|
@ttl = args[:ttl]
|
15
60
|
@cache = args[:cache]
|
16
61
|
|
17
|
-
raise ArgumentError, "
|
18
|
-
raise ArgumentError, "
|
62
|
+
raise ArgumentError, "Folder.new should receive name, keys, cache and ttl" if @ttl.nil? || args[:cache].nil?
|
63
|
+
raise ArgumentError, "Folder.new should not receive ttl bigger than #seconds in 30 days" if @ttl > 2592000
|
19
64
|
|
20
65
|
create_children children
|
21
|
-
|
66
|
+
|
22
67
|
instance_eval(&block) unless block.nil?
|
23
68
|
|
24
69
|
end
|
@@ -40,9 +85,9 @@ module Pulso
|
|
40
85
|
ttl = args[:ttl]
|
41
86
|
ttl ||= @ttl
|
42
87
|
@folders << name
|
43
|
-
self[name] =
|
88
|
+
self[name] = Folder.new "#{@name}.#{name}", keys, :cache => @cache, :ttl => ttl, &block
|
44
89
|
instance_eval %Q{def #{name}; self[:#{name}]._update ;self[:#{name}]; end}
|
45
|
-
|
90
|
+
|
46
91
|
end
|
47
92
|
|
48
93
|
def create_children children
|
@@ -61,7 +106,7 @@ module Pulso
|
|
61
106
|
return if object.timestamp < @items[name]
|
62
107
|
|
63
108
|
@items[name] = object.timestamp
|
64
|
-
obj =
|
109
|
+
obj = Data.new(name, object)
|
65
110
|
@cache.set "#{@name}.#{name}", obj, obj_ttl
|
66
111
|
end
|
67
112
|
|
@@ -86,58 +131,8 @@ module Pulso
|
|
86
131
|
end
|
87
132
|
|
88
133
|
end
|
134
|
+
end
|
89
135
|
|
90
|
-
|
91
|
-
|
92
|
-
require 'rubygems'
|
93
|
-
require 'memcache'
|
94
|
-
|
95
|
-
@cache = nil
|
96
|
-
|
97
|
-
attr_reader :folders
|
98
|
-
|
99
|
-
def initialize opts = {}, &block
|
100
|
-
@folders = {}
|
101
|
-
@ttl = opts[:ttl] || 60
|
102
|
-
raise ArgumentError, "Pulso::BlackBoard.new should not receive ttl bigger than #seconds in 30 days" if @ttl > 2592000
|
103
|
-
@servers = opts[:servers]
|
104
|
-
@servers ||= "127.0.0.1:11411"
|
105
|
-
@cache = MemCache.new(@servers, :namespace => 'blackboard')
|
106
|
-
instance_eval(&block) unless block.nil?
|
107
|
-
end
|
108
|
-
|
109
|
-
def active?
|
110
|
-
@cache.active?
|
111
|
-
end
|
112
|
-
|
113
|
-
def has_folders?
|
114
|
-
!@folders.empty?
|
115
|
-
end
|
116
|
-
|
117
|
-
def empty?
|
118
|
-
@cache.stats.inject(0) {|sum, server| sum + server.last["curr_items"]} == 0
|
119
|
-
end
|
120
|
-
|
121
|
-
def folder name, keys, args = {}, &block
|
122
|
-
raise BlackBoardError, "Folder #{name} already exists" if @folders.has_key?(name)
|
123
|
-
ttl = args[:ttl]
|
124
|
-
ttl ||= @ttl
|
125
|
-
instance_eval %Q{def #{name}; @folders[:#{name}]._update; @folders[:#{name}]; end}
|
126
|
-
@folders[name] = Pulso::Folder.new name, keys, :cache => @cache, :ttl => ttl, &block
|
127
|
-
end
|
128
|
-
|
129
|
-
def clean
|
130
|
-
@cache.flush_all
|
131
|
-
end
|
132
|
-
|
133
|
-
def method_missing folder
|
134
|
-
raise BlackBoardError, "Folder #{folder} not found"
|
135
|
-
end
|
136
|
-
|
137
|
-
end
|
138
|
-
|
139
|
-
class BlackBoardError < RuntimeError
|
140
|
-
|
141
|
-
end
|
142
|
-
|
136
|
+
class BlackBoardError < RuntimeError
|
143
137
|
end
|
138
|
+
|
data/spec/blackboard_spec.rb
CHANGED
@@ -11,7 +11,7 @@ class TestObject
|
|
11
11
|
attr_reader :timestamp
|
12
12
|
end
|
13
13
|
|
14
|
-
describe
|
14
|
+
describe BlackBoard::Folder do
|
15
15
|
|
16
16
|
before :each do
|
17
17
|
@cache = MemCache.new("127.0.0.1:11411", :namespace => 'blackboard')
|
@@ -19,35 +19,35 @@ describe Pulso::Folder do
|
|
19
19
|
|
20
20
|
it "should be created with a name, servers and ttl" do
|
21
21
|
f = nil
|
22
|
-
lambda { f =
|
23
|
-
lambda { f =
|
24
|
-
lambda { f =
|
25
|
-
lambda { f =
|
22
|
+
lambda { f = BlackBoard::Folder.new }.should raise_error ArgumentError
|
23
|
+
lambda { f = BlackBoard::Folder.new :folder1, [], :cache => @cache }.should raise_error ArgumentError
|
24
|
+
lambda { f = BlackBoard::Folder.new :folder1, [], :ttl => 20 }.should raise_error ArgumentError
|
25
|
+
lambda { f = BlackBoard::Folder.new :folder1, [], :cache => @cache, :ttl => 20 }.should_not raise_error ArgumentError
|
26
26
|
f.name.should == :folder1
|
27
27
|
end
|
28
28
|
|
29
29
|
it "should complain if ttl is bigger than seconds in 30 days" do
|
30
|
-
lambda {
|
31
|
-
lambda {
|
30
|
+
lambda { BlackBoard::Folder.new :folder1, [], :cache => @cache, :ttl => 30*24*3600+1 }.should raise_error ArgumentError
|
31
|
+
lambda { BlackBoard::Folder.new :folder1, [], :cache => @cache, :ttl => 30*24*3600 }.should_not raise_error ArgumentError
|
32
32
|
end
|
33
33
|
|
34
34
|
it "should not complain when creating subfolders" do
|
35
35
|
lambda {
|
36
|
-
|
36
|
+
BlackBoard::Folder.new :folder1, [:name1, :name2], :cache => @cache, :ttl => 30*24*3600 do
|
37
37
|
folder :folder2, [:name4, :name5], :ttl => 30*24*3600
|
38
38
|
end
|
39
39
|
}.should_not raise_error ArgumentError
|
40
40
|
end
|
41
41
|
|
42
42
|
it "should return a kind of Hash" do
|
43
|
-
f =
|
43
|
+
f = BlackBoard::Folder.new :folder1, [:name1], :cache => @cache, :ttl => 20
|
44
44
|
f.should be_a_kind_of Hash
|
45
45
|
f.should == { :name1 => nil }
|
46
46
|
end
|
47
47
|
|
48
48
|
it "should respond to folder name method" do
|
49
49
|
`memcached -d -p 11411 -P /tmp/memcached-test.pid`
|
50
|
-
k =
|
50
|
+
k = BlackBoard::Folder.new :folder1, [:name1, :name2], :cache => @cache, :ttl => 30*24*3600 do
|
51
51
|
folder :folder2, [:name1]
|
52
52
|
end
|
53
53
|
lambda { k.folder2 }.should_not raise_error
|
@@ -57,29 +57,29 @@ describe Pulso::Folder do
|
|
57
57
|
|
58
58
|
end
|
59
59
|
|
60
|
-
describe
|
60
|
+
describe BlackBoard::Data do
|
61
61
|
|
62
62
|
it "should be initialized with a name and an object that responds to :timestamp" do
|
63
|
-
lambda {
|
64
|
-
lambda {
|
63
|
+
lambda { BlackBoard::Data.new }.should raise_error
|
64
|
+
lambda { BlackBoard::Data.new :name1, Object.new }.should raise_error BlackBoardError
|
65
65
|
obj = TestObject.new
|
66
66
|
data = nil
|
67
|
-
lambda { data =
|
67
|
+
lambda { data = BlackBoard::Data.new :name1, obj }.should_not raise_error BlackBoardError
|
68
68
|
data.name.should == :name1
|
69
69
|
data.data.should == obj
|
70
70
|
end
|
71
71
|
|
72
72
|
it "should have a timestamp" do
|
73
|
-
|
73
|
+
BlackBoard::Data.new(:name1, TestObject.new).timestamp.should be_close Time.now,1
|
74
74
|
end
|
75
75
|
|
76
76
|
end
|
77
77
|
|
78
|
-
describe
|
78
|
+
describe BlackBoard do
|
79
79
|
|
80
80
|
before :all do
|
81
81
|
`memcached -d -p 11411 -P /tmp/memcached-test.pid`
|
82
|
-
@blackboard =
|
82
|
+
@blackboard = BlackBoard.new :ttl => 2 do
|
83
83
|
folder :folder1, [:name1, :name2]
|
84
84
|
end
|
85
85
|
end
|
@@ -95,8 +95,8 @@ describe Pulso::BlackBoard do
|
|
95
95
|
end
|
96
96
|
|
97
97
|
it "should complain if ttl is bigger than seconds in 30 days" do
|
98
|
-
lambda {
|
99
|
-
lambda {
|
98
|
+
lambda { BlackBoard.new :ttl => 30*24*3600+1 }.should raise_error ArgumentError
|
99
|
+
lambda { BlackBoard.new :ttl => 30*24*3600 }.should_not raise_error ArgumentError
|
100
100
|
end
|
101
101
|
|
102
102
|
end
|
@@ -106,7 +106,7 @@ describe Pulso::BlackBoard do
|
|
106
106
|
it { @blackboard.should be_empty }
|
107
107
|
|
108
108
|
it "should have folders after adding one" do
|
109
|
-
bb =
|
109
|
+
bb = BlackBoard.new do
|
110
110
|
folder :folder1, [:name1, :name2]
|
111
111
|
end
|
112
112
|
bb.should have_folders
|
@@ -115,7 +115,7 @@ describe Pulso::BlackBoard do
|
|
115
115
|
|
116
116
|
# TODO improve by regexp matching
|
117
117
|
it "should complain when retrieving from inexistant folder" do
|
118
|
-
lambda { @blackboard.folder2.name1 }.should raise_error
|
118
|
+
lambda { @blackboard.folder2.name1 }.should raise_error BlackBoardError
|
119
119
|
end
|
120
120
|
|
121
121
|
it "should return nil when retrieving known data key from folder" do
|
@@ -123,7 +123,7 @@ describe Pulso::BlackBoard do
|
|
123
123
|
end
|
124
124
|
|
125
125
|
it "should complain when retrieving unknown data key from folder" do
|
126
|
-
lambda { @blackboard.folder1.name5 }.should raise_error
|
126
|
+
lambda { @blackboard.folder1.name5 }.should raise_error BlackBoardError
|
127
127
|
end
|
128
128
|
|
129
129
|
end
|
@@ -131,7 +131,7 @@ describe Pulso::BlackBoard do
|
|
131
131
|
describe "(non-empty)" do
|
132
132
|
|
133
133
|
before :all do
|
134
|
-
@blackboard =
|
134
|
+
@blackboard = BlackBoard.new :ttl => 2 do
|
135
135
|
folder :folder1, [:name1, :name2, :name3]
|
136
136
|
folder :folder2, [:name4, :name5, :name6]
|
137
137
|
end
|
@@ -233,7 +233,7 @@ describe Pulso::BlackBoard do
|
|
233
233
|
it "should allow subfolders" do
|
234
234
|
|
235
235
|
lambda {
|
236
|
-
@blackboard =
|
236
|
+
@blackboard = BlackBoard.new :ttl => 2 do
|
237
237
|
folder :folder1, [:name1, :name2, :name3] do
|
238
238
|
folder :folder2, [:name4, :name5]
|
239
239
|
end
|
@@ -246,7 +246,7 @@ describe Pulso::BlackBoard do
|
|
246
246
|
|
247
247
|
it "should be possible to write to a subfolder" do
|
248
248
|
|
249
|
-
@blackboard =
|
249
|
+
@blackboard = BlackBoard.new :ttl => 2 do
|
250
250
|
folder :folder1, [:name1, :name2, :name3] do
|
251
251
|
folder :folder2, [:name4, :name5]
|
252
252
|
end
|
@@ -269,7 +269,7 @@ describe Pulso::BlackBoard do
|
|
269
269
|
end
|
270
270
|
|
271
271
|
it "should allow different ttl for subfolders" do
|
272
|
-
@blackboard =
|
272
|
+
@blackboard = BlackBoard.new :ttl => 2 do
|
273
273
|
folder :folder1, [:name1], :ttl => 1
|
274
274
|
folder :folder2, [:name2], :ttl => 2
|
275
275
|
end
|
@@ -288,7 +288,7 @@ describe Pulso::BlackBoard do
|
|
288
288
|
end
|
289
289
|
|
290
290
|
it "should allow different ttl between folder and subfolder" do
|
291
|
-
@blackboard =
|
291
|
+
@blackboard = BlackBoard.new :ttl => 2 do
|
292
292
|
folder :folder1, [:name1], :ttl => 1 do
|
293
293
|
folder :folder2, [:name2], :ttl => 2
|
294
294
|
end
|
@@ -309,7 +309,7 @@ describe Pulso::BlackBoard do
|
|
309
309
|
end
|
310
310
|
|
311
311
|
it "should propagate tll to subfolders " do
|
312
|
-
@blackboard =
|
312
|
+
@blackboard = BlackBoard.new :ttl => 2 do
|
313
313
|
folder :folder1, [:name1], :ttl => 1 do
|
314
314
|
folder :folder2, [:name2]
|
315
315
|
end
|
@@ -330,7 +330,7 @@ describe Pulso::BlackBoard do
|
|
330
330
|
end
|
331
331
|
|
332
332
|
it "should support writing to two elements with same name on different folders" do
|
333
|
-
@blackboard =
|
333
|
+
@blackboard = BlackBoard.new :ttl => 10 do
|
334
334
|
folder :folder1, [:name1]
|
335
335
|
folder :folder2, [:name1]
|
336
336
|
end
|
@@ -346,7 +346,7 @@ describe Pulso::BlackBoard do
|
|
346
346
|
end
|
347
347
|
|
348
348
|
it "should not complain when creating sub sub folders" do
|
349
|
-
lambda { @blackboard =
|
349
|
+
lambda { @blackboard = BlackBoard.new :ttl => 10 do
|
350
350
|
folder :folder1, [:name1] do
|
351
351
|
folder :folder1, [:name1] do
|
352
352
|
folder :folder1, [:name1] do
|