event_sourcery-postgres 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -1
- data/README.md +0 -1
- data/lib/event_sourcery/postgres/config.rb +19 -17
- data/lib/event_sourcery/postgres/event_store.rb +9 -9
- data/lib/event_sourcery/postgres/optimised_event_poll_waiter.rb +3 -3
- data/lib/event_sourcery/postgres/projector.rb +1 -2
- data/lib/event_sourcery/postgres/schema.rb +1 -1
- data/lib/event_sourcery/postgres/table_owner.rb +2 -2
- data/lib/event_sourcery/postgres/tracker.rb +11 -11
- data/lib/event_sourcery/postgres/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c2860efca21f5ae2a7a8ae316ea70db1fcb1aa1e
|
4
|
+
data.tar.gz: 56fe6bc5b9233ffc8795ba6b37cff8763bf1b166
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8b1ef120a33fa76da1698f68a063c07293d82ff1a8310682dbf7be812156216c18061ad7fb5706d412d03f60a67dc1dbd33d05637c12891018fb2cdd7cfbbd42
|
7
|
+
data.tar.gz: 9310dbd856abac2ffe24f9a6b78f1fc3b6baf23ecfdf087fa5e2349210c343a1f4533c876df9fb5e21107cd5e7bf5fd197fe8cc8fbe4a5eea56ce96aa67c7f37
|
data/CHANGELOG.md
CHANGED
@@ -4,8 +4,14 @@ All notable changes to this project will be documented in this file.
|
|
4
4
|
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
5
5
|
and this project adheres to [Semantic Versioning](http://semver.org/).
|
6
6
|
|
7
|
-
## [
|
7
|
+
## [0.6.0] - 2018-1-2
|
8
|
+
### Changed
|
9
|
+
|
10
|
+
- Only send info log after processing a group of events
|
8
11
|
|
12
|
+
### Removed
|
13
|
+
- Remove `processes_events` and `projects_events` as these have been [removed
|
14
|
+
in event_sourcery](https://github.com/envato/event_sourcery/pull/161).
|
9
15
|
|
10
16
|
## [0.5.0] - 2017-7-27
|
11
17
|
- First Version of YARD documentation.
|
data/README.md
CHANGED
@@ -22,7 +22,6 @@ gem 'event_sourcery-postgres'
|
|
22
22
|
EventSourcery::Postgres.configure do |config|
|
23
23
|
config.event_store_database = Sequel.connect(...)
|
24
24
|
config.projections_database = Sequel.connect(...)
|
25
|
-
config.use_optimistic_concurrency = true
|
26
25
|
config.write_events_function_name = 'writeEvents'
|
27
26
|
config.events_table_name = :events
|
28
27
|
config.aggregates_table_name = :aggregates
|
@@ -1,19 +1,21 @@
|
|
1
1
|
module EventSourcery
|
2
2
|
module Postgres
|
3
3
|
class Config
|
4
|
-
attr_accessor :
|
5
|
-
:lock_table_to_guarantee_linear_sequence_id_growth,
|
4
|
+
attr_accessor :lock_table_to_guarantee_linear_sequence_id_growth,
|
6
5
|
:write_events_function_name,
|
7
6
|
:events_table_name,
|
8
7
|
:aggregates_table_name,
|
9
8
|
:tracker_table_name,
|
10
9
|
:callback_interval_if_no_new_events,
|
11
10
|
:auto_create_projector_tracker,
|
12
|
-
:event_tracker
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
11
|
+
:event_tracker
|
12
|
+
|
13
|
+
attr_writer :event_store,
|
14
|
+
:event_source,
|
15
|
+
:event_sink
|
16
|
+
|
17
|
+
attr_reader :event_store_database,
|
18
|
+
:projections_database
|
17
19
|
|
18
20
|
def initialize
|
19
21
|
@lock_table_to_guarantee_linear_sequence_id_growth = true
|
@@ -38,25 +40,25 @@ module EventSourcery
|
|
38
40
|
@event_sink ||= ::EventSourcery::EventStore::EventSink.new(event_store)
|
39
41
|
end
|
40
42
|
|
41
|
-
def event_store_database=(
|
42
|
-
setup_connection(
|
43
|
+
def event_store_database=(db_connection)
|
44
|
+
setup_connection(db_connection)
|
43
45
|
|
44
|
-
@event_store_database =
|
46
|
+
@event_store_database = db_connection
|
45
47
|
end
|
46
48
|
|
47
|
-
def projections_database=(
|
48
|
-
setup_connection(
|
49
|
+
def projections_database=(db_connection)
|
50
|
+
setup_connection(db_connection)
|
49
51
|
|
50
|
-
@projections_database =
|
51
|
-
@event_tracker = Postgres::Tracker.new(
|
52
|
+
@projections_database = db_connection
|
53
|
+
@event_tracker = Postgres::Tracker.new(db_connection)
|
52
54
|
end
|
53
55
|
|
54
56
|
private
|
55
57
|
|
56
|
-
def setup_connection(
|
57
|
-
return unless
|
58
|
+
def setup_connection(db_connection)
|
59
|
+
return unless db_connection
|
58
60
|
|
59
|
-
|
61
|
+
db_connection.extension :pg_json
|
60
62
|
end
|
61
63
|
end
|
62
64
|
end
|
@@ -3,19 +3,19 @@ module EventSourcery
|
|
3
3
|
class EventStore
|
4
4
|
include EventSourcery::EventStore::EachByRange
|
5
5
|
|
6
|
-
def initialize(
|
6
|
+
def initialize(db_connection,
|
7
7
|
events_table_name: EventSourcery::Postgres.config.events_table_name,
|
8
8
|
lock_table: EventSourcery::Postgres.config.lock_table_to_guarantee_linear_sequence_id_growth,
|
9
9
|
write_events_function_name: EventSourcery::Postgres.config.write_events_function_name,
|
10
10
|
event_builder: EventSourcery.config.event_builder)
|
11
|
-
@
|
11
|
+
@db_connection = db_connection
|
12
12
|
@events_table_name = events_table_name
|
13
13
|
@write_events_function_name = write_events_function_name
|
14
14
|
@lock_table = lock_table
|
15
15
|
@event_builder = event_builder
|
16
16
|
end
|
17
17
|
|
18
|
-
# Like water flowing into a sink
|
18
|
+
# Like water flowing into a sink eventually it will go down the drain
|
19
19
|
# into the goodness of the plumbing system.
|
20
20
|
# So to will the given events you put in this 'sink'. Except the plumbing
|
21
21
|
# system is the data base events table.
|
@@ -31,7 +31,7 @@ module EventSourcery
|
|
31
31
|
aggregate_ids = events.map(&:aggregate_id).uniq
|
32
32
|
raise AtomicWriteToMultipleAggregatesNotSupported unless aggregate_ids.count == 1
|
33
33
|
sql = write_events_sql(aggregate_ids.first, events, expected_version)
|
34
|
-
@
|
34
|
+
@db_connection.run(sql)
|
35
35
|
log_events_saved(events)
|
36
36
|
true
|
37
37
|
rescue Sequel::DatabaseError => e
|
@@ -43,10 +43,10 @@ module EventSourcery
|
|
43
43
|
end
|
44
44
|
|
45
45
|
# Get the next set of events from the given event id. You can
|
46
|
-
# specify event
|
46
|
+
# specify event types and a limit.
|
47
47
|
# Default limit is 1000 and the default event types will be all.
|
48
48
|
#
|
49
|
-
# @param id the event id to get next
|
49
|
+
# @param id the event id to get next events from
|
50
50
|
# @param event_types the event types to filter, default nil = all
|
51
51
|
# @param limit the limit to the results, default 1000
|
52
52
|
#
|
@@ -94,7 +94,7 @@ module EventSourcery
|
|
94
94
|
# @param after_listen the after listen call back block. default nil.
|
95
95
|
# @param subscription_master the subscription master block
|
96
96
|
def subscribe(from_id:, event_types: nil, after_listen: nil, subscription_master:, &block)
|
97
|
-
poll_waiter = OptimisedEventPollWaiter.new(
|
97
|
+
poll_waiter = OptimisedEventPollWaiter.new(db_connection: @db_connection, after_listen: after_listen)
|
98
98
|
args = {
|
99
99
|
poll_waiter: poll_waiter,
|
100
100
|
event_store: self,
|
@@ -110,7 +110,7 @@ module EventSourcery
|
|
110
110
|
private
|
111
111
|
|
112
112
|
def events_table
|
113
|
-
@
|
113
|
+
@db_connection[@events_table_name]
|
114
114
|
end
|
115
115
|
|
116
116
|
def build_event(data)
|
@@ -159,7 +159,7 @@ module EventSourcery
|
|
159
159
|
else
|
160
160
|
value
|
161
161
|
end
|
162
|
-
@
|
162
|
+
@db_connection.literal(wrapped_value)
|
163
163
|
end
|
164
164
|
|
165
165
|
def log_events_saved(events)
|
@@ -4,8 +4,8 @@ module EventSourcery
|
|
4
4
|
class OptimisedEventPollWaiter
|
5
5
|
ListenThreadDied = Class.new(StandardError)
|
6
6
|
|
7
|
-
def initialize(
|
8
|
-
@
|
7
|
+
def initialize(db_connection:, timeout: 30, after_listen: proc {})
|
8
|
+
@db_connection = db_connection
|
9
9
|
@timeout = timeout
|
10
10
|
@events_queue = QueueWithIntervalCallback.new
|
11
11
|
@after_listen = after_listen
|
@@ -65,7 +65,7 @@ module EventSourcery
|
|
65
65
|
end
|
66
66
|
|
67
67
|
def listen_for_new_events(loop: true, after_listen: nil, timeout: 30)
|
68
|
-
@
|
68
|
+
@db_connection.listen('new_event',
|
69
69
|
loop: loop,
|
70
70
|
after_listen: after_listen,
|
71
71
|
timeout: timeout) do |_channel, _pid, _payload|
|
@@ -10,7 +10,6 @@ module EventSourcery
|
|
10
10
|
|
11
11
|
class << self
|
12
12
|
alias_method :project, :process
|
13
|
-
alias_method :projects_events, :processes_events
|
14
13
|
alias_method :projector_name, :processor_name
|
15
14
|
end
|
16
15
|
end
|
@@ -33,8 +32,8 @@ module EventSourcery
|
|
33
32
|
tracker.processed_event(processor_name, event.id)
|
34
33
|
end
|
35
34
|
EventSourcery.logger.debug { "[#{processor_name}] Processed event: #{event.inspect}" }
|
36
|
-
EventSourcery.logger.info { "[#{processor_name}] Processed up to event id: #{events.last.id}" }
|
37
35
|
end
|
36
|
+
EventSourcery.logger.info { "[#{processor_name}] Processed up to event id: #{events.last.id}" }
|
38
37
|
end
|
39
38
|
end
|
40
39
|
end
|
@@ -58,7 +58,7 @@ module EventSourcery
|
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
61
|
-
# Create the 'create or update'
|
61
|
+
# Create the 'create or update' functions.
|
62
62
|
# Needs the database, table name, function name and aggregates table name.
|
63
63
|
# The defaults will be whats specified in config.
|
64
64
|
#
|
@@ -9,14 +9,14 @@ module EventSourcery
|
|
9
9
|
end
|
10
10
|
|
11
11
|
module ClassMethods
|
12
|
-
# Hash of the tables and
|
12
|
+
# Hash of the tables and their corresponding blocks.
|
13
13
|
#
|
14
14
|
# @return [Hash] hash keyed by table names and block values
|
15
15
|
def tables
|
16
16
|
@tables ||= {}
|
17
17
|
end
|
18
18
|
|
19
|
-
# For the
|
19
|
+
# For the given table name assign to give block as the value.
|
20
20
|
#
|
21
21
|
# @param name the name of the table
|
22
22
|
# @param block the block of code to assign for the table
|
@@ -3,19 +3,19 @@ module EventSourcery
|
|
3
3
|
# This will set up a persisted event id tracker for processors.
|
4
4
|
class Tracker
|
5
5
|
|
6
|
-
def initialize(
|
6
|
+
def initialize(db_connection = EventSourcery::Postgres.config.projections_database,
|
7
7
|
table_name: EventSourcery::Postgres.config.tracker_table_name,
|
8
8
|
obtain_processor_lock: true)
|
9
|
-
@
|
9
|
+
@db_connection = db_connection
|
10
10
|
@table_name = table_name.to_sym
|
11
11
|
@obtain_processor_lock = obtain_processor_lock
|
12
12
|
end
|
13
13
|
|
14
14
|
# Set up the given processor.
|
15
|
-
# This will create the projector tracker table if it does not
|
15
|
+
# This will create the projector tracker table if it does not exist.
|
16
16
|
# If given a processor_name it will then attempt to get a lock on the db.
|
17
17
|
#
|
18
|
-
# @param processor_name the name of the
|
18
|
+
# @param processor_name the name of the processor
|
19
19
|
def setup(processor_name = nil)
|
20
20
|
create_table_if_not_exists if EventSourcery::Postgres.config.auto_create_projector_tracker
|
21
21
|
|
@@ -34,7 +34,7 @@ module EventSourcery
|
|
34
34
|
# This will updated the tracker table to the given event id value
|
35
35
|
# for the given processor name.
|
36
36
|
#
|
37
|
-
# @param processor_name the name of the processor to
|
37
|
+
# @param processor_name the name of the processor to update
|
38
38
|
# @param event_id the event id number to update to
|
39
39
|
def processed_event(processor_name, event_id)
|
40
40
|
table.
|
@@ -44,13 +44,13 @@ module EventSourcery
|
|
44
44
|
end
|
45
45
|
|
46
46
|
# This allows you to process an event and update the tracker table in
|
47
|
-
# a single transaction. Will
|
47
|
+
# a single transaction. Will yield the given block first then update the
|
48
48
|
# the tracker table to the give event id for the given processor name.
|
49
49
|
#
|
50
50
|
# @param processor_name the name of the processor to update
|
51
51
|
# @param event_id the event id number to update to
|
52
52
|
def processing_event(processor_name, event_id)
|
53
|
-
@
|
53
|
+
@db_connection.transaction do
|
54
54
|
yield
|
55
55
|
processed_event(processor_name, event_id)
|
56
56
|
end
|
@@ -82,7 +82,7 @@ module EventSourcery
|
|
82
82
|
private
|
83
83
|
|
84
84
|
def obtain_global_lock_on_processor(processor_name)
|
85
|
-
lock_obtained = @
|
85
|
+
lock_obtained = @db_connection.fetch("select pg_try_advisory_lock(#{@track_entry_id})").to_a.first[:pg_try_advisory_lock]
|
86
86
|
if lock_obtained == false
|
87
87
|
raise UnableToLockProcessorError, "Unable to get a lock on #{processor_name} #{@track_entry_id}"
|
88
88
|
end
|
@@ -91,7 +91,7 @@ module EventSourcery
|
|
91
91
|
def create_table_if_not_exists
|
92
92
|
unless tracker_table_exists?
|
93
93
|
EventSourcery.logger.info { "Projector tracker missing - attempting to create 'projector_tracker' table" }
|
94
|
-
EventSourcery::Postgres::Schema.create_projector_tracker(db: @
|
94
|
+
EventSourcery::Postgres::Schema.create_projector_tracker(db: @db_connection, table_name: @table_name)
|
95
95
|
end
|
96
96
|
end
|
97
97
|
|
@@ -105,11 +105,11 @@ module EventSourcery
|
|
105
105
|
end
|
106
106
|
|
107
107
|
def table
|
108
|
-
@
|
108
|
+
@db_connection[@table_name]
|
109
109
|
end
|
110
110
|
|
111
111
|
def tracker_table_exists?
|
112
|
-
@
|
112
|
+
@db_connection.table_exists?(@table_name)
|
113
113
|
end
|
114
114
|
end
|
115
115
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: event_sourcery-postgres
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Envato
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-01-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sequel
|