etzetera 0.0.3 → 0.0.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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/lib/etzetera/client.rb +59 -61
- data/lib/etzetera/error.rb +2 -0
- data/lib/etzetera/version.rb +1 -1
- metadata +12 -12
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 47fa8b1efad7c677d6530ef9cf8c0aab5e11141a
|
4
|
+
data.tar.gz: c52221bb46aeae8a74de23793b20f4f8b25dcb01
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bf5cea647017f105ccc35f7d00452fbb628d0358c79cbe3dbe6b864651c56c922eba3cf7a9e47b1b5787999bfa897d7e202c77a14294dc16b17033328bd6a3ab
|
7
|
+
data.tar.gz: d535bc3b57d27b98685e6df01927c4a3d6ee5820bc7ff38da27133192852a207e37abbbbcc41d30c66e87816ff44caac3c5b060c86b853aaf09e87f1fb0e6993
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/lib/etzetera/client.rb
CHANGED
@@ -1,143 +1,140 @@
|
|
1
1
|
require 'celluloid/io'
|
2
|
+
require 'time'
|
2
3
|
require 'multi_json'
|
3
4
|
|
4
5
|
module Etzetera
|
5
6
|
class Client
|
6
7
|
include Celluloid::IO
|
7
|
-
|
8
|
+
API_VERSION = 'v2'.freeze
|
9
|
+
KEYS_PREFIX = "/#{API_VERSION}/keys".freeze
|
10
|
+
LOCK_PREFIX = "/mod/#{API_VERSION}/lock/".freeze
|
11
|
+
LEADER_PREFIX = "/mod/#{API_VERSION}/leader/".freeze
|
12
|
+
STATS_PREFIX = "/#{API_VERSION}/stats/".freeze
|
13
|
+
|
14
|
+
execute_block_on_receiver :wait
|
8
15
|
|
9
16
|
attr_accessor :servers
|
10
17
|
|
11
18
|
def initialize(servers = ['http://127.0.0.1:4001'], default_options = {})
|
12
19
|
|
13
|
-
self.servers = servers
|
20
|
+
self.servers = servers.dup
|
21
|
+
|
22
|
+
def_opts = default_options.dup
|
14
23
|
|
15
24
|
opts = {}
|
16
|
-
opts[:follow] = true
|
17
25
|
opts[:headers] = {:accept => 'application/json'}
|
18
26
|
opts[:response] = :object
|
19
|
-
opts[:election_timeout] = 200
|
20
|
-
opts[:heartbeat_interval] = 50
|
21
27
|
opts[:socket_class] = Celluloid::IO::TCPSocket
|
22
28
|
opts[:ssl_socket_class] = Celluloid::IO::SSLSocket
|
23
29
|
|
24
|
-
@
|
30
|
+
@etcd_opts = {}
|
31
|
+
@etcd_opts[:election_timeout] = def_opts.delete(:election_timeout) {|key| 200}
|
32
|
+
@etcd_opts[:heartbeat_interval] = def_opts.delete(:heartbeat_interval) {|key| 50}
|
33
|
+
|
34
|
+
|
35
|
+
@default_options = ::HTTP::Options.new(opts.merge(def_opts))
|
25
36
|
end
|
26
37
|
|
27
38
|
def get(key, params = {})
|
28
|
-
request(:get,
|
39
|
+
request(:get, KEYS_PREFIX, key, :params => params)
|
29
40
|
end
|
30
41
|
|
31
42
|
def set(key, form, params = {})
|
32
|
-
request(:put,
|
43
|
+
request(:put, KEYS_PREFIX, key, form: form, :params => params)
|
33
44
|
end
|
34
45
|
|
35
46
|
def delete(key, params = {})
|
36
|
-
request(:delete,
|
47
|
+
request(:delete, KEYS_PREFIX, key, :params => params)
|
37
48
|
end
|
38
49
|
|
39
|
-
def wait(key, params = {}
|
40
|
-
response = request(:get,
|
50
|
+
def wait(key, callback = nil, params = {})
|
51
|
+
response = request(:get, KEYS_PREFIX, key, :params => params.merge({:wait => true}))
|
41
52
|
|
42
53
|
if block_given?
|
43
54
|
yield response
|
44
55
|
elsif callback
|
45
|
-
|
46
|
-
|
47
|
-
end
|
56
|
+
#sleep (@etcd_opts[:heartbeat_interval] / 1000.0)
|
57
|
+
callback.call(response)
|
48
58
|
else
|
49
59
|
parse_response(response)
|
50
60
|
end
|
51
61
|
end
|
52
62
|
|
53
63
|
def create(key, form, params = {})
|
54
|
-
request(:put,
|
64
|
+
request(:put, KEYS_PREFIX, key, form: form, :params => params.merge({:prevExist => false}))
|
55
65
|
end
|
56
66
|
|
57
67
|
def update(key, form, params = {})
|
58
|
-
request(:put,
|
68
|
+
request(:put, KEYS_PREFIX, key, form: form, :params => params.merge({:prevExist => true}))
|
69
|
+
end
|
70
|
+
|
71
|
+
def mkdir(dir)
|
72
|
+
request(:put, KEYS_PREFIX, dir, :params => {dir: true})
|
59
73
|
end
|
60
74
|
|
61
75
|
def dir(dir, params = {})
|
62
|
-
request(:get,
|
76
|
+
request(:get, KEYS_PREFIX, dir, :params => params.merge({:recursive => true}))
|
63
77
|
end
|
64
78
|
|
65
79
|
def rmdir(dir, params = {})
|
66
|
-
request(:delete,
|
80
|
+
request(:delete, KEYS_PREFIX, dir, :params => {:recursive => true}.merge(params))
|
67
81
|
end
|
68
82
|
|
69
|
-
def compareAndSwap(key, prevValue)
|
70
|
-
request(:put,
|
83
|
+
def compareAndSwap(key, prevValue, form)
|
84
|
+
request(:put, KEYS_PREFIX, key, :form => form, :params => {:prevValue => prevValue})
|
71
85
|
end
|
72
86
|
|
73
87
|
def compareAndDelete(key, prevValue)
|
74
|
-
request(:delete,
|
88
|
+
request(:delete, KEYS_PREFIX, key, :params => {:prevValue => prevValue})
|
75
89
|
end
|
76
90
|
|
77
91
|
def acquire_lock(name, ttl)
|
78
|
-
request(:post,
|
92
|
+
request(:post, LOCK_PREFIX, name, :form => {:ttl => ttl})
|
79
93
|
end
|
80
94
|
|
81
95
|
def renew_lock(name, form)
|
82
|
-
request(:put,
|
96
|
+
request(:put, LOCK_PREFIX, name, :form => form)
|
83
97
|
end
|
84
98
|
|
85
99
|
def release_lock(name, form)
|
86
|
-
request(:delete,
|
100
|
+
request(:delete, LOCK_PREFIX, name, :form => form)
|
87
101
|
end
|
88
102
|
|
89
103
|
def retrieve_lock(name, params)
|
90
|
-
request(:get,
|
104
|
+
request(:get, LOCK_PREFIX, name, :params => params)
|
91
105
|
end
|
92
106
|
|
93
107
|
def set_leader(clustername, name, ttl)
|
94
|
-
request(:put,
|
108
|
+
request(:put, LEADER_PREFIX, clustername, :form => {:name => name, :ttl => ttl})
|
95
109
|
end
|
96
110
|
|
97
111
|
def get_leader(clustername, params = {})
|
98
|
-
request(:get,
|
112
|
+
request(:get, LEADER_PREFIX, clustername, :params => params)
|
99
113
|
end
|
100
114
|
|
101
115
|
def delete_leader(clustername, name)
|
102
|
-
request(:delete,
|
116
|
+
request(:delete, LEADER_PREFIX, clustername, :form => {:name => name})
|
103
117
|
end
|
104
118
|
|
105
119
|
def stats(type)
|
106
|
-
request(:get,
|
120
|
+
request(:get, STATS_PREFIX, type)
|
107
121
|
end
|
108
122
|
|
109
123
|
private
|
110
|
-
def
|
111
|
-
"/#{API_ENDPOINT}/keys/#{key}"
|
112
|
-
end
|
113
|
-
|
114
|
-
def lock_path(name)
|
115
|
-
"/mod/#{API_ENDPOINT}/lock/#{name}"
|
116
|
-
end
|
117
|
-
|
118
|
-
def leader_path(clustername)
|
119
|
-
"/mod/#{API_ENDPOINT}/leader/#{clustername}"
|
120
|
-
end
|
121
|
-
|
122
|
-
def stats_path(type)
|
123
|
-
"/#{API_ENDPOINT}/stats/#{type}"
|
124
|
-
end
|
125
|
-
|
126
|
-
def request(verb, path, options = {})
|
124
|
+
def request(verb, prefix, path, options = {})
|
127
125
|
opts = @default_options.merge(options)
|
128
126
|
|
127
|
+
if opts[:form] && !opts[:form].is_a?(Hash)
|
128
|
+
opts = opts.with_form({:value => opts[:form]})
|
129
|
+
end
|
130
|
+
|
129
131
|
client = ::HTTP::Client.new(opts)
|
130
132
|
server = servers.first
|
131
133
|
retries = servers.count - 1
|
132
134
|
request = nil
|
133
|
-
|
134
135
|
begin
|
135
|
-
request = client.request(verb, "#{server}#{path}")
|
136
|
-
|
137
|
-
if response['errorCode']
|
138
|
-
abort Error::CODES[response['errorCode']].new(response['message'])
|
139
|
-
end
|
140
|
-
parse_response(response)
|
136
|
+
request = client.request(verb, "#{server}#{prefix}#{path}")
|
137
|
+
MultiJson.load(request.body)
|
141
138
|
rescue IOError => e
|
142
139
|
abort e if retries < 1
|
143
140
|
|
@@ -152,11 +149,16 @@ module Etzetera
|
|
152
149
|
|
153
150
|
retries -= 1
|
154
151
|
|
155
|
-
|
156
|
-
|
157
|
-
end
|
152
|
+
#sleep (@etcd_opts[:election_timeout] / 1000.0)
|
153
|
+
retry
|
158
154
|
rescue MultiJson::LoadError => e
|
159
|
-
if request.code.between?(
|
155
|
+
if request.code.between?(200, 299)
|
156
|
+
request.body.to_s
|
157
|
+
elsif request.code.between?(300, 399)
|
158
|
+
if request.headers['Location']
|
159
|
+
request(verb, request.headers['Location'], opts)
|
160
|
+
end
|
161
|
+
elsif request.code.between?(400, 499)
|
160
162
|
abort Error::HttpClientError.new("#{request.reason}\n#{request.body.to_s}")
|
161
163
|
elsif request.code.between?(500, 599)
|
162
164
|
abort Error::HttpServerError.new("#{request.reason}\n#{request.body.to_s}")
|
@@ -165,9 +167,5 @@ module Etzetera
|
|
165
167
|
end
|
166
168
|
end
|
167
169
|
end
|
168
|
-
|
169
|
-
def parse_response(response)
|
170
|
-
response
|
171
|
-
end
|
172
170
|
end
|
173
171
|
end
|
data/lib/etzetera/error.rb
CHANGED
@@ -21,6 +21,7 @@ module Etzetera
|
|
21
21
|
class NotDir < CommandError; end
|
22
22
|
class NodeExist < CommandError; end
|
23
23
|
class KeyIsPreserved < CommandError; end
|
24
|
+
class RootROnly < CommandError; end
|
24
25
|
|
25
26
|
class ValueRequired < PostFormError; end
|
26
27
|
class PrevValueRequired < PostFormError; end
|
@@ -41,6 +42,7 @@ module Etzetera
|
|
41
42
|
104 => NotDir,
|
42
43
|
105 => NodeExist,
|
43
44
|
106 => KeyIsPreserved,
|
45
|
+
107 => RootROnly,
|
44
46
|
200 => ValueRequired,
|
45
47
|
201 => PrevValueRequired,
|
46
48
|
202 => TTLNaN,
|
data/lib/etzetera/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: etzetera
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hendrik
|
@@ -31,62 +31,62 @@ cert_chain:
|
|
31
31
|
fESaRa24pr3CGd0AyltcRbKGfNpZfj1zfqWXrDUJj0Y1sOASd8+UZPmBFS2feJqy
|
32
32
|
het/fGFD7akMwHXIlNxNsg==
|
33
33
|
-----END CERTIFICATE-----
|
34
|
-
date: 2014-03-
|
34
|
+
date: 2014-03-05 00:00:00.000000000 Z
|
35
35
|
dependencies:
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: celluloid-io
|
38
38
|
requirement: !ruby/object:Gem::Requirement
|
39
39
|
requirements:
|
40
|
-
- - "
|
40
|
+
- - ">="
|
41
41
|
- !ruby/object:Gem::Version
|
42
42
|
version: '0.15'
|
43
43
|
type: :runtime
|
44
44
|
prerelease: false
|
45
45
|
version_requirements: !ruby/object:Gem::Requirement
|
46
46
|
requirements:
|
47
|
-
- - "
|
47
|
+
- - ">="
|
48
48
|
- !ruby/object:Gem::Version
|
49
49
|
version: '0.15'
|
50
50
|
- !ruby/object:Gem::Dependency
|
51
51
|
name: http
|
52
52
|
requirement: !ruby/object:Gem::Requirement
|
53
53
|
requirements:
|
54
|
-
- - "
|
54
|
+
- - ">="
|
55
55
|
- !ruby/object:Gem::Version
|
56
56
|
version: '0.5'
|
57
57
|
type: :runtime
|
58
58
|
prerelease: false
|
59
59
|
version_requirements: !ruby/object:Gem::Requirement
|
60
60
|
requirements:
|
61
|
-
- - "
|
61
|
+
- - ">="
|
62
62
|
- !ruby/object:Gem::Version
|
63
63
|
version: '0.5'
|
64
64
|
- !ruby/object:Gem::Dependency
|
65
65
|
name: multi_json
|
66
66
|
requirement: !ruby/object:Gem::Requirement
|
67
67
|
requirements:
|
68
|
-
- - "
|
68
|
+
- - ">="
|
69
69
|
- !ruby/object:Gem::Version
|
70
|
-
version:
|
70
|
+
version: 1.8.4
|
71
71
|
type: :runtime
|
72
72
|
prerelease: false
|
73
73
|
version_requirements: !ruby/object:Gem::Requirement
|
74
74
|
requirements:
|
75
|
-
- - "
|
75
|
+
- - ">="
|
76
76
|
- !ruby/object:Gem::Version
|
77
|
-
version:
|
77
|
+
version: 1.8.4
|
78
78
|
- !ruby/object:Gem::Dependency
|
79
79
|
name: bundler
|
80
80
|
requirement: !ruby/object:Gem::Requirement
|
81
81
|
requirements:
|
82
|
-
- - "
|
82
|
+
- - ">="
|
83
83
|
- !ruby/object:Gem::Version
|
84
84
|
version: '1.5'
|
85
85
|
type: :development
|
86
86
|
prerelease: false
|
87
87
|
version_requirements: !ruby/object:Gem::Requirement
|
88
88
|
requirements:
|
89
|
-
- - "
|
89
|
+
- - ">="
|
90
90
|
- !ruby/object:Gem::Version
|
91
91
|
version: '1.5'
|
92
92
|
description: A etcd Client written in Ruby
|
metadata.gz.sig
CHANGED
Binary file
|