etcdv3 0.8.3 → 0.9.0
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
- data/.travis.yml +10 -7
- data/README.md +21 -1
- data/Rakefile +16 -0
- data/etcdv3.gemspec +4 -2
- data/lib/etcdv3.rb +38 -0
- data/lib/etcdv3/auth.rb +2 -1
- data/lib/etcdv3/connection.rb +2 -1
- data/lib/etcdv3/etcdrpc/annotations_pb.rb +13 -0
- data/lib/etcdv3/etcdrpc/rpc_pb.rb +1 -0
- data/lib/etcdv3/etcdrpc/rpc_services_pb.rb +2 -0
- data/lib/etcdv3/etcdrpc/v3lock_pb.rb +30 -0
- data/lib/etcdv3/etcdrpc/v3lock_services_pb.rb +25 -0
- data/lib/etcdv3/kv.rb +2 -1
- data/lib/etcdv3/lease.rb +10 -1
- data/lib/etcdv3/lock.rb +27 -0
- data/lib/etcdv3/protos/v3lock.proto +55 -0
- data/lib/etcdv3/version.rb +1 -1
- data/spec/etcdv3/lease_spec.rb +10 -0
- data/spec/etcdv3/lock_spec.rb +23 -0
- data/spec/etcdv3_spec.rb +36 -1
- data/spec/helpers/shared_examples_for_timeout.rb +9 -8
- data/spec/helpers/test_instance.rb +2 -0
- data/spec/spec_helper.rb +8 -7
- metadata +45 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2c90b3d66d75efdf3c6c608cc1ccaf9673731070
|
4
|
+
data.tar.gz: 7698e02e69968d2e6348dd01a7e6813d27d5d50e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 634ec36c4eccf0b93dd69b51a25e6515c06a26a1677264fb02d035c793cf905feb739ad9bde6e40ae30617416aebe7b85706bb4a1060cbb3d26d8b68e42a702f
|
7
|
+
data.tar.gz: 7043f69c71837cefc8168ff3d5c0225afc9109c4a1c5e9aab1bec7b5fcf56999c9866abac23c3a7b13e9de5422b1983ffae57448f85dafd65f5d369837d7d286
|
data/.travis.yml
CHANGED
@@ -1,16 +1,19 @@
|
|
1
1
|
language: ruby
|
2
2
|
rvm:
|
3
|
-
- 2.
|
4
|
-
- 2.
|
3
|
+
- 2.5.3
|
4
|
+
- 2.4.5
|
5
|
+
- 2.3.8
|
5
6
|
|
6
7
|
env:
|
7
|
-
|
8
|
-
|
8
|
+
- ETCD_VERSION=v3.1.20
|
9
|
+
- ETCD_VERSION=v3.2.25
|
10
|
+
# v3.3.10 is not working for whatever reason (at least in travis, spec passes
|
11
|
+
# locally for me)
|
12
|
+
# - ETCD_VERSION=v3.3.10
|
9
13
|
|
10
14
|
install:
|
11
15
|
- bundle install
|
12
|
-
-
|
13
|
-
-
|
14
|
-
- export PATH=$PATH:etcd-$ETCD_VERSION-linux-amd64
|
16
|
+
- bundle exec rake download-etcd
|
17
|
+
- export PATH="$(dirname $(find /tmp -name 'etcd')):$PATH"
|
15
18
|
|
16
19
|
script: bundle exec rspec
|
data/README.md
CHANGED
@@ -43,6 +43,9 @@ In the event of a failure, the client will work to restore connectivity by cycli
|
|
43
43
|
# Get
|
44
44
|
conn.get('my')
|
45
45
|
|
46
|
+
# Get actual value
|
47
|
+
value = conn.get('my').kvs.first.value
|
48
|
+
|
46
49
|
# Get Key Range
|
47
50
|
conn.get('foo', range_end: 'foo80')
|
48
51
|
|
@@ -110,7 +113,7 @@ conn.auth_disable
|
|
110
113
|
conn.lease_grant(100)
|
111
114
|
|
112
115
|
# Attach key to lease
|
113
|
-
conn.put('foo', 'bar',
|
116
|
+
conn.put('foo', 'bar', lease: 1234566789)
|
114
117
|
|
115
118
|
# Get information about lease and its attached keys
|
116
119
|
conn.lease_ttl(1234566789)
|
@@ -161,6 +164,23 @@ conn.watch('boom') do |events|
|
|
161
164
|
end
|
162
165
|
```
|
163
166
|
|
167
|
+
## Locks
|
168
|
+
```ruby
|
169
|
+
# First, get yourself a lease
|
170
|
+
lease_id = conn.lease_grant(100)['ID']
|
171
|
+
|
172
|
+
# Attempt to lock distibuted lock 'foo', wait at most 10 seconds
|
173
|
+
lock_key = conn.lock('foo', lease_id, timeout: 10).key
|
174
|
+
|
175
|
+
# Unlock the 'foo' lock using the key returned from `lock`
|
176
|
+
conn.unlock(key)
|
177
|
+
|
178
|
+
# Perform a critical section while holding the lock 'hello'
|
179
|
+
conn.with_lock('hello', lease_id) do
|
180
|
+
puts "kitty!"
|
181
|
+
end
|
182
|
+
```
|
183
|
+
|
164
184
|
## Alarms
|
165
185
|
```ruby
|
166
186
|
# List all active Alarms
|
data/Rakefile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
ETCD_VERSION = ENV["ETCD_VERSION"] || "v3.2.0"
|
4
|
+
ETCD_URL = "https://github.com/coreos/etcd/releases/download/#{ETCD_VERSION}/etcd-#{ETCD_VERSION}-linux-amd64.tar.gz"
|
5
|
+
|
6
|
+
require "tmpdir"
|
7
|
+
|
8
|
+
desc "Download etcd for it can be used in rspec"
|
9
|
+
task :"download-etcd" do
|
10
|
+
tmpdir = Dir.mktmpdir
|
11
|
+
system("wget", ETCD_URL, "-O", "#{tmpdir}/etcd.tar.gz") || exit(1)
|
12
|
+
system(*%W{tar -C #{tmpdir} -zxvf #{tmpdir}/etcd.tar.gz}) || exit(1)
|
13
|
+
|
14
|
+
puts "Etcd downloaded and extracted. Add it to the path:"
|
15
|
+
puts " export PATH=\"#{tmpdir}/etcd-#{ETCD_VERSION}-linux-amd64:$PATH\""
|
16
|
+
end
|
data/etcdv3.gemspec
CHANGED
@@ -14,6 +14,8 @@ Gem::Specification.new do |s|
|
|
14
14
|
s.files = `git ls-files`.split("\n")
|
15
15
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
16
16
|
|
17
|
-
s.add_dependency("grpc", "~> 1.
|
18
|
-
s.add_development_dependency("
|
17
|
+
s.add_dependency("grpc", "~> 1.17")
|
18
|
+
s.add_development_dependency("pry-byebug", "~> 3.6")
|
19
|
+
s.add_development_dependency("rake", "~> 12.3")
|
20
|
+
s.add_development_dependency("rspec", "~> 3.6")
|
19
21
|
end
|
data/lib/etcdv3.rb
CHANGED
@@ -2,6 +2,7 @@ require 'grpc'
|
|
2
2
|
require 'uri'
|
3
3
|
|
4
4
|
require 'etcdv3/etcdrpc/rpc_services_pb'
|
5
|
+
require 'etcdv3/etcdrpc/v3lock_services_pb'
|
5
6
|
require 'etcdv3/auth'
|
6
7
|
require 'etcdv3/kv/requests'
|
7
8
|
require 'etcdv3/kv/transaction'
|
@@ -9,6 +10,7 @@ require 'etcdv3/kv'
|
|
9
10
|
require 'etcdv3/maintenance'
|
10
11
|
require 'etcdv3/lease'
|
11
12
|
require 'etcdv3/watch'
|
13
|
+
require 'etcdv3/lock'
|
12
14
|
require 'etcdv3/connection'
|
13
15
|
require 'etcdv3/connection_wrapper'
|
14
16
|
|
@@ -84,6 +86,37 @@ class Etcdv3
|
|
84
86
|
@conn.handle(:kv, 'get', [key, opts])
|
85
87
|
end
|
86
88
|
|
89
|
+
# Locks distributed lock with the given name. The lock will unlock automatically
|
90
|
+
# when lease with the given ID expires. If this is not desirable, provide a non-expiring
|
91
|
+
# lease ID as an argument.
|
92
|
+
# name - string
|
93
|
+
# lease_id - integer
|
94
|
+
# optional :timeout - integer
|
95
|
+
def lock(name, lease_id, timeout: nil)
|
96
|
+
@conn.handle(:lock, 'lock', [name, lease_id, {timeout: timeout}])
|
97
|
+
end
|
98
|
+
|
99
|
+
# Unlock distributed lock using the key previously obtained from lock.
|
100
|
+
# key - string
|
101
|
+
# optional :timeout - integer
|
102
|
+
def unlock(key, timeout: nil)
|
103
|
+
@conn.handle(:lock, 'unlock', [key, {timeout: timeout}])
|
104
|
+
end
|
105
|
+
|
106
|
+
# Yield into the critical section while holding lock with the given
|
107
|
+
# name. The lock will be unlocked even if the block throws.
|
108
|
+
# name - string
|
109
|
+
# lease_id - integer
|
110
|
+
# optional :timeout - integer
|
111
|
+
def with_lock(name, lease_id, timeout: nil)
|
112
|
+
key = lock(name, lease_id, timeout: timeout).key
|
113
|
+
begin
|
114
|
+
yield
|
115
|
+
ensure
|
116
|
+
unlock(key, timeout: timeout)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
87
120
|
# Inserts a new key.
|
88
121
|
# key - string
|
89
122
|
# value - string
|
@@ -116,6 +149,11 @@ class Etcdv3
|
|
116
149
|
@conn.handle(:lease, 'lease_ttl', [id, timeout: timeout])
|
117
150
|
end
|
118
151
|
|
152
|
+
# Sends one lease keep-alive request
|
153
|
+
def lease_keep_alive_once(id, timeout: nil)
|
154
|
+
@conn.handle(:lease, 'lease_keep_alive_once', [id, timeout: timeout])
|
155
|
+
end
|
156
|
+
|
119
157
|
# List all roles.
|
120
158
|
def role_list(timeout: nil)
|
121
159
|
@conn.handle(:auth, 'role_list', [timeout: timeout])
|
data/lib/etcdv3/auth.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
|
2
2
|
class Etcdv3
|
3
3
|
class Auth
|
4
|
+
include GRPC::Core::TimeConsts
|
4
5
|
|
5
6
|
PERMISSIONS = {
|
6
7
|
:read => Authpb::Permission::Type::READ,
|
@@ -122,7 +123,7 @@ class Etcdv3
|
|
122
123
|
private
|
123
124
|
|
124
125
|
def deadline(timeout)
|
125
|
-
|
126
|
+
from_relative_time(timeout || @timeout)
|
126
127
|
end
|
127
128
|
end
|
128
129
|
end
|
data/lib/etcdv3/connection.rb
CHANGED
@@ -0,0 +1,30 @@
|
|
1
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
2
|
+
# source: v3lock.proto
|
3
|
+
|
4
|
+
require 'google/protobuf'
|
5
|
+
|
6
|
+
require_relative 'annotations_pb'
|
7
|
+
require_relative 'rpc_pb'
|
8
|
+
Google::Protobuf::DescriptorPool.generated_pool.build do
|
9
|
+
add_message "v3lockpb.LockRequest" do
|
10
|
+
optional :name, :bytes, 1
|
11
|
+
optional :lease, :int64, 2
|
12
|
+
end
|
13
|
+
add_message "v3lockpb.LockResponse" do
|
14
|
+
optional :header, :message, 1, "etcdserverpb.ResponseHeader"
|
15
|
+
optional :key, :bytes, 2
|
16
|
+
end
|
17
|
+
add_message "v3lockpb.UnlockRequest" do
|
18
|
+
optional :key, :bytes, 1
|
19
|
+
end
|
20
|
+
add_message "v3lockpb.UnlockResponse" do
|
21
|
+
optional :header, :message, 1, "etcdserverpb.ResponseHeader"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
module V3lockpb
|
26
|
+
LockRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("v3lockpb.LockRequest").msgclass
|
27
|
+
LockResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("v3lockpb.LockResponse").msgclass
|
28
|
+
UnlockRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("v3lockpb.UnlockRequest").msgclass
|
29
|
+
UnlockResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("v3lockpb.UnlockResponse").msgclass
|
30
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
2
|
+
# Source: v3lock.proto for package 'v3lockpb'
|
3
|
+
|
4
|
+
require 'grpc'
|
5
|
+
require_relative 'v3lock_pb'
|
6
|
+
|
7
|
+
module V3lockpb
|
8
|
+
module Lock
|
9
|
+
class Service
|
10
|
+
|
11
|
+
include GRPC::GenericService
|
12
|
+
|
13
|
+
self.marshal_class_method = :encode
|
14
|
+
self.unmarshal_class_method = :decode
|
15
|
+
self.service_name = 'v3lockpb.Lock'
|
16
|
+
|
17
|
+
# Lock acquires a distributed shared lock on a given named lock.
|
18
|
+
rpc :Lock, LockRequest, LockResponse
|
19
|
+
# Unlock takes a key returned by Lock and releases the hold on lock.
|
20
|
+
rpc :Unlock, UnlockRequest, UnlockResponse
|
21
|
+
end
|
22
|
+
|
23
|
+
Stub = Service.rpc_stub_class
|
24
|
+
end
|
25
|
+
end
|
data/lib/etcdv3/kv.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
class Etcdv3
|
3
3
|
class KV
|
4
4
|
include Etcdv3::KV::Requests
|
5
|
+
include GRPC::Core::TimeConsts
|
5
6
|
|
6
7
|
def initialize(hostname, credentials, timeout, metadata={})
|
7
8
|
@stub = Etcdserverpb::KV::Stub.new(hostname, credentials)
|
@@ -36,7 +37,7 @@ class Etcdv3
|
|
36
37
|
private
|
37
38
|
|
38
39
|
def deadline(timeout)
|
39
|
-
|
40
|
+
from_relative_time(timeout || @timeout)
|
40
41
|
end
|
41
42
|
|
42
43
|
def generate_request_ops(requests)
|
data/lib/etcdv3/lease.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
class Etcdv3
|
2
2
|
class Lease
|
3
|
+
include GRPC::Core::TimeConsts
|
4
|
+
|
3
5
|
def initialize(hostname, credentials, timeout, metadata={})
|
4
6
|
@stub = Etcdserverpb::Lease::Stub.new(hostname, credentials)
|
5
7
|
@timeout = timeout
|
@@ -21,10 +23,17 @@ class Etcdv3
|
|
21
23
|
@stub.lease_time_to_live(request, metadata: @metadata, deadline: deadline(timeout))
|
22
24
|
end
|
23
25
|
|
26
|
+
def lease_keep_alive_once(id, timeout: nil)
|
27
|
+
request = Etcdserverpb::LeaseKeepAliveRequest.new(ID: id)
|
28
|
+
@stub.lease_keep_alive([request], metadata: @metadata, deadline: deadline(timeout)).each do |resp|
|
29
|
+
return resp
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
24
33
|
private
|
25
34
|
|
26
35
|
def deadline(timeout)
|
27
|
-
|
36
|
+
from_relative_time(timeout || @timeout)
|
28
37
|
end
|
29
38
|
end
|
30
39
|
end
|
data/lib/etcdv3/lock.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
class Etcdv3
|
2
|
+
class Lock
|
3
|
+
include GRPC::Core::TimeConsts
|
4
|
+
|
5
|
+
def initialize(hostname, credentials, timeout, metadata = {})
|
6
|
+
@stub = V3lockpb::Lock::Stub.new(hostname, credentials)
|
7
|
+
@timeout = timeout
|
8
|
+
@metadata = metadata
|
9
|
+
end
|
10
|
+
|
11
|
+
def lock(name, lease_id, timeout: nil)
|
12
|
+
request = V3lockpb::LockRequest.new(name: name, lease: lease_id)
|
13
|
+
@stub.lock(request, deadline: deadline(timeout))
|
14
|
+
end
|
15
|
+
|
16
|
+
def unlock(key, timeout: nil)
|
17
|
+
request = V3lockpb::UnlockRequest.new(key: key)
|
18
|
+
@stub.unlock(request, deadline: deadline(timeout))
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def deadline(timeout)
|
24
|
+
from_relative_time(timeout || @timeout)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
syntax = "proto3";
|
2
|
+
package v3lockpb;
|
3
|
+
|
4
|
+
import "annotations.proto";
|
5
|
+
import "rpc.proto";
|
6
|
+
import "gogo.proto";
|
7
|
+
|
8
|
+
option (gogoproto.marshaler_all) = true;
|
9
|
+
option (gogoproto.unmarshaler_all) = true;
|
10
|
+
|
11
|
+
service Lock {
|
12
|
+
// Lock acquires a distributed shared lock on a given named lock.
|
13
|
+
rpc Lock(LockRequest) returns (LockResponse) {
|
14
|
+
option (google.api.http) = {
|
15
|
+
post: "/v3alpha/lock/lock"
|
16
|
+
body: "*"
|
17
|
+
};
|
18
|
+
}
|
19
|
+
|
20
|
+
// Unlock takes a key returned by Lock and releases the hold on lock.
|
21
|
+
rpc Unlock(UnlockRequest) returns (UnlockResponse) {
|
22
|
+
option (google.api.http) = {
|
23
|
+
post: "/v3alpha/lock/unlock"
|
24
|
+
body: "*"
|
25
|
+
};
|
26
|
+
}
|
27
|
+
}
|
28
|
+
|
29
|
+
message LockRequest {
|
30
|
+
// name is the identifier for the distributed shared lock to be acquired.
|
31
|
+
bytes name = 1;
|
32
|
+
// lease is the ID of the lease that will be attached to ownership of the
|
33
|
+
// lock. If the lease expires or is revoked and currently holds the lock,
|
34
|
+
// the lock is automatically released. Calls to Lock with the same lease will
|
35
|
+
// be treated as a single acquisition; locking twice with the same lease is a
|
36
|
+
// no-op.
|
37
|
+
int64 lease = 2;
|
38
|
+
}
|
39
|
+
|
40
|
+
message LockResponse {
|
41
|
+
etcdserverpb.ResponseHeader header = 1;
|
42
|
+
// key is a key that will exist on etcd for the duration that the Lock caller
|
43
|
+
// owns the lock. Users should not modify this key or the lock may exhibit
|
44
|
+
// undefined behavior.
|
45
|
+
bytes key = 2;
|
46
|
+
}
|
47
|
+
|
48
|
+
message UnlockRequest {
|
49
|
+
// key is the lock ownership key granted by Lock.
|
50
|
+
bytes key = 1;
|
51
|
+
}
|
52
|
+
|
53
|
+
message UnlockResponse {
|
54
|
+
etcdserverpb.ResponseHeader header = 1;
|
55
|
+
}
|
data/lib/etcdv3/version.rb
CHANGED
data/spec/etcdv3/lease_spec.rb
CHANGED
@@ -24,6 +24,16 @@ describe Etcdv3::Lease do
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
+
describe '#lease_keep_alive_once' do
|
28
|
+
let(:id) { stub.lease_grant(60)['ID'] }
|
29
|
+
subject { stub.lease_keep_alive_once(id) }
|
30
|
+
it { is_expected.to be_an_instance_of(Etcdserverpb::LeaseKeepAliveResponse) }
|
31
|
+
it 'raises a GRPC:DeadlineExceeded if the request takes too long' do
|
32
|
+
stub = local_stub(Etcdv3::Lease, 0)
|
33
|
+
expect { stub.lease_keep_alive_once(id) }.to raise_error(GRPC::DeadlineExceeded)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
27
37
|
describe '#lease_ttl' do
|
28
38
|
let(:stub) { local_stub(Etcdv3::Lease, 1) }
|
29
39
|
let(:lease_id) { stub.lease_grant(10)['ID'] }
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
# Locking is not implemented in etcd v3.1.X
|
4
|
+
unless $instance.version < Gem::Version.new("3.2.0")
|
5
|
+
describe Etcdv3::Lock do
|
6
|
+
let(:stub) { local_stub(Etcdv3::Lock, 1) }
|
7
|
+
let(:lease_stub) { local_stub(Etcdv3::Lease, 1) }
|
8
|
+
|
9
|
+
it_should_behave_like "a method with a GRPC timeout", described_class, :unlock, :unlock, 'foo'
|
10
|
+
#it_should_behave_like "a method with a GRPC timeout", described_class, :lock, :lock, 'foo'
|
11
|
+
|
12
|
+
describe '#lock' do
|
13
|
+
let(:lease_id) { lease_stub.lease_grant(10)['ID'] }
|
14
|
+
subject { stub.lock('foo', lease_id) }
|
15
|
+
it { is_expected.to be_an_instance_of(V3lockpb::LockResponse) }
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#unlock' do
|
19
|
+
subject { stub.unlock('foo') }
|
20
|
+
it { is_expected.to be_an_instance_of(V3lockpb::UnlockResponse) }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/spec/etcdv3_spec.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Etcdv3 do
|
4
|
-
|
4
|
+
let(:lease_stub) { local_stub(Etcdv3::Lease, 1) }
|
5
5
|
|
6
|
+
context 'Insecure connection without Auth' do
|
6
7
|
let(:conn) { local_connection }
|
7
8
|
|
8
9
|
describe '#initialize' do
|
@@ -103,6 +104,26 @@ describe Etcdv3 do
|
|
103
104
|
it_should_behave_like "Etcdv3 instance using a timeout", :get, 'apple'
|
104
105
|
end
|
105
106
|
|
107
|
+
# Locking is not implemented in etcd v3.1.X
|
108
|
+
unless $instance.version < Gem::Version.new("3.2.0")
|
109
|
+
describe '#lock' do
|
110
|
+
let(:lease_id) { lease_stub.lease_grant(10)['ID'] }
|
111
|
+
subject { conn.lock('bar', lease_id) }
|
112
|
+
it { is_expected.to be_an_instance_of(V3lockpb::LockResponse) }
|
113
|
+
end
|
114
|
+
|
115
|
+
describe '#with_lock' do
|
116
|
+
let(:lease_id) { lease_stub.lease_grant(10)['ID'] }
|
117
|
+
let(:lease_id_2) { lease_stub.lease_grant(15)['ID'] }
|
118
|
+
it 'locks' do
|
119
|
+
conn.with_lock('foobar', lease_id) do
|
120
|
+
expect { conn.lock('foobar', lease_id_2, timeout: 0.1) }
|
121
|
+
.to raise_error(GRPC::DeadlineExceeded)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
106
127
|
describe '#put' do
|
107
128
|
subject { conn.put('test', 'value') }
|
108
129
|
it { is_expected.to_not be_nil }
|
@@ -160,6 +181,20 @@ describe Etcdv3 do
|
|
160
181
|
end
|
161
182
|
end
|
162
183
|
|
184
|
+
describe '#lease_keep_alive_once' do
|
185
|
+
let!(:lease_id) { conn.lease_grant(2)['ID'] }
|
186
|
+
subject { conn.lease_keep_alive_once(lease_id) }
|
187
|
+
it { is_expected.to_not be_nil }
|
188
|
+
it "raises a GRPC::DeadlineExceeded exception when it takes too long" do
|
189
|
+
expect do
|
190
|
+
conn.lease_keep_alive_once(lease_id, timeout: 0)
|
191
|
+
end.to raise_exception(GRPC::DeadlineExceeded)
|
192
|
+
end
|
193
|
+
it "accepts a timeout" do
|
194
|
+
expect{ conn.lease_keep_alive_once(lease_id, timeout: 10) }.to_not raise_exception
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
163
198
|
describe '#user_add' do
|
164
199
|
after { conn.user_delete('test') rescue nil }
|
165
200
|
subject { conn.user_add('test', 'user') }
|
@@ -1,22 +1,23 @@
|
|
1
1
|
shared_examples_for "a method with a GRPC timeout" do |stub_class, method_name, expectation_target, *args|
|
2
|
+
include GRPC::Core::TimeConsts
|
3
|
+
|
2
4
|
context "#{stub_class} timeouts for #{method_name}" do
|
3
5
|
let(:handler) { local_stub(stub_class, 5) }
|
4
6
|
let(:client_stub) { handler.instance_variable_get "@stub"}
|
5
7
|
it 'uses the timeout value' do
|
6
|
-
|
7
|
-
|
8
|
-
allow(
|
8
|
+
deadline = from_relative_time(5)
|
9
|
+
allow(handler).to receive(:deadline).with(nil).and_return(deadline)
|
10
|
+
allow(handler).to receive(:deadline).with(5).and_return(deadline)
|
9
11
|
|
10
|
-
expect(client_stub).to receive(expectation_target).with(anything, hash_including(deadline:
|
12
|
+
expect(client_stub).to receive(expectation_target).with(anything, hash_including(deadline: deadline)).and_call_original
|
11
13
|
|
12
14
|
handler.public_send(method_name, *args)
|
13
15
|
end
|
14
16
|
|
15
17
|
it "can have a seperate timeout passed in" do
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
expect(client_stub).to receive(expectation_target).with(anything, hash_including(deadline: deadline_time)).and_call_original
|
18
|
+
deadline = from_relative_time(1)
|
19
|
+
allow(handler).to receive(:deadline).with(1).and_return(deadline)
|
20
|
+
expect(client_stub).to receive(expectation_target).with(anything, hash_including(deadline: deadline)).and_call_original
|
20
21
|
handler.public_send(method_name, *args, timeout: 1)
|
21
22
|
end
|
22
23
|
|
data/spec/spec_helper.rb
CHANGED
@@ -1,15 +1,17 @@
|
|
1
1
|
$LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
|
2
2
|
$LOAD_PATH.unshift File.expand_path('./helpers', __FILE__)
|
3
3
|
|
4
|
-
require 'etcdv3'
|
5
4
|
require 'simplecov'
|
6
5
|
require 'codecov'
|
6
|
+
SimpleCov.start
|
7
|
+
SimpleCov.formatter = SimpleCov::Formatter::Codecov
|
8
|
+
|
9
|
+
require 'etcdv3'
|
7
10
|
require 'helpers/test_instance'
|
8
11
|
require 'helpers/connections'
|
9
12
|
require 'helpers/shared_examples_for_timeout'
|
10
13
|
|
11
|
-
|
12
|
-
SimpleCov.formatter = SimpleCov::Formatter::Codecov
|
14
|
+
$instance = Helpers::TestInstance.new
|
13
15
|
|
14
16
|
RSpec.configure do |config|
|
15
17
|
config.include(Helpers::Connections)
|
@@ -22,12 +24,11 @@ RSpec.configure do |config|
|
|
22
24
|
end
|
23
25
|
config.shared_context_metadata_behavior = :apply_to_host_groups
|
24
26
|
|
25
|
-
instance = Helpers::TestInstance.new
|
26
27
|
config.before(:suite) do
|
27
|
-
|
28
|
-
instance.start
|
28
|
+
$stderr = File.open(File::NULL, "w")
|
29
|
+
$instance.start
|
29
30
|
end
|
30
31
|
config.after(:suite) do
|
31
|
-
instance.stop
|
32
|
+
$instance.stop
|
32
33
|
end
|
33
34
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: etcdv3
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shaun Davis
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-12-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: grpc
|
@@ -16,28 +16,56 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '1.
|
19
|
+
version: '1.17'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '1.
|
26
|
+
version: '1.17'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: pry-byebug
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3.6'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '3.6'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '12.3'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '12.3'
|
27
55
|
- !ruby/object:Gem::Dependency
|
28
56
|
name: rspec
|
29
57
|
requirement: !ruby/object:Gem::Requirement
|
30
58
|
requirements:
|
31
|
-
- - "
|
59
|
+
- - "~>"
|
32
60
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
61
|
+
version: '3.6'
|
34
62
|
type: :development
|
35
63
|
prerelease: false
|
36
64
|
version_requirements: !ruby/object:Gem::Requirement
|
37
65
|
requirements:
|
38
|
-
- - "
|
66
|
+
- - "~>"
|
39
67
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
68
|
+
version: '3.6'
|
41
69
|
description: Etcd v3 Ruby Client
|
42
70
|
email: davissp14@gmail.com
|
43
71
|
executables: []
|
@@ -50,19 +78,24 @@ files:
|
|
50
78
|
- Gemfile
|
51
79
|
- LICENSE
|
52
80
|
- README.md
|
81
|
+
- Rakefile
|
53
82
|
- etcdv3.gemspec
|
54
83
|
- lib/etcdv3.rb
|
55
84
|
- lib/etcdv3/auth.rb
|
56
85
|
- lib/etcdv3/connection.rb
|
57
86
|
- lib/etcdv3/connection_wrapper.rb
|
87
|
+
- lib/etcdv3/etcdrpc/annotations_pb.rb
|
58
88
|
- lib/etcdv3/etcdrpc/auth_pb.rb
|
59
89
|
- lib/etcdv3/etcdrpc/kv_pb.rb
|
60
90
|
- lib/etcdv3/etcdrpc/rpc_pb.rb
|
61
91
|
- lib/etcdv3/etcdrpc/rpc_services_pb.rb
|
92
|
+
- lib/etcdv3/etcdrpc/v3lock_pb.rb
|
93
|
+
- lib/etcdv3/etcdrpc/v3lock_services_pb.rb
|
62
94
|
- lib/etcdv3/kv.rb
|
63
95
|
- lib/etcdv3/kv/requests.rb
|
64
96
|
- lib/etcdv3/kv/transaction.rb
|
65
97
|
- lib/etcdv3/lease.rb
|
98
|
+
- lib/etcdv3/lock.rb
|
66
99
|
- lib/etcdv3/maintenance.rb
|
67
100
|
- lib/etcdv3/protos/annotations.proto
|
68
101
|
- lib/etcdv3/protos/auth.proto
|
@@ -71,6 +104,7 @@ files:
|
|
71
104
|
- lib/etcdv3/protos/http.proto
|
72
105
|
- lib/etcdv3/protos/kv.proto
|
73
106
|
- lib/etcdv3/protos/rpc.proto
|
107
|
+
- lib/etcdv3/protos/v3lock.proto
|
74
108
|
- lib/etcdv3/version.rb
|
75
109
|
- lib/etcdv3/watch.rb
|
76
110
|
- spec/etcdv3/auth_spec.rb
|
@@ -78,6 +112,7 @@ files:
|
|
78
112
|
- spec/etcdv3/connection_wrapper_spec.rb
|
79
113
|
- spec/etcdv3/kv_spec.rb
|
80
114
|
- spec/etcdv3/lease_spec.rb
|
115
|
+
- spec/etcdv3/lock_spec.rb
|
81
116
|
- spec/etcdv3/maintenance_spec.rb
|
82
117
|
- spec/etcdv3_spec.rb
|
83
118
|
- spec/helpers/connections.rb
|
@@ -104,7 +139,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
104
139
|
version: '0'
|
105
140
|
requirements: []
|
106
141
|
rubyforge_project:
|
107
|
-
rubygems_version: 2.
|
142
|
+
rubygems_version: 2.4.5.1
|
108
143
|
signing_key:
|
109
144
|
specification_version: 4
|
110
145
|
summary: A Etcd client library for Version 3
|
@@ -114,6 +149,7 @@ test_files:
|
|
114
149
|
- spec/etcdv3/connection_wrapper_spec.rb
|
115
150
|
- spec/etcdv3/kv_spec.rb
|
116
151
|
- spec/etcdv3/lease_spec.rb
|
152
|
+
- spec/etcdv3/lock_spec.rb
|
117
153
|
- spec/etcdv3/maintenance_spec.rb
|
118
154
|
- spec/etcdv3_spec.rb
|
119
155
|
- spec/helpers/connections.rb
|