pg_eventstore 1.13.4 → 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 +11 -2
- data/CHANGELOG.md +195 -16
- data/README.md +33 -10
- data/db/migrations/10_setup_pg_cron.rb +1 -0
- data/db/migrations/11_add_events_link_global_position.sql +1 -0
- data/db/migrations/12_migrate_legacy_links.rb +83 -0
- data/db/migrations/13_remove_events_link_id.sql +6 -0
- data/db/migrations/14_remove_ids_events_id_index.sql +1 -0
- 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/db/migrations/9_create_events_horizon.sql +21 -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 +30 -6
- 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/callbacks.rb +7 -5
- 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/cli/try_to_delete_subscriptions_set.rb +2 -2
- data/lib/pg_eventstore/client.rb +167 -52
- 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 +11 -6
- data/lib/pg_eventstore/commands/event_modifiers/prepare_regular_event.rb +12 -7
- data/lib/pg_eventstore/commands/link_to.rb +9 -9
- data/lib/pg_eventstore/commands/multiple.rb +2 -2
- 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 +22 -37
- data/lib/pg_eventstore/errors.rb +137 -11
- data/lib/pg_eventstore/event.rb +39 -7
- 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 +42 -13
- 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 +9 -95
- 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 +10 -7
- data/lib/pg_eventstore/queries/maintenance_queries.rb +159 -42
- data/lib/pg_eventstore/queries/partition_queries.rb +46 -104
- 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 +58 -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 +14 -17
- data/lib/pg_eventstore/stream_global_index.rb +28 -0
- data/lib/pg_eventstore/subscriptions/basic_runner.rb +4 -4
- 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 +13 -1
- data/lib/pg_eventstore/subscriptions/callback_handlers/subscription_runner_handlers.rb +19 -14
- data/lib/pg_eventstore/subscriptions/events_processor.rb +21 -19
- 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_command_queries.rb +5 -5
- data/lib/pg_eventstore/subscriptions/queries/subscription_queries.rb +80 -56
- data/lib/pg_eventstore/subscriptions/queries/subscriptions_set_command_queries.rb +2 -2
- data/lib/pg_eventstore/subscriptions/queries/subscriptions_set_queries.rb +1 -1
- 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 +9 -7
- 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 +26 -2
- data/lib/pg_eventstore/subscriptions/subscription_handler_performance.rb +5 -5
- data/lib/pg_eventstore/subscriptions/subscription_runner.rb +20 -22
- data/lib/pg_eventstore/subscriptions/subscription_runner_commands/reset_position.rb +1 -1
- data/lib/pg_eventstore/subscriptions/subscription_runners_feeder.rb +10 -11
- data/lib/pg_eventstore/subscriptions/subscriptions_lifecycle.rb +0 -12
- data/lib/pg_eventstore/subscriptions/subscriptions_manager.rb +84 -29
- data/lib/pg_eventstore/{subscriptions/synchronized_array.rb → synchronized_array.rb} +15 -0
- data/lib/pg_eventstore/tasks/setup.rake +32 -33
- data/lib/pg_eventstore/utils.rb +39 -0
- data/lib/pg_eventstore/version.rb +1 -1
- data/lib/pg_eventstore/web/application.rb +104 -20
- 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 +19 -12
- 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/helpers.rb +2 -2
- 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 +26 -63
- 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 +41 -43
- 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/multiple.rbs +1 -1
- 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 +20 -6
- 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/extensions/options_extension.rbs +9 -1
- 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 +6 -38
- 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 +7 -11
- 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 +4 -2
- 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 +16 -8
- 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 +18 -50
- 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 -5
- data/sig/pg_eventstore/subscriptions/subscription_runners_feeder.rbs +5 -5
- 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 +18 -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 +181 -21
- 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/service_queries.rb +0 -73
- data/lib/pg_eventstore/subscriptions/subscription_position_evaluation.rb +0 -195
- 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/service_queries.rbs +0 -15
- data/sig/pg_eventstore/subscriptions/subscription_position_evaluation.rbs +0 -53
- data/sig/pg_eventstore/subscriptions/synchronized_array.rbs +0 -4
- /data/sig/interfaces/{_raw_event_handler.rbs → raw_event_handler.rbs} +0 -0
|
@@ -8,36 +8,6 @@ require_relative 'pg_connection'
|
|
|
8
8
|
|
|
9
9
|
module PgEventstore
|
|
10
10
|
class Connection
|
|
11
|
-
# Starting from ruby v3.1 ConnectionPool closes connections after forking by default. For ruby v3 we need this patch
|
|
12
|
-
# to correctly reload the ConnectionPool. Otherwise the same connection will leak into another process which will
|
|
13
|
-
# result in disaster.
|
|
14
|
-
# @!visibility private
|
|
15
|
-
module Ruby30Patch
|
|
16
|
-
def initialize(**)
|
|
17
|
-
@current_pid = Process.pid
|
|
18
|
-
@mutext = Mutex.new
|
|
19
|
-
super
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def with(&blk)
|
|
23
|
-
reload_after_fork
|
|
24
|
-
super
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
private
|
|
28
|
-
|
|
29
|
-
def reload_after_fork
|
|
30
|
-
return if @current_pid == Process.pid
|
|
31
|
-
|
|
32
|
-
@mutext.synchronize do
|
|
33
|
-
return if @current_pid == Process.pid
|
|
34
|
-
|
|
35
|
-
@pool.reload(&:close)
|
|
36
|
-
@current_pid = Process.pid
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
|
|
41
11
|
# @!attribute uri
|
|
42
12
|
# @return [String]
|
|
43
13
|
attr_reader :uri
|
|
@@ -61,17 +31,22 @@ module PgEventstore
|
|
|
61
31
|
end
|
|
62
32
|
|
|
63
33
|
# A shorthand from ConnectionPool#with.
|
|
64
|
-
# @yieldparam connection [
|
|
34
|
+
# @yieldparam connection [PgEventstore::PgConnection] PostgreSQL connection instance
|
|
65
35
|
# @return [Object] a value of a given block
|
|
66
|
-
def with(&
|
|
36
|
+
def with(&)
|
|
67
37
|
should_retry = true
|
|
68
38
|
@pool.with do |conn|
|
|
69
39
|
yield conn
|
|
70
40
|
rescue PG::ConnectionBad, PG::UnableToSend
|
|
41
|
+
unless should_retry
|
|
42
|
+
# Connection is broken. We should throw it away
|
|
43
|
+
@pool.discard_current_connection
|
|
44
|
+
raise
|
|
45
|
+
end
|
|
46
|
+
|
|
71
47
|
# Recover a connection after fork or when we lost a connection to PostgreSQL. We retry only once and without any
|
|
72
48
|
# delay.
|
|
73
49
|
conn.sync_reset
|
|
74
|
-
raise unless should_retry
|
|
75
50
|
|
|
76
51
|
should_retry = false
|
|
77
52
|
retry
|
|
@@ -83,6 +58,20 @@ module PgEventstore
|
|
|
83
58
|
@pool.shutdown(&:close)
|
|
84
59
|
end
|
|
85
60
|
|
|
61
|
+
# Restore connection after shutdown by re-initializing connection pool
|
|
62
|
+
# @return [void]
|
|
63
|
+
def establish_connection
|
|
64
|
+
@pool = nil
|
|
65
|
+
init_pool
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# @return [void]
|
|
69
|
+
def discard_current_connection
|
|
70
|
+
@pool.discard_current_connection do |conn|
|
|
71
|
+
conn.close unless conn.finished?
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
86
75
|
private
|
|
87
76
|
|
|
88
77
|
# @return [ConnectionPool]
|
|
@@ -107,7 +96,3 @@ module PgEventstore
|
|
|
107
96
|
end
|
|
108
97
|
end
|
|
109
98
|
end
|
|
110
|
-
|
|
111
|
-
if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('3.1')
|
|
112
|
-
PgEventstore::Connection.prepend(PgEventstore::Connection::Ruby30Patch)
|
|
113
|
-
end
|
data/lib/pg_eventstore/errors.rb
CHANGED
|
@@ -55,14 +55,19 @@ module PgEventstore
|
|
|
55
55
|
# @!attribute expected_revision
|
|
56
56
|
# @return [Integer, Symbol]
|
|
57
57
|
attr_reader :expected_revision
|
|
58
|
+
# @!attribute verdict
|
|
59
|
+
# @return [Symbol]
|
|
60
|
+
attr_reader :verdict
|
|
58
61
|
|
|
59
62
|
# @param revision [Integer]
|
|
60
63
|
# @param expected_revision [Integer, Symbol]
|
|
61
64
|
# @param stream [PgEventstore::Stream]
|
|
62
|
-
|
|
65
|
+
# @param verdict [Symbol]
|
|
66
|
+
def initialize(revision:, expected_revision:, stream:, verdict:)
|
|
63
67
|
@revision = revision
|
|
64
68
|
@expected_revision = expected_revision
|
|
65
69
|
@stream = stream
|
|
70
|
+
@verdict = verdict
|
|
66
71
|
super(user_friendly_message)
|
|
67
72
|
end
|
|
68
73
|
|
|
@@ -70,13 +75,18 @@ module PgEventstore
|
|
|
70
75
|
|
|
71
76
|
# @return [String]
|
|
72
77
|
def user_friendly_message
|
|
73
|
-
|
|
74
|
-
|
|
78
|
+
case verdict
|
|
79
|
+
when :expected_to_have_stream_with_given_revision
|
|
80
|
+
current_no_stream
|
|
81
|
+
when :unmatched_stream_revision
|
|
82
|
+
unmatched_stream_revision
|
|
83
|
+
when :expected_to_have_stream
|
|
84
|
+
expected_stream_exists
|
|
85
|
+
when :expected_not_to_have_stream
|
|
86
|
+
expected_no_stream
|
|
87
|
+
else
|
|
88
|
+
Utils.missing_implementation!(verdict)
|
|
75
89
|
end
|
|
76
|
-
return expected_no_stream if revision > Stream::NON_EXISTING_STREAM_REVISION && expected_revision == :no_stream
|
|
77
|
-
return current_no_stream if revision == Stream::NON_EXISTING_STREAM_REVISION && expected_revision.is_a?(Integer)
|
|
78
|
-
|
|
79
|
-
unmatched_stream_revision
|
|
80
90
|
end
|
|
81
91
|
|
|
82
92
|
# @return [String]
|
|
@@ -108,16 +118,129 @@ module PgEventstore
|
|
|
108
118
|
end
|
|
109
119
|
end
|
|
110
120
|
|
|
121
|
+
class WrongExpectedTypesRevisionError < Error
|
|
122
|
+
class Verdict
|
|
123
|
+
include Extensions::OptionsExtension
|
|
124
|
+
include Extensions::OptionsDefaults
|
|
125
|
+
|
|
126
|
+
# @!attribute verdict
|
|
127
|
+
# @return [Symbol]
|
|
128
|
+
attribute(:verdict)
|
|
129
|
+
# @!attribute event_type
|
|
130
|
+
# @return [String, Symbol]
|
|
131
|
+
attribute(:event_type)
|
|
132
|
+
# @!attribute current_revision
|
|
133
|
+
# @return [Integer]
|
|
134
|
+
attribute(:current_revision)
|
|
135
|
+
# @!attribute expected_revision
|
|
136
|
+
# @return [Integer, Symbol]
|
|
137
|
+
attribute(:expected_revision)
|
|
138
|
+
# @!attribute expected_markers
|
|
139
|
+
# @return [Array<String>, nil]
|
|
140
|
+
attribute(:expected_markers)
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# @!attribute stream
|
|
144
|
+
# @return [PgEventstore::Stream]
|
|
145
|
+
attr_reader :stream
|
|
146
|
+
# @!attribute verdicts
|
|
147
|
+
# @return [Array<PgEventstore::WrongExpectedTypesRevisionError::Verdict>]
|
|
148
|
+
attr_reader :verdicts
|
|
149
|
+
|
|
150
|
+
# @param stream [PgEventstore::Stream]
|
|
151
|
+
# @param verdicts [Array<PgEventstore::WrongExpectedTypesRevisionError::Verdict>]
|
|
152
|
+
def initialize(stream:, verdicts:)
|
|
153
|
+
@stream = stream
|
|
154
|
+
@verdicts = verdicts
|
|
155
|
+
super(user_friendly_message)
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
private
|
|
159
|
+
|
|
160
|
+
# @return [String]
|
|
161
|
+
def user_friendly_message
|
|
162
|
+
messages =
|
|
163
|
+
verdicts.map do |verdict|
|
|
164
|
+
case verdict.verdict
|
|
165
|
+
when :event_is_absent
|
|
166
|
+
event_is_absent(verdict)
|
|
167
|
+
when :event_revision_does_not_match
|
|
168
|
+
event_revision_does_not_match(verdict)
|
|
169
|
+
when :event_is_present
|
|
170
|
+
event_is_present(verdict)
|
|
171
|
+
else
|
|
172
|
+
Utils.missing_implementation!(verdict.verdict)
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
messages.join('; ')
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
# @param verdict [PgEventstore::WrongExpectedTypesRevisionError::Verdict]
|
|
179
|
+
# @return [String]
|
|
180
|
+
def event_is_absent(verdict)
|
|
181
|
+
<<~TEXT.strip
|
|
182
|
+
Expected #{stream_descr} stream to contain #{event_descr(verdict)} with #{revision_descr(verdict)}, \
|
|
183
|
+
but this event does not exist.
|
|
184
|
+
TEXT
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
# @param verdict [PgEventstore::WrongExpectedTypesRevisionError::Verdict]
|
|
188
|
+
# @return [String]
|
|
189
|
+
def event_is_present(verdict)
|
|
190
|
+
"Expected #{stream_descr} stream not to contain #{event_descr(verdict)}, but it actually exists."
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# @param verdict [PgEventstore::WrongExpectedTypesRevisionError::Verdict]
|
|
194
|
+
# @return [String]
|
|
195
|
+
def event_revision_does_not_match(verdict)
|
|
196
|
+
<<~TEXT.strip
|
|
197
|
+
Expected #{stream_descr} stream to contain #{event_descr(verdict)} with #{revision_descr(verdict)}, \
|
|
198
|
+
but it actually has #{verdict.current_revision} revision.
|
|
199
|
+
TEXT
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
# @return [String]
|
|
203
|
+
def stream_descr
|
|
204
|
+
stream.to_hash.inspect
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
# @param verdict [PgEventstore::WrongExpectedTypesRevisionError::Verdict]
|
|
208
|
+
# @return [String]
|
|
209
|
+
def event_descr(verdict)
|
|
210
|
+
if verdict.event_type == :any
|
|
211
|
+
markers = verdict.expected_markers.map(&:inspect).join(', ')
|
|
212
|
+
"any event with some of #{markers} marker(s)"
|
|
213
|
+
elsif verdict.expected_markers
|
|
214
|
+
markers = verdict.expected_markers.map(&:inspect).join(', ')
|
|
215
|
+
"#{verdict.event_type.inspect} event with some of #{markers} marker(s)"
|
|
216
|
+
else
|
|
217
|
+
"#{verdict.event_type.inspect} event"
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
# @param verdict [PgEventstore::WrongExpectedTypesRevisionError::Verdict]
|
|
222
|
+
# @return [String]
|
|
223
|
+
def revision_descr(verdict)
|
|
224
|
+
if verdict.expected_revision.is_a?(Integer)
|
|
225
|
+
"#{verdict.expected_revision} revision"
|
|
226
|
+
elsif verdict.expected_revision == :event_exists
|
|
227
|
+
'some revision'
|
|
228
|
+
else
|
|
229
|
+
"#{verdict.expected_revision.inspect} revision"
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
|
|
111
234
|
class RecordNotFound < Error
|
|
112
235
|
# @!attribute table_name
|
|
113
236
|
# @return [String]
|
|
114
237
|
attr_reader :table_name
|
|
115
238
|
# @!attribute id
|
|
116
|
-
# @return [
|
|
239
|
+
# @return [Object]
|
|
117
240
|
attr_reader :id
|
|
118
241
|
|
|
119
242
|
# @param table_name [String]
|
|
120
|
-
# @param id [
|
|
243
|
+
# @param id [Object]
|
|
121
244
|
def initialize(table_name, id)
|
|
122
245
|
@table_name = table_name
|
|
123
246
|
@id = id
|
|
@@ -126,7 +249,7 @@ module PgEventstore
|
|
|
126
249
|
|
|
127
250
|
# @return [String]
|
|
128
251
|
def user_friendly_message
|
|
129
|
-
"Could not find/update #{table_name.inspect} record
|
|
252
|
+
"Could not find/update/delete #{table_name.inspect} record by #{@id.inspect}."
|
|
130
253
|
end
|
|
131
254
|
end
|
|
132
255
|
|
|
@@ -203,7 +326,7 @@ module PgEventstore
|
|
|
203
326
|
|
|
204
327
|
# @return [String]
|
|
205
328
|
def user_friendly_message
|
|
206
|
-
"Event
|
|
329
|
+
"Event #{event.inspect} is not persisted a persisted event."
|
|
207
330
|
end
|
|
208
331
|
end
|
|
209
332
|
|
|
@@ -255,4 +378,7 @@ module PgEventstore
|
|
|
255
378
|
super()
|
|
256
379
|
end
|
|
257
380
|
end
|
|
381
|
+
|
|
382
|
+
class NotSupportedError < Error
|
|
383
|
+
end
|
|
258
384
|
end
|
data/lib/pg_eventstore/event.rb
CHANGED
|
@@ -7,11 +7,17 @@ module PgEventstore
|
|
|
7
7
|
# @return [String] a type of link event
|
|
8
8
|
LINK_TYPE = '$>'
|
|
9
9
|
# @return [String]
|
|
10
|
+
SYSTEM_SYMBOL = "\u2592"
|
|
11
|
+
# @return [String]
|
|
12
|
+
MARKERS_METADATA_KEY = "#{SYSTEM_SYMBOL}m".freeze
|
|
13
|
+
# @return [String]
|
|
10
14
|
PRIMARY_TABLE_NAME = 'events'
|
|
15
|
+
# @return [Integer]
|
|
16
|
+
NON_EXISTING_EVENT_REVISION = -1
|
|
11
17
|
|
|
12
18
|
# @!attribute id
|
|
13
|
-
# @return [String]
|
|
14
|
-
attribute(:id)
|
|
19
|
+
# @return [String] UUIDv7
|
|
20
|
+
attribute(:id) { SecureRandom.uuid_v7 }
|
|
15
21
|
# @!attribute type
|
|
16
22
|
# @return [String] event type
|
|
17
23
|
attribute(:type) { self.class.name }
|
|
@@ -27,13 +33,19 @@ module PgEventstore
|
|
|
27
33
|
# @!attribute data
|
|
28
34
|
# @return [Hash] event's data
|
|
29
35
|
attribute(:data) { {} }
|
|
36
|
+
# @!attribute markers
|
|
37
|
+
# @return [Array<String>] event markers
|
|
38
|
+
attribute(:markers) { [] }
|
|
39
|
+
# @!attribute feature_markers
|
|
40
|
+
# @return [Array<FeatureMarker>] feature-specific markers that can't be put under #markers
|
|
41
|
+
attribute(:feature_markers) { [] }
|
|
30
42
|
# @!attribute metadata
|
|
31
43
|
# @return [Hash] event's metadata
|
|
32
44
|
attribute(:metadata) { {} }
|
|
33
|
-
# @!attribute
|
|
34
|
-
# @return [
|
|
35
|
-
# event is a link
|
|
36
|
-
attribute(:
|
|
45
|
+
# @!attribute link_global_position
|
|
46
|
+
# @return [Integer, nil] global_position of an event the current event points to. If it is not nil, then the
|
|
47
|
+
# current event is a link
|
|
48
|
+
attribute(:link_global_position)
|
|
37
49
|
# @!attribute link_partition_id
|
|
38
50
|
# @return [Integer, nil] a partition id of an event the link event points to. It is used to load original event
|
|
39
51
|
# when resolve_link_tos: true option is provided when reading events.
|
|
@@ -45,6 +57,15 @@ module PgEventstore
|
|
|
45
57
|
# @!attribute created_at
|
|
46
58
|
# @return [Time, nil] a timestamp an event was created at
|
|
47
59
|
attribute(:created_at)
|
|
60
|
+
# @!attribute caused_by
|
|
61
|
+
# @return [PgEventstore::Event, nil]
|
|
62
|
+
attribute(:caused_by)
|
|
63
|
+
# @!attribute correlation_id
|
|
64
|
+
# @return [String, nil] UUIDv7
|
|
65
|
+
attribute(:correlation_id)
|
|
66
|
+
# @!attribute causation_id
|
|
67
|
+
# @return [String, nil] UUIDv7
|
|
68
|
+
attribute(:causation_id)
|
|
48
69
|
|
|
49
70
|
# Implements comparison of `PgEventstore::Event`-s. Two events matches if all of their attributes matches
|
|
50
71
|
# @param other [Object, PgEventstore::Event]
|
|
@@ -54,11 +75,17 @@ module PgEventstore
|
|
|
54
75
|
|
|
55
76
|
attributes_hash.except(:link) == other.attributes_hash.except(:link)
|
|
56
77
|
end
|
|
78
|
+
alias eql? ==
|
|
57
79
|
|
|
58
80
|
# Detect whether an event is a link event
|
|
59
81
|
# @return [Boolean]
|
|
60
82
|
def link?
|
|
61
|
-
!
|
|
83
|
+
!link_global_position.nil?
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# @return [Integer]
|
|
87
|
+
def hash
|
|
88
|
+
attributes_hash.except(:link).hash
|
|
62
89
|
end
|
|
63
90
|
|
|
64
91
|
# Detect whether an event is a system event
|
|
@@ -66,5 +93,10 @@ module PgEventstore
|
|
|
66
93
|
def system?
|
|
67
94
|
type.start_with?('$')
|
|
68
95
|
end
|
|
96
|
+
|
|
97
|
+
# @return [self]
|
|
98
|
+
def dup
|
|
99
|
+
self.class.new(**Utils.deep_dup(options_hash))
|
|
100
|
+
end
|
|
69
101
|
end
|
|
70
102
|
end
|
|
@@ -4,20 +4,20 @@ module PgEventstore
|
|
|
4
4
|
# @!visibility private
|
|
5
5
|
class EventDeserializer
|
|
6
6
|
# @!attribute middlewares
|
|
7
|
-
# @return [Array
|
|
7
|
+
# @return [Array<Middleware>]
|
|
8
8
|
attr_reader :middlewares
|
|
9
9
|
# @!attribute event_class_resolver
|
|
10
10
|
# @return [#call]
|
|
11
11
|
attr_reader :event_class_resolver
|
|
12
12
|
|
|
13
|
-
# @param middlewares [Array<
|
|
13
|
+
# @param middlewares [Array<Middleware>]
|
|
14
14
|
# @param event_class_resolver [#call]
|
|
15
15
|
def initialize(middlewares, event_class_resolver)
|
|
16
16
|
@middlewares = middlewares
|
|
17
17
|
@event_class_resolver = event_class_resolver
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
-
# @param raw_events [Array<Hash>]
|
|
20
|
+
# @param raw_events [Array<Hash>, Enumerator<Hash>]
|
|
21
21
|
# @return [Array<PgEventstore::Event>]
|
|
22
22
|
def deserialize_many(raw_events)
|
|
23
23
|
raw_events.map(&method(:deserialize))
|
|
@@ -33,7 +33,8 @@ module PgEventstore
|
|
|
33
33
|
event.stream = PgEventstore::Stream.new(
|
|
34
34
|
**attrs.slice('context', 'stream_name', 'stream_id').transform_keys(&:to_sym)
|
|
35
35
|
)
|
|
36
|
-
event.link =
|
|
36
|
+
event.link = deserialize(attrs['link']) if attrs.key?('link')
|
|
37
|
+
event.markers = event.metadata[Event::MARKERS_METADATA_KEY] || []
|
|
37
38
|
event
|
|
38
39
|
end
|
|
39
40
|
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PgEventstore
|
|
4
|
+
# @!visibility private
|
|
5
|
+
class EventGlobalIndex
|
|
6
|
+
include Extensions::OptionsExtension
|
|
7
|
+
include Extensions::OptionsDefaults
|
|
8
|
+
|
|
9
|
+
# @!attribute global_position
|
|
10
|
+
# @return [Integer]
|
|
11
|
+
attribute(:global_position)
|
|
12
|
+
# @!attribute stream_revision
|
|
13
|
+
# @return [Integer]
|
|
14
|
+
attribute(:stream_revision)
|
|
15
|
+
# @!attribute context_partition_id
|
|
16
|
+
# @return [Integer]
|
|
17
|
+
attribute(:context_partition_id)
|
|
18
|
+
# @!attribute stream_name_partition_id
|
|
19
|
+
# @return [Integer]
|
|
20
|
+
attribute(:stream_name_partition_id)
|
|
21
|
+
# @!attribute event_type_partition_id
|
|
22
|
+
# @return [Integer]
|
|
23
|
+
attribute(:event_type_partition_id)
|
|
24
|
+
# @!attribute streams_global_index_id
|
|
25
|
+
# @return [Integer]
|
|
26
|
+
attribute(:streams_global_index_id)
|
|
27
|
+
|
|
28
|
+
# EventGlobalIndex representation that is used in subscriptions
|
|
29
|
+
class SubscriptionRepr
|
|
30
|
+
include Extensions::OptionsExtension
|
|
31
|
+
include Extensions::OptionsDefaults
|
|
32
|
+
|
|
33
|
+
# @!attribute global_position
|
|
34
|
+
# @return [Integer]
|
|
35
|
+
attribute(:global_position)
|
|
36
|
+
# @!attribute subscription_position
|
|
37
|
+
# @return [Integer]
|
|
38
|
+
attribute(:subscription_position)
|
|
39
|
+
# @!attribute event_type_partition_id
|
|
40
|
+
# @return [Integer]
|
|
41
|
+
attribute(:event_type_partition_id)
|
|
42
|
+
|
|
43
|
+
# @return [Hash]
|
|
44
|
+
def to_subscription_position_attrs
|
|
45
|
+
{ global_position:, subscription_position: }
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# EventGlobalIndex representation that is used in Read API
|
|
50
|
+
class ReadApiRepr
|
|
51
|
+
include Extensions::OptionsExtension
|
|
52
|
+
include Extensions::OptionsDefaults
|
|
53
|
+
|
|
54
|
+
# @!attribute global_position
|
|
55
|
+
# @return [Integer]
|
|
56
|
+
attribute(:global_position)
|
|
57
|
+
# @!attribute event_type_partition_id
|
|
58
|
+
# @return [Integer]
|
|
59
|
+
attribute(:event_type_partition_id)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# EventGlobalIndex representation that is used in Write API
|
|
63
|
+
class WriteApiRepr
|
|
64
|
+
include Extensions::OptionsExtension
|
|
65
|
+
include Extensions::OptionsDefaults
|
|
66
|
+
|
|
67
|
+
# @!attribute global_position
|
|
68
|
+
# @return [Integer]
|
|
69
|
+
attribute(:global_position)
|
|
70
|
+
# @!attribute event_type_partition_id
|
|
71
|
+
# @return [Integer]
|
|
72
|
+
attribute(:event_type_partition_id)
|
|
73
|
+
# @!attribute stream_revision
|
|
74
|
+
# @return [Integer]
|
|
75
|
+
attribute(:stream_revision)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# EventGlobalIndex representation for revision validation in #append_to_stream
|
|
79
|
+
class RevisionCheckRepr
|
|
80
|
+
include Extensions::OptionsExtension
|
|
81
|
+
include Extensions::OptionsDefaults
|
|
82
|
+
|
|
83
|
+
# @!attribute stream_revision
|
|
84
|
+
# @return [Integer]
|
|
85
|
+
attribute(:stream_revision)
|
|
86
|
+
# @!attribute sequence_number
|
|
87
|
+
# @return [Integer]
|
|
88
|
+
attribute(:sequence_number)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
module ReprType
|
|
92
|
+
SUBSCRIPTION = :subscription
|
|
93
|
+
READ_API = :read_api
|
|
94
|
+
WRITE_API = :write_api
|
|
95
|
+
REVISION_CHECK = :revision_check
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
class << self
|
|
99
|
+
# @param attributes [Hash<Symbol, Object>]
|
|
100
|
+
# @param repr [Symbol, nil]
|
|
101
|
+
# @return [EventGlobalIndex, SubscriptionRepr, ReadApiRepr, WriteApiRepr, RevisionCheckRepr]
|
|
102
|
+
def create_representation(attributes, repr: nil)
|
|
103
|
+
case repr
|
|
104
|
+
when ReprType::SUBSCRIPTION
|
|
105
|
+
SubscriptionRepr.new(**attributes)
|
|
106
|
+
when ReprType::READ_API
|
|
107
|
+
ReadApiRepr.new(**attributes)
|
|
108
|
+
when ReprType::WRITE_API
|
|
109
|
+
WriteApiRepr.new(**attributes)
|
|
110
|
+
when ReprType::REVISION_CHECK
|
|
111
|
+
RevisionCheckRepr.new(**attributes)
|
|
112
|
+
else
|
|
113
|
+
new(**attributes)
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PgEventstore
|
|
4
|
+
# @!visibility private
|
|
5
|
+
class EventMarker
|
|
6
|
+
include Extensions::OptionsExtension
|
|
7
|
+
include Extensions::OptionsDefaults
|
|
8
|
+
|
|
9
|
+
# @!attribute id
|
|
10
|
+
# @return [Integer]
|
|
11
|
+
attribute(:id)
|
|
12
|
+
# @!attribute name
|
|
13
|
+
# @return [String]
|
|
14
|
+
attribute(:name)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PgEventstore
|
|
4
|
+
# @!visibility private
|
|
5
|
+
class EventMarkerIndex
|
|
6
|
+
include Extensions::OptionsExtension
|
|
7
|
+
include Extensions::OptionsDefaults
|
|
8
|
+
|
|
9
|
+
# @!attribute marker_id
|
|
10
|
+
# @return [Integer]
|
|
11
|
+
attribute(:marker_id)
|
|
12
|
+
# @!attribute streams_global_index_id
|
|
13
|
+
# @return [Integer]
|
|
14
|
+
attribute(:streams_global_index_id)
|
|
15
|
+
# @!attribute event_type_partition_id
|
|
16
|
+
# @return [Integer]
|
|
17
|
+
attribute(:event_type_partition_id)
|
|
18
|
+
# @!attribute global_position
|
|
19
|
+
# @return [Integer]
|
|
20
|
+
attribute(:global_position)
|
|
21
|
+
# @!attribute stream_revision
|
|
22
|
+
# @return [Integer]
|
|
23
|
+
attribute(:stream_revision)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -18,6 +18,12 @@ module PgEventstore
|
|
|
18
18
|
@middlewares.each do |middleware|
|
|
19
19
|
middleware.serialize(event)
|
|
20
20
|
end
|
|
21
|
+
event.markers.uniq!
|
|
22
|
+
if event.markers.any?
|
|
23
|
+
event.metadata[Event::MARKERS_METADATA_KEY] = event.markers
|
|
24
|
+
else
|
|
25
|
+
event.metadata.delete(Event::MARKERS_METADATA_KEY)
|
|
26
|
+
end
|
|
21
27
|
event
|
|
22
28
|
end
|
|
23
29
|
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PgEventstore
|
|
4
|
+
module Extensions
|
|
5
|
+
module ActsAsConfigurable
|
|
6
|
+
# @param config_class [Class<PgEventstore:::BasicConfig>]
|
|
7
|
+
# @param default_config [Symbol]
|
|
8
|
+
# @return [void]
|
|
9
|
+
def acts_as_configurable(config_class:, default_config: :default)
|
|
10
|
+
const_set(:DEFAULT_CONFIG, default_config)
|
|
11
|
+
const_set(:CONFIG_CLASS, config_class)
|
|
12
|
+
extend Configurable
|
|
13
|
+
init_variables
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
module Configurable
|
|
17
|
+
# @!attribute mutex
|
|
18
|
+
# @return [Thread::Mutex]
|
|
19
|
+
attr_reader :mutex
|
|
20
|
+
private :mutex
|
|
21
|
+
|
|
22
|
+
# Creates a Config if not exists and yields it to the given block.
|
|
23
|
+
# @param name [Symbol] a name to assign to a config
|
|
24
|
+
# @return [Object] a result of the given block
|
|
25
|
+
def configure(name: const_get(:DEFAULT_CONFIG))
|
|
26
|
+
config_class = const_get(:CONFIG_CLASS)
|
|
27
|
+
mutex.synchronize do
|
|
28
|
+
@config[name] = @config[name] ? config_class.new(name:, **@config[name].options_hash) : config_class.new(name:)
|
|
29
|
+
connection_config_was = connection_options(@config[name])
|
|
30
|
+
|
|
31
|
+
yield(@config[name]).tap do
|
|
32
|
+
@config[name].freeze
|
|
33
|
+
next if connection_config_was == connection_options(@config[name])
|
|
34
|
+
|
|
35
|
+
# Reset the connection if user decided to reconfigure connection's options
|
|
36
|
+
@connection.delete(name)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# @return [Array<Symbol>]
|
|
42
|
+
def available_configs
|
|
43
|
+
@config.keys
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# @param name [Symbol]
|
|
47
|
+
# @return [PgEventstore::Config]
|
|
48
|
+
def config(name = const_get(:DEFAULT_CONFIG))
|
|
49
|
+
return @config[name] if @config[name]
|
|
50
|
+
|
|
51
|
+
error_message = <<~TEXT
|
|
52
|
+
Could not find #{name.inspect} config. You can define it like this:
|
|
53
|
+
#{self}.configure(name: #{name.inspect}) do |config|
|
|
54
|
+
# your config goes here
|
|
55
|
+
end
|
|
56
|
+
TEXT
|
|
57
|
+
raise error_message
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Look ups and returns a Connection, based on the given config. If not exists - it creates one. This operation
|
|
61
|
+
# is a thread-safe
|
|
62
|
+
# @param name [Symbol]
|
|
63
|
+
# @return [PgEventstore::Connection]
|
|
64
|
+
def connection(name = const_get(:DEFAULT_CONFIG))
|
|
65
|
+
mutex.synchronize do
|
|
66
|
+
@connection[name] ||= Connection.new(**connection_options(config(name)))
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
private
|
|
71
|
+
|
|
72
|
+
# @param config [PgEventstore::Extensions::OptionsExtension]
|
|
73
|
+
# @return [Hash] { uri: String, pool_size: Integer, pool_timeout: Integer }
|
|
74
|
+
def connection_options(config)
|
|
75
|
+
raise NotImplementedError
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# @return [void]
|
|
79
|
+
def init_variables
|
|
80
|
+
default_config = const_get(:DEFAULT_CONFIG)
|
|
81
|
+
@config = { default_config => const_get(:CONFIG_CLASS).new(name: default_config) }
|
|
82
|
+
@connection = {}
|
|
83
|
+
@mutex = Thread::Mutex.new
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|