pg_eventstore 2.0.0 → 3.0.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/.rubocop.yml +10 -1
- data/CHANGELOG.md +186 -20
- data/README.md +25 -15
- data/db/migrations/10_setup_pg_cron.rb +1 -23
- data/db/migrations/15_create_streams_global_index.sql +17 -0
- data/db/migrations/16_populate_streams_global_index.rb +150 -0
- data/db/migrations/17_create_events_global_index.sql +62 -0
- data/db/migrations/18_populate_events_global_index.rb +124 -0
- data/db/migrations/19_populate_events_global_index_p2.rb +25 -0
- data/db/migrations/20_migrate_subscriptions_current_position.sql +19 -0
- data/db/migrations/21_create_partitions_stats.sql +2 -0
- data/db/migrations/22_drop_streams_sql_view.sql +2 -0
- data/db/migrations/23_adjust_partitions_indexes.sql +5 -0
- data/db/migrations/24_drop_legacy_events_indexes.sql +3 -0
- data/db/migrations/25_add_parent_partitions_info_to_partitions.sql +16 -0
- data/db/migrations/26_change_events_stream_revision_type.rb +35 -0
- data/db/migrations/27_drop_events_horizon.sql +3 -0
- data/db/migrations/28_create_maintenance_tasks.sql +8 -0
- data/db/migrations/29_create_event_markers.sql +35 -0
- data/db/migrations/30_improve_partitions_search_in_admin_ui.rb +24 -0
- data/db/migrations/31_drop_events_id_default_value.sql +1 -0
- data/db/migrations/32_create_parittions_triggers.sql +101 -0
- data/docs/AGENTS.fragment.md +696 -0
- data/docs/admin_ui.md +3 -1
- data/docs/appending_events.md +110 -49
- data/docs/configuration.md +69 -36
- data/docs/event_tracing.md +55 -0
- data/docs/events_and_streams.md +54 -30
- data/docs/how_it_works.md +57 -16
- data/docs/linking_events.md +2 -1
- data/docs/maintenance.md +14 -5
- data/docs/multiple_commands.md +17 -8
- data/docs/reading_events.md +208 -43
- data/docs/reading_streams.md +50 -0
- data/docs/replication.md +99 -0
- data/docs/subscriptions.md +165 -35
- data/docs/writing_middleware.md +25 -8
- data/ext/pg_eventstore_ext/extconf.rb +5 -0
- data/ext/pg_eventstore_ext/pg_eventstore_ext.c +74 -0
- data/lib/pg_eventstore/async_runner.rb +63 -0
- data/lib/pg_eventstore/basic_config.rb +15 -0
- data/lib/pg_eventstore/chunks/chunk.rb +31 -0
- data/lib/pg_eventstore/chunks/read_api_events_index_chunk.rb +83 -0
- data/lib/pg_eventstore/chunks/replica_events_index_chunk.rb +35 -0
- data/lib/pg_eventstore/chunks/repository.rb +73 -0
- data/lib/pg_eventstore/chunks/subscription_checkpoint_chunk.rb +48 -0
- data/lib/pg_eventstore/chunks/subscription_events_index_chunk.rb +99 -0
- data/lib/pg_eventstore/chunks.rb +14 -0
- data/lib/pg_eventstore/client.rb +163 -50
- data/lib/pg_eventstore/commands/append.rb +62 -43
- data/lib/pg_eventstore/commands/delete_event.rb +7 -8
- data/lib/pg_eventstore/commands/delete_stream.rb +3 -3
- data/lib/pg_eventstore/commands/event_modifiers/prepare_link_event.rb +9 -7
- data/lib/pg_eventstore/commands/event_modifiers/prepare_regular_event.rb +12 -7
- data/lib/pg_eventstore/commands/link_to.rb +5 -5
- data/lib/pg_eventstore/commands/read.rb +23 -5
- data/lib/pg_eventstore/commands/read_grouped.rb +46 -0
- data/lib/pg_eventstore/commands/read_streams.rb +18 -0
- data/lib/pg_eventstore/commands/read_streams_paginated.rb +56 -0
- data/lib/pg_eventstore/commands/regular_stream_read_paginated.rb +4 -4
- data/lib/pg_eventstore/commands/revision_check/current_revision.rb +51 -0
- data/lib/pg_eventstore/commands/revision_check/event_type_revisions_comparison.rb +46 -0
- data/lib/pg_eventstore/commands/revision_check/expected_revision.rb +135 -0
- data/lib/pg_eventstore/commands/revision_check/stream_revision_check.rb +98 -0
- data/lib/pg_eventstore/commands/revision_check/stream_revision_comparison.rb +36 -0
- data/lib/pg_eventstore/commands/stream_revision.rb +14 -0
- data/lib/pg_eventstore/commands/system_stream_read_paginated.rb +4 -4
- data/lib/pg_eventstore/commands.rb +4 -2
- data/lib/pg_eventstore/config.rb +30 -9
- data/lib/pg_eventstore/connection.rb +21 -2
- data/lib/pg_eventstore/errors.rb +136 -10
- data/lib/pg_eventstore/event.rb +34 -2
- data/lib/pg_eventstore/event_deserializer.rb +5 -4
- data/lib/pg_eventstore/event_global_index.rb +118 -0
- data/lib/pg_eventstore/event_marker.rb +16 -0
- data/lib/pg_eventstore/event_marker_index.rb +25 -0
- data/lib/pg_eventstore/event_serializer.rb +6 -0
- data/lib/pg_eventstore/extensions/acts_as_configurable.rb +88 -0
- data/lib/pg_eventstore/extensions/options_defaults.rb +25 -0
- data/lib/pg_eventstore/extensions/options_extension.rb +2 -2
- data/lib/pg_eventstore/feature_marker.rb +18 -0
- data/lib/pg_eventstore/maintenance.rb +11 -6
- data/lib/pg_eventstore/middleware/event_tracing.rb +53 -0
- data/lib/pg_eventstore/partition.rb +6 -0
- data/lib/pg_eventstore/pg_connection.rb +70 -14
- data/lib/pg_eventstore/queries/event_marker_queries.rb +74 -0
- data/lib/pg_eventstore/queries/event_queries.rb +7 -93
- data/lib/pg_eventstore/queries/events_global_index_queries.rb +131 -0
- data/lib/pg_eventstore/queries/index_filtering_queries.rb +179 -0
- data/lib/pg_eventstore/queries/links_resolver.rb +4 -4
- data/lib/pg_eventstore/queries/maintenance_queries.rb +159 -42
- data/lib/pg_eventstore/queries/partition_queries.rb +45 -103
- data/lib/pg_eventstore/queries/replica_queries.rb +110 -0
- data/lib/pg_eventstore/queries/streams_global_index_queries.rb +163 -0
- data/lib/pg_eventstore/queries/transaction_queries.rb +52 -10
- data/lib/pg_eventstore/queries.rb +29 -1
- data/lib/pg_eventstore/query_builders/basic_filtering.rb +38 -5
- data/lib/pg_eventstore/query_builders/event_markers_filtering.rb +47 -0
- data/lib/pg_eventstore/query_builders/event_markers_index_filtering.rb +275 -0
- data/lib/pg_eventstore/query_builders/event_subscription_positions_filtering.rb +37 -0
- data/lib/pg_eventstore/query_builders/events_filtering.rb +15 -164
- data/lib/pg_eventstore/query_builders/events_global_index_filtering.rb +227 -0
- data/lib/pg_eventstore/query_builders/filters/collection.rb +324 -0
- data/lib/pg_eventstore/query_builders/filters/event_type_filter.rb +37 -0
- data/lib/pg_eventstore/query_builders/filters/filter_row.rb +54 -0
- data/lib/pg_eventstore/query_builders/filters/marker_filter.rb +20 -0
- data/lib/pg_eventstore/query_builders/filters/marker_filter_row.rb +49 -0
- data/lib/pg_eventstore/query_builders/filters/stream_filter.rb +48 -0
- data/lib/pg_eventstore/query_builders/index_based_events_filtering.rb +260 -0
- data/lib/pg_eventstore/query_builders/partitions_filtering.rb +175 -51
- data/lib/pg_eventstore/query_builders/read_cursor/stream_cursor.rb +122 -0
- data/lib/pg_eventstore/query_builders/streams_global_index_filtering.rb +83 -0
- data/lib/pg_eventstore/query_builders/subscription_events_filtering.rb +79 -0
- data/lib/pg_eventstore/query_strategy/async.rb +64 -0
- data/lib/pg_eventstore/query_strategy/foreground.rb +25 -0
- data/lib/pg_eventstore/query_strategy.rb +19 -0
- data/lib/pg_eventstore/raw_event.rb +46 -0
- data/lib/pg_eventstore/rspec/test_helpers.rb +21 -8
- data/lib/pg_eventstore/sql_builder.rb +87 -8
- data/lib/pg_eventstore/stream.rb +13 -16
- data/lib/pg_eventstore/stream_global_index.rb +28 -0
- data/lib/pg_eventstore/subscriptions/callback_handlers/events_processor_handlers.rb +5 -17
- data/lib/pg_eventstore/subscriptions/callback_handlers/events_subscription_position_worker_handlers.rb +36 -0
- data/lib/pg_eventstore/subscriptions/callback_handlers/subscription_feeder_handlers.rb +12 -0
- data/lib/pg_eventstore/subscriptions/callback_handlers/subscription_runner_handlers.rb +21 -7
- data/lib/pg_eventstore/subscriptions/events_processor.rb +20 -18
- data/lib/pg_eventstore/subscriptions/events_processor_consumer/multiple.rb +63 -0
- data/lib/pg_eventstore/subscriptions/events_processor_consumer/replica.rb +68 -0
- data/lib/pg_eventstore/subscriptions/events_processor_consumer/single.rb +62 -0
- data/lib/pg_eventstore/subscriptions/events_processor_consumer.rb +44 -0
- data/lib/pg_eventstore/subscriptions/events_subscription_position_worker.rb +68 -0
- data/lib/pg_eventstore/subscriptions/queries/event_subscription_position_queries.rb +177 -0
- data/lib/pg_eventstore/subscriptions/queries/subscription_queries.rb +78 -54
- data/lib/pg_eventstore/subscriptions/replica_subscription_handler.rb +140 -0
- data/lib/pg_eventstore/subscriptions/replica_subscription_runner.rb +9 -0
- data/lib/pg_eventstore/subscriptions/subscription.rb +2 -1
- data/lib/pg_eventstore/subscriptions/subscription_feed_strategies/collection.rb +36 -0
- data/lib/pg_eventstore/subscriptions/subscription_feed_strategies/index_read_strategy.rb +82 -0
- data/lib/pg_eventstore/subscriptions/subscription_feed_strategies/replication_strategy.rb +75 -0
- data/lib/pg_eventstore/subscriptions/subscription_feed_strategy.rb +31 -0
- data/lib/pg_eventstore/subscriptions/subscription_feeder.rb +24 -0
- data/lib/pg_eventstore/subscriptions/subscription_handler_performance.rb +4 -2
- data/lib/pg_eventstore/subscriptions/subscription_runner.rb +20 -9
- data/lib/pg_eventstore/subscriptions/subscription_runner_commands/reset_position.rb +1 -1
- data/lib/pg_eventstore/subscriptions/subscription_runners_feeder.rb +9 -18
- data/lib/pg_eventstore/subscriptions/subscriptions_lifecycle.rb +0 -12
- data/lib/pg_eventstore/subscriptions/subscriptions_manager.rb +74 -14
- data/lib/pg_eventstore/{subscriptions/synchronized_array.rb → synchronized_array.rb} +15 -0
- data/lib/pg_eventstore/tasks/setup.rake +2 -2
- data/lib/pg_eventstore/utils.rb +31 -0
- data/lib/pg_eventstore/version.rb +1 -1
- data/lib/pg_eventstore/web/application.rb +100 -16
- data/lib/pg_eventstore/web/paginator/base_collection.rb +5 -1
- data/lib/pg_eventstore/web/paginator/event_types_collection.rb +14 -4
- data/lib/pg_eventstore/web/paginator/events_collection.rb +29 -33
- data/lib/pg_eventstore/web/paginator/helpers.rb +16 -9
- data/lib/pg_eventstore/web/paginator/markers_collection.rb +48 -0
- data/lib/pg_eventstore/web/paginator/stream_contexts_collection.rb +13 -2
- data/lib/pg_eventstore/web/paginator/stream_ids_collection.rb +21 -11
- data/lib/pg_eventstore/web/paginator/stream_names_collection.rb +18 -4
- data/lib/pg_eventstore/web/paginator/streams_collection.rb +95 -0
- data/lib/pg_eventstore/web/public/javascripts/pg_eventstore.js +49 -22
- data/lib/pg_eventstore/web/subscriptions/set_collection.rb +1 -1
- data/lib/pg_eventstore/web/subscriptions/subscriptions.rb +1 -1
- data/lib/pg_eventstore/web/subscriptions/with_state/set_collection.rb +1 -1
- data/lib/pg_eventstore/web/subscriptions/with_state/subscriptions.rb +1 -1
- data/lib/pg_eventstore/web/views/home/dashboard.erb +11 -9
- data/lib/pg_eventstore/web/views/home/partials/event_filter.erb +18 -5
- data/lib/pg_eventstore/web/views/home/partials/events.erb +38 -1
- data/lib/pg_eventstore/web/views/home/partials/markers_filter.erb +18 -0
- data/lib/pg_eventstore/web/views/layouts/application.erb +6 -0
- data/lib/pg_eventstore/web/views/streams/index.erb +110 -0
- data/lib/pg_eventstore/web/views/streams/partials/streams.erb +11 -0
- data/lib/pg_eventstore/web/views/subscriptions/index.erb +4 -1
- data/lib/pg_eventstore/web.rb +2 -0
- data/lib/pg_eventstore.rb +23 -60
- data/pg_eventstore.gemspec +6 -4
- data/sig/interfaces/_raw_events_handler.rbs +3 -0
- data/sig/interfaces/subscription_handler.rbs +1 -1
- data/sig/pg/result.rbs +9 -0
- data/sig/pg_eventstore/async_runner.rbs +13 -0
- data/sig/pg_eventstore/basic_config.rbs +9 -0
- data/sig/pg_eventstore/chunks/chunk.rbs +13 -0
- data/sig/pg_eventstore/chunks/read_api_events_index_chunk.rbs +30 -0
- data/sig/pg_eventstore/chunks/replica_events_index_chunk.rbs +11 -0
- data/sig/pg_eventstore/chunks/repository.rbs +22 -0
- data/sig/pg_eventstore/chunks/subscription_checkpoint_chunk.rbs +18 -0
- data/sig/pg_eventstore/chunks/subscription_events_index_chunk.rbs +37 -0
- data/sig/pg_eventstore/client.rbs +40 -42
- data/sig/pg_eventstore/commands/append.rbs +11 -25
- data/sig/pg_eventstore/commands/event_modifiers/prepare_link_event.rbs +9 -12
- data/sig/pg_eventstore/commands/event_modifiers/prepare_regular_event.rbs +5 -4
- data/sig/pg_eventstore/commands/link_to.rbs +6 -11
- data/sig/pg_eventstore/commands/read.rbs +2 -5
- data/sig/pg_eventstore/commands/read_grouped.rbs +7 -0
- data/sig/pg_eventstore/commands/read_streams.rbs +7 -0
- data/sig/pg_eventstore/commands/read_streams_paginated.rbs +16 -0
- data/sig/pg_eventstore/commands/regular_stream_read_paginated.rbs +9 -17
- data/sig/pg_eventstore/commands/revision_check/current_revision.rbs +25 -0
- data/sig/pg_eventstore/commands/revision_check/event_type_revisions_comparison.rbs +14 -0
- data/sig/pg_eventstore/commands/revision_check/expected_revision.rbs +67 -0
- data/sig/pg_eventstore/commands/revision_check/stream_revision_check.rbs +20 -0
- data/sig/pg_eventstore/commands/revision_check/stream_revision_comparison.rbs +9 -0
- data/sig/pg_eventstore/commands/stream_revision.rbs +7 -0
- data/sig/pg_eventstore/commands/system_stream_read_paginated.rbs +9 -14
- data/sig/pg_eventstore/config.rbs +15 -6
- data/sig/pg_eventstore/connection.rbs +11 -18
- data/sig/pg_eventstore/errors.rbs +64 -34
- data/sig/pg_eventstore/event.rbs +16 -2
- data/sig/pg_eventstore/event_deserializer.rbs +5 -10
- data/sig/pg_eventstore/event_global_index.rbs +60 -0
- data/sig/pg_eventstore/event_marker.rbs +9 -0
- data/sig/pg_eventstore/event_marker_index.rbs +12 -0
- data/sig/pg_eventstore/extensions/acts_as_configurable.rbs +29 -0
- data/sig/pg_eventstore/extensions/options_defaults.rbs +7 -0
- data/sig/pg_eventstore/feature_marker.rbs +10 -0
- data/sig/pg_eventstore/maintenance.rbs +12 -8
- data/sig/pg_eventstore/middleware/event_trace.rbs +14 -0
- data/sig/pg_eventstore/partition.rbs +2 -4
- data/sig/pg_eventstore/pg_connection.rbs +8 -0
- data/sig/pg_eventstore/queries/event_marker_queries.rbs +21 -0
- data/sig/pg_eventstore/queries/event_queries.rbs +4 -36
- data/sig/pg_eventstore/queries/events_global_index_queries.rbs +37 -0
- data/sig/pg_eventstore/queries/index_filtering_queries.rbs +50 -0
- data/sig/pg_eventstore/queries/links_resolver.rbs +5 -9
- data/sig/pg_eventstore/queries/maintenance_queries.rbs +12 -9
- data/sig/pg_eventstore/queries/partition_queries.rbs +32 -67
- data/sig/pg_eventstore/queries/replica_queries.rbs +31 -0
- data/sig/pg_eventstore/queries/streams_global_index_queries.rbs +39 -0
- data/sig/pg_eventstore/queries/transaction_queries.rbs +2 -0
- data/sig/pg_eventstore/queries.rbs +11 -21
- data/sig/pg_eventstore/query_builders/basic_filtering.rbs +10 -3
- data/sig/pg_eventstore/query_builders/event_markers_filtering.rbs +17 -0
- data/sig/pg_eventstore/query_builders/event_markers_index_filtering.rbs +69 -0
- data/sig/pg_eventstore/query_builders/event_subscription_positions_filtering.rbs +15 -0
- data/sig/pg_eventstore/query_builders/events_filtering_query.rbs +9 -51
- data/sig/pg_eventstore/query_builders/events_global_index_filtering.rbs +68 -0
- data/sig/pg_eventstore/query_builders/filters/collection.rbs +84 -0
- data/sig/pg_eventstore/query_builders/filters/event_type_filter.rbs +19 -0
- data/sig/pg_eventstore/query_builders/filters/filter_row.rbs +21 -0
- data/sig/pg_eventstore/query_builders/filters/marker_filter.rbs +13 -0
- data/sig/pg_eventstore/query_builders/filters/marker_filter_row.rbs +19 -0
- data/sig/pg_eventstore/query_builders/filters/stream_filter.rbs +24 -0
- data/sig/pg_eventstore/query_builders/index_based_events_filtering.rbs +60 -0
- data/sig/pg_eventstore/query_builders/partitions_filtering.rbs +29 -10
- data/sig/pg_eventstore/query_builders/read_cursor/stream_cursor.rbs +47 -0
- data/sig/pg_eventstore/query_builders/streams_global_index_filtering.rbs +27 -0
- data/sig/pg_eventstore/query_builders/subscription_events_filtering.rbs +26 -0
- data/sig/pg_eventstore/query_strategy/async.rbs +17 -0
- data/sig/pg_eventstore/query_strategy/foreground.rbs +11 -0
- data/sig/pg_eventstore/query_strategy.rbs +7 -0
- data/sig/pg_eventstore/raw_event.rbs +20 -0
- data/sig/pg_eventstore/sql_builder.rbs +32 -10
- data/sig/pg_eventstore/stream.rbs +10 -18
- data/sig/pg_eventstore/stream_global_index.rbs +14 -0
- data/sig/pg_eventstore/subscriptions/callback_handlers/events_processor_handlers.rbs +5 -4
- data/sig/pg_eventstore/subscriptions/callback_handlers/events_subscription_position_worker_handlers.rbs +9 -0
- data/sig/pg_eventstore/subscriptions/callback_handlers/subscription_feeder_handlers.rbs +17 -12
- data/sig/pg_eventstore/subscriptions/callback_handlers/subscription_runner_handlers.rbs +17 -6
- data/sig/pg_eventstore/subscriptions/event_subscription_position_queries.rbs +30 -0
- data/sig/pg_eventstore/subscriptions/events_processor.rbs +12 -5
- data/sig/pg_eventstore/subscriptions/events_processor_consumer/multiple.rbs +17 -0
- data/sig/pg_eventstore/subscriptions/events_processor_consumer/replica.rbs +17 -0
- data/sig/pg_eventstore/subscriptions/events_processor_consumer/single.rbs +17 -0
- data/sig/pg_eventstore/subscriptions/events_processor_consumer.rbs +14 -0
- data/sig/pg_eventstore/subscriptions/events_subscription_position_worker.rbs +28 -0
- data/sig/pg_eventstore/subscriptions/queries/subscription_queries.rbs +7 -39
- data/sig/pg_eventstore/subscriptions/replica_subscription_handler.rbs +33 -0
- data/sig/pg_eventstore/subscriptions/replica_subscription_runner.rbs +4 -0
- data/sig/pg_eventstore/subscriptions/subscription_feed_strategy/collection.rbs +14 -0
- data/sig/pg_eventstore/subscriptions/subscription_feed_strategy/index_read_strategy.rbs +23 -0
- data/sig/pg_eventstore/subscriptions/subscription_feed_strategy/replication_strategy.rbs +23 -0
- data/sig/pg_eventstore/subscriptions/subscription_feed_strategy.rbs +11 -0
- data/sig/pg_eventstore/subscriptions/subscription_feeder.rbs +13 -10
- data/sig/pg_eventstore/subscriptions/subscription_handler_performance.rbs +1 -1
- data/sig/pg_eventstore/subscriptions/subscription_runner.rbs +13 -2
- data/sig/pg_eventstore/subscriptions/subscription_runners_feeder.rbs +1 -8
- data/sig/pg_eventstore/subscriptions/subscriptions_lifecycle.rbs +4 -6
- data/sig/pg_eventstore/subscriptions/subscriptions_manager.rbs +29 -43
- data/sig/pg_eventstore/synchronized_array.rbs +4 -0
- data/sig/pg_eventstore/utils.rbs +10 -11
- data/sig/pg_eventstore/web/application.rbs +13 -3
- data/sig/pg_eventstore/web/paginator/base_collection.rbs +2 -0
- data/sig/pg_eventstore/web/paginator/event_types_collection.rbs +4 -0
- data/sig/pg_eventstore/web/paginator/events_collection.rbs +11 -11
- data/sig/pg_eventstore/web/paginator/helpers.rbs +6 -15
- data/sig/pg_eventstore/web/paginator/markers_collection.rbs +13 -0
- data/sig/pg_eventstore/web/paginator/stream_contexts_collection.rbs +4 -0
- data/sig/pg_eventstore/web/paginator/stream_names_collection.rbs +4 -0
- data/sig/pg_eventstore/web/paginator/streams_collection.rbs +30 -0
- data/sig/pg_eventstore.rbs +8 -26
- metadata +175 -20
- data/Dockerfile +0 -3
- data/lib/pg_eventstore/commands/all_stream_read_grouped.rb +0 -69
- data/lib/pg_eventstore/commands/regular_stream_read_grouped.rb +0 -31
- data/lib/pg_eventstore/subscriptions/queries/subscription_service_queries.rb +0 -78
- data/lib/pg_eventstore/web/views/home/partials/system_stream_filter.erb +0 -15
- data/sig/pg_eventstore/commands/all_stream_read_grouped.rbs +0 -16
- data/sig/pg_eventstore/commands/regular_stream_read_grouped.rbs +0 -8
- data/sig/pg_eventstore/subscriptions/queries/subscription_service_queries.rbs +0 -19
- data/sig/pg_eventstore/subscriptions/synchronized_array.rbs +0 -4
- /data/sig/interfaces/{_raw_event_handler.rbs → raw_event_handler.rbs} +0 -0
data/lib/pg_eventstore/stream.rb
CHANGED
|
@@ -4,12 +4,10 @@ require 'digest/md5'
|
|
|
4
4
|
|
|
5
5
|
module PgEventstore
|
|
6
6
|
class Stream
|
|
7
|
-
# @return [String] a stream prefix of the system stream
|
|
8
|
-
SYSTEM_STREAM_PREFIX = '$'
|
|
9
7
|
# @return [Integer]
|
|
10
8
|
NON_EXISTING_STREAM_REVISION = -1
|
|
11
9
|
# @return [Array<String>]
|
|
12
|
-
KNOWN_SYSTEM_STREAMS = %w[
|
|
10
|
+
KNOWN_SYSTEM_STREAMS = %w[].freeze
|
|
13
11
|
|
|
14
12
|
class << self
|
|
15
13
|
# Produces "all" stream instance. "all" stream does not represent any specific stream. Instead, it indicates that
|
|
@@ -20,12 +18,6 @@ module PgEventstore
|
|
|
20
18
|
stream.instance_variable_set(:@all_stream, true)
|
|
21
19
|
end
|
|
22
20
|
end
|
|
23
|
-
|
|
24
|
-
# @param name [String]
|
|
25
|
-
# @return [PgEventstore::Stream]
|
|
26
|
-
def system_stream(name)
|
|
27
|
-
new(context: name, stream_name: '', stream_id: '')
|
|
28
|
-
end
|
|
29
21
|
end
|
|
30
22
|
|
|
31
23
|
# @!attribute context
|
|
@@ -37,26 +29,31 @@ module PgEventstore
|
|
|
37
29
|
# @!attribute stream_id
|
|
38
30
|
# @return [String]
|
|
39
31
|
attr_reader :stream_id
|
|
32
|
+
# @!attribute stream_revision
|
|
33
|
+
# @return [Integer, nil]
|
|
34
|
+
attr_reader :stream_revision
|
|
35
|
+
# @!attribute starting_position
|
|
36
|
+
# @return [Integer, nil]
|
|
37
|
+
attr_reader :starting_position
|
|
40
38
|
|
|
41
39
|
# @param context [String]
|
|
42
40
|
# @param stream_name [String]
|
|
43
41
|
# @param stream_id [String]
|
|
44
|
-
|
|
42
|
+
# @param stream_revision [Integer, nil]
|
|
43
|
+
# @param starting_position [Integer, nil]
|
|
44
|
+
def initialize(context:, stream_name:, stream_id:, stream_revision: nil, starting_position: nil)
|
|
45
45
|
@context = context
|
|
46
46
|
@stream_name = stream_name
|
|
47
47
|
@stream_id = stream_id
|
|
48
|
+
@stream_revision = stream_revision
|
|
49
|
+
@starting_position = starting_position
|
|
48
50
|
end
|
|
49
51
|
|
|
50
52
|
# @return [Boolean]
|
|
51
53
|
def all_stream?
|
|
52
54
|
!!@all_stream
|
|
53
55
|
end
|
|
54
|
-
|
|
55
|
-
# Determine whether a stream is reserved by `pg_eventstore`. You can't append events to such streams.
|
|
56
|
-
# @return [Boolean]
|
|
57
|
-
def system?
|
|
58
|
-
all_stream? || context.start_with?(SYSTEM_STREAM_PREFIX)
|
|
59
|
-
end
|
|
56
|
+
alias system? all_stream?
|
|
60
57
|
|
|
61
58
|
# @return [Array]
|
|
62
59
|
def deconstruct
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PgEventstore
|
|
4
|
+
# @!visibility private
|
|
5
|
+
class StreamGlobalIndex
|
|
6
|
+
include Extensions::OptionsExtension
|
|
7
|
+
include Extensions::OptionsDefaults
|
|
8
|
+
|
|
9
|
+
# @return [Integer]
|
|
10
|
+
INITIAL_STARTING_POSITION = -1
|
|
11
|
+
|
|
12
|
+
# @!attribute id
|
|
13
|
+
# @return [Integer]
|
|
14
|
+
attribute(:id)
|
|
15
|
+
# @!attribute partition_id
|
|
16
|
+
# @return [Integer]
|
|
17
|
+
attribute(:partition_id)
|
|
18
|
+
# @!attribute stream_id
|
|
19
|
+
# @return [String]
|
|
20
|
+
attribute(:stream_id)
|
|
21
|
+
# @!attribute stream_revision
|
|
22
|
+
# @return [Integer]
|
|
23
|
+
attribute(:stream_revision)
|
|
24
|
+
# @!attribute starting_position
|
|
25
|
+
# @return [Integer]
|
|
26
|
+
attribute(:starting_position)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -6,25 +6,13 @@ module PgEventstore
|
|
|
6
6
|
include Extensions::CallbackHandlersExtension
|
|
7
7
|
|
|
8
8
|
class << self
|
|
9
|
+
# @param consumer [PgEventstore::EventsProcessorConsumer]
|
|
9
10
|
# @param callbacks [PgEventstore::Callbacks]
|
|
10
|
-
# @param
|
|
11
|
-
# @param
|
|
12
|
-
# @param raw_events_cond [MonitorMixin::ConditionVariable]
|
|
11
|
+
# @param events_repository [PgEventstore::Chunks::Repository]
|
|
12
|
+
# @param repository_cond [MonitorMixin::ConditionVariable]
|
|
13
13
|
# @return [void]
|
|
14
|
-
def
|
|
15
|
-
|
|
16
|
-
raw_events.synchronize do
|
|
17
|
-
raw_events_cond.wait(0.5) if raw_events.empty?
|
|
18
|
-
raw_event = raw_events.shift
|
|
19
|
-
end
|
|
20
|
-
return if raw_event.nil?
|
|
21
|
-
|
|
22
|
-
callbacks.run_callbacks(:process, Utils.original_global_position(raw_event)) do
|
|
23
|
-
handler.call(raw_event)
|
|
24
|
-
rescue => exception
|
|
25
|
-
raw_events.unshift(raw_event)
|
|
26
|
-
raise Utils.wrap_exception(exception, global_position: Utils.original_global_position(raw_event))
|
|
27
|
-
end
|
|
14
|
+
def consume_events(consumer, callbacks, events_repository, repository_cond)
|
|
15
|
+
consumer.call(callbacks, events_repository, repository_cond)
|
|
28
16
|
end
|
|
29
17
|
|
|
30
18
|
# @param callbacks [PgEventstore::Callbacks]
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PgEventstore
|
|
4
|
+
# @!visibility private
|
|
5
|
+
class EventsSubscriptionPositionWorkerHandlers
|
|
6
|
+
include Extensions::CallbackHandlersExtension
|
|
7
|
+
|
|
8
|
+
class << self
|
|
9
|
+
# @param event_subscription_position_queries [PgEventstore::EventSubscriptionPositionQueries]
|
|
10
|
+
# @param update_interval [Integer, Float]
|
|
11
|
+
# @return [void]
|
|
12
|
+
def assign_subscription_position(event_subscription_position_queries, update_interval)
|
|
13
|
+
affected_records = event_subscription_position_queries.assign_subscription_position
|
|
14
|
+
# In case if assigning subscription position process is locked by someone else or if we updated less than
|
|
15
|
+
# MAX_INDEX_RECORDS_TO_UPDATE_SUBSCRIPTION_POSITION number of records(which basically means we are on the edge
|
|
16
|
+
# of the table) - take some delay before the next attempt.
|
|
17
|
+
if affected_records.nil? ||
|
|
18
|
+
affected_records < EventSubscriptionPositionQueries::MAX_INDEX_RECORDS_TO_UPDATE_SUBSCRIPTION_POSITION
|
|
19
|
+
sleep update_interval
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# @param event_subscription_position_queries [PgEventstore::EventSubscriptionPositionQueries]
|
|
24
|
+
# @param next_reindex_at [PgEventstore::EventsSubscriptionPositionWorker::ReindexTime]
|
|
25
|
+
# @return [void]
|
|
26
|
+
def reindex(event_subscription_position_queries, next_reindex_at)
|
|
27
|
+
return if next_reindex_at.time && next_reindex_at.time > Time.now
|
|
28
|
+
|
|
29
|
+
time = event_subscription_position_queries.reindex_unprocessed_positions
|
|
30
|
+
return unless time
|
|
31
|
+
|
|
32
|
+
next_reindex_at.time = time
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -85,6 +85,18 @@ module PgEventstore
|
|
|
85
85
|
last_restarted_at: Time.now.utc, restart_count: subscriptions_set.restart_count + 1
|
|
86
86
|
)
|
|
87
87
|
end
|
|
88
|
+
|
|
89
|
+
# @param worker [PgEventstore::EventsSubscriptionPositionWorker]
|
|
90
|
+
# @return [void]
|
|
91
|
+
def start_events_subscription_position_worker(worker)
|
|
92
|
+
worker.start
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# @param worker [PgEventstore::EventsSubscriptionPositionWorker]
|
|
96
|
+
# @return [void]
|
|
97
|
+
def stop_events_subscription_position_worker(worker)
|
|
98
|
+
worker.stop_async.wait_for_finish
|
|
99
|
+
end
|
|
88
100
|
end
|
|
89
101
|
end
|
|
90
102
|
end
|
|
@@ -9,20 +9,22 @@ module PgEventstore
|
|
|
9
9
|
# @param stats [PgEventstore::SubscriptionHandlerPerformance]
|
|
10
10
|
# @param action [Proc]
|
|
11
11
|
# @param _current_position [Integer]
|
|
12
|
+
# @param events_number [Integer]
|
|
12
13
|
# @return [void]
|
|
13
|
-
def track_exec_time(stats, action, _current_position)
|
|
14
|
-
stats.track_exec_time { action.call }
|
|
14
|
+
def track_exec_time(stats, action, _current_position, events_number)
|
|
15
|
+
stats.track_exec_time(events_number) { action.call }
|
|
15
16
|
end
|
|
16
17
|
|
|
17
18
|
# @param subscription [PgEventstore::Subscription]
|
|
18
19
|
# @param stats [PgEventstore::SubscriptionHandlerPerformance]
|
|
19
20
|
# @param current_position [Integer]
|
|
21
|
+
# @param events_number [Integer]
|
|
20
22
|
# @return [void]
|
|
21
|
-
def update_subscription_stats(subscription, stats, current_position)
|
|
23
|
+
def update_subscription_stats(subscription, stats, current_position, events_number)
|
|
22
24
|
subscription.update(
|
|
23
25
|
average_event_processing_time: stats.average_event_processing_time,
|
|
24
26
|
current_position:,
|
|
25
|
-
total_processed_events: subscription.total_processed_events +
|
|
27
|
+
total_processed_events: subscription.total_processed_events + events_number
|
|
26
28
|
)
|
|
27
29
|
end
|
|
28
30
|
|
|
@@ -34,10 +36,12 @@ module PgEventstore
|
|
|
34
36
|
end
|
|
35
37
|
|
|
36
38
|
# @param subscription [PgEventstore::Subscription]
|
|
37
|
-
# @param
|
|
39
|
+
# @param subscription_position [Integer]
|
|
38
40
|
# @return [void]
|
|
39
|
-
def update_subscription_chunk_stats(subscription,
|
|
40
|
-
subscription.
|
|
41
|
+
def update_subscription_chunk_stats(subscription, subscription_position)
|
|
42
|
+
return if subscription.last_chunk_greatest_position == subscription_position
|
|
43
|
+
|
|
44
|
+
subscription.update(last_chunk_fed_at: Time.now.utc, last_chunk_greatest_position: subscription_position)
|
|
41
45
|
end
|
|
42
46
|
|
|
43
47
|
# @param subscription [PgEventstore::Subscription]
|
|
@@ -52,6 +56,16 @@ module PgEventstore
|
|
|
52
56
|
def update_subscription_state(subscription, state)
|
|
53
57
|
subscription.update(state:)
|
|
54
58
|
end
|
|
59
|
+
|
|
60
|
+
# @param subscription [PgEventstore::Subscription]
|
|
61
|
+
# @param global_position [Integer]
|
|
62
|
+
# @return [void]
|
|
63
|
+
def checkpoint(subscription, global_position)
|
|
64
|
+
return if subscription.current_position == subscription.last_chunk_greatest_position &&
|
|
65
|
+
subscription.current_position == global_position
|
|
66
|
+
|
|
67
|
+
subscription.update(current_position: global_position, last_chunk_greatest_position: global_position)
|
|
68
|
+
end
|
|
55
69
|
end
|
|
56
70
|
end
|
|
57
71
|
end
|
|
@@ -10,14 +10,16 @@ module PgEventstore
|
|
|
10
10
|
def_delegators :@basic_runner, :state, :start, :stop, :wait_for_finish, :stop_async, :restore, :running?,
|
|
11
11
|
:within_state
|
|
12
12
|
|
|
13
|
-
# @param handler [#call]
|
|
14
13
|
# @param graceful_shutdown_timeout [Integer, Float] seconds. Determines how long to wait before force-shutdown
|
|
15
14
|
# the runner when stopping it using #stop_async
|
|
15
|
+
# @param consumer [PgEventstore::EventsProcessorConsumer]
|
|
16
|
+
# @param events_repository [PgEventstore::Chunks::Repository]
|
|
16
17
|
# @param recovery_strategies [Array<PgEventstore::RunnerRecoveryStrategy>]
|
|
17
|
-
def initialize(
|
|
18
|
-
|
|
19
|
-
@
|
|
20
|
-
@
|
|
18
|
+
def initialize(graceful_shutdown_timeout:, consumer:, events_repository: Chunks::Repository.new,
|
|
19
|
+
recovery_strategies: [])
|
|
20
|
+
@consumer = consumer
|
|
21
|
+
@events_repository = events_repository
|
|
22
|
+
@repository_cond = @events_repository.new_cond
|
|
21
23
|
@basic_runner = BasicRunner.new(
|
|
22
24
|
run_interval: 0,
|
|
23
25
|
async_shutdown_time: graceful_shutdown_timeout,
|
|
@@ -26,29 +28,27 @@ module PgEventstore
|
|
|
26
28
|
attach_runner_callbacks
|
|
27
29
|
end
|
|
28
30
|
|
|
29
|
-
# @param
|
|
31
|
+
# @param chunk [PgEventstore::Chunks::Chunk]
|
|
30
32
|
# @return [void]
|
|
31
|
-
def feed(
|
|
32
|
-
raise EmptyChunkFedError.new('Empty chunk was fed!') if
|
|
33
|
+
def feed(chunk)
|
|
34
|
+
raise EmptyChunkFedError.new('Empty chunk was fed!') if chunk.drained?
|
|
33
35
|
|
|
34
36
|
within_state(:running) do
|
|
35
|
-
callbacks.run_callbacks(:feed,
|
|
36
|
-
@
|
|
37
|
-
@raw_events.push(*raw_events)
|
|
38
|
-
@raw_events_cond.broadcast
|
|
39
|
-
end
|
|
37
|
+
callbacks.run_callbacks(:feed, chunk.last.subscription_position)
|
|
38
|
+
@events_repository.add_chunk(chunk, condition: @repository_cond)
|
|
40
39
|
end
|
|
41
40
|
end
|
|
42
41
|
|
|
43
42
|
# Number of unprocessed events which are currently in a queue
|
|
44
43
|
# @return [Integer]
|
|
45
|
-
def
|
|
46
|
-
@
|
|
44
|
+
def events_left_in_repo
|
|
45
|
+
@events_repository.size
|
|
47
46
|
end
|
|
48
47
|
|
|
49
48
|
# @return [void]
|
|
50
|
-
def
|
|
51
|
-
@
|
|
49
|
+
def clear_events_repository
|
|
50
|
+
@events_repository.clear
|
|
51
|
+
@consumer.clear_unprocessed_events
|
|
52
52
|
end
|
|
53
53
|
|
|
54
54
|
private
|
|
@@ -56,7 +56,9 @@ module PgEventstore
|
|
|
56
56
|
def attach_runner_callbacks
|
|
57
57
|
@basic_runner.define_callback(
|
|
58
58
|
:process_async, :before,
|
|
59
|
-
EventsProcessorHandlers.setup_handler(
|
|
59
|
+
EventsProcessorHandlers.setup_handler(
|
|
60
|
+
:consume_events, @consumer, @callbacks, @events_repository, @repository_cond
|
|
61
|
+
)
|
|
60
62
|
)
|
|
61
63
|
|
|
62
64
|
@basic_runner.define_callback(
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PgEventstore
|
|
4
|
+
module EventsProcessorConsumer
|
|
5
|
+
# @!visibility private
|
|
6
|
+
class Multiple
|
|
7
|
+
include EventsProcessorConsumer
|
|
8
|
+
|
|
9
|
+
# @return [Float, Integer]
|
|
10
|
+
EVENTS_WAIT_TIMEOUT = 0.5
|
|
11
|
+
|
|
12
|
+
class << self
|
|
13
|
+
# @param handler [#call]
|
|
14
|
+
# @param deserializer [PgEventstore::EventDeserializer]
|
|
15
|
+
# @return [PgEventstore::EventsProcessorConsumer::Multiple]
|
|
16
|
+
def create_consumer(handler, deserializer)
|
|
17
|
+
raw_handler = ->(raw_events) { handler.call(raw_events.map(&deserializer.method(:deserialize))) }
|
|
18
|
+
new(raw_handler)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# @param handler [#call]
|
|
23
|
+
def initialize(handler)
|
|
24
|
+
@handler = handler
|
|
25
|
+
@last_unprocessed_events = nil
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# @return [void]
|
|
29
|
+
def clear_unprocessed_events
|
|
30
|
+
@last_unprocessed_events = nil
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# @param callbacks [PgEventstore::Callbacks]
|
|
34
|
+
# @param events_repository [PgEventstore::Chunks::Repository]
|
|
35
|
+
# @param repository_cond [MonitorMixin::ConditionVariable]
|
|
36
|
+
# @return [void]
|
|
37
|
+
def call(callbacks, events_repository, repository_cond)
|
|
38
|
+
events_to_process =
|
|
39
|
+
@last_unprocessed_events ||
|
|
40
|
+
events_repository.wait_and_consume(
|
|
41
|
+
entities_num: nil, timeout: EVENTS_WAIT_TIMEOUT, condition: repository_cond
|
|
42
|
+
)
|
|
43
|
+
return if events_to_process.empty?
|
|
44
|
+
|
|
45
|
+
if events_to_process.first.is_a?(Chunks::SubscriptionCheckpointChunk::Checkpoint)
|
|
46
|
+
callbacks.run_callbacks(:checkpoint, events_to_process.first.subscription_position)
|
|
47
|
+
return
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
callbacks.run_callbacks(:process, events_to_process.last.subscription_position, events_to_process.size) do
|
|
51
|
+
@handler.call(events_to_process.map(&:attributes))
|
|
52
|
+
rescue => exception
|
|
53
|
+
@last_unprocessed_events = events_to_process
|
|
54
|
+
raise Utils.wrap_exception(
|
|
55
|
+
exception, subscription_positions: events_to_process.map(&:subscription_position)
|
|
56
|
+
)
|
|
57
|
+
else
|
|
58
|
+
clear_unprocessed_events
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PgEventstore
|
|
4
|
+
module EventsProcessorConsumer
|
|
5
|
+
# @!visibility private
|
|
6
|
+
class Replica
|
|
7
|
+
include EventsProcessorConsumer
|
|
8
|
+
|
|
9
|
+
# @return [Float, Integer]
|
|
10
|
+
EVENTS_WAIT_TIMEOUT = 0.5
|
|
11
|
+
|
|
12
|
+
class << self
|
|
13
|
+
# @param config_name [Symbol]
|
|
14
|
+
# @param replica_config_name [Symbol]
|
|
15
|
+
# @return [PgEventstore::EventsProcessorConsumer::Replica]
|
|
16
|
+
def create_consumer(config_name, replica_config_name)
|
|
17
|
+
handler = ReplicaSubscriptionHandler.new(config_name, replica_config_name)
|
|
18
|
+
raw_handler = ->(events) { handler.call(events) }
|
|
19
|
+
new(raw_handler)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# @param handler [#call]
|
|
24
|
+
def initialize(handler)
|
|
25
|
+
@handler = handler
|
|
26
|
+
@last_unprocessed_events = nil
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# @return [void]
|
|
30
|
+
def clear_unprocessed_events
|
|
31
|
+
@last_unprocessed_events = nil
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# @param callbacks [PgEventstore::Callbacks]
|
|
35
|
+
# @param events_repository [PgEventstore::Chunks::Repository]
|
|
36
|
+
# @param repository_cond [MonitorMixin::ConditionVariable]
|
|
37
|
+
# @return [void]
|
|
38
|
+
def call(callbacks, events_repository, repository_cond)
|
|
39
|
+
events_to_process =
|
|
40
|
+
@last_unprocessed_events ||
|
|
41
|
+
events_repository.wait_and_consume(
|
|
42
|
+
entities_num: nil, timeout: EVENTS_WAIT_TIMEOUT, condition: repository_cond
|
|
43
|
+
)
|
|
44
|
+
return if events_to_process.empty?
|
|
45
|
+
|
|
46
|
+
if events_to_process.first.is_a?(Chunks::SubscriptionCheckpointChunk::Checkpoint)
|
|
47
|
+
callbacks.run_callbacks(:checkpoint, events_to_process.first.subscription_position)
|
|
48
|
+
return
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
callbacks.run_callbacks(:process, events_to_process.last.subscription_position, events_to_process.size) do
|
|
52
|
+
@handler.call(events_to_process)
|
|
53
|
+
rescue => exception
|
|
54
|
+
@last_unprocessed_events = events_to_process
|
|
55
|
+
raise Utils.wrap_exception(
|
|
56
|
+
exception,
|
|
57
|
+
subscription_position_range: [
|
|
58
|
+
events_to_process.first.subscription_position,
|
|
59
|
+
events_to_process.last.subscription_position,
|
|
60
|
+
]
|
|
61
|
+
)
|
|
62
|
+
else
|
|
63
|
+
clear_unprocessed_events
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PgEventstore
|
|
4
|
+
module EventsProcessorConsumer
|
|
5
|
+
# @!visibility private
|
|
6
|
+
class Single
|
|
7
|
+
include EventsProcessorConsumer
|
|
8
|
+
|
|
9
|
+
# @return [Float, Integer]
|
|
10
|
+
EVENT_WAIT_TIMEOUT = 0.5
|
|
11
|
+
|
|
12
|
+
class << self
|
|
13
|
+
# @param handler [#call]
|
|
14
|
+
# @param deserializer [PgEventstore::EventDeserializer]
|
|
15
|
+
# @return [PgEventstore::EventsProcessorConsumer::Single]
|
|
16
|
+
def create_consumer(handler, deserializer)
|
|
17
|
+
raw_handler = ->(raw_event) { handler.call(deserializer.deserialize(raw_event)) }
|
|
18
|
+
new(raw_handler)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# @param handler [#call]
|
|
23
|
+
def initialize(handler)
|
|
24
|
+
@handler = handler
|
|
25
|
+
@last_unprocessed_event = nil
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# @return [void]
|
|
29
|
+
def clear_unprocessed_events
|
|
30
|
+
@last_unprocessed_event = nil
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# @param callbacks [PgEventstore::Callbacks]
|
|
34
|
+
# @param events_repository [PgEventstore::Chunks::Repository]
|
|
35
|
+
# @param repository_cond [MonitorMixin::ConditionVariable]
|
|
36
|
+
# @return [void]
|
|
37
|
+
def call(callbacks, events_repository, repository_cond)
|
|
38
|
+
raw_event =
|
|
39
|
+
@last_unprocessed_event ||
|
|
40
|
+
events_repository.wait_and_consume(
|
|
41
|
+
entities_num: 1, timeout: EVENT_WAIT_TIMEOUT, condition: repository_cond
|
|
42
|
+
).first
|
|
43
|
+
|
|
44
|
+
return if raw_event.nil?
|
|
45
|
+
|
|
46
|
+
if raw_event.is_a?(Chunks::SubscriptionCheckpointChunk::Checkpoint)
|
|
47
|
+
callbacks.run_callbacks(:checkpoint, raw_event.subscription_position)
|
|
48
|
+
return
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
callbacks.run_callbacks(:process, raw_event.subscription_position, 1) do
|
|
52
|
+
@handler.call(raw_event.attributes)
|
|
53
|
+
rescue => exception
|
|
54
|
+
@last_unprocessed_event = raw_event
|
|
55
|
+
raise Utils.wrap_exception(exception, global_position: raw_event.subscription_position)
|
|
56
|
+
else
|
|
57
|
+
clear_unprocessed_events
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PgEventstore
|
|
4
|
+
# @!visibility private
|
|
5
|
+
module EventsProcessorConsumer
|
|
6
|
+
class << self
|
|
7
|
+
# @param in_batches [Boolean]
|
|
8
|
+
# @return [Class]
|
|
9
|
+
def consumer_class(in_batches)
|
|
10
|
+
return Multiple if in_batches
|
|
11
|
+
|
|
12
|
+
Single
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def included(othermod)
|
|
16
|
+
othermod.extend(ClassMethods)
|
|
17
|
+
super
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
module ClassMethods
|
|
22
|
+
def create_consumer(handler, deserializer)
|
|
23
|
+
raise NotImplementedError
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# @param callbacks [PgEventstore::Callbacks]
|
|
28
|
+
# @param repository [PgEventstore::Chunks::Repository]
|
|
29
|
+
# @param repository_cond [MonitorMixin::ConditionVariable]
|
|
30
|
+
# @return [void]
|
|
31
|
+
def call(callbacks, repository, repository_cond)
|
|
32
|
+
raise NotImplementedError
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# @return [void]
|
|
36
|
+
def clear_unprocessed_events
|
|
37
|
+
raise NotImplementedError
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
require_relative 'events_processor_consumer/single'
|
|
43
|
+
require_relative 'events_processor_consumer/multiple'
|
|
44
|
+
require_relative 'events_processor_consumer/replica'
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PgEventstore
|
|
4
|
+
# @!visibility private
|
|
5
|
+
class EventsSubscriptionPositionWorker
|
|
6
|
+
extend Forwardable
|
|
7
|
+
|
|
8
|
+
attr_reader :config_name
|
|
9
|
+
|
|
10
|
+
def_delegators :@basic_runner, :start, :stop, :state, :stop_async, :wait_for_finish
|
|
11
|
+
|
|
12
|
+
class ReindexTime
|
|
13
|
+
include Extensions::OptionsExtension
|
|
14
|
+
include Extensions::OptionsDefaults
|
|
15
|
+
|
|
16
|
+
option(:time)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# @param config_name [Symbol]
|
|
20
|
+
def initialize(config_name)
|
|
21
|
+
@config_name = config_name
|
|
22
|
+
@basic_runner = BasicRunner.new(
|
|
23
|
+
run_interval: 0,
|
|
24
|
+
async_shutdown_time: 5,
|
|
25
|
+
recovery_strategies: [RunnerRecoveryStrategies::RestoreConnection.new(config_name)]
|
|
26
|
+
)
|
|
27
|
+
@next_reindex_at = ReindexTime.new
|
|
28
|
+
attach_runner_callbacks
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
# @return [void]
|
|
34
|
+
def attach_runner_callbacks
|
|
35
|
+
@basic_runner.define_callback(
|
|
36
|
+
:process_async, :before,
|
|
37
|
+
EventsSubscriptionPositionWorkerHandlers.setup_handler(
|
|
38
|
+
:assign_subscription_position,
|
|
39
|
+
event_subscription_position_queries,
|
|
40
|
+
config.events_subscription_position_update_interval
|
|
41
|
+
)
|
|
42
|
+
)
|
|
43
|
+
@basic_runner.define_callback(
|
|
44
|
+
:process_async, :before,
|
|
45
|
+
EventsSubscriptionPositionWorkerHandlers.setup_handler(
|
|
46
|
+
:reindex,
|
|
47
|
+
event_subscription_position_queries,
|
|
48
|
+
@next_reindex_at
|
|
49
|
+
)
|
|
50
|
+
)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# @return [PgEventstore::EventSubscriptionPositionQueries]
|
|
54
|
+
def event_subscription_position_queries
|
|
55
|
+
EventSubscriptionPositionQueries.new(connection)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# @return [PgEventstore::Connection]
|
|
59
|
+
def connection
|
|
60
|
+
PgEventstore.connection(config_name)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# @return [PgEventstore::Config]
|
|
64
|
+
def config
|
|
65
|
+
PgEventstore.config(config_name)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|