fraggle 3.0.0 → 4.0.0.pre.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,7 +1,6 @@
1
- # Fraggle (v3.0.0 is compatible with Doozer 0.6)
1
+ # Fraggle (v4.0.0.pre.1 is compatible with Doozer 0.6)
2
2
 
3
3
  Fraggle currently is only a raw interface to Doozer 0.6.
4
- Sugar for `WALK`, `GETDIR`, etc are to come in v3.0.0.
5
4
 
6
5
  **An EventMachine based Doozer client**
7
6
 
@@ -11,31 +10,42 @@ Sugar for `WALK`, `GETDIR`, etc are to come in v3.0.0.
11
10
 
12
11
  ## Use
13
12
 
13
+ *Connecting to a cluster*
14
+
15
+ Use `Fraggle.connect`. It takes an optional [doozer uri][] (String). If no
16
+ parameters are given, it will use the DOOZER_URI` environment variable if
17
+ present, otherwise it will default to the uri containing the default doozer
18
+ addresses with IP 127.0.0.1 and ports 8046, 8041, 8042, 8043.
19
+
20
+ *simple example*
21
+
14
22
  require 'rubygems'
15
23
  require 'eventmachine'
16
24
  require 'fraggle'
17
25
 
18
- EM.start do
26
+ EM.run do
19
27
  # In the event of a lost connection, fraggle will attempt
20
28
  # other doozers until one accepts or it runs out of options; A NoAddrs
21
29
  # exception will be raised if that later happens.
22
- c = Fraggle.connect "doozerd://127.0.0.1:8046"
23
30
 
24
- req = c.get("/foo") do |e|
25
- if e.ok?
26
- e.value # => nil
27
- e.rev # => 0
28
- e.missing? # => true
29
- else
30
- e.err_code # => Fraggle::<CONST>
31
- e.err_detail # => "bad path" or something
32
- end
33
- end
31
+ c = Fraggle.connect
34
32
 
35
33
  c.rev do |v|
34
+ c.get(v.rev, "/foo") do |e|
35
+ p [:get, e]
36
+ if e.ok?
37
+ e.value # => nil
38
+ e.rev # => 0
39
+ e.missing? # => true
40
+ else
41
+ e.err_code # => nil
42
+ e.err_detail # => nil
43
+ end
44
+ end
45
+
36
46
  ## Obtain the current revision the store is at and watch from then on for
37
47
  ## any SET or DEL to /foo.
38
- c.wait("/foo", v.rev) do |e|
48
+ c.wait(v.rev, "/foo") do |e|
39
49
  # The event has:
40
50
  # ------------------------
41
51
  e.err_code # => nil
@@ -45,11 +55,13 @@ Sugar for `WALK`, `GETDIR`, etc are to come in v3.0.0.
45
55
  e.rev # => 123
46
56
  e.set? # => true
47
57
  e.del? # => false
58
+
59
+ p [:wait, e]
48
60
  end
49
61
  end
50
62
 
51
63
  ## Setting a key (this will trigger the watch above)
52
- req = c.set("/foo", "zomg!", 0) do |e|
64
+ c.set(Fraggle::Clobber, "/foo", "zomg!") do |e|
53
65
  # Success!
54
66
  case e.err_code
55
67
  when Fraggle::REV_MISMATCH
@@ -57,7 +69,7 @@ Sugar for `WALK`, `GETDIR`, etc are to come in v3.0.0.
57
69
  when nil
58
70
  # Success!
59
71
  else
60
- fail "something bad happened"
72
+ fail "something bad happened: " + e.inspect
61
73
  end
62
74
  end
63
75
 
@@ -70,17 +82,17 @@ the most up-to-date data. If you need to do multiple reads at certain
70
82
  point in time for consistency, use the `rev` command.
71
83
 
72
84
  c.rev do |v|
73
- c.get("/a", v.rev) { ... }
74
- c.get("/b", v.rev) { ... }
75
- c.get("/c", v.rev) { ... }
85
+ c.get(v.rev, "/a") { ... }
86
+ c.get(v.rev, "/b") { ... }
87
+ c.get(v.rev, "/c") { ... }
76
88
  end
77
89
 
78
90
  This also means you can go back in time or into the future!
79
91
 
80
92
  # This will not yield until the data store is at revision 100,000
81
- c.get("/a", 100_000) { ... }
93
+ c.get(100_000, "/a") { ... }
82
94
 
83
- NOTE: Doozer's data store is a persistent data structure. You can reference the
95
+ NOTE: Doozer's data store is a [persistent data structure][pd]. You can reference the
84
96
  stores history as far back as it is configured to hold it. The default is
85
97
  360,000 revisions. See [data model][] for more information.
86
98
 
@@ -103,11 +115,54 @@ stores history as far back as it is configured to hold it. The default is
103
115
  You will have to handle these yourself because Fraggle cannot know whether or
104
116
  not it's safe to retry on your behalf.
105
117
 
118
+ ## Commands
119
+
120
+ Each command behaves according to the [proto spec][], respectively.
121
+ Their `blk`s are called with one parameter, a `Fraggle::Response`, when a response is
122
+ returned from the server.
123
+
124
+ `set(rev, path, value, &blk)`
125
+
126
+ `del(rev, path, &blk)`
127
+
128
+ `get(rev, path, &blk)`
129
+
130
+ `getdir(rev, path, offset, &blk)`
131
+
132
+ `walk(rev, path, offset, &blk)`
133
+
134
+ `wait(rev, path, &blk)`
135
+
136
+ `rev(&blk)`
137
+
138
+ `stat(rev, path, &blk)`
139
+
140
+ ## Sugar commands
141
+
142
+ `watch(rev, path, &blk)`
143
+
144
+ Watches `path` (a glob pattern) for changes, from `rev` in history on. Its
145
+ `blk` is called with a `Fraggle::Response` for each event.
146
+
147
+ `getdir_all(rev, path, off=0, lim=MaxInt64, ents=[], &blk)`
148
+
149
+ Behaves like `getdir` but collects `ents`, starting at `off` until all or `lim`
150
+ entries are read. When done `blk` is called with the result as the first
151
+ parameter or an error as the second. Depending on the response, one or the
152
+ other will be set and the other with be `nil`.
153
+
154
+ `walk_all(rev, path, off=0, lim=MaxInt64, ents=[], &blk)`
155
+
156
+ Behaves like `walk` but collects `ents`, starting at `off` until all or `lim`
157
+ entries are read. When done `blk` is called with the result as the first
158
+ parameter or an error as the second. Depending on the response, one or the
159
+ other will be set and the other with be `nil`.
160
+
106
161
  ## Dev
107
162
 
108
163
  **Clone**
109
164
 
110
- $ git clone http://github.com/bmizerany/fraggle.git
165
+ $ git clone http://github.com/ha/fraggle.git
111
166
 
112
167
  **Test**
113
168
 
@@ -121,3 +176,6 @@ Please join the Doozer mailing list for help:
121
176
  http://groups.google.com/forum/#!forum/doozer
122
177
 
123
178
  [data model]: https://github.com/ha/doozerd/blob/master/doc/data-model.md
179
+ [doozer uri]: https://github.com/ha/doozerd/blob/master/doc/uri.md
180
+ [proto spec]: https://github.com/ha/doozerd/blob/master/doc/proto.md
181
+ [pd]: http://en.wikipedia.org/wiki/Persistent_data_structure
@@ -0,0 +1,29 @@
1
+ require 'rubygems'
2
+ require 'fraggle'
3
+
4
+ EM.run do
5
+ c = Fraggle.connect
6
+
7
+ c.rev do |v|
8
+ # Valid
9
+ req = c.getdir_all("/ctl/node", v.rev) do |ents, err|
10
+ if err
11
+ p [:err, err]
12
+ else
13
+ ents.each do |e|
14
+ puts File.join(req.path, e.path)
15
+ end
16
+ end
17
+ end
18
+
19
+ # Limit 0 return nothing
20
+ c.getdir_all("/ctl/node", v.rev, 0, 0) do |ents, err|
21
+ p [:ret, ents, err]
22
+ end
23
+
24
+ # Error
25
+ c.getdir_all("/nothere", v.rev) do |ents, err|
26
+ p [:ret, ents, err]
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,56 @@
1
+ require 'rubygems'
2
+ require 'eventmachine'
3
+ require 'fraggle'
4
+
5
+ EM.run do
6
+ # In the event of a lost connection, fraggle will attempt
7
+ # other doozers until one accepts or it runs out of options; A NoAddrs
8
+ # exception will be raised if that later happens.
9
+
10
+ c = Fraggle.connect
11
+
12
+ c.rev do |v|
13
+ c.get(v.rev, "/foo") do |e|
14
+ p [:get, e]
15
+ if e.ok?
16
+ e.value # => nil
17
+ e.rev # => 0
18
+ e.missing? # => true
19
+ else
20
+ e.err_code # => nil
21
+ e.err_detail # => nil
22
+ end
23
+ end
24
+
25
+ ## Obtain the current revision the store is at and watch from then on for
26
+ ## any SET or DEL to /foo.
27
+ c.wait(v.rev, "/foo") do |e|
28
+ # The event has:
29
+ # ------------------------
30
+ e.err_code # => nil
31
+ e.err_detail # => nil
32
+ e.path # => "/foo"
33
+ e.value # => "zomg!"
34
+ e.rev # => 123
35
+ e.set? # => true
36
+ e.del? # => false
37
+
38
+ p [:wait, e]
39
+ end
40
+ end
41
+
42
+ ## Setting a key (this will trigger the watch above)
43
+ c.set(0, "/foo", "zomg!") do |e|
44
+ # Success!
45
+ case e.err_code
46
+ when Fraggle::REV_MISMATCH
47
+ p :not_it
48
+ when nil
49
+ # Success!
50
+ p :it
51
+ else
52
+ fail "something bad happened: " + e.inspect
53
+ end
54
+ end
55
+
56
+ end
@@ -0,0 +1,29 @@
1
+ require 'rubygems'
2
+ require 'fraggle'
3
+
4
+ EM.run do
5
+ c = Fraggle.connect
6
+
7
+ c.rev do |v|
8
+ # Valid
9
+ req = c.walk_all("/ctl/node/**", v.rev) do |ents, err|
10
+ if err
11
+ p [:err, err]
12
+ else
13
+ ents.each do |e|
14
+ puts File.join(req.path, e.path) + "=" + e.value
15
+ end
16
+ end
17
+ end
18
+
19
+ # Limit 0 return nothing
20
+ c.walk_all("/ctl/node/**", v.rev, 0, 0) do |ents, err|
21
+ p [:ret, ents, err]
22
+ end
23
+
24
+ # Error
25
+ c.walk_all("/nothere", v.rev) do |ents, err|
26
+ p [:ret, ents, err]
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,12 @@
1
+ require 'rubygems'
2
+ require 'fraggle'
3
+
4
+ EM.run do
5
+ c = Fraggle.connect
6
+
7
+ c.rev do |v|
8
+ c.watch("/ctl/node/**", v.rev) do |e|
9
+ p e
10
+ end
11
+ end
12
+ end
@@ -1,6 +1,9 @@
1
1
  require 'fraggle/client'
2
2
 
3
3
  module Fraggle
4
+ include Response::Err
5
+
6
+ Clobber = Client::MaxInt64
4
7
 
5
8
  DEFAULT_URI = "doozer:?" + [
6
9
  "ca=127.0.0.1:8046",
@@ -6,6 +6,8 @@ module Fraggle
6
6
  class Client
7
7
  include Request::Verb
8
8
 
9
+ MaxInt64 = 1<<63 - 1
10
+
9
11
  class NoMoreAddrs < StandardError
10
12
  end
11
13
 
@@ -22,7 +24,7 @@ module Fraggle
22
24
  cn.addr
23
25
  end
24
26
 
25
- def set(path, value, rev, &blk)
27
+ def set(rev, path, value, &blk)
26
28
  req = Request.new
27
29
  req.verb = SET
28
30
  req.rev = rev
@@ -32,7 +34,7 @@ module Fraggle
32
34
  idemp(req, &blk)
33
35
  end
34
36
 
35
- def get(path, rev=nil, &blk)
37
+ def get(rev, path, &blk)
36
38
  req = Request.new
37
39
  req.verb = GET
38
40
  req.rev = rev
@@ -41,7 +43,7 @@ module Fraggle
41
43
  resend(req, &blk)
42
44
  end
43
45
 
44
- def del(path, rev, &blk)
46
+ def del(rev, path, &blk)
45
47
  req = Request.new
46
48
  req.verb = DEL
47
49
  req.rev = rev
@@ -50,7 +52,7 @@ module Fraggle
50
52
  idemp(req, &blk)
51
53
  end
52
54
 
53
- def getdir(path, rev=nil, offset=nil, &blk)
55
+ def getdir(rev, path, offset, &blk)
54
56
  req = Request.new
55
57
  req.verb = GETDIR
56
58
  req.rev = rev
@@ -60,7 +62,7 @@ module Fraggle
60
62
  resend(req, &blk)
61
63
  end
62
64
 
63
- def walk(path, rev=nil, offset=nil, &blk)
65
+ def walk(rev, path, offset, &blk)
64
66
  req = Request.new
65
67
  req.verb = WALK
66
68
  req.rev = rev
@@ -70,7 +72,7 @@ module Fraggle
70
72
  resend(req, &blk)
71
73
  end
72
74
 
73
- def wait(path, rev=nil, &blk)
75
+ def wait(rev, path, &blk)
74
76
  req = Request.new
75
77
  req.verb = WAIT
76
78
  req.rev = rev
@@ -86,7 +88,7 @@ module Fraggle
86
88
  resend(req, &blk)
87
89
  end
88
90
 
89
- def stat(path, rev=nil, &blk)
91
+ def stat(rev, path, &blk)
90
92
  req = Request.new
91
93
  req.rev = rev
92
94
  req.verb = STAT
@@ -95,19 +97,51 @@ module Fraggle
95
97
  resend(req, &blk)
96
98
  end
97
99
 
100
+ def watch(rev, path, &blk)
101
+ wait(rev, path, rev) do |e|
102
+ blk.call(e)
103
+ if e.ok?
104
+ watch(rev, path, e.rev+1, &blk)
105
+ end
106
+ end
107
+ end
108
+
109
+ def getdir_all(rev, path, off=0, lim=MaxInt64, ents=[], &blk)
110
+ all(:getdir, rev, path, off, lim, ents, &blk)
111
+ end
112
+
113
+ def walk_all(rev, path, off=0, lim=MaxInt64, ents=[], &blk)
114
+ all(:walk, rev, path, off, lim, ents, &blk)
115
+ end
116
+
117
+ def all(m, rev, path, off, lim, ents=[], &blk)
118
+ if lim == 0
119
+ cn.next_tick { blk.call([], nil) }
120
+ return
121
+ end
122
+
123
+ __send__(m, rev, path, off) do |e|
124
+ case e.err_code
125
+ when nil
126
+ ents << e
127
+ all(m, rev, path, off+1, lim-1, ents, &blk)
128
+ when Fraggle::Response::Err::RANGE
129
+ blk.call(ents, nil)
130
+ else
131
+ blk.call(nil, e)
132
+ end
133
+ end
134
+ end
135
+
98
136
  # Sends a request to the server. Returns the request with a new tag
99
137
  # assigned.
100
138
  def send(req, &blk)
101
139
  cb = Proc.new do |e|
102
140
  log.debug("response: #{e.inspect} for #{req.inspect}")
103
141
 
104
- case true
105
- when e.disconnected?
106
- # If we haven't already reconnected, do so.
107
- if cn.err?
108
- log.error("conn err: #{req.inspect}")
109
- reconnect!
110
- end
142
+ if e.disconnected? && cn.err?
143
+ log.error("conn err: #{req.inspect}")
144
+ reconnect!
111
145
  end
112
146
 
113
147
  blk.call(e)
@@ -1,3 +1,3 @@
1
1
  module Fraggle
2
- VERSION = "3.0.0"
2
+ VERSION = "4.0.0.pre.1"
3
3
  end
@@ -150,7 +150,7 @@ class FraggleClientTest < Test::Unit::TestCase
150
150
  :value => "bar"
151
151
  }
152
152
 
153
- assert_verb exp, :set, "/foo", "bar", 0
153
+ assert_verb exp, :set, 0, "/foo", "bar"
154
154
  end
155
155
 
156
156
  def test_get
@@ -160,7 +160,7 @@ class FraggleClientTest < Test::Unit::TestCase
160
160
  :path => "/foo"
161
161
  }
162
162
 
163
- assert_verb exp, :get, "/foo", 0
163
+ assert_verb exp, :get, 0, "/foo"
164
164
  end
165
165
 
166
166
  def test_del
@@ -170,7 +170,7 @@ class FraggleClientTest < Test::Unit::TestCase
170
170
  :path => "/foo"
171
171
  }
172
172
 
173
- assert_verb exp, :del, "/foo", 0
173
+ assert_verb exp, :del, 0, "/foo"
174
174
  end
175
175
 
176
176
  def test_getdir
@@ -181,7 +181,7 @@ class FraggleClientTest < Test::Unit::TestCase
181
181
  :offset => 0
182
182
  }
183
183
 
184
- assert_verb exp, :getdir, "/foo", 0, 0
184
+ assert_verb exp, :getdir, 0, "/foo", 0
185
185
  end
186
186
 
187
187
  def test_rev
@@ -199,7 +199,7 @@ class FraggleClientTest < Test::Unit::TestCase
199
199
  :path => "/foo"
200
200
  }
201
201
 
202
- assert_verb exp, :stat, "/foo", 0
202
+ assert_verb exp, :stat, 0, "/foo"
203
203
  end
204
204
 
205
205
  def test_walk
@@ -210,7 +210,7 @@ class FraggleClientTest < Test::Unit::TestCase
210
210
  :offset => 0
211
211
  }
212
212
 
213
- assert_verb exp, :walk, "/foo/*", 0, 0
213
+ assert_verb exp, :walk, 0, "/foo/*", 0
214
214
  end
215
215
 
216
216
  def test_wait
@@ -220,7 +220,7 @@ class FraggleClientTest < Test::Unit::TestCase
220
220
  :path => "/foo/*"
221
221
  }
222
222
 
223
- assert_verb exp, :wait, "/foo/*", 0
223
+ assert_verb exp, :wait, 0, "/foo/*"
224
224
  end
225
225
 
226
226
  end
metadata CHANGED
@@ -1,13 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fraggle
3
3
  version: !ruby/object:Gem::Version
4
- hash: 7
5
- prerelease:
4
+ hash: 1923831851
5
+ prerelease: 6
6
6
  segments:
7
- - 3
7
+ - 4
8
8
  - 0
9
9
  - 0
10
- version: 3.0.0
10
+ - pre
11
+ - 1
12
+ version: 4.0.0.pre.1
11
13
  platform: ruby
12
14
  authors:
13
15
  - Blake Mizerany
@@ -15,7 +17,7 @@ autorequire:
15
17
  bindir: bin
16
18
  cert_chain: []
17
19
 
18
- date: 2011-04-29 00:00:00 -07:00
20
+ date: 2011-05-02 00:00:00 -07:00
19
21
  default_executable:
20
22
  dependencies:
21
23
  - !ruby/object:Gem::Dependency
@@ -77,6 +79,10 @@ files:
77
79
  - README.md
78
80
  - Rakefile
79
81
  - bench/gets.rb
82
+ - example/getdir_all.rb
83
+ - example/readme.rb
84
+ - example/walk_all.rb
85
+ - example/watch.rb
80
86
  - fraggle.gemspec
81
87
  - lib/fraggle.rb
82
88
  - lib/fraggle/client.rb
@@ -110,12 +116,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
110
116
  required_rubygems_version: !ruby/object:Gem::Requirement
111
117
  none: false
112
118
  requirements:
113
- - - ">="
119
+ - - ">"
114
120
  - !ruby/object:Gem::Version
115
- hash: 3
121
+ hash: 25
116
122
  segments:
117
- - 0
118
- version: "0"
123
+ - 1
124
+ - 3
125
+ - 1
126
+ version: 1.3.1
119
127
  requirements: []
120
128
 
121
129
  rubyforge_project: fraggle