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
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4425f2f4cffd24b06156465726034e4c8da383fed7f0576837851a65390068e0
|
|
4
|
+
data.tar.gz: bb809d708eaea98368d54bae14a8d35f36265a7a5ad66c4b8fd9b5dc57293163
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e86a98610d16b95eeb4bffa5a3b0d74055ac7901a30f20d297aee1b37786e06f94ff483c135f99df255cd23f50b3cac4d9360c6338ccbdab7d58d14b05fc5578
|
|
7
|
+
data.tar.gz: cdfe9c6093814265d91905f1405ff39bbd347a4e844c75961f3b3db56eb0fb4f32537b4cd26a0bb7c46b82abb21d25cb2aa7831623466cd3e2a3d5d50caf4a42
|
data/.rubocop.yml
CHANGED
|
@@ -2,7 +2,7 @@ plugins:
|
|
|
2
2
|
- rubocop-rspec
|
|
3
3
|
|
|
4
4
|
AllCops:
|
|
5
|
-
TargetRubyVersion: '3.
|
|
5
|
+
TargetRubyVersion: '3.2'
|
|
6
6
|
NewCops: enable
|
|
7
7
|
Exclude:
|
|
8
8
|
- 'benchmark/*'
|
|
@@ -27,7 +27,7 @@ RSpec/IndexedLet:
|
|
|
27
27
|
Enabled: false
|
|
28
28
|
|
|
29
29
|
RSpec/NestedGroups:
|
|
30
|
-
|
|
30
|
+
Enabled: false
|
|
31
31
|
|
|
32
32
|
RSpec/LetSetup:
|
|
33
33
|
Enabled: false
|
|
@@ -124,3 +124,12 @@ Gemspec/RequiredRubyVersion:
|
|
|
124
124
|
|
|
125
125
|
Gemspec/RequireMFA:
|
|
126
126
|
Enabled: false
|
|
127
|
+
|
|
128
|
+
Style/StructInheritance:
|
|
129
|
+
Enabled: false
|
|
130
|
+
|
|
131
|
+
Lint/NonLocalExitFromIterator:
|
|
132
|
+
Enabled: false
|
|
133
|
+
|
|
134
|
+
Style/RegexpLiteral:
|
|
135
|
+
Enabled: false
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,142 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [3.0.0]
|
|
4
|
+
|
|
5
|
+
- New feature: pg_eventstore replication
|
|
6
|
+
- **Breaking change**: drop support of Ruby v3.2. The gem now requires Ruby v3.3+
|
|
7
|
+
- New feature: event tracing. You can now configure pg_eventstore to trace causation dependencies of events.
|
|
8
|
+
Read more [here](docs/event_tracing.md)
|
|
9
|
+
- **Breaking change**: when event is persisted using `#append_to_stream` - it now gets deserialized via each registered
|
|
10
|
+
middleware by default. Previously this wasn't the case - the deserialization phase was skipped. Such behavior was
|
|
11
|
+
creating ambiguity about assumptions when deserialization happens. If you need old behavior - you have to create
|
|
12
|
+
another middleware class which skips deserialization when publishing events and use it instead. Example:
|
|
13
|
+
Let's say you have this middleware configured
|
|
14
|
+
```ruby
|
|
15
|
+
class MyMiddleware
|
|
16
|
+
include PgEventstore::Middleware
|
|
17
|
+
|
|
18
|
+
def serialize(event)
|
|
19
|
+
# do something with event before persisting it
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def deserialize(event)
|
|
23
|
+
# do something with event after reading it from db
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
PgEventstore.configure do |config|
|
|
28
|
+
config.middleware = { my_middleware: MyMiddleware.new }
|
|
29
|
+
end
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Now define another middleware that has empty `#deserialize` method
|
|
33
|
+
|
|
34
|
+
```ruby
|
|
35
|
+
class MyMiddlewareWithoutDeserialize < MyMiddleware
|
|
36
|
+
def deserialize(event)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
PgEventstore.configure do |config|
|
|
41
|
+
config.middleware = {
|
|
42
|
+
my_middleware: MyMiddleware.new,
|
|
43
|
+
my_middleware_wo_deserialize: MyMiddlewareWithoutDeserialize.new
|
|
44
|
+
}
|
|
45
|
+
end
|
|
46
|
+
```
|
|
47
|
+
and use only it when publishing events:
|
|
48
|
+
|
|
49
|
+
```ruby
|
|
50
|
+
PgEventstore.client.append_to_stream(stream, event, middlewares: [:my_middleware_wo_deserialize])
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Alternatively, if you don't rely on `#multiple`, you can create another config specially for write operations:
|
|
54
|
+
|
|
55
|
+
```ruby
|
|
56
|
+
# this is your default
|
|
57
|
+
PgEventstore.configure do |config|
|
|
58
|
+
config.middleware = { my_middleware: MyMiddleware.new }
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
PgEventstore.configure(name: :write) do |config|
|
|
62
|
+
config.middleware = { my_middleware: MyMiddlewareWithoutDeserialize.new }
|
|
63
|
+
end
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
and use it for write operations:
|
|
67
|
+
|
|
68
|
+
```ruby
|
|
69
|
+
PgEventstore.client(:write).append_to_stream(stream, event)
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
- **Breaking change**: `Event#id` uniqueness is no longer guaranteed. It was dropped because there is not much usage of
|
|
73
|
+
it internally. The default value was moved from the database(it was `gen_random_uuid()`) to the application level and
|
|
74
|
+
is `SecureRandom.uuid_v7` now.
|
|
75
|
+
- **Breaking change**: event types, stream attributes, event metadata keys, markers that start from `▒`(`"\u2592"`
|
|
76
|
+
Unicode character) character are now reserved by pg_eventstore. It is less likely you have any, but if you do - you have
|
|
77
|
+
to adjust your implementation to no longer rely on it.
|
|
78
|
+
- New feature: event markers. You can now mark an event and later use those markers to read events, build a projection
|
|
79
|
+
using subscriptions or validate stream revision scoped to an event type and specific markers when publishing events as
|
|
80
|
+
a part of Dynamic Consistency Boundaries. Find more in [docs](docs/appending_events.md#event-markers)
|
|
81
|
+
- New config option `config.events_subscription_position_update_interval`. See more
|
|
82
|
+
in [Configuration](docs/configuration.md) docs
|
|
83
|
+
- **Breaking change**: `:from_position` option of `SubscriptionManager#subscribe`, "Current position" column in admin
|
|
84
|
+
web UI, "Reset position" form in admin web UI now refers to the event subscription position instead
|
|
85
|
+
`Event#global_position`. See more information in related
|
|
86
|
+
docs [Subscription position](docs/subscriptions.md#subscription-position)
|
|
87
|
+
- **Breaking change**: Drop `pg_cron` dependency
|
|
88
|
+
- Remove deprecated `SubscriptionsManager#force_lock!`
|
|
89
|
+
- New feature: explicit support of Dynamic Consistency Boundaries when publishing events. You can now provide "event
|
|
90
|
+
type"-to-"expected stream revision" hash map into `:expected_revision` option. It allows to validate against stream
|
|
91
|
+
revision at the specific event type instead validating the whole stream. Example:
|
|
92
|
+
`PgEventstore.client.append_to_stream(stream, events, options: { expected_revision: { 'Foo' => 10, 'Bar' => 20 } })`
|
|
93
|
+
- **Breaking change**: `WrongExpectedRevisionError#new` now requires `:verdict` keyword argument.
|
|
94
|
+
`Client#append_to_stream` now also may raise `WrongExpectedTypesRevisionError` error in case `:expected_revision`
|
|
95
|
+
option is "event type"-to-"expected stream revision" hash map
|
|
96
|
+
- Remove any practical limit of `Event#stream_revision` by changing its type to `bigint`. Stream size can be practically
|
|
97
|
+
unreachable now
|
|
98
|
+
- Fix issue when incomplete transaction block may be interrupted half way and commited successfully. The issue is
|
|
99
|
+
related to incorrect transaction termination flow during non-graceful thread shutdown(e.g. via `Thread.exit`)
|
|
100
|
+
- New feature: `Client#stream_revision` allows to quickly get stream's revision. Example:
|
|
101
|
+
`PgEventstore.client.stream_revision(stream) #=> number, greater than or equal to 0 or -1 if stream does not exist`
|
|
102
|
+
- **Breaking change**: `Client#read_grouped` now requires to provide `event_types` filter option explicitly. Example:
|
|
103
|
+
`PgEventstore.client.read_grouped(stream, options: { filter: { event_types: ['Foo', 'Bar'] } })`
|
|
104
|
+
- New feature: Subscription event types filter now support prefixes. So, if you have subscriptions like
|
|
105
|
+
`manager.subscribe('MyAwesomeSubscription', handler: my_handler, options: { filter: { event_types: ['Foo1', 'Foo2', 'Foo3'] } })`,
|
|
106
|
+
you can replace its filter as follows: `{ event_types: [{ prefix: 'Foo' }] }`. **Read API does not support this
|
|
107
|
+
feature yet**
|
|
108
|
+
- New feature: Read API now supports `:to_position`(and `:to_revision` when reading from specific stream) option. Use it
|
|
109
|
+
if you want to limit your result alongside `:max_count` option. Example:
|
|
110
|
+
`PgEventstore.client.read(PgEventstore::Stream.all_stream, options: { from_position: 100, to_position: 200 })`
|
|
111
|
+
- **Breaking change**: `Middleware#serialize` is now called outside SQL transaction that inserts an event tuple.
|
|
112
|
+
Previously it was happening right before an `INSERT` statement
|
|
113
|
+
- **Breaking change**: Database structure and the implementation of `#append_to_stream` was changed in a way it is not
|
|
114
|
+
compatible with v2. Public API stays the same
|
|
115
|
+
- New feature: allow subscription to process events in batches. You can now provide `in_batches: true` to `#subscribe`
|
|
116
|
+
to yield an array of events. See [docs](docs/subscriptions.md#processing-events-in-batches) for more info
|
|
117
|
+
- Introduce `PgEventstore::BasicConfig` and `PgEventstore::Extensions::ActsAsConfigurable` to allow to easily create
|
|
118
|
+
configurable objects
|
|
119
|
+
|
|
120
|
+
## [2.0.0]
|
|
121
|
+
|
|
122
|
+
- **Breaking change**: `pg_eventstore` now requires [pg_cron](https://github.com/citusdata/pg_cron) extension
|
|
123
|
+
- **Breaking change**: `pg_eventstore` now requires PostgreSQL v16+
|
|
124
|
+
- Greatly decreased the number of connections, used by `pg_eventstore` subscriptions
|
|
125
|
+
- **Breaking change**: drop support of Ruby v3.0 and v3.1. The gem now requires Ruby v3.2+
|
|
126
|
+
- **Breaking change**: `PgEventstore::Extensions::OptionsExtension::Options` class is no longer a child of `Set` class -
|
|
127
|
+
it has independent implementation now
|
|
128
|
+
- Add support of Ruby v4.0
|
|
129
|
+
- `Client#multiple` method now accepts `read_only` keyword argument. When it is set to true - transaction is run in
|
|
130
|
+
read-only mode
|
|
131
|
+
- **Breaking change**: rework links implementation. This change boosts performance, but affects the database structure,
|
|
132
|
+
so your previous database dumps become incompatible with this change. `PgEventstore::Event#link_id` was replaced by
|
|
133
|
+
`PgEventstore::Event#link_global_position`
|
|
134
|
+
|
|
135
|
+
Changes above require you to run migrations - `bundle exec rake pg_eventstore:migrate`. One of the migrations also
|
|
136
|
+
migrates existing data using several concurrent workers(threads). You can adjust the number of workers using
|
|
137
|
+
`CONCURRENCY` environment variable. Default number of concurrent workers is `10`. **Migrations require a downtime - no
|
|
138
|
+
reads/writes should be performed during the time of the migrations, so plan your maintenance downtime accordingly.**
|
|
139
|
+
|
|
3
140
|
## [1.13.4]
|
|
4
141
|
|
|
5
142
|
- Fix subscriptions potentially skipping events when multiple events are appended in concurrent transactions
|
|
@@ -18,7 +155,8 @@
|
|
|
18
155
|
|
|
19
156
|
## [1.13.0]
|
|
20
157
|
|
|
21
|
-
- Introduce automatic subscriptions recovery from connection errors. This way if a subscription process loses the
|
|
158
|
+
- Introduce automatic subscriptions recovery from connection errors. This way if a subscription process loses the
|
|
159
|
+
connection to the database - it will be trying to reconnect until the connection is restored.
|
|
22
160
|
- Resolve ambiguity in usage of `PgEventstore.config` method. It now returns the frozen object.
|
|
23
161
|
|
|
24
162
|
## [1.12.0]
|
|
@@ -27,12 +165,17 @@
|
|
|
27
165
|
|
|
28
166
|
## [1.11.0]
|
|
29
167
|
|
|
30
|
-
- Add a global position that caused an error to the subscription's error JSON info. This will help you understand what
|
|
168
|
+
- Add a global position that caused an error to the subscription's error JSON info. This will help you understand what
|
|
169
|
+
event caused your subscription to fail.
|
|
31
170
|
- Improve long payloads in JSON preview in admin web UI in the way it does not moves content out of the visible area.
|
|
32
|
-
- Admin UI: adjust events filtering and displaying of stream context, stream name, stream id and event type when values
|
|
171
|
+
- Admin UI: adjust events filtering and displaying of stream context, stream name, stream id and event type when values
|
|
172
|
+
of them contain empty strings or non-displayable characters
|
|
33
173
|
|
|
34
174
|
## [1.10.0]
|
|
35
|
-
|
|
175
|
+
|
|
176
|
+
- Admin UI: Adjust `SubscriptionSet` "Stop"/"Delete" buttons appearance. Now if `SubscriptionsSet` is not alive anymore(
|
|
177
|
+
the related process is dead or does not exist anymore) - "Delete" button is shown. If `SubscriptionSet` is alive - "
|
|
178
|
+
Stop" button is shown
|
|
36
179
|
- Admin IU: fixed several potential XSS vulnerabilities
|
|
37
180
|
- Admin IU: Add "Copy to clipboard" button near stream id that copies ruby stream definition
|
|
38
181
|
- Admin UI: allow deletion of streams with empty attribute values
|
|
@@ -44,23 +187,33 @@
|
|
|
44
187
|
- Add "Delete event" and "Delete stream" buttons into admin UI
|
|
45
188
|
|
|
46
189
|
## [1.8.0]
|
|
47
|
-
|
|
190
|
+
|
|
191
|
+
- Introduce default config for admin web UI. Now if you define `:admin_web_ui` config - it will be preferred over
|
|
192
|
+
default config
|
|
48
193
|
- Fix pagination of events in admin UI
|
|
49
194
|
- Improve partial index for `$streams` system stream
|
|
50
195
|
|
|
51
196
|
## [1.7.0]
|
|
197
|
+
|
|
52
198
|
- Implement reading from `"$streams"` system stream
|
|
53
199
|
- Disable Host authorization introduced in sinatra v4.1
|
|
54
200
|
|
|
55
201
|
## [1.6.0]
|
|
56
|
-
|
|
202
|
+
|
|
203
|
+
- Introduce subscriptions CLI. Type `pg-eventstore subscriptions --help` to see available commands. The main purpose of
|
|
204
|
+
it is to provide the single way to start/stop subscription processes.
|
|
205
|
+
Check [Subscriptions](docs/subscriptions.md#creating-a-subscription) docs about the new way to start and keep running
|
|
206
|
+
a subscriptions process.
|
|
57
207
|
|
|
58
208
|
## [1.5.0]
|
|
209
|
+
|
|
59
210
|
- Add ability to toggle link events in the admin UI
|
|
60
211
|
- Mark linked events in the admin UI with "link" icon
|
|
61
212
|
|
|
62
213
|
## [1.4.0]
|
|
63
|
-
|
|
214
|
+
|
|
215
|
+
- Add an ability to configure subscription graceful shutdown timeout globally and per subscription. Default value is 15
|
|
216
|
+
seconds. Previously it was hardcoded to 5 seconds. Examples:
|
|
64
217
|
|
|
65
218
|
```ruby
|
|
66
219
|
# Set it globally, for all subscriptions
|
|
@@ -77,18 +230,24 @@ subscriptions_manager.subscribe(
|
|
|
77
230
|
```
|
|
78
231
|
|
|
79
232
|
## [1.3.4]
|
|
80
|
-
|
|
233
|
+
|
|
234
|
+
- Fix `NoMethodError` error in `Client#read_paginated` when stream does not exist or when there are no events matching
|
|
235
|
+
the given filter
|
|
81
236
|
|
|
82
237
|
## [1.3.3]
|
|
238
|
+
|
|
83
239
|
- Adjust default value of `subscription_max_retries` setting
|
|
84
240
|
|
|
85
241
|
## [1.3.2]
|
|
242
|
+
|
|
86
243
|
- Fix UI when switching subscription status
|
|
87
244
|
|
|
88
245
|
## [1.3.1]
|
|
246
|
+
|
|
89
247
|
- Swap "Search" button and "Add filter" button on Dashboard page
|
|
90
248
|
|
|
91
249
|
## [1.3.0]
|
|
250
|
+
|
|
92
251
|
- Add ability to filter subscriptions by state in admin UI
|
|
93
252
|
- Reset error-related subscription's attributes on subscription restore
|
|
94
253
|
- Reset total processed events number when user changes subscription's position
|
|
@@ -96,9 +255,12 @@ subscriptions_manager.subscribe(
|
|
|
96
255
|
- Relax sinatra version requirement to v3+
|
|
97
256
|
|
|
98
257
|
## [1.2.0]
|
|
258
|
+
|
|
99
259
|
- Implement `failed_subscription_notifier` subscription hook.
|
|
100
260
|
|
|
101
|
-
Now you are able to define a function that is called when subscription fails and no longer can be automatically
|
|
261
|
+
Now you are able to define a function that is called when subscription fails and no longer can be automatically
|
|
262
|
+
restarted because it hit max number of retries. You can define the hook globally in the config and per subscription.
|
|
263
|
+
Examples:
|
|
102
264
|
|
|
103
265
|
```ruby
|
|
104
266
|
PgEventstore.configure do |config|
|
|
@@ -122,36 +284,48 @@ subscriptions_manager.subscribe(
|
|
|
122
284
|
```
|
|
123
285
|
|
|
124
286
|
## [1.1.5]
|
|
125
|
-
|
|
287
|
+
|
|
288
|
+
- Review the way to handle SubscriptionAlreadyLockedError error. This removes noise when attempting to lock an already
|
|
289
|
+
locked subscription.
|
|
126
290
|
|
|
127
291
|
## [1.1.4]
|
|
292
|
+
|
|
128
293
|
- Add rbs signatures
|
|
129
294
|
|
|
130
295
|
## [1.1.3]
|
|
296
|
+
|
|
131
297
|
- Fix issue with assets caching between different gem's versions
|
|
132
298
|
|
|
133
299
|
## [1.1.2]
|
|
300
|
+
|
|
134
301
|
- Improve web app compatibility with rails
|
|
135
302
|
|
|
136
303
|
## [1.1.1]
|
|
304
|
+
|
|
137
305
|
- Allow case insensitive search by context, stream name and event type in admin UI
|
|
138
306
|
|
|
139
307
|
## [1.1.0]
|
|
308
|
+
|
|
140
309
|
- Add "Reset position" button on Subscriptions Admin UI page
|
|
141
310
|
|
|
142
|
-
**Note** This release includes a migration to support new functional. Please don't forget to run
|
|
311
|
+
**Note** This release includes a migration to support new functional. Please don't forget to run
|
|
312
|
+
`rake pg_eventstore:migrate` to apply latest db changes.
|
|
143
313
|
|
|
144
314
|
## [1.0.4]
|
|
315
|
+
|
|
145
316
|
- Fix bug which caused slow Subscriptions to stop processing new events
|
|
146
317
|
- Optimize Subscriptions update queries
|
|
147
318
|
|
|
148
319
|
## [1.0.3]
|
|
320
|
+
|
|
149
321
|
- Do no update `Subscription#last_chunk_fed_at` if the chunk is empty
|
|
150
322
|
|
|
151
323
|
## [1.0.2]
|
|
324
|
+
|
|
152
325
|
- UI: Fix opening of SubscriptionsSet tab of non-existing SubscriptionsSet
|
|
153
326
|
|
|
154
327
|
## [1.0.1]
|
|
328
|
+
|
|
155
329
|
- Adjust assets urls to correctly act when mounting sinatra app under non-root url
|
|
156
330
|
|
|
157
331
|
## [1.0.0]
|
|
@@ -189,7 +363,8 @@ subscriptions_manager.subscribe(
|
|
|
189
363
|
|
|
190
364
|
## [0.8.0] - 2024-02-20
|
|
191
365
|
|
|
192
|
-
- Allow float values for `subscription_pull_interval`. The default value of it was also set to `1.0`(it was `2`
|
|
366
|
+
- Allow float values for `subscription_pull_interval`. The default value of it was also set to `1.0`(it was `2`
|
|
367
|
+
previously)
|
|
193
368
|
|
|
194
369
|
## [0.7.2] - 2024-02-14
|
|
195
370
|
|
|
@@ -201,7 +376,8 @@ subscriptions_manager.subscribe(
|
|
|
201
376
|
|
|
202
377
|
## [0.7.0] - 2024-02-09
|
|
203
378
|
|
|
204
|
-
- Refactor `pg_eventstore:create` and `pg_eventstore:drop` rake tasks. They now actually create/drop the database. You
|
|
379
|
+
- Refactor `pg_eventstore:create` and `pg_eventstore:drop` rake tasks. They now actually create/drop the database. You
|
|
380
|
+
will have to execute `delete from migrations where number > 6` query before deploying this version.
|
|
205
381
|
- Drop legacy migrations
|
|
206
382
|
|
|
207
383
|
## [0.6.0] - 2024-02-08
|
|
@@ -246,9 +422,11 @@ subscriptions_manager.subscribe(
|
|
|
246
422
|
|
|
247
423
|
## [0.2.4] - 2023-12-20
|
|
248
424
|
|
|
249
|
-
Due to performance issues under certain circumstances, searching by event type was giving bad performance. I decided to
|
|
425
|
+
Due to performance issues under certain circumstances, searching by event type was giving bad performance. I decided to
|
|
426
|
+
extract `type` column from `events` table into separated table. **No breaking changes in public API though.**
|
|
250
427
|
|
|
251
|
-
**Warning** The migrations this version has, requires you to shut down applications that use `pg_eventstore` and only
|
|
428
|
+
**Warning** The migrations this version has, requires you to shut down applications that use `pg_eventstore` and only
|
|
429
|
+
then run `rake pg_eventstore:migrate`.
|
|
252
430
|
|
|
253
431
|
## [0.2.3] - 2023-12-18
|
|
254
432
|
|
|
@@ -260,7 +438,8 @@ Due to performance issues under certain circumstances, searching by event type w
|
|
|
260
438
|
|
|
261
439
|
## [0.2.1] - 2023-12-14
|
|
262
440
|
|
|
263
|
-
Under certain circumstances `PG::TRSerializationFailure` exception wasn't retried. Adjust connection's states list to
|
|
441
|
+
Under certain circumstances `PG::TRSerializationFailure` exception wasn't retried. Adjust connection's states list to
|
|
442
|
+
fix that.
|
|
264
443
|
|
|
265
444
|
## [0.2.0] - 2023-12-14
|
|
266
445
|
|
data/README.md
CHANGED
|
@@ -4,27 +4,40 @@ Implements database and API to store and read events in event sourced systems.
|
|
|
4
4
|
|
|
5
5
|
## Requirements
|
|
6
6
|
|
|
7
|
-
- `pg_eventstore` requires a PostgreSQL
|
|
8
|
-
-
|
|
7
|
+
- `pg_eventstore` requires a PostgreSQL v16+.
|
|
8
|
+
- `pg_evenstore` requires a separate database. However, it is recommended that you spin it up on a separate PostgreSQL instance in a production environment.
|
|
9
|
+
- `pg_eventstore` requires `default_transaction_isolation` server config option to be set to `'read committed'` (default behavior). Having this value set to move strict isolation level may result in unexpected behavior.
|
|
9
10
|
- It is recommended to use a connection pooler (for example [PgBouncer](https://www.pgbouncer.org/)) in `transaction` pool mode to lower the load on a database.
|
|
10
|
-
- `pg_eventstore` requires ruby v3+. The development of this gem is targeted at [current](https://endoflife.date/ruby) ruby versions.
|
|
11
|
+
- `pg_eventstore` requires ruby v3.3+. The development of this gem is targeted at [current](https://endoflife.date/ruby) ruby versions.
|
|
12
|
+
|
|
13
|
+
### Migrating to v3
|
|
14
|
+
|
|
15
|
+
If you are migrating from v2 - please don't forget to delete cron jobs and `pg_cron` extension after migration to v3.
|
|
16
|
+
You can remove cron jobs as follows:
|
|
17
|
+
|
|
18
|
+
```sql
|
|
19
|
+
SELECT cron.unschedule('prune_eventstore_events_horizon');
|
|
20
|
+
SELECT cron.unschedule('delete-job-run-details');
|
|
21
|
+
```
|
|
11
22
|
|
|
12
23
|
## Installation
|
|
13
24
|
|
|
14
25
|
Install the gem and add to the application's Gemfile by executing:
|
|
15
|
-
|
|
16
|
-
|
|
26
|
+
```bash
|
|
27
|
+
bundle add pg_eventstore
|
|
28
|
+
```
|
|
17
29
|
|
|
18
30
|
If bundler is not being used to manage dependencies, install the gem by executing:
|
|
19
|
-
|
|
20
|
-
|
|
31
|
+
```bash
|
|
32
|
+
gem install pg_eventstore
|
|
33
|
+
```
|
|
21
34
|
|
|
22
35
|
## Usage
|
|
23
36
|
|
|
24
37
|
Before start using the gem - you have to create the database. Please include this line into your `Rakefile`:
|
|
25
38
|
|
|
26
39
|
```ruby
|
|
27
|
-
load
|
|
40
|
+
load 'pg_eventstore/tasks/setup.rake'
|
|
28
41
|
```
|
|
29
42
|
|
|
30
43
|
This will include necessary rake tasks. You can now run
|
|
@@ -44,11 +57,17 @@ Documentation chapters:
|
|
|
44
57
|
- [Appending events](docs/appending_events.md)
|
|
45
58
|
- [Linking events](docs/linking_events.md)
|
|
46
59
|
- [Reading events](docs/reading_events.md)
|
|
60
|
+
- [Reading streams](docs/reading_streams.md)
|
|
61
|
+
- [Tracing events](docs/event_tracing.md)
|
|
47
62
|
- [Subscriptions](docs/subscriptions.md)
|
|
48
63
|
- [Maintenance functions](docs/maintenance.md)
|
|
49
64
|
- [Writing middlewares](docs/writing_middleware.md)
|
|
50
65
|
- [How to make multiple commands atomic](docs/multiple_commands.md)
|
|
51
66
|
- [Admin UI](docs/admin_ui.md)
|
|
67
|
+
- [Replication](docs/replication.md)
|
|
68
|
+
|
|
69
|
+
To help your AI assistant to better recognize the capabilities of this gem - there is a crafted [instructions](docs/AGENTS.fragment.md)
|
|
70
|
+
you can include into your `AGENTS.md`.
|
|
52
71
|
|
|
53
72
|
## CLI
|
|
54
73
|
|
|
@@ -104,14 +123,18 @@ end
|
|
|
104
123
|
After checking out the repo, run:
|
|
105
124
|
- `bundle` to install dependencies
|
|
106
125
|
- `docker compose up` to start dev/test services
|
|
126
|
+
- `bundle exec rake compile` to compile native extension
|
|
107
127
|
- `bin/setup_db` to create/re-create development and test databases, tables and related objects
|
|
108
128
|
- `bundle exec rbs collection install` to install external rbs definitions
|
|
109
129
|
|
|
110
|
-
Then, run `bin/rspec` to run the tests
|
|
130
|
+
Then, run `bin/rspec` to run the tests(or just `rspec` if you want to temporary skip rbs checks). Optional env variables for testing:
|
|
131
|
+
- `DEBUG=1 bin/rspec`. Enable nicely formatted and highlighted SQL output into stdout.
|
|
132
|
+
|
|
133
|
+
You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
111
134
|
|
|
112
135
|
To install this gem onto your local machine, run `bundle exec rake install`.
|
|
113
136
|
|
|
114
|
-
To run admin UI web server - run `puma` in your terminal. By default it will start web server on `http://0.0.0.0:9292`.
|
|
137
|
+
To run admin UI web server - run `puma` in your terminal. By default, it will start web server on `http://0.0.0.0:9292`.
|
|
115
138
|
|
|
116
139
|
### Benchmarks
|
|
117
140
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# pg_cron was removed. This file is kept for informative purpose.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ALTER TABLE public.events ADD COLUMN link_global_position bigint;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
CONCURRENCY = ENV['CONCURRENCY']&.to_i || 10
|
|
4
|
+
|
|
5
|
+
PgEventstore.configure(name: :_eventstore_db_connection) do |config|
|
|
6
|
+
config.connection_pool_size = CONCURRENCY
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
partitions = PgEventstore.connection(:_eventstore_db_connection).with do |conn|
|
|
10
|
+
conn.exec('select id, table_name from partitions')
|
|
11
|
+
end
|
|
12
|
+
partitions = partitions.to_h { |attrs| [attrs['id'], attrs['table_name']] }
|
|
13
|
+
|
|
14
|
+
total_links = PgEventstore.connection(:_eventstore_db_connection).with do |conn|
|
|
15
|
+
conn.exec_params(
|
|
16
|
+
'select count(*) all_count from events where events.type = $1 and link_global_position is null',
|
|
17
|
+
[PgEventstore::Event::LINK_TYPE]
|
|
18
|
+
)
|
|
19
|
+
end.first['all_count']
|
|
20
|
+
|
|
21
|
+
puts "Migrating legacy links. Links to process: #{total_links}. Concurrency is #{CONCURRENCY} concurrent writers."
|
|
22
|
+
processed = 0
|
|
23
|
+
processed_was = 0
|
|
24
|
+
time = Time.now
|
|
25
|
+
lock = Thread::Mutex.new
|
|
26
|
+
threads = CONCURRENCY.times.map do |t|
|
|
27
|
+
Thread.new do
|
|
28
|
+
loop do
|
|
29
|
+
link_events = PgEventstore.connection(:_eventstore_db_connection).with do |conn|
|
|
30
|
+
conn.exec_params(<<~SQL, [PgEventstore::Event::LINK_TYPE, CONCURRENCY, t])
|
|
31
|
+
select * from events
|
|
32
|
+
where events.type = $1 and events.link_global_position is null and global_position % $2 = $3
|
|
33
|
+
limit 1_000
|
|
34
|
+
SQL
|
|
35
|
+
end.to_a
|
|
36
|
+
break if link_events.empty?
|
|
37
|
+
|
|
38
|
+
lock.synchronize { processed += link_events.size }
|
|
39
|
+
link_events = link_events.to_h { [_1['global_position'], _1] }
|
|
40
|
+
builders = link_events.values.map do |event|
|
|
41
|
+
builder = PgEventstore::SQLBuilder.new
|
|
42
|
+
builder.select("global_position, #{event['global_position']} as link_event_global_position")
|
|
43
|
+
builder.from(partitions[event['link_partition_id']]).where('id = ?', event['link_id'])
|
|
44
|
+
end
|
|
45
|
+
final_builder = PgEventstore::SQLBuilder.union_builders(builders)
|
|
46
|
+
|
|
47
|
+
positions_map = PgEventstore.connection(:_eventstore_db_connection).with do |conn|
|
|
48
|
+
conn.exec_params(*final_builder.to_exec_params)
|
|
49
|
+
end.to_a
|
|
50
|
+
|
|
51
|
+
update_queries = positions_map.map do |attrs|
|
|
52
|
+
<<~SQL
|
|
53
|
+
UPDATE events SET link_global_position = #{attrs['global_position']}
|
|
54
|
+
WHERE global_position = #{attrs['link_event_global_position']};
|
|
55
|
+
SQL
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
PgEventstore.connection(:_eventstore_db_connection).with do |conn|
|
|
59
|
+
conn.exec(update_queries.join("\n"))
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Only log from the first thread to prevent messages spam
|
|
63
|
+
next unless t == 0
|
|
64
|
+
|
|
65
|
+
lock.synchronize do
|
|
66
|
+
time_was = time
|
|
67
|
+
time = Time.now
|
|
68
|
+
|
|
69
|
+
performance_info = <<~TEXT.strip
|
|
70
|
+
Processed: #{processed}. Left: #{total_links - processed}. \
|
|
71
|
+
Performance: #{((processed - processed_was) / (time - time_was)).round(2)} events/second.
|
|
72
|
+
TEXT
|
|
73
|
+
processed_was = processed
|
|
74
|
+
print "#{performance_info} \r"
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
threads.each(&:join)
|
|
80
|
+
|
|
81
|
+
PgEventstore.connection(:_eventstore_db_connection).with do |conn|
|
|
82
|
+
conn.exec('VACUUM (ANALYZE) events;')
|
|
83
|
+
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
DROP INDEX idx_events_id;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
CREATE TABLE public.streams_global_index
|
|
2
|
+
(
|
|
3
|
+
id bigserial NOT NULL,
|
|
4
|
+
partition_id bigint NOT NULL,
|
|
5
|
+
stream_id character varying COLLATE "POSIX" NOT NULL,
|
|
6
|
+
stream_revision bigint NOT NULL,
|
|
7
|
+
starting_position bigint NOT NULL
|
|
8
|
+
);
|
|
9
|
+
|
|
10
|
+
ALTER TABLE ONLY public.streams_global_index
|
|
11
|
+
ADD CONSTRAINT streams_global_index_pkey PRIMARY KEY (id);
|
|
12
|
+
|
|
13
|
+
CREATE UNIQUE INDEX idx_streams_global_index_on_stream_id_and_partition_id ON public.streams_global_index
|
|
14
|
+
USING btree (stream_id, partition_id) INCLUDE (id);
|
|
15
|
+
|
|
16
|
+
CREATE INDEX idx_streams_global_index_on_starting_position ON public.streams_global_index
|
|
17
|
+
USING btree (starting_position);
|