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
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PgEventstore
|
|
4
|
+
module SubscriptionFeedStrategy
|
|
5
|
+
# @!visibility private
|
|
6
|
+
class ReplicationStrategy
|
|
7
|
+
include SubscriptionFeedStrategy
|
|
8
|
+
|
|
9
|
+
# Allow subscriptions to scan through up to this amount of events per a single query. This allows to make query
|
|
10
|
+
# plan more predictable.
|
|
11
|
+
# @return [Integer]
|
|
12
|
+
INDEX_LOOK_UP_DISTANCE = 100_000
|
|
13
|
+
|
|
14
|
+
# @param connection [PgEventstore::Connection]
|
|
15
|
+
# @param query_strategy [PgEventstore::QueryStrategy]
|
|
16
|
+
def initialize(connection, query_strategy)
|
|
17
|
+
@connection = connection
|
|
18
|
+
@query_strategy = query_strategy
|
|
19
|
+
@runners = []
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# @param runners [Array<PgEventstore::ReplicaSubscriptionRunner>]
|
|
23
|
+
# @return [Array<PgEventstore::ReplicaSubscriptionRunner>]
|
|
24
|
+
def add(*runners)
|
|
25
|
+
@runners.push(*runners)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# @return [Integer]
|
|
29
|
+
def size
|
|
30
|
+
@runners.size
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# @return [Boolean]
|
|
34
|
+
def any?
|
|
35
|
+
@runners.any?
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# @return [void]
|
|
39
|
+
def feed
|
|
40
|
+
runners_query_options = @runners.to_h do |runner|
|
|
41
|
+
next_chunk_query_opts = runner.next_chunk_query_opts
|
|
42
|
+
next_chunk_query_opts[:to_position] =
|
|
43
|
+
[next_chunk_query_opts[:from_position] + INDEX_LOOK_UP_DISTANCE, safe_position].min
|
|
44
|
+
[runner.id, next_chunk_query_opts]
|
|
45
|
+
end
|
|
46
|
+
grouped_indexes = events_global_index_queries.fetch_indexes_for_subscriptions(runners_query_options)
|
|
47
|
+
@runners.each do |runner|
|
|
48
|
+
if grouped_indexes[runner.id]
|
|
49
|
+
chunk = Chunks::ReplicaEventsIndexChunk.new(grouped_indexes[runner.id])
|
|
50
|
+
runner.feed(chunk)
|
|
51
|
+
else
|
|
52
|
+
runner.feed(Chunks::SubscriptionCheckpointChunk.new(runners_query_options[runner.id][:to_position]))
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
private
|
|
58
|
+
|
|
59
|
+
# @return [Integer]
|
|
60
|
+
def safe_position
|
|
61
|
+
event_subscription_position_queries.max_subscription_position || 0
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# @return [PgEventstore::EventsGlobalIndexQueries]
|
|
65
|
+
def events_global_index_queries
|
|
66
|
+
EventsGlobalIndexQueries.new(@connection, @query_strategy)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# @return [PgEventstore::EventSubscriptionPositionQueries]
|
|
70
|
+
def event_subscription_position_queries
|
|
71
|
+
EventSubscriptionPositionQueries.new(@connection)
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PgEventstore
|
|
4
|
+
# @!visibility private
|
|
5
|
+
module SubscriptionFeedStrategy
|
|
6
|
+
# @param runners [PgEventstore::SubscriptionRunner, Array<PgEventstore::SubscriptionRunner>]
|
|
7
|
+
# @return [Array<PgEventstore::SubscriptionRunner>]
|
|
8
|
+
def add(*runners)
|
|
9
|
+
raise NotImplementedError
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# @return [Integer]
|
|
13
|
+
def size
|
|
14
|
+
raise NotImplementedError
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# @return [Boolean]
|
|
18
|
+
def any?
|
|
19
|
+
raise NotImplementedError
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# @return [void]
|
|
23
|
+
def feed
|
|
24
|
+
raise NotImplementedError
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
require_relative 'subscription_feed_strategies/collection'
|
|
30
|
+
require_relative 'subscription_feed_strategies/index_read_strategy'
|
|
31
|
+
require_relative 'subscription_feed_strategies/replication_strategy'
|
|
@@ -30,6 +30,9 @@ module PgEventstore
|
|
|
30
30
|
@subscriptions_set_lifecycle = subscriptions_set_lifecycle
|
|
31
31
|
@subscriptions_lifecycle = subscriptions_lifecycle
|
|
32
32
|
@commands_handler = CommandsHandler.new(@config_name, self, @subscriptions_lifecycle.runners)
|
|
33
|
+
if requires_subscription_position_assignment?
|
|
34
|
+
@events_subscription_position_worker = EventsSubscriptionPositionWorker.new(@config_name)
|
|
35
|
+
end
|
|
33
36
|
attach_runner_callbacks
|
|
34
37
|
end
|
|
35
38
|
|
|
@@ -77,6 +80,14 @@ module PgEventstore
|
|
|
77
80
|
:before_runner_started, :before,
|
|
78
81
|
SubscriptionFeederHandlers.setup_handler(:start_cmds_handler, @commands_handler)
|
|
79
82
|
)
|
|
83
|
+
if requires_subscription_position_assignment?
|
|
84
|
+
@basic_runner.define_callback(
|
|
85
|
+
:before_runner_started, :before,
|
|
86
|
+
SubscriptionFeederHandlers.setup_handler(
|
|
87
|
+
:start_events_subscription_position_worker, @events_subscription_position_worker
|
|
88
|
+
)
|
|
89
|
+
)
|
|
90
|
+
end
|
|
80
91
|
|
|
81
92
|
@basic_runner.define_callback(
|
|
82
93
|
:after_runner_died, :before,
|
|
@@ -108,6 +119,14 @@ module PgEventstore
|
|
|
108
119
|
:after_runner_stopped, :before,
|
|
109
120
|
SubscriptionFeederHandlers.setup_handler(:stop_commands_handler, @commands_handler)
|
|
110
121
|
)
|
|
122
|
+
if requires_subscription_position_assignment?
|
|
123
|
+
@basic_runner.define_callback(
|
|
124
|
+
:after_runner_stopped, :before,
|
|
125
|
+
SubscriptionFeederHandlers.setup_handler(
|
|
126
|
+
:stop_events_subscription_position_worker, @events_subscription_position_worker
|
|
127
|
+
)
|
|
128
|
+
)
|
|
129
|
+
end
|
|
111
130
|
|
|
112
131
|
@basic_runner.define_callback(
|
|
113
132
|
:before_runner_restored, :after,
|
|
@@ -126,5 +145,10 @@ module PgEventstore
|
|
|
126
145
|
),
|
|
127
146
|
]
|
|
128
147
|
end
|
|
148
|
+
|
|
149
|
+
# @return [Boolean]
|
|
150
|
+
def requires_subscription_position_assignment?
|
|
151
|
+
Config::NodeRole.writable.include?(PgEventstore.config(@config_name).eventstore_role)
|
|
152
|
+
end
|
|
129
153
|
end
|
|
130
154
|
end
|
|
@@ -8,7 +8,7 @@ module PgEventstore
|
|
|
8
8
|
extend Forwardable
|
|
9
9
|
|
|
10
10
|
# @return [Integer] the number of measurements to keep
|
|
11
|
-
TIMINGS_TO_KEEP =
|
|
11
|
+
TIMINGS_TO_KEEP = 10
|
|
12
12
|
|
|
13
13
|
def_delegators :@lock, :synchronize
|
|
14
14
|
|
|
@@ -18,10 +18,12 @@ module PgEventstore
|
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
# Yields the given block to measure its execution time
|
|
21
|
+
# @param events_number [Integer] number of events processed by the given block
|
|
21
22
|
# @return [Object] the result of yielded block
|
|
22
|
-
def track_exec_time
|
|
23
|
+
def track_exec_time(events_number)
|
|
23
24
|
result = nil
|
|
24
25
|
time = Utils.benchmark { result = yield }
|
|
26
|
+
time /= events_number
|
|
25
27
|
synchronize do
|
|
26
28
|
@timings.shift if @timings.size == TIMINGS_TO_KEEP
|
|
27
29
|
@timings.push(time)
|
|
@@ -11,37 +11,43 @@ module PgEventstore
|
|
|
11
11
|
extend Forwardable
|
|
12
12
|
|
|
13
13
|
# @return [Integer]
|
|
14
|
-
|
|
14
|
+
DEFAULT_MAX_EVENTS_PER_CHUNK = 1_000
|
|
15
15
|
# @return [Integer]
|
|
16
16
|
MIN_EVENTS_PER_CHUNK = 10
|
|
17
17
|
# @return [Integer]
|
|
18
|
-
|
|
18
|
+
DEFAULT_INITIAL_EVENTS_PER_CHUNK = 10
|
|
19
19
|
|
|
20
20
|
# @!attribute subscription
|
|
21
21
|
# @return [PgEventstore::Subscription]
|
|
22
22
|
attr_reader :subscription
|
|
23
23
|
|
|
24
24
|
def_delegators :@events_processor, :start, :stop, :stop_async, :feed, :wait_for_finish, :restore, :state, :running?,
|
|
25
|
-
:
|
|
25
|
+
:clear_events_repository, :within_state
|
|
26
26
|
def_delegators :@subscription, :lock!, :id
|
|
27
27
|
|
|
28
28
|
# @param stats [PgEventstore::SubscriptionHandlerPerformance]
|
|
29
29
|
# @param events_processor [PgEventstore::EventsProcessor]
|
|
30
30
|
# @param subscription [PgEventstore::Subscription]
|
|
31
|
-
|
|
31
|
+
# @param max_events_per_chunk [Integer]
|
|
32
|
+
def initialize(stats:, events_processor:, subscription:,
|
|
33
|
+
initial_events_per_chunk: DEFAULT_INITIAL_EVENTS_PER_CHUNK,
|
|
34
|
+
max_events_per_chunk: DEFAULT_MAX_EVENTS_PER_CHUNK)
|
|
32
35
|
@stats = stats
|
|
33
36
|
@events_processor = events_processor
|
|
34
37
|
@subscription = subscription
|
|
38
|
+
@max_events_per_chunk = max_events_per_chunk
|
|
39
|
+
@initial_events_per_chunk = initial_events_per_chunk
|
|
35
40
|
|
|
36
41
|
attach_callbacks
|
|
37
42
|
end
|
|
38
43
|
|
|
39
44
|
# @return [Hash]
|
|
40
45
|
def next_chunk_query_opts
|
|
41
|
-
|
|
46
|
+
{
|
|
42
47
|
from_position: next_chunk_global_position,
|
|
43
|
-
max_count: estimate_events_number
|
|
44
|
-
|
|
48
|
+
max_count: estimate_events_number,
|
|
49
|
+
resolve_link_tos: @subscription.options[:resolve_link_tos] || false,
|
|
50
|
+
}
|
|
45
51
|
end
|
|
46
52
|
|
|
47
53
|
# @return [Boolean]
|
|
@@ -61,10 +67,10 @@ module PgEventstore
|
|
|
61
67
|
|
|
62
68
|
# @return [Integer]
|
|
63
69
|
def estimate_events_number
|
|
64
|
-
return
|
|
70
|
+
return @initial_events_per_chunk if @stats.average_event_processing_time == 0
|
|
65
71
|
|
|
66
72
|
events_per_chunk = (@subscription.chunk_query_interval / @stats.average_event_processing_time).round
|
|
67
|
-
events_to_fetch = [events_per_chunk,
|
|
73
|
+
events_to_fetch = [events_per_chunk, @max_events_per_chunk].min - @events_processor.events_left_in_repo
|
|
68
74
|
return 0 if events_to_fetch < 0 # We still have a lot of events in the chunk - no need to fetch more
|
|
69
75
|
|
|
70
76
|
[events_to_fetch, MIN_EVENTS_PER_CHUNK].max
|
|
@@ -91,6 +97,11 @@ module PgEventstore
|
|
|
91
97
|
SubscriptionRunnerHandlers.setup_handler(:update_subscription_chunk_stats, @subscription)
|
|
92
98
|
)
|
|
93
99
|
|
|
100
|
+
@events_processor.define_callback(
|
|
101
|
+
:checkpoint, :after,
|
|
102
|
+
SubscriptionRunnerHandlers.setup_handler(:checkpoint, @subscription)
|
|
103
|
+
)
|
|
104
|
+
|
|
94
105
|
@events_processor.define_callback(
|
|
95
106
|
:restart, :after,
|
|
96
107
|
SubscriptionRunnerHandlers.setup_handler(:update_subscription_restarts, @subscription)
|
|
@@ -16,7 +16,7 @@ module PgEventstore
|
|
|
16
16
|
# @return [void]
|
|
17
17
|
def exec_cmd(subscription_runner)
|
|
18
18
|
subscription_runner.within_state(:stopped) do
|
|
19
|
-
subscription_runner.
|
|
19
|
+
subscription_runner.clear_events_repository
|
|
20
20
|
subscription_runner.subscription.update(
|
|
21
21
|
last_chunk_greatest_position: nil, current_position: data['position'], total_processed_events: 0
|
|
22
22
|
)
|
|
@@ -15,15 +15,16 @@ module PgEventstore
|
|
|
15
15
|
runners = runners.select(&:running?).select(&:time_to_feed?)
|
|
16
16
|
return if runners.empty?
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
18
|
+
feed_strategies_collection = SubscriptionFeedStrategy::Collection.create(
|
|
19
|
+
runners,
|
|
20
|
+
connection,
|
|
21
|
+
QueryStrategy::Async.new(connection)
|
|
22
|
+
)
|
|
23
|
+
query_runner = AsyncRunner.new
|
|
24
|
+
feed_strategies_collection.each do |strategy|
|
|
25
|
+
query_runner.async { strategy.feed }
|
|
26
26
|
end
|
|
27
|
+
query_runner.run
|
|
27
28
|
end
|
|
28
29
|
|
|
29
30
|
private
|
|
@@ -32,15 +33,5 @@ module PgEventstore
|
|
|
32
33
|
def connection
|
|
33
34
|
PgEventstore.connection(@config_name)
|
|
34
35
|
end
|
|
35
|
-
|
|
36
|
-
# @return [PgEventstore::SubscriptionQueries]
|
|
37
|
-
def subscription_queries
|
|
38
|
-
SubscriptionQueries.new(connection)
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
# @return [PgEventstore::SubscriptionServiceQueries]
|
|
42
|
-
def subscription_service_queries
|
|
43
|
-
SubscriptionServiceQueries.new(connection)
|
|
44
|
-
end
|
|
45
36
|
end
|
|
46
37
|
end
|
|
@@ -56,18 +56,6 @@ module PgEventstore
|
|
|
56
56
|
@runners.map(&:subscription)
|
|
57
57
|
end
|
|
58
58
|
|
|
59
|
-
# Sets the force_lock flag to true. If set - all related Subscriptions will ignore their lock state and will be
|
|
60
|
-
# locked by the new SubscriptionsSet.
|
|
61
|
-
# @return [void]
|
|
62
|
-
def force_lock!
|
|
63
|
-
message = <<~TEXT
|
|
64
|
-
Usage of #force_lock! is deprecated and will be removed in v2. Please pass :force_lock keyword argument when \
|
|
65
|
-
initializing SubscriptionsManager. Example: PgEventstore.subscriptions_manager(force_lock: true)
|
|
66
|
-
TEXT
|
|
67
|
-
Utils.deprecation_warning(message)
|
|
68
|
-
@force_lock = true
|
|
69
|
-
end
|
|
70
|
-
|
|
71
59
|
# @return [Boolean]
|
|
72
60
|
def force_locked?
|
|
73
61
|
@force_lock
|
|
@@ -6,18 +6,22 @@ require_relative 'basic_runner'
|
|
|
6
6
|
require_relative 'runner_recovery_strategy'
|
|
7
7
|
require_relative 'runner_recovery_strategies'
|
|
8
8
|
require_relative 'subscription'
|
|
9
|
-
require_relative '
|
|
9
|
+
require_relative 'events_processor_consumer'
|
|
10
10
|
require_relative 'events_processor'
|
|
11
11
|
require_relative 'subscription_handler_performance'
|
|
12
12
|
require_relative 'subscription_runner'
|
|
13
13
|
require_relative 'subscriptions_set'
|
|
14
|
+
require_relative 'subscription_feed_strategy'
|
|
14
15
|
require_relative 'subscription_runners_feeder'
|
|
15
16
|
require_relative 'subscriptions_set_lifecycle'
|
|
16
17
|
require_relative 'subscriptions_lifecycle'
|
|
17
18
|
require_relative 'callback_handlers/subscription_feeder_handlers'
|
|
18
19
|
require_relative 'callback_handlers/subscription_runner_handlers'
|
|
19
20
|
require_relative 'callback_handlers/events_processor_handlers'
|
|
21
|
+
require_relative 'callback_handlers/events_subscription_position_worker_handlers'
|
|
20
22
|
require_relative 'callback_handlers/commands_handler_handlers'
|
|
23
|
+
require_relative 'commands_handler'
|
|
24
|
+
require_relative 'events_subscription_position_worker'
|
|
21
25
|
require_relative 'subscription_feeder'
|
|
22
26
|
require_relative 'extensions/command_class_lookup_extension'
|
|
23
27
|
require_relative 'extensions/base_command_extension'
|
|
@@ -25,10 +29,11 @@ require_relative 'subscription_feeder_commands'
|
|
|
25
29
|
require_relative 'subscription_runner_commands'
|
|
26
30
|
require_relative 'queries/subscription_command_queries'
|
|
27
31
|
require_relative 'queries/subscription_queries'
|
|
28
|
-
require_relative 'queries/
|
|
32
|
+
require_relative 'queries/event_subscription_position_queries'
|
|
29
33
|
require_relative 'queries/subscriptions_set_command_queries'
|
|
30
34
|
require_relative 'queries/subscriptions_set_queries'
|
|
31
|
-
require_relative '
|
|
35
|
+
require_relative 'replica_subscription_handler'
|
|
36
|
+
require_relative 'replica_subscription_runner'
|
|
32
37
|
|
|
33
38
|
module PgEventstore
|
|
34
39
|
# The public Subscriptions API, available to the user.
|
|
@@ -41,7 +46,6 @@ module PgEventstore
|
|
|
41
46
|
private :config
|
|
42
47
|
|
|
43
48
|
def_delegators :@subscription_feeder, :stop, :running?
|
|
44
|
-
def_delegators :@subscriptions_lifecycle, :force_lock!
|
|
45
49
|
|
|
46
50
|
# @param config [PgEventstore::Config]
|
|
47
51
|
# @param set_name [String]
|
|
@@ -71,8 +75,8 @@ module PgEventstore
|
|
|
71
75
|
|
|
72
76
|
# @param subscription_name [String] subscription's name
|
|
73
77
|
# @param handler [#call] subscription's handler
|
|
74
|
-
# @param options [Hash]
|
|
75
|
-
# @option options [Integer
|
|
78
|
+
# @param options [Hash] subscription options
|
|
79
|
+
# @option options [Integer] :from_position a starting subscription position
|
|
76
80
|
# @option options [Boolean] :resolve_link_tos When using projections to create new events you
|
|
77
81
|
# can set whether the generated events are pointers to existing events. Setting this option to true tells
|
|
78
82
|
# PgEventstore to return the original event instead a link event.
|
|
@@ -91,6 +95,7 @@ module PgEventstore
|
|
|
91
95
|
# notification about failed subscription.
|
|
92
96
|
# @param graceful_shutdown_timeout [integer, Float] the number of seconds to wait until force-shutdown the
|
|
93
97
|
# subscription during the stop process
|
|
98
|
+
# @param in_batches [Boolean] whether a batch of events should be yielded instead a single event
|
|
94
99
|
# @return [void]
|
|
95
100
|
def subscribe(subscription_name, handler:, options: {}, middlewares: nil,
|
|
96
101
|
pull_interval: config.subscription_pull_interval,
|
|
@@ -98,16 +103,18 @@ module PgEventstore
|
|
|
98
103
|
retries_interval: config.subscription_retries_interval,
|
|
99
104
|
restart_terminator: config.subscription_restart_terminator,
|
|
100
105
|
failed_subscription_notifier: config.failed_subscription_notifier,
|
|
101
|
-
graceful_shutdown_timeout: config.subscription_graceful_shutdown_timeout
|
|
106
|
+
graceful_shutdown_timeout: config.subscription_graceful_shutdown_timeout,
|
|
107
|
+
in_batches: false)
|
|
102
108
|
subscription = Subscription.using_connection(config.name).new(
|
|
103
109
|
set: @set_name, name: subscription_name, options:, chunk_query_interval: pull_interval,
|
|
104
110
|
max_restarts_number: max_retries, time_between_restarts: retries_interval
|
|
105
111
|
)
|
|
112
|
+
consumer_class = EventsProcessorConsumer.consumer_class(in_batches)
|
|
106
113
|
runner = SubscriptionRunner.new(
|
|
107
114
|
stats: SubscriptionHandlerPerformance.new,
|
|
108
115
|
events_processor: EventsProcessor.new(
|
|
109
|
-
create_raw_event_handler(middlewares, handler),
|
|
110
116
|
graceful_shutdown_timeout:,
|
|
117
|
+
consumer: consumer_class.create_consumer(handler, deserializer(middlewares)),
|
|
111
118
|
recovery_strategies: recovery_strategies(subscription, restart_terminator, failed_subscription_notifier)
|
|
112
119
|
),
|
|
113
120
|
subscription:
|
|
@@ -117,6 +124,63 @@ module PgEventstore
|
|
|
117
124
|
true
|
|
118
125
|
end
|
|
119
126
|
|
|
127
|
+
# @param subscription_name [String] subscription's name. For example, you can name it after the target database:
|
|
128
|
+
# "Target: my_eventstore_replica1"
|
|
129
|
+
# @param replica_config_name [Symbol] the destination replica database config to replicate events into. You have to
|
|
130
|
+
# have it preconfigured with PgEventstore.configure(). Example:
|
|
131
|
+
# PgEventstore.configure(name: :my_eventstore_replica1) do |config|
|
|
132
|
+
# config.pg_uri = 'postgresql://postgres:postgres@localhost:5432/my_eventstore_replica1'
|
|
133
|
+
# end
|
|
134
|
+
# Refer to the docs/configuration.md for more info
|
|
135
|
+
# @param options [Hash] subscription options
|
|
136
|
+
# @option options [Integer] :from_position a starting subscription position
|
|
137
|
+
# @option options [Hash] :filter provide it to filter events. It works the same way as a :filter option of
|
|
138
|
+
# {PgEventstore::Client#read} method. Use this option when you want to replicate certain set of events.
|
|
139
|
+
# @param max_events_to_replicate [Integer] set the upper limit of how many events the handler can copy per turn
|
|
140
|
+
# @param pull_interval [Integer, Float] an interval in seconds to determine how often to query new events of the
|
|
141
|
+
# given subscription.
|
|
142
|
+
# @param max_retries [Integer] max number of retries of failed Subscription
|
|
143
|
+
# @param retries_interval [Integer, Float] a delay between retries of failed Subscription
|
|
144
|
+
# @param restart_terminator [#call, nil] a callable object which is invoked with PgEventstore::Subscription instance
|
|
145
|
+
# to determine whether restarts should be stopped(true - stops restarts, false - continues restarts)
|
|
146
|
+
# @param failed_subscription_notifier [#call, nil] a callable object which is invoked with
|
|
147
|
+
# PgEventstore::Subscription instance and error instance after the related subscription died due to error and no
|
|
148
|
+
# longer can be automatically restarted due to max retries number reached. You can use this hook to send a
|
|
149
|
+
# notification about failed subscription.
|
|
150
|
+
# @param graceful_shutdown_timeout [Integer, Float] the number of seconds to wait until force-shutdown the
|
|
151
|
+
# subscription during the stop process
|
|
152
|
+
# @return [void]
|
|
153
|
+
def create_replication(subscription_name,
|
|
154
|
+
replica_config_name,
|
|
155
|
+
options: {},
|
|
156
|
+
max_events_to_replicate: config.max_events_to_replicate,
|
|
157
|
+
pull_interval: config.subscription_pull_interval,
|
|
158
|
+
max_retries: config.subscription_max_retries,
|
|
159
|
+
retries_interval: config.subscription_retries_interval,
|
|
160
|
+
restart_terminator: config.subscription_restart_terminator,
|
|
161
|
+
failed_subscription_notifier: config.failed_subscription_notifier,
|
|
162
|
+
graceful_shutdown_timeout: config.subscription_graceful_shutdown_timeout)
|
|
163
|
+
Utils.assert_node_role!(config, [Config::NodeRole::PRIMARY])
|
|
164
|
+
subscription = Subscription.using_connection(config.name).new(
|
|
165
|
+
set: @set_name, name: subscription_name, options:, chunk_query_interval: pull_interval,
|
|
166
|
+
max_restarts_number: max_retries, time_between_restarts: retries_interval
|
|
167
|
+
)
|
|
168
|
+
runner = ReplicaSubscriptionRunner.new(
|
|
169
|
+
stats: SubscriptionHandlerPerformance.new,
|
|
170
|
+
events_processor: EventsProcessor.new(
|
|
171
|
+
graceful_shutdown_timeout:,
|
|
172
|
+
consumer: EventsProcessorConsumer::Replica.create_consumer(config_name, replica_config_name),
|
|
173
|
+
recovery_strategies: recovery_strategies(subscription, restart_terminator, failed_subscription_notifier)
|
|
174
|
+
),
|
|
175
|
+
subscription:,
|
|
176
|
+
max_events_per_chunk: max_events_to_replicate,
|
|
177
|
+
initial_events_per_chunk: max_events_to_replicate
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
@subscriptions_lifecycle.runners.push(runner)
|
|
181
|
+
true
|
|
182
|
+
end
|
|
183
|
+
|
|
120
184
|
# @return [Array<PgEventstore::Subscription>]
|
|
121
185
|
def subscriptions
|
|
122
186
|
@subscriptions_lifecycle.subscriptions.map(&:dup)
|
|
@@ -157,12 +221,8 @@ module PgEventstore
|
|
|
157
221
|
PgEventstore::CLI.callbacks.run_callbacks(:start_manager, self, &)
|
|
158
222
|
end
|
|
159
223
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
# @return [Proc]
|
|
163
|
-
def create_raw_event_handler(middlewares, handler)
|
|
164
|
-
deserializer = EventDeserializer.new(select_middlewares(middlewares), config.event_class_resolver)
|
|
165
|
-
->(raw_event) { handler.call(deserializer.deserialize(raw_event)) }
|
|
224
|
+
def deserializer(middlewares)
|
|
225
|
+
EventDeserializer.new(select_middlewares(middlewares), config.event_class_resolver)
|
|
166
226
|
end
|
|
167
227
|
|
|
168
228
|
# @param middlewares [Array, nil]
|
|
@@ -13,6 +13,9 @@ module PgEventstore
|
|
|
13
13
|
alias old_clear clear
|
|
14
14
|
alias old_size size
|
|
15
15
|
alias old_empty? empty?
|
|
16
|
+
alias old_slice slice
|
|
17
|
+
alias old_slice! slice!
|
|
18
|
+
alias old_at at
|
|
16
19
|
|
|
17
20
|
def shift(...)
|
|
18
21
|
synchronize { old_shift(...) }
|
|
@@ -37,5 +40,17 @@ module PgEventstore
|
|
|
37
40
|
def empty?(...)
|
|
38
41
|
synchronize { old_empty?(...) }
|
|
39
42
|
end
|
|
43
|
+
|
|
44
|
+
def slice(...)
|
|
45
|
+
synchronize { old_slice(...) }
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def slice!(...)
|
|
49
|
+
synchronize { old_slice!(...) }
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def at(...)
|
|
53
|
+
synchronize { old_at(...) }
|
|
54
|
+
end
|
|
40
55
|
end
|
|
41
56
|
end
|
|
@@ -46,7 +46,7 @@ namespace :pg_eventstore do
|
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
task :migrate do
|
|
49
|
-
migration_files_root =
|
|
49
|
+
migration_files_root = File.join(Gem.loaded_specs.fetch('pg_eventstore').gem_dir, 'db/migrations')
|
|
50
50
|
|
|
51
51
|
PgEventstore.connection(:_eventstore_db_connection).with do |conn|
|
|
52
52
|
conn.exec('CREATE TABLE IF NOT EXISTS migrations (number int NOT NULL)')
|
|
@@ -59,7 +59,7 @@ namespace :pg_eventstore do
|
|
|
59
59
|
next if latest_migration >= number
|
|
60
60
|
|
|
61
61
|
if File.extname(f_name) == '.rb'
|
|
62
|
-
load
|
|
62
|
+
load(f_name, true)
|
|
63
63
|
else
|
|
64
64
|
conn.exec(File.read(f_name))
|
|
65
65
|
end
|
data/lib/pg_eventstore/utils.rb
CHANGED
|
@@ -132,6 +132,37 @@ module PgEventstore
|
|
|
132
132
|
yield
|
|
133
133
|
Process.clock_gettime(Process::CLOCK_MONOTONIC) - start_time
|
|
134
134
|
end
|
|
135
|
+
|
|
136
|
+
# @param truthy [boolish]
|
|
137
|
+
# @param message [String, nil]
|
|
138
|
+
# @raise ArgumentError
|
|
139
|
+
def assert!(truthy, message = nil)
|
|
140
|
+
raise ArgumentError, message unless truthy
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# @param obj
|
|
144
|
+
# @raise NotImplementedError
|
|
145
|
+
def missing_implementation!(obj)
|
|
146
|
+
raise NotImplementedError, obj.inspect
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# @param config [PgEventstore::Config]
|
|
150
|
+
# @param expected_roles [Array<Symbol>]
|
|
151
|
+
# @return [void]
|
|
152
|
+
def assert_node_role!(config, expected_roles)
|
|
153
|
+
return if expected_roles.include?(config.eventstore_role)
|
|
154
|
+
|
|
155
|
+
raise "You can't perform this operation on #{config.eventstore_role.inspect} node!"
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
# Takes a collection of partition ids, the number of partitions per call and determines the position in the
|
|
159
|
+
# partition_ids at which we have max_partitions_to_resolve_per_call unique partitions
|
|
160
|
+
# @param partition_ids [Array<Integer>]
|
|
161
|
+
# @param max_partitions_to_resolve_per_call [Integer]
|
|
162
|
+
# @return [Range]
|
|
163
|
+
def range_to_slice(partition_ids, max_partitions_to_resolve_per_call)
|
|
164
|
+
# This is stub, used for indexing
|
|
165
|
+
end
|
|
135
166
|
end
|
|
136
167
|
end
|
|
137
168
|
end
|