event_store_subscriptions 1.0.0 → 1.1.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/lib/event_store_subscriptions/make_atomic.rb +23 -0
- data/lib/event_store_subscriptions/object_state.rb +2 -3
- data/lib/event_store_subscriptions/subscription.rb +33 -33
- data/lib/event_store_subscriptions/subscriptions.rb +11 -10
- data/lib/event_store_subscriptions/version.rb +1 -1
- data/lib/event_store_subscriptions/watch_dog.rb +1 -12
- data/lib/event_store_subscriptions.rb +1 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a7e6e16c2a7382f97ae35a90701acbcd6d1ddbb76f3de3d8d91fb4f5a5970301
|
4
|
+
data.tar.gz: 297942167731aa297bd5d1d036cba81fc8a5b2f050abc5a46c2918ffe43260c3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f5425d9761f330cd9cbabf2b19947709cb75cfecb7a604015fc6c1a8f768ebc97d9d35d87191e14706db7f9bfe2b79fce2a39608cca004116333f80ea7356d95
|
7
|
+
data.tar.gz: b3e1c417218056c29a85ef135a270296e2683258cc57b49bc19c7e12a7949b8aac2076fc9aa45fbd6c1bc69c4809a77b89b56c68bc91467a6d39a89c0f7228b3
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module EventStoreSubscriptions
|
4
|
+
module MakeAtomic
|
5
|
+
# Wraps method in Mutex#synchronize to make it atomic. You should have #semaphore method
|
6
|
+
# implemented in order this to work.
|
7
|
+
# @param method [Symbol] a name of the method
|
8
|
+
# @return [Symbol]
|
9
|
+
def make_atomic(method)
|
10
|
+
module_to_prepend = Module.new do
|
11
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
12
|
+
def #{method}(*args, **kwargs, &blk)
|
13
|
+
semaphore.synchronize do
|
14
|
+
super
|
15
|
+
end
|
16
|
+
end
|
17
|
+
RUBY
|
18
|
+
end
|
19
|
+
prepend module_to_prepend
|
20
|
+
method
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -10,7 +10,6 @@ module EventStoreSubscriptions
|
|
10
10
|
STATES = %i(initial running halting stopped dead).freeze
|
11
11
|
|
12
12
|
def initialize
|
13
|
-
@semaphore = Thread::Mutex.new
|
14
13
|
initial!
|
15
14
|
end
|
16
15
|
|
@@ -18,13 +17,13 @@ module EventStoreSubscriptions
|
|
18
17
|
# Checks whether the object is in appropriate state
|
19
18
|
# @return [Boolean]
|
20
19
|
define_method "#{state}?" do
|
21
|
-
|
20
|
+
self.state == state
|
22
21
|
end
|
23
22
|
|
24
23
|
# Sets the state.
|
25
24
|
# @return [Symbol]
|
26
25
|
define_method "#{state}!" do
|
27
|
-
|
26
|
+
self.state = state
|
28
27
|
end
|
29
28
|
end
|
30
29
|
|
@@ -3,11 +3,12 @@
|
|
3
3
|
module EventStoreSubscriptions
|
4
4
|
class Subscription
|
5
5
|
include WaitForFinish
|
6
|
+
extend MakeAtomic
|
6
7
|
|
7
8
|
FORCED_SHUTDOWN_DELAY = 60 # seconds
|
8
9
|
|
9
10
|
attr_accessor :runner
|
10
|
-
attr_reader :client, :setup, :state, :position, :statistic
|
11
|
+
attr_reader :client, :setup, :state, :position, :statistic, :semaphore
|
11
12
|
private :runner, :runner=
|
12
13
|
|
13
14
|
# @param position [EventStoreSubscriptions::SubscriptionPosition, EventStoreSubscriptions::SubscriptionRevision]
|
@@ -21,36 +22,19 @@ module EventStoreSubscriptions
|
|
21
22
|
@state = ObjectState.new
|
22
23
|
@statistic = statistic
|
23
24
|
@runner = nil
|
25
|
+
@semaphore = Mutex.new
|
24
26
|
end
|
25
27
|
|
26
28
|
# Start listening for the events
|
27
29
|
# @return [EventStoreSubscriptions::Subscription] returns self
|
28
|
-
def listen
|
29
|
-
|
30
|
-
begin
|
31
|
-
state.running!
|
32
|
-
Thread.new do
|
33
|
-
Thread.current.abort_on_exception = false
|
34
|
-
Thread.current.report_on_exception = false
|
35
|
-
client.subscribe_to_stream(
|
36
|
-
*setup.args,
|
37
|
-
**adjusted_kwargs,
|
38
|
-
&setup.blk
|
39
|
-
)
|
40
|
-
rescue StandardError => e
|
41
|
-
statistic.last_error = e
|
42
|
-
statistic.errors_count += 1
|
43
|
-
state.dead!
|
44
|
-
raise
|
45
|
-
end
|
46
|
-
end
|
47
|
-
self
|
30
|
+
make_atomic def listen
|
31
|
+
_listen
|
48
32
|
end
|
49
33
|
|
50
34
|
# Stops listening for events. This command is async - the result is not immediate. Use the #wait_for_finish
|
51
35
|
# method to wait until the runner has fully stopped.
|
52
36
|
# @return [EventStoreSubscriptions::Subscription] returns self
|
53
|
-
def stop_listening
|
37
|
+
make_atomic def stop_listening
|
54
38
|
return self unless runner&.alive?
|
55
39
|
|
56
40
|
state.halting!
|
@@ -71,22 +55,38 @@ module EventStoreSubscriptions
|
|
71
55
|
self
|
72
56
|
end
|
73
57
|
|
74
|
-
|
75
|
-
|
76
|
-
# @return [EventStoreSubscriptions::Subscription] frozen object
|
77
|
-
# @raise [EventStoreSubscriptions::ThreadNotDeadError] raises this error in case runner Thread
|
78
|
-
# is still alive for some reason. Normally this should never happen.
|
79
|
-
def delete
|
80
|
-
if runner&.alive?
|
81
|
-
raise ThreadNotDeadError, "Can not delete alive Subscription #{self.inspect}"
|
82
|
-
end
|
58
|
+
make_atomic def restart
|
59
|
+
return self if runner&.alive?
|
83
60
|
|
84
|
-
|
85
|
-
|
61
|
+
statistic.last_restart_at = Time.now.utc
|
62
|
+
_listen
|
86
63
|
end
|
87
64
|
|
88
65
|
private
|
89
66
|
|
67
|
+
# @return [EventStoreSubscriptions::Subscription] returns self
|
68
|
+
def _listen
|
69
|
+
self.runner ||=
|
70
|
+
begin
|
71
|
+
state.running!
|
72
|
+
Thread.new do
|
73
|
+
Thread.current.abort_on_exception = false
|
74
|
+
Thread.current.report_on_exception = false
|
75
|
+
client.subscribe_to_stream(
|
76
|
+
*setup.args,
|
77
|
+
**adjusted_kwargs,
|
78
|
+
&setup.blk
|
79
|
+
)
|
80
|
+
rescue StandardError => e
|
81
|
+
statistic.last_error = e
|
82
|
+
statistic.errors_count += 1
|
83
|
+
state.dead!
|
84
|
+
raise
|
85
|
+
end
|
86
|
+
end
|
87
|
+
self
|
88
|
+
end
|
89
|
+
|
90
90
|
# Wraps original handler into our own handler to provide extended functionality.
|
91
91
|
# @param original_handler [#call]
|
92
92
|
# @return [Proc]
|
@@ -3,6 +3,7 @@
|
|
3
3
|
module EventStoreSubscriptions
|
4
4
|
# Implements Subscription-s collection
|
5
5
|
class Subscriptions
|
6
|
+
extend MakeAtomic
|
6
7
|
ALL_STREAM = '$all'
|
7
8
|
|
8
9
|
attr_reader :client
|
@@ -37,34 +38,34 @@ module EventStoreSubscriptions
|
|
37
38
|
# Adds Subscription to the collection
|
38
39
|
# @param subscription [EventStoreSubscriptions::Subscription]
|
39
40
|
# @return [Array<EventStoreSubscriptions::Subscription>] current subscription's collection
|
40
|
-
def add(subscription)
|
41
|
-
|
41
|
+
make_atomic def add(subscription)
|
42
|
+
@subscriptions << subscription
|
42
43
|
end
|
43
44
|
|
44
45
|
# Removes subscription from the collection
|
45
46
|
# @param subscription [EventStoreSubscriptions::Subscription]
|
46
47
|
# @return [EventStoreSubscriptions::Subscription, nil] returns deleted subscription or nil if it
|
47
48
|
# wasn't present in the collection
|
48
|
-
def remove(subscription)
|
49
|
-
|
49
|
+
make_atomic def remove(subscription)
|
50
|
+
@subscriptions.delete(subscription)
|
50
51
|
end
|
51
52
|
|
52
53
|
# Starts listening to all subscriptions in the collection
|
53
54
|
# @return [Array<EventStoreSubscriptions::Subscription>]
|
54
|
-
def listen_all
|
55
|
-
|
55
|
+
make_atomic def listen_all
|
56
|
+
@subscriptions.each(&:listen)
|
56
57
|
end
|
57
58
|
|
58
59
|
# Stops listening to all subscriptions in the collection
|
59
60
|
# @return [Array<EventStoreSubscriptions::Subscription>]
|
60
|
-
def stop_all
|
61
|
-
|
61
|
+
make_atomic def stop_all
|
62
|
+
@subscriptions.each(&:stop_listening)
|
62
63
|
end
|
63
64
|
|
64
65
|
# @return [Array<EventStoreSubscriptions::Subscription>]
|
65
|
-
def subscriptions
|
66
|
+
make_atomic def subscriptions
|
66
67
|
# Duping original collection to prevent potential mutable operations over it from user's side
|
67
|
-
|
68
|
+
@subscriptions.dup
|
68
69
|
end
|
69
70
|
|
70
71
|
private
|
@@ -92,19 +92,8 @@ module EventStoreSubscriptions
|
|
92
92
|
# @return [EventStoreSubscriptions::Subscription] newly created Subscription
|
93
93
|
def restart_subscription(failed_sub)
|
94
94
|
return if restart_terminator&.call(failed_sub)
|
95
|
-
# Check if no one else did this job
|
96
|
-
return unless collection.remove(failed_sub)
|
97
95
|
|
98
|
-
|
99
|
-
position: failed_sub.position,
|
100
|
-
client: failed_sub.client,
|
101
|
-
setup: failed_sub.setup,
|
102
|
-
statistic: failed_sub.statistic
|
103
|
-
)
|
104
|
-
new_sub.statistic.last_restart_at = Time.now.utc
|
105
|
-
collection.add(new_sub)
|
106
|
-
failed_sub.delete
|
107
|
-
new_sub.listen
|
96
|
+
failed_sub.restart
|
108
97
|
end
|
109
98
|
end
|
110
99
|
end
|
@@ -4,6 +4,7 @@ require 'event_store_client'
|
|
4
4
|
require_relative 'event_store_subscriptions/version'
|
5
5
|
require_relative 'event_store_subscriptions/error'
|
6
6
|
require_relative 'event_store_subscriptions/wait_for_finish'
|
7
|
+
require_relative 'event_store_subscriptions/make_atomic'
|
7
8
|
require_relative 'event_store_subscriptions/object_state'
|
8
9
|
require_relative 'event_store_subscriptions/subscription_statistic'
|
9
10
|
require_relative 'event_store_subscriptions/subscription'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: event_store_subscriptions
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ivan Dzyzenko
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-10-
|
11
|
+
date: 2022-10-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: event_store_client
|
@@ -77,6 +77,7 @@ files:
|
|
77
77
|
- README.md
|
78
78
|
- lib/event_store_subscriptions.rb
|
79
79
|
- lib/event_store_subscriptions/error.rb
|
80
|
+
- lib/event_store_subscriptions/make_atomic.rb
|
80
81
|
- lib/event_store_subscriptions/object_state.rb
|
81
82
|
- lib/event_store_subscriptions/subscription.rb
|
82
83
|
- lib/event_store_subscriptions/subscription_position.rb
|