pg_eventstore 1.1.5 → 1.2.0

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: 5fce9f1f61310bfc9c12afdb89b0a6589e9116133255eeb62ac406b24e351b72
4
- data.tar.gz: 0a03a441f9e26a040f026fc7fac5d034c81b91d6f0e0bee98646b39a2f809147
3
+ metadata.gz: 7d3773773af377d169523f80ce08e439e019c33b94acd369f9927bf116d9bd4e
4
+ data.tar.gz: 3d131cf8aab4cc5f2996bc7f78c200d9b0c2455f2430863681056d569852d24e
5
5
  SHA512:
6
- metadata.gz: 26a0a9b9cf70e32fd73d5f729d5d9654ec23cd90aa57a3bfdf4cae5603f58d56d62a1406df477200390497141e5c4bb89f157c749bd1df680c1b404898428094
7
- data.tar.gz: 85aeeffcfc9ddfba2733e7362958a9d1528eb043ae5025c2d8bd055aa708e5c20eb2fef555be711174f3c058235c0f5b97c780b9f68b3a52e92592fe58d8f8c3
6
+ metadata.gz: 5b6af4853352632ce2b50306b200c5790e0f41e2063de53fe827985237665c48af5aa080072d8c1612888193f9a82050672888fc3bde0af31a77a35743a69e33
7
+ data.tar.gz: ee65c7f22d76c2b530783c1eeea8416962c5c969d50188f4a6c0a0d22746b1045ff5fc0b2d9a8ee3dcdeb6d8df6a4d46087ae09c7093fead0d3276bc11f45a98
data/CHANGELOG.md CHANGED
@@ -1,5 +1,31 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [1.2.0]
4
+ - Implement `failed_subscription_notifier` subscription hook.
5
+
6
+ Now you are able to define a function that is called when subscription fails and no longer can be automatically restarted because it hit max number of retries. You can define the hook globally in the config and per subscription. Examples:
7
+
8
+ ```ruby
9
+ PgEventstore.configure do |config|
10
+ config.failed_subscription_notifier = proc { |sub, error| puts "Subscription: #{sub.inspect}, error: #{error.inspect}" }
11
+ end
12
+
13
+ subscriptions_manager = PgEventstore.subscriptions_manager(subscription_set: 'MyApp')
14
+ # Overrides config.failed_subscription_notifier function
15
+ subscriptions_manager.subscribe(
16
+ 'My Subscription 1',
17
+ handler: Handler.new('My Subscription 1'),
18
+ options: { filter: { event_types: ['Foo'] } },
19
+ failed_subscription_notifier: proc { |_subscription, err| p err }
20
+ )
21
+ # Uses config.failed_subscription_notifier function
22
+ subscriptions_manager.subscribe(
23
+ 'My Subscription 2',
24
+ handler: Handler.new('My Subscription 2'),
25
+ options: { filter: { event_types: ['Bar'] } }
26
+ )
27
+ ```
28
+
3
29
  ## [1.1.5]
4
30
  - Review the way to handle SubscriptionAlreadyLockedError error. This removes noise when attempting to lock an already locked subscription.
5
31
 
@@ -16,6 +16,7 @@ Configuration options:
16
16
  | subscriptions_set_max_retries | Integer | `10` | Max number of retries for failed subscription sets. |
17
17
  | subscriptions_set_retries_interval | Integer | `1` | Interval in seconds between retries of failed subscription sets. |
18
18
  | subscription_restart_terminator | `#call` | `nil` | A callable object that accepts `PgEventstore::Subscription` object to determine whether restarts should be stopped(true - stops restarts, false - continues restarts). |
19
+ | failed_subscription_notifier | `#call` | `nil` | A callable object which is invoked with `PgEventstore::Subscription` instance and error instance after the related subscription died due to error and no longer can be automatically restarted due to max retries number reached. You can use this hook to send a notification about failed subscription. |
19
20
 
20
21
  ## Multiple configurations
21
22
 
@@ -151,7 +151,7 @@ You will then see the output of your subscription handlers. To gracefully stop t
151
151
 
152
152
  ## Overriding Subscription config values
153
153
 
154
- You can override `subscription_pull_interval`, `subscription_max_retries`, `subscription_retries_interval` and `subscription_restart_terminator` config values (see [**Configuration**](configuration.md) chapter for details) for the specific subscription by providing the corresponding arguments. Example:
154
+ You can override `subscription_pull_interval`, `subscription_max_retries`, `subscription_retries_interval`, `subscription_restart_terminator` and `failed_subscription_notifier` config values (see [**Configuration**](configuration.md) chapter for details) for the specific subscription by providing the corresponding arguments. Example:
155
155
 
156
156
  ```ruby
157
157
  subscriptions_manager.subscribe(
@@ -164,7 +164,9 @@ subscriptions_manager.subscribe(
164
164
  # overrides config.subscription_retries_interval
165
165
  retries_interval: 2,
166
166
  # overrides config.subscription_restart_terminator
167
- restart_terminator: proc { |subscription| subscription.last_error['class'] == 'NoMethodError' },
167
+ restart_terminator: proc { |subscription| subscription.last_error['class'] == 'NoMethodError' },
168
+ # overrides config.failed_subscription_notifier
169
+ failed_subscription_notifier: proc { |_subscription, err| p err }
168
170
  )
169
171
  ```
170
172
 
@@ -48,6 +48,10 @@ module PgEventstore
48
48
  # @!attribute subscriptions_set_retries_interval
49
49
  # @return [Integer] interval in seconds between retries of failed SubscriptionsSet
50
50
  option(:subscriptions_set_retries_interval) { 1 }
51
+ # @!attribute failed_subscription_notifier
52
+ # @return [#call, nil] provide callable object that accepts Subscription instance and error. It is useful when you
53
+ # want to be get notified when your Subscription fails and no longer can be restarted
54
+ option(:failed_subscription_notifier)
51
55
 
52
56
  # @param name [Symbol] config's name. Its value matches the appropriate key in PgEventstore.config hash
53
57
  def initialize(name:, **options)
@@ -29,11 +29,14 @@ module PgEventstore
29
29
  # @param events_processor [PgEventstore::EventsProcessor]
30
30
  # @param subscription [PgEventstore::Subscription]
31
31
  # @param restart_terminator [#call, nil]
32
- def initialize(stats:, events_processor:, subscription:, restart_terminator: nil)
32
+ # @param failed_subscription_notifier [#call, nil]
33
+ def initialize(stats:, events_processor:, subscription:, restart_terminator: nil,
34
+ failed_subscription_notifier: nil)
33
35
  @stats = stats
34
36
  @events_processor = events_processor
35
37
  @subscription = subscription
36
38
  @restart_terminator = restart_terminator
39
+ @failed_subscription_notifier = failed_subscription_notifier
37
40
 
38
41
  attach_callbacks
39
42
  end
@@ -119,11 +122,13 @@ module PgEventstore
119
122
  @subscription.update(last_chunk_fed_at: Time.now.utc, last_chunk_greatest_position: global_position)
120
123
  end
121
124
 
122
- # @param _error [StandardError]
125
+ # @param error [StandardError]
123
126
  # @return [void]
124
- def restart_subscription(_error)
127
+ def restart_subscription(error)
125
128
  return if @restart_terminator&.call(@subscription.dup)
126
- return if @subscription.restart_count >= @subscription.max_restarts_number
129
+ if @subscription.restart_count >= @subscription.max_restarts_number
130
+ return @failed_subscription_notifier&.call(@subscription.dup, error)
131
+ end
127
132
 
128
133
  Thread.new do
129
134
  sleep @subscription.time_between_restarts
@@ -61,14 +61,19 @@ module PgEventstore
61
61
  # given subscription.
62
62
  # @param max_retries [Integer] max number of retries of failed Subscription
63
63
  # @param retries_interval [Integer, Float] a delay between retries of failed Subscription
64
- # @param restart_terminator [#call, nil] a callable object which, when called - accepts PgEventstore::Subscription
65
- # object to determine whether restarts should be stopped(true - stops restarts, false - continues restarts)
64
+ # @param restart_terminator [#call, nil] a callable object which is invoked with PgEventstore::Subscription instance
65
+ # to determine whether restarts should be stopped(true - stops restarts, false - continues restarts)
66
+ # @param failed_subscription_notifier [#call, nil] a callable object which is invoked with
67
+ # PgEventstore::Subscription instance and error instance after the related subscription died due to error and no
68
+ # longer can be automatically restarted due to max retries number reached. You can use this hook to send a
69
+ # notification about failed subscription.
66
70
  # @return [void]
67
71
  def subscribe(subscription_name, handler:, options: {}, middlewares: nil,
68
72
  pull_interval: config.subscription_pull_interval,
69
73
  max_retries: config.subscription_max_retries,
70
74
  retries_interval: config.subscription_retries_interval,
71
- restart_terminator: config.subscription_restart_terminator)
75
+ restart_terminator: config.subscription_restart_terminator,
76
+ failed_subscription_notifier: config.failed_subscription_notifier)
72
77
  subscription = Subscription.using_connection(config.name).new(
73
78
  set: @set_name, name: subscription_name, options: options, chunk_query_interval: pull_interval,
74
79
  max_restarts_number: max_retries, time_between_restarts: retries_interval
@@ -77,7 +82,8 @@ module PgEventstore
77
82
  stats: SubscriptionHandlerPerformance.new,
78
83
  events_processor: EventsProcessor.new(create_event_handler(middlewares, handler)),
79
84
  subscription: subscription,
80
- restart_terminator: restart_terminator
85
+ restart_terminator: restart_terminator,
86
+ failed_subscription_notifier: failed_subscription_notifier
81
87
  )
82
88
 
83
89
  @subscription_feeder.add(runner)
@@ -2,5 +2,5 @@
2
2
 
3
3
  module PgEventstore
4
4
  # @return [String]
5
- VERSION = "1.1.5"
5
+ VERSION = "1.2.0"
6
6
  end
@@ -0,0 +1,3 @@
1
+ interface _FailedSubscriptionNotifier
2
+ def call: (PgEventstore::Subscription subscription, StandardError error) -> void
3
+ end
@@ -44,6 +44,8 @@ module PgEventstore
44
44
 
45
45
  attr_accessor subscription_restart_terminator: _RestartTerminator?
46
46
 
47
+ attr_accessor failed_subscription_notifier: _FailedSubscriptionNotifier?
48
+
47
49
  attr_accessor subscriptions_set_max_retries: Integer
48
50
 
49
51
  attr_accessor subscriptions_set_retries_interval: Integer
@@ -12,11 +12,14 @@ module PgEventstore
12
12
  # _@param_ `subscription`
13
13
  #
14
14
  # _@param_ `restart_terminator`
15
+ #
16
+ # _@param_ `failed_subscription_notifier`
15
17
  def initialize: (
16
18
  stats: PgEventstore::SubscriptionHandlerPerformance,
17
19
  events_processor: PgEventstore::EventsProcessor,
18
20
  subscription: PgEventstore::Subscription,
19
- ?restart_terminator: _RestartTerminator?
21
+ ?restart_terminator: _RestartTerminator?,
22
+ ?failed_subscription_notifier: _FailedSubscriptionNotifier?
20
23
  ) -> void
21
24
 
22
25
  def next_chunk_query_opts: () -> ::Hash[untyped, untyped]
@@ -47,7 +50,7 @@ module PgEventstore
47
50
  def update_subscription_chunk_stats: (Integer global_position) -> void
48
51
 
49
52
  # _@param_ `_error`
50
- def restart_subscription: (StandardError _error) -> void
53
+ def restart_subscription: (StandardError error) -> void
51
54
 
52
55
  # Returns the value of attribute subscription.
53
56
  attr_accessor subscription: PgEventstore::Subscription
@@ -30,7 +30,9 @@ module PgEventstore
30
30
  #
31
31
  # _@param_ `retries_interval` — a delay between retries of failed Subscription
32
32
  #
33
- # _@param_ `restart_terminator` — a callable object which, when called - accepts PgEventstore::Subscription object to determine whether restarts should be stopped(true - stops restarts, false - continues restarts)
33
+ # _@param_ `restart_terminator` — a callable object which is invoked with PgEventstore::Subscription instance to determine whether restarts should be stopped(true - stops restarts, false - continues restarts)
34
+ #
35
+ # _@param_ `failed_subscription_notifier` - a callable object which is invoked with PgEventstore::Subscription instance and error instance after the related subscription died due to error and no longer can be automatically restarted due to max retries number reached. You can use this hook to send a notification about failed subscription.
34
36
  def subscribe: (
35
37
  String subscription_name,
36
38
  handler: _SubscriptionHandler,
@@ -39,7 +41,8 @@ module PgEventstore
39
41
  ?pull_interval: Integer | Float,
40
42
  ?max_retries: Integer,
41
43
  ?retries_interval: Integer | Float,
42
- ?restart_terminator: _RestartTerminator?
44
+ ?restart_terminator: _RestartTerminator?,
45
+ ?failed_subscription_notifier: _FailedSubscriptionNotifier?
43
46
  ) -> void
44
47
 
45
48
  def subscriptions: () -> ::Array[PgEventstore::Subscription]
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pg_eventstore
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.5
4
+ version: 1.2.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: 2024-07-25 00:00:00.000000000 Z
11
+ date: 2024-07-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pg
@@ -195,6 +195,7 @@ files:
195
195
  - sig/interfaces/callback.rbs
196
196
  - sig/interfaces/event_class_resolver.rbs
197
197
  - sig/interfaces/event_modifier.rbs
198
+ - sig/interfaces/failed_subscription_notifier.rbs
198
199
  - sig/interfaces/restart_terminator.rbs
199
200
  - sig/interfaces/subscription_handler.rbs
200
201
  - sig/pg/basic_type_registry.rbs