pg_eventstore 0.10.1 → 0.10.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/docs/configuration.md +1 -1
- data/lib/pg_eventstore/event.rb +5 -1
- data/lib/pg_eventstore/event_deserializer.rb +1 -0
- data/lib/pg_eventstore/queries/event_queries.rb +6 -0
- data/lib/pg_eventstore/queries/links_resolver.rb +31 -0
- data/lib/pg_eventstore/queries/subscription_queries.rb +12 -7
- data/lib/pg_eventstore/queries.rb +1 -0
- data/lib/pg_eventstore/query_builders/events_filtering_query.rb +0 -13
- data/lib/pg_eventstore/subscriptions/events_processor.rb +10 -2
- data/lib/pg_eventstore/subscriptions/subscription.rb +1 -0
- data/lib/pg_eventstore/subscriptions/subscription_feeder.rb +1 -1
- data/lib/pg_eventstore/subscriptions/subscription_runners_feeder.rb +2 -3
- data/lib/pg_eventstore/version.rb +1 -1
- 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: ccfbe47f6f178820e5f7b5ccc9fb9298bf6beba4fa10081cd01bcd6ce3fe1001
|
4
|
+
data.tar.gz: b55180dc1c24ec04d13e99b0d4ba920eae5eef652ccde632f332ab67b27cc14e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4226be0aa1f6109b5a956febca5343b1a1d215c6a16e056267027287bcb629295cd4af1a7f6fc093e781c90a48f885f2b5932faff7962bdd993305519bfca053
|
7
|
+
data.tar.gz: 2eb04ad6b29569f29282768e806813823e990493674c627252963d312966aa1806f06139b4b01937699c0fcf4b25034c2e02cb7375710d65838d62bb3934099d
|
data/CHANGELOG.md
CHANGED
data/docs/configuration.md
CHANGED
@@ -10,7 +10,7 @@ Configuration options:
|
|
10
10
|
| event_class_resolver | `#call` | `PgEventstore::EventClassResolver.new` | A `#call`-able object that accepts a string and returns an event's class. See **Resolving events classes** chapter bellow for more info. |
|
11
11
|
| connection_pool_size | Integer | `5` | Max number of connections per ruby process. It must equal the number of threads of your application. When using subscriptions it is recommended to set it to the number of subscriptions divided by two or greater. See [**Picking max connections number**](#picking-max-connections-number) chapter of this section. |
|
12
12
|
| connection_pool_timeout | Integer | `5` | Time in seconds to wait for a connection in the pool to be released. If no connections are available during this time - `ConnectionPool::TimeoutError` will be raised. See `connection_pool` gem [docs](https://github.com/mperham/connection_pool#usage) for more info. |
|
13
|
-
| subscription_pull_interval | Float | `1.0` | How often to pull new subscription events in seconds.
|
13
|
+
| subscription_pull_interval | Float | `1.0` | How often to pull new subscription events in seconds. The minimum meaningful value is `0.2`. Values less than `0.2` will act as it is `0.2`. |
|
14
14
|
| subscription_max_retries | Integer | `5` | Max number of retries of failed subscription. |
|
15
15
|
| subscription_retries_interval | Integer | `1` | Interval in seconds between retries of failed subscriptions. |
|
16
16
|
| subscriptions_set_max_retries | Integer | `10` | Max number of retries for failed subscription sets. |
|
data/lib/pg_eventstore/event.rb
CHANGED
@@ -31,6 +31,10 @@ module PgEventstore
|
|
31
31
|
# @return [String, nil] UUIDv4 of an event the current event points to. If it is not nil, then the current
|
32
32
|
# event is a link
|
33
33
|
attribute(:link_id)
|
34
|
+
# @!attribute link
|
35
|
+
# @return [PgEventstore::Event, nil] when resolve_link_tos: true option is provided during the read of events and
|
36
|
+
# event is a link event - this attribute will be pointing on that link
|
37
|
+
attribute(:link)
|
34
38
|
# @!attribute created_at
|
35
39
|
# @return [Time, nil] a timestamp an event was created at
|
36
40
|
attribute(:created_at)
|
@@ -41,7 +45,7 @@ module PgEventstore
|
|
41
45
|
def ==(other)
|
42
46
|
return false unless other.is_a?(PgEventstore::Event)
|
43
47
|
|
44
|
-
attributes_hash == other.attributes_hash
|
48
|
+
attributes_hash.except(:link) == other.attributes_hash.except(:link)
|
45
49
|
end
|
46
50
|
|
47
51
|
# Detect whether an event is a link event
|
@@ -47,6 +47,7 @@ module PgEventstore
|
|
47
47
|
raw_events = connection.with do |conn|
|
48
48
|
conn.exec_params(*exec_params)
|
49
49
|
end.to_a
|
50
|
+
raw_events = links_resolver.resolve(raw_events) if options[:resolve_link_tos]
|
50
51
|
deserializer.deserialize_many(raw_events)
|
51
52
|
end
|
52
53
|
|
@@ -106,5 +107,10 @@ module PgEventstore
|
|
106
107
|
|
107
108
|
QueryBuilders::EventsFiltering.specific_stream_filtering(stream, options)
|
108
109
|
end
|
110
|
+
|
111
|
+
# @return [PgEventstore::LinksResolver]
|
112
|
+
def links_resolver
|
113
|
+
LinksResolver.new(connection)
|
114
|
+
end
|
109
115
|
end
|
110
116
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PgEventstore
|
4
|
+
# @!visibility private
|
5
|
+
class LinksResolver
|
6
|
+
attr_reader :connection
|
7
|
+
private :connection
|
8
|
+
|
9
|
+
# @param connection [PgEventstore::Connection]
|
10
|
+
def initialize(connection)
|
11
|
+
@connection = connection
|
12
|
+
end
|
13
|
+
|
14
|
+
# @param raw_events [Array<Hash>]
|
15
|
+
def resolve(raw_events)
|
16
|
+
ids = raw_events.map { _1['link_id'] }.compact.uniq
|
17
|
+
return raw_events if ids.empty?
|
18
|
+
|
19
|
+
original_events = connection.with do |conn|
|
20
|
+
conn.exec_params('select * from events where id = ANY($1::uuid[])', [ids])
|
21
|
+
end.to_h { |attrs| [attrs['id'], attrs] }
|
22
|
+
|
23
|
+
raw_events.map do |attrs|
|
24
|
+
original_event = original_events[attrs['link_id']]
|
25
|
+
next attrs unless original_event
|
26
|
+
|
27
|
+
original_event.merge('link' => attrs).merge(attrs.except(*original_event.keys))
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -73,15 +73,20 @@ module PgEventstore
|
|
73
73
|
deserialize(pg_result.to_a.first)
|
74
74
|
end
|
75
75
|
|
76
|
-
# @param query_options [
|
77
|
-
# @return [
|
76
|
+
# @param query_options [Hash{Integer => Hash}] runner_id/query options association
|
77
|
+
# @return [Hash{Integer => Hash}] runner_id/events association
|
78
78
|
def subscriptions_events(query_options)
|
79
|
-
return
|
79
|
+
return {} if query_options.empty?
|
80
80
|
|
81
81
|
final_builder = union_builders(query_options.map { |id, opts| query_builder(id, opts) })
|
82
|
-
connection.with do |conn|
|
82
|
+
raw_events = connection.with do |conn|
|
83
83
|
conn.exec_params(*final_builder.to_exec_params)
|
84
84
|
end.to_a
|
85
|
+
raw_events.group_by { _1['runner_id'] }.to_h do |runner_id, runner_raw_events|
|
86
|
+
next [runner_id, runner_raw_events] unless query_options[runner_id][:resolve_link_tos]
|
87
|
+
|
88
|
+
[runner_id, links_resolver.resolve(runner_raw_events)]
|
89
|
+
end
|
85
90
|
end
|
86
91
|
|
87
92
|
# @param id [Integer] subscription's id
|
@@ -144,9 +149,9 @@ module PgEventstore
|
|
144
149
|
TransactionQueries.new(connection)
|
145
150
|
end
|
146
151
|
|
147
|
-
# @return [PgEventstore::
|
148
|
-
def
|
149
|
-
|
152
|
+
# @return [PgEventstore::LinksResolver]
|
153
|
+
def links_resolver
|
154
|
+
LinksResolver.new(connection)
|
150
155
|
end
|
151
156
|
|
152
157
|
# @param hash [Hash]
|
@@ -9,6 +9,7 @@ require_relative 'queries/subscription_queries'
|
|
9
9
|
require_relative 'queries/subscriptions_set_queries'
|
10
10
|
require_relative 'queries/subscription_command_queries'
|
11
11
|
require_relative 'queries/subscriptions_set_command_queries'
|
12
|
+
require_relative 'queries/links_resolver'
|
12
13
|
|
13
14
|
module PgEventstore
|
14
15
|
# @!visibility private
|
@@ -31,7 +31,6 @@ module PgEventstore
|
|
31
31
|
options in { filter: { event_types: Array => event_type_ids } }
|
32
32
|
event_filter.add_event_types(event_type_ids)
|
33
33
|
event_filter.add_limit(options[:max_count])
|
34
|
-
event_filter.resolve_links(options[:resolve_link_tos])
|
35
34
|
options in { filter: { streams: Array => streams } }
|
36
35
|
streams&.each { |attrs| event_filter.add_stream_attrs(**attrs) }
|
37
36
|
event_filter.add_global_position(options[:from_position], options[:direction])
|
@@ -47,7 +46,6 @@ module PgEventstore
|
|
47
46
|
options in { filter: { event_types: Array => event_type_ids } }
|
48
47
|
event_filter.add_event_types(event_type_ids)
|
49
48
|
event_filter.add_limit(options[:max_count])
|
50
|
-
event_filter.resolve_links(options[:resolve_link_tos])
|
51
49
|
event_filter.add_stream_attrs(**stream.to_hash)
|
52
50
|
event_filter.add_revision(options[:from_revision], options[:direction])
|
53
51
|
event_filter.add_stream_direction(options[:direction])
|
@@ -128,17 +126,6 @@ module PgEventstore
|
|
128
126
|
@sql_builder.limit(limit)
|
129
127
|
end
|
130
128
|
|
131
|
-
# @param should_resolve [Boolean]
|
132
|
-
# @return [void]
|
133
|
-
def resolve_links(should_resolve)
|
134
|
-
return unless should_resolve
|
135
|
-
|
136
|
-
@sql_builder.
|
137
|
-
unselect.
|
138
|
-
select("(COALESCE(original_events.*, events.*)).*").
|
139
|
-
join("LEFT JOIN events original_events ON original_events.id = events.link_id")
|
140
|
-
end
|
141
|
-
|
142
129
|
# @return [PgEventstore::SQLBuilder]
|
143
130
|
def to_sql_builder
|
144
131
|
@sql_builder
|
@@ -20,7 +20,7 @@ module PgEventstore
|
|
20
20
|
# @param raw_events [Array<Hash>]
|
21
21
|
# @return [void]
|
22
22
|
def feed(raw_events)
|
23
|
-
callbacks.run_callbacks(:feed, raw_events.last
|
23
|
+
callbacks.run_callbacks(:feed, global_position(raw_events.last))
|
24
24
|
@raw_events.push(*raw_events)
|
25
25
|
end
|
26
26
|
|
@@ -35,7 +35,7 @@ module PgEventstore
|
|
35
35
|
# @param raw_event [Hash]
|
36
36
|
# @return [void]
|
37
37
|
def process_event(raw_event)
|
38
|
-
callbacks.run_callbacks(:process, raw_event
|
38
|
+
callbacks.run_callbacks(:process, global_position(raw_event)) do
|
39
39
|
@handler.call(raw_event)
|
40
40
|
end
|
41
41
|
end
|
@@ -68,5 +68,13 @@ module PgEventstore
|
|
68
68
|
def change_state(...)
|
69
69
|
callbacks.run_callbacks(:change_state, ...)
|
70
70
|
end
|
71
|
+
|
72
|
+
# @param raw_event [Hash, nil]
|
73
|
+
# @return [Integer, nil]
|
74
|
+
def global_position(raw_event)
|
75
|
+
return unless raw_event
|
76
|
+
|
77
|
+
raw_event['link'] ? raw_event['link']['global_position'] : raw_event['global_position']
|
78
|
+
end
|
71
79
|
end
|
72
80
|
end
|
@@ -21,7 +21,7 @@ module PgEventstore
|
|
21
21
|
@max_retries = max_retries
|
22
22
|
@retries_interval = retries_interval
|
23
23
|
@commands_handler = CommandsHandler.new(@config_name, self, @runners)
|
24
|
-
@basic_runner = BasicRunner.new(
|
24
|
+
@basic_runner = BasicRunner.new(0.2, 0)
|
25
25
|
@force_lock = false
|
26
26
|
attach_runner_callbacks
|
27
27
|
end
|
@@ -15,9 +15,8 @@ module PgEventstore
|
|
15
15
|
runners = runners.select(&:running?).select(&:time_to_feed?)
|
16
16
|
return if runners.empty?
|
17
17
|
|
18
|
-
runners_query_options = runners.
|
19
|
-
|
20
|
-
grouped_events = raw_events.group_by { |attrs| attrs['runner_id'] }
|
18
|
+
runners_query_options = runners.to_h { |runner| [runner.id, runner.next_chunk_query_opts] }
|
19
|
+
grouped_events = subscription_queries.subscriptions_events(runners_query_options)
|
21
20
|
runners.each do |runner|
|
22
21
|
runner.feed(grouped_events[runner.id]) if grouped_events[runner.id]
|
23
22
|
end
|
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: 0.10.
|
4
|
+
version: 0.10.2
|
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-03-
|
11
|
+
date: 2024-03-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pg
|
@@ -91,6 +91,7 @@ files:
|
|
91
91
|
- lib/pg_eventstore/pg_connection.rb
|
92
92
|
- lib/pg_eventstore/queries.rb
|
93
93
|
- lib/pg_eventstore/queries/event_queries.rb
|
94
|
+
- lib/pg_eventstore/queries/links_resolver.rb
|
94
95
|
- lib/pg_eventstore/queries/partition_queries.rb
|
95
96
|
- lib/pg_eventstore/queries/subscription_command_queries.rb
|
96
97
|
- lib/pg_eventstore/queries/subscription_queries.rb
|