lusnoc 0.1.2.16550 → 0.1.2.16562

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e4af65d48d9995e47998f8bea63ce80596b489ef15c1a55ce2a507f89ed99d1e
4
- data.tar.gz: 0d11b3ac2e867299c66d188fa9f10317d66b24df6bd17102e9c1d4c6ed0643f8
3
+ metadata.gz: e6702f81592770f748868d48751530d7cfb483b54b6a36c1d97df5cf1feeceb2
4
+ data.tar.gz: f2ba75f441735a84d4763db29a02fdcfedb30c019aa5da2d7ee09b9cd0a3592b
5
5
  SHA512:
6
- metadata.gz: '03873f94e76a5859aba8579aca0c734119946a261ae46267b79b51f1bd171771253c6707e3b7f2b57b1ce2315d3e7a4c39f6a207c67e66a1257d7c56d6c0944a'
7
- data.tar.gz: 1e2b77c07bcf4d44385fd6e2574aee7b633eafeaf34cdc0fe7c15309e6ddd248e84f469532dea4506698c7d6e9a03abf48cfa84846d69e18ee6ba5684f7deb6a
6
+ metadata.gz: 16dea1103ba3cc6489916bfdfb3c7aee0253bcb794a072f4acb407155f9ab50974ab67621bc6745b21ffecd86b13fb08f714ba75d58d6e7a2bf3fb5720014e79
7
+ data.tar.gz: d778a22d40088c0b257a289694a2e43f8b2aabcbce5c1ac72e8d1102057c30d1fe33f18b029a6f678c798e0d8d74499436305fc3466237e82782738cf78ac81c
data/lib/lusnoc/guard.rb CHANGED
@@ -6,33 +6,26 @@ module Lusnoc
6
6
 
7
7
  include Helper
8
8
 
9
+ attr_reader :callbacks
10
+
9
11
  def initialize(base_url)
10
12
  @base_url = base_url
13
+ @callbacks = {}
11
14
  yield(self) if block_given?
12
15
  end
13
16
 
14
17
  def condition(&block)
15
- @condition = block
18
+ @callbacks[:condition] = block
16
19
  self
17
20
  end
18
21
 
19
22
  def then(&block)
20
- @callback = block
23
+ @callbacks[:then] = block
21
24
  self
22
25
  end
23
26
 
24
27
  def run
25
- th = Thread.new do
26
- logger.info "Guard[#{@base_url.inspect}] thread started"
27
- watch_forever(@base_url)
28
- fire!
29
- rescue StandardError => e
30
- logger.error "Guard[#{@base_url.inspect}] error: #{e.inspect}"
31
- fire!
32
- ensure
33
- logger.info "Guard[#{@base_url.inspect}] finihsed"
34
- end
35
-
28
+ th = start_thread
36
29
  yield
37
30
  ensure
38
31
  th.kill rescue nil
@@ -40,28 +33,48 @@ module Lusnoc
40
33
 
41
34
  private
42
35
 
43
- def fire!
44
- @callback&.tap do |cb|
45
- @callback = nil
36
+ def start_thread
37
+ Thread.new do
38
+ logger.info "Guard[#{@base_url.inspect}] thread started"
39
+ watch_forever(@base_url)
40
+ fire!
41
+ rescue StandardError => e
42
+ logger.error "Guard[#{@base_url.inspect}] error: #{e.inspect}"
43
+ logger.error e.backtrace
44
+ fire!(e)
45
+ ensure
46
+ logger.info "Guard[#{@base_url.inspect}] finihsed"
47
+ end
48
+ end
49
+
50
+ def fire!(*args)
51
+ @callbacks[:then]&.tap do |cb|
52
+ @callbacks[:then] = nil
46
53
  logger.info "Guard[#{@base_url.inspect}] fired"
47
- cb.call
54
+ cb.call(*args)
48
55
  end
49
56
  end
50
57
 
51
58
  def watch_forever(base_url)
52
- last_x_consul_index = 1
53
-
54
- Kernel.loop do
55
- resp = Lusnoc.http_get("#{base_url}?index=#{last_x_consul_index}&wait=10s", timeout: 15)
56
- logger.debug "Guard[#{@base_url.inspect}] response: #{resp.body}"
57
- return unless @condition.call(resp.body)
58
-
59
- index = [Integer(resp['x-consul-index']), 1].max
60
- last_x_consul_index = (index < last_x_consul_index ? 1 : index)
61
- sleep 1
59
+ Lusnoc::Watcher.new(base_url).run(max_consul_wait: 10) do |body|
60
+ return true unless @callbacks[:condition].call(body)
62
61
  end
63
62
  end
64
63
 
64
+ # def watch_forever(base_url)
65
+ # last_x_consul_index = 1
66
+
67
+ # Kernel.loop do
68
+ # resp = Lusnoc.http_get("#{base_url}?index=#{last_x_consul_index}&wait=10s", timeout: 15)
69
+ # logger.debug "Guard[#{@base_url.inspect}] response: #{resp.body}"
70
+ # return unless @callbacks[:condition].call(resp.body)
71
+
72
+ # index = [Integer(resp['x-consul-index']), 1].max
73
+ # last_x_consul_index = (index < last_x_consul_index ? 1 : index)
74
+ # sleep 0.4
75
+ # end
76
+ # end
77
+
65
78
  end
66
79
  end
67
80
 
data/lib/lusnoc/mutex.rb CHANGED
@@ -46,7 +46,7 @@ module Lusnoc
46
46
  return acquisition_loop! key, session, value, t, &block
47
47
  ensure
48
48
  release(key, session.id, timeout: 2) rescue nil
49
- logger.info("Lock #{key} released for session #{session.name}[#{session.id}]")
49
+ logger.info("Mutex[#{key}] released for Session[#{session.name}:#{session.id}]")
50
50
  @owner = nil
51
51
  @session = nil
52
52
  end
@@ -59,7 +59,7 @@ module Lusnoc
59
59
  return false if resp.body.chomp != 'true'
60
60
 
61
61
  @owner = Thread.current
62
- logger.info("Lock #{key} acquired for session #{session.name}[#{session.id}]")
62
+ logger.info("Mutex[#{key}] acquired for Session[#{session.name}:#{session.id}]")
63
63
  renew
64
64
  true
65
65
  end
@@ -69,22 +69,44 @@ module Lusnoc
69
69
  end
70
70
 
71
71
  def acquisition_loop!(key, session, value, t)
72
- return yield(self) if acquire(key, session, value)
72
+ if acquire(key, session, value)
73
+ prepare_guard(session, key).run do
74
+ return yield(self)
75
+ end
76
+ end
73
77
 
74
- logger.debug("Start #{key} acquisition loop for session #{session.name}[#{session.id}]")
78
+ logger.debug("Mutex[#{key}] run acquisition loop for Session[#{session.name}:#{session.id}]")
75
79
  t.loop! do
76
80
  session.alive!(TimeoutError)
77
81
  wait_for_key_released(key, t.left)
78
82
 
79
- return yield(self) if acquire(key, session, value)
83
+ if acquire(key, session, value)
84
+ prepare_guard(session, key).run do
85
+ return yield(self)
86
+ end
87
+ end
88
+
89
+ logger.debug("Mutex[#{key}] acquisition failed for Session[#{session.name}:#{session.id}]")
90
+ sleep 0.4
91
+ end
92
+ end
80
93
 
81
- logger.debug("Lock #{key} acquisition failed for session #{session.name}[#{session.id}]")
82
- sleep 1
94
+ def prepare_guard(session, key)
95
+ Lusnoc::Guard.new(build_url("/v1/kv/#{key}")) do |guard|
96
+ guard.condition do |body|
97
+ JSON.parse(body).first['Session'] == session.id rescue false
98
+ end
99
+
100
+ guard.then do
101
+ @owner = nil
102
+ logger.info("Mutex[#{key}] LOST for Session[#{session.name}:#{session.id}]")
103
+ @on_mutex_lost&.call(self)
104
+ end
83
105
  end
84
106
  end
85
107
 
86
108
  def wait_for_key_released(key, timeout = nil)
87
- logger.debug "Waiting for key #{key} to be fre of any session"
109
+ logger.debug("Mutex[#{key}] start waiting of key releasing...")
88
110
  Lusnoc::Watcher.new(build_url("/v1/kv/#{key}"),
89
111
  timeout: timeout,
90
112
  eclass: TimeoutError,
@@ -8,10 +8,14 @@ module Lusnoc
8
8
 
9
9
  attr_reader :id, :name, :ttl, :alive, :expired_at
10
10
 
11
- def initialize(name, ttl: 20)
11
+ def initialize(name, ttl: 20, &block)
12
12
  @name = name
13
13
  @ttl = ttl
14
14
 
15
+ run(&block) if block_given?
16
+ end
17
+
18
+ def run
15
19
  @id = create_session(name, ttl)
16
20
 
17
21
  prepare_guard(@id).run do
@@ -38,7 +42,7 @@ module Lusnoc
38
42
  end
39
43
 
40
44
  def alive!(exception_class = ExpiredError)
41
- alive? || (raise exception_class.new("Session[#{@name}:#{@id}] expired"))
45
+ @alive || (raise exception_class.new("Session[#{@name}:#{@id}] expired"))
42
46
  end
43
47
 
44
48
  def renew
@@ -50,6 +54,8 @@ module Lusnoc
50
54
 
51
55
  def on_session_die(&block)
52
56
  @session_die_cb = block
57
+ @session_die_cb&.call(self) if @alive == false
58
+ self
53
59
  end
54
60
 
55
61
  private
@@ -12,19 +12,19 @@ module Lusnoc
12
12
  eclass: Lusnoc::TimeoutError,
13
13
  emessage: 'watch timeout')
14
14
  @base_url = base_url
15
- @timeout = timeout
16
- @eclass = eclass
15
+ @timeout = timeout
16
+ @eclass = eclass
17
17
  @emessage = emessage
18
18
  end
19
19
 
20
20
  # run Consul blocking request in a loop with timeout support.
21
21
  # break condition yielded by block call with response body
22
- def run
22
+ def run(max_consul_wait: nil)
23
23
  logger.debug "Watch #{@base_url} with #{@timeout.inspect} timeout"
24
24
  last_x_consul_index = 1
25
25
 
26
26
  Timeouter.loop!(@timeout, eclass: @eclass, message: @emessage) do |t|
27
- wait_condition = t.left ? "&wait=#{t.left.to_i}s" : ''
27
+ wait_condition = build_wait_condition(@base_url, t.left, max_consul_wait)
28
28
  url = "#{@base_url}?index=#{last_x_consul_index}#{wait_condition}"
29
29
 
30
30
  resp = Lusnoc.http_get(url, timeout: t.left)
@@ -34,7 +34,18 @@ module Lusnoc
34
34
 
35
35
  index = [Integer(resp['x-consul-index']), 1].max
36
36
  last_x_consul_index = (index < last_x_consul_index ? 1 : index)
37
- sleep 1
37
+ sleep 0.4
38
+ end
39
+ end
40
+
41
+ def build_wait_condition(_url, time_left, max_consul_wait)
42
+ if time_left
43
+ max = [t.left.to_i, max_consul_wait.to_i].max
44
+ "&wait=#{max}s"
45
+ elsif max_consul_wait
46
+ "&wait=#{max_consul_wait.to_i}s"
47
+ else
48
+ ''
38
49
  end
39
50
  end
40
51
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lusnoc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2.16550
4
+ version: 0.1.2.16562
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samoilenko Yuri
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-09-23 00:00:00.000000000 Z
11
+ date: 2019-09-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler