pg_eventstore 2.0.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (303) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +10 -1
  3. data/CHANGELOG.md +186 -20
  4. data/README.md +25 -15
  5. data/db/migrations/10_setup_pg_cron.rb +1 -23
  6. data/db/migrations/15_create_streams_global_index.sql +17 -0
  7. data/db/migrations/16_populate_streams_global_index.rb +150 -0
  8. data/db/migrations/17_create_events_global_index.sql +62 -0
  9. data/db/migrations/18_populate_events_global_index.rb +124 -0
  10. data/db/migrations/19_populate_events_global_index_p2.rb +25 -0
  11. data/db/migrations/20_migrate_subscriptions_current_position.sql +19 -0
  12. data/db/migrations/21_create_partitions_stats.sql +2 -0
  13. data/db/migrations/22_drop_streams_sql_view.sql +2 -0
  14. data/db/migrations/23_adjust_partitions_indexes.sql +5 -0
  15. data/db/migrations/24_drop_legacy_events_indexes.sql +3 -0
  16. data/db/migrations/25_add_parent_partitions_info_to_partitions.sql +16 -0
  17. data/db/migrations/26_change_events_stream_revision_type.rb +35 -0
  18. data/db/migrations/27_drop_events_horizon.sql +3 -0
  19. data/db/migrations/28_create_maintenance_tasks.sql +8 -0
  20. data/db/migrations/29_create_event_markers.sql +35 -0
  21. data/db/migrations/30_improve_partitions_search_in_admin_ui.rb +24 -0
  22. data/db/migrations/31_drop_events_id_default_value.sql +1 -0
  23. data/db/migrations/32_create_parittions_triggers.sql +101 -0
  24. data/docs/AGENTS.fragment.md +696 -0
  25. data/docs/admin_ui.md +3 -1
  26. data/docs/appending_events.md +110 -49
  27. data/docs/configuration.md +69 -36
  28. data/docs/event_tracing.md +55 -0
  29. data/docs/events_and_streams.md +54 -30
  30. data/docs/how_it_works.md +57 -16
  31. data/docs/linking_events.md +2 -1
  32. data/docs/maintenance.md +14 -5
  33. data/docs/multiple_commands.md +17 -8
  34. data/docs/reading_events.md +208 -43
  35. data/docs/reading_streams.md +50 -0
  36. data/docs/replication.md +99 -0
  37. data/docs/subscriptions.md +165 -35
  38. data/docs/writing_middleware.md +25 -8
  39. data/ext/pg_eventstore_ext/extconf.rb +5 -0
  40. data/ext/pg_eventstore_ext/pg_eventstore_ext.c +74 -0
  41. data/lib/pg_eventstore/async_runner.rb +63 -0
  42. data/lib/pg_eventstore/basic_config.rb +15 -0
  43. data/lib/pg_eventstore/chunks/chunk.rb +31 -0
  44. data/lib/pg_eventstore/chunks/read_api_events_index_chunk.rb +83 -0
  45. data/lib/pg_eventstore/chunks/replica_events_index_chunk.rb +35 -0
  46. data/lib/pg_eventstore/chunks/repository.rb +73 -0
  47. data/lib/pg_eventstore/chunks/subscription_checkpoint_chunk.rb +48 -0
  48. data/lib/pg_eventstore/chunks/subscription_events_index_chunk.rb +99 -0
  49. data/lib/pg_eventstore/chunks.rb +14 -0
  50. data/lib/pg_eventstore/client.rb +163 -50
  51. data/lib/pg_eventstore/commands/append.rb +62 -43
  52. data/lib/pg_eventstore/commands/delete_event.rb +7 -8
  53. data/lib/pg_eventstore/commands/delete_stream.rb +3 -3
  54. data/lib/pg_eventstore/commands/event_modifiers/prepare_link_event.rb +9 -7
  55. data/lib/pg_eventstore/commands/event_modifiers/prepare_regular_event.rb +12 -7
  56. data/lib/pg_eventstore/commands/link_to.rb +5 -5
  57. data/lib/pg_eventstore/commands/read.rb +23 -5
  58. data/lib/pg_eventstore/commands/read_grouped.rb +46 -0
  59. data/lib/pg_eventstore/commands/read_streams.rb +18 -0
  60. data/lib/pg_eventstore/commands/read_streams_paginated.rb +56 -0
  61. data/lib/pg_eventstore/commands/regular_stream_read_paginated.rb +4 -4
  62. data/lib/pg_eventstore/commands/revision_check/current_revision.rb +51 -0
  63. data/lib/pg_eventstore/commands/revision_check/event_type_revisions_comparison.rb +46 -0
  64. data/lib/pg_eventstore/commands/revision_check/expected_revision.rb +135 -0
  65. data/lib/pg_eventstore/commands/revision_check/stream_revision_check.rb +98 -0
  66. data/lib/pg_eventstore/commands/revision_check/stream_revision_comparison.rb +36 -0
  67. data/lib/pg_eventstore/commands/stream_revision.rb +14 -0
  68. data/lib/pg_eventstore/commands/system_stream_read_paginated.rb +4 -4
  69. data/lib/pg_eventstore/commands.rb +4 -2
  70. data/lib/pg_eventstore/config.rb +30 -9
  71. data/lib/pg_eventstore/connection.rb +21 -2
  72. data/lib/pg_eventstore/errors.rb +136 -10
  73. data/lib/pg_eventstore/event.rb +34 -2
  74. data/lib/pg_eventstore/event_deserializer.rb +5 -4
  75. data/lib/pg_eventstore/event_global_index.rb +118 -0
  76. data/lib/pg_eventstore/event_marker.rb +16 -0
  77. data/lib/pg_eventstore/event_marker_index.rb +25 -0
  78. data/lib/pg_eventstore/event_serializer.rb +6 -0
  79. data/lib/pg_eventstore/extensions/acts_as_configurable.rb +88 -0
  80. data/lib/pg_eventstore/extensions/options_defaults.rb +25 -0
  81. data/lib/pg_eventstore/extensions/options_extension.rb +2 -2
  82. data/lib/pg_eventstore/feature_marker.rb +18 -0
  83. data/lib/pg_eventstore/maintenance.rb +11 -6
  84. data/lib/pg_eventstore/middleware/event_tracing.rb +53 -0
  85. data/lib/pg_eventstore/partition.rb +6 -0
  86. data/lib/pg_eventstore/pg_connection.rb +70 -14
  87. data/lib/pg_eventstore/queries/event_marker_queries.rb +74 -0
  88. data/lib/pg_eventstore/queries/event_queries.rb +7 -93
  89. data/lib/pg_eventstore/queries/events_global_index_queries.rb +131 -0
  90. data/lib/pg_eventstore/queries/index_filtering_queries.rb +179 -0
  91. data/lib/pg_eventstore/queries/links_resolver.rb +4 -4
  92. data/lib/pg_eventstore/queries/maintenance_queries.rb +159 -42
  93. data/lib/pg_eventstore/queries/partition_queries.rb +45 -103
  94. data/lib/pg_eventstore/queries/replica_queries.rb +110 -0
  95. data/lib/pg_eventstore/queries/streams_global_index_queries.rb +163 -0
  96. data/lib/pg_eventstore/queries/transaction_queries.rb +52 -10
  97. data/lib/pg_eventstore/queries.rb +29 -1
  98. data/lib/pg_eventstore/query_builders/basic_filtering.rb +38 -5
  99. data/lib/pg_eventstore/query_builders/event_markers_filtering.rb +47 -0
  100. data/lib/pg_eventstore/query_builders/event_markers_index_filtering.rb +275 -0
  101. data/lib/pg_eventstore/query_builders/event_subscription_positions_filtering.rb +37 -0
  102. data/lib/pg_eventstore/query_builders/events_filtering.rb +15 -164
  103. data/lib/pg_eventstore/query_builders/events_global_index_filtering.rb +227 -0
  104. data/lib/pg_eventstore/query_builders/filters/collection.rb +324 -0
  105. data/lib/pg_eventstore/query_builders/filters/event_type_filter.rb +37 -0
  106. data/lib/pg_eventstore/query_builders/filters/filter_row.rb +54 -0
  107. data/lib/pg_eventstore/query_builders/filters/marker_filter.rb +20 -0
  108. data/lib/pg_eventstore/query_builders/filters/marker_filter_row.rb +49 -0
  109. data/lib/pg_eventstore/query_builders/filters/stream_filter.rb +48 -0
  110. data/lib/pg_eventstore/query_builders/index_based_events_filtering.rb +260 -0
  111. data/lib/pg_eventstore/query_builders/partitions_filtering.rb +175 -51
  112. data/lib/pg_eventstore/query_builders/read_cursor/stream_cursor.rb +122 -0
  113. data/lib/pg_eventstore/query_builders/streams_global_index_filtering.rb +83 -0
  114. data/lib/pg_eventstore/query_builders/subscription_events_filtering.rb +79 -0
  115. data/lib/pg_eventstore/query_strategy/async.rb +64 -0
  116. data/lib/pg_eventstore/query_strategy/foreground.rb +25 -0
  117. data/lib/pg_eventstore/query_strategy.rb +19 -0
  118. data/lib/pg_eventstore/raw_event.rb +46 -0
  119. data/lib/pg_eventstore/rspec/test_helpers.rb +21 -8
  120. data/lib/pg_eventstore/sql_builder.rb +87 -8
  121. data/lib/pg_eventstore/stream.rb +13 -16
  122. data/lib/pg_eventstore/stream_global_index.rb +28 -0
  123. data/lib/pg_eventstore/subscriptions/callback_handlers/events_processor_handlers.rb +5 -17
  124. data/lib/pg_eventstore/subscriptions/callback_handlers/events_subscription_position_worker_handlers.rb +36 -0
  125. data/lib/pg_eventstore/subscriptions/callback_handlers/subscription_feeder_handlers.rb +12 -0
  126. data/lib/pg_eventstore/subscriptions/callback_handlers/subscription_runner_handlers.rb +21 -7
  127. data/lib/pg_eventstore/subscriptions/events_processor.rb +20 -18
  128. data/lib/pg_eventstore/subscriptions/events_processor_consumer/multiple.rb +63 -0
  129. data/lib/pg_eventstore/subscriptions/events_processor_consumer/replica.rb +68 -0
  130. data/lib/pg_eventstore/subscriptions/events_processor_consumer/single.rb +62 -0
  131. data/lib/pg_eventstore/subscriptions/events_processor_consumer.rb +44 -0
  132. data/lib/pg_eventstore/subscriptions/events_subscription_position_worker.rb +68 -0
  133. data/lib/pg_eventstore/subscriptions/queries/event_subscription_position_queries.rb +177 -0
  134. data/lib/pg_eventstore/subscriptions/queries/subscription_queries.rb +78 -54
  135. data/lib/pg_eventstore/subscriptions/replica_subscription_handler.rb +140 -0
  136. data/lib/pg_eventstore/subscriptions/replica_subscription_runner.rb +9 -0
  137. data/lib/pg_eventstore/subscriptions/subscription.rb +2 -1
  138. data/lib/pg_eventstore/subscriptions/subscription_feed_strategies/collection.rb +36 -0
  139. data/lib/pg_eventstore/subscriptions/subscription_feed_strategies/index_read_strategy.rb +82 -0
  140. data/lib/pg_eventstore/subscriptions/subscription_feed_strategies/replication_strategy.rb +75 -0
  141. data/lib/pg_eventstore/subscriptions/subscription_feed_strategy.rb +31 -0
  142. data/lib/pg_eventstore/subscriptions/subscription_feeder.rb +24 -0
  143. data/lib/pg_eventstore/subscriptions/subscription_handler_performance.rb +4 -2
  144. data/lib/pg_eventstore/subscriptions/subscription_runner.rb +20 -9
  145. data/lib/pg_eventstore/subscriptions/subscription_runner_commands/reset_position.rb +1 -1
  146. data/lib/pg_eventstore/subscriptions/subscription_runners_feeder.rb +9 -18
  147. data/lib/pg_eventstore/subscriptions/subscriptions_lifecycle.rb +0 -12
  148. data/lib/pg_eventstore/subscriptions/subscriptions_manager.rb +74 -14
  149. data/lib/pg_eventstore/{subscriptions/synchronized_array.rb → synchronized_array.rb} +15 -0
  150. data/lib/pg_eventstore/tasks/setup.rake +2 -2
  151. data/lib/pg_eventstore/utils.rb +31 -0
  152. data/lib/pg_eventstore/version.rb +1 -1
  153. data/lib/pg_eventstore/web/application.rb +100 -16
  154. data/lib/pg_eventstore/web/paginator/base_collection.rb +5 -1
  155. data/lib/pg_eventstore/web/paginator/event_types_collection.rb +14 -4
  156. data/lib/pg_eventstore/web/paginator/events_collection.rb +29 -33
  157. data/lib/pg_eventstore/web/paginator/helpers.rb +16 -9
  158. data/lib/pg_eventstore/web/paginator/markers_collection.rb +48 -0
  159. data/lib/pg_eventstore/web/paginator/stream_contexts_collection.rb +13 -2
  160. data/lib/pg_eventstore/web/paginator/stream_ids_collection.rb +21 -11
  161. data/lib/pg_eventstore/web/paginator/stream_names_collection.rb +18 -4
  162. data/lib/pg_eventstore/web/paginator/streams_collection.rb +95 -0
  163. data/lib/pg_eventstore/web/public/javascripts/pg_eventstore.js +49 -22
  164. data/lib/pg_eventstore/web/subscriptions/set_collection.rb +1 -1
  165. data/lib/pg_eventstore/web/subscriptions/subscriptions.rb +1 -1
  166. data/lib/pg_eventstore/web/subscriptions/with_state/set_collection.rb +1 -1
  167. data/lib/pg_eventstore/web/subscriptions/with_state/subscriptions.rb +1 -1
  168. data/lib/pg_eventstore/web/views/home/dashboard.erb +11 -9
  169. data/lib/pg_eventstore/web/views/home/partials/event_filter.erb +18 -5
  170. data/lib/pg_eventstore/web/views/home/partials/events.erb +38 -1
  171. data/lib/pg_eventstore/web/views/home/partials/markers_filter.erb +18 -0
  172. data/lib/pg_eventstore/web/views/layouts/application.erb +6 -0
  173. data/lib/pg_eventstore/web/views/streams/index.erb +110 -0
  174. data/lib/pg_eventstore/web/views/streams/partials/streams.erb +11 -0
  175. data/lib/pg_eventstore/web/views/subscriptions/index.erb +4 -1
  176. data/lib/pg_eventstore/web.rb +2 -0
  177. data/lib/pg_eventstore.rb +23 -60
  178. data/pg_eventstore.gemspec +6 -4
  179. data/sig/interfaces/_raw_events_handler.rbs +3 -0
  180. data/sig/interfaces/subscription_handler.rbs +1 -1
  181. data/sig/pg/result.rbs +9 -0
  182. data/sig/pg_eventstore/async_runner.rbs +13 -0
  183. data/sig/pg_eventstore/basic_config.rbs +9 -0
  184. data/sig/pg_eventstore/chunks/chunk.rbs +13 -0
  185. data/sig/pg_eventstore/chunks/read_api_events_index_chunk.rbs +30 -0
  186. data/sig/pg_eventstore/chunks/replica_events_index_chunk.rbs +11 -0
  187. data/sig/pg_eventstore/chunks/repository.rbs +22 -0
  188. data/sig/pg_eventstore/chunks/subscription_checkpoint_chunk.rbs +18 -0
  189. data/sig/pg_eventstore/chunks/subscription_events_index_chunk.rbs +37 -0
  190. data/sig/pg_eventstore/client.rbs +40 -42
  191. data/sig/pg_eventstore/commands/append.rbs +11 -25
  192. data/sig/pg_eventstore/commands/event_modifiers/prepare_link_event.rbs +9 -12
  193. data/sig/pg_eventstore/commands/event_modifiers/prepare_regular_event.rbs +5 -4
  194. data/sig/pg_eventstore/commands/link_to.rbs +6 -11
  195. data/sig/pg_eventstore/commands/read.rbs +2 -5
  196. data/sig/pg_eventstore/commands/read_grouped.rbs +7 -0
  197. data/sig/pg_eventstore/commands/read_streams.rbs +7 -0
  198. data/sig/pg_eventstore/commands/read_streams_paginated.rbs +16 -0
  199. data/sig/pg_eventstore/commands/regular_stream_read_paginated.rbs +9 -17
  200. data/sig/pg_eventstore/commands/revision_check/current_revision.rbs +25 -0
  201. data/sig/pg_eventstore/commands/revision_check/event_type_revisions_comparison.rbs +14 -0
  202. data/sig/pg_eventstore/commands/revision_check/expected_revision.rbs +67 -0
  203. data/sig/pg_eventstore/commands/revision_check/stream_revision_check.rbs +20 -0
  204. data/sig/pg_eventstore/commands/revision_check/stream_revision_comparison.rbs +9 -0
  205. data/sig/pg_eventstore/commands/stream_revision.rbs +7 -0
  206. data/sig/pg_eventstore/commands/system_stream_read_paginated.rbs +9 -14
  207. data/sig/pg_eventstore/config.rbs +15 -6
  208. data/sig/pg_eventstore/connection.rbs +11 -18
  209. data/sig/pg_eventstore/errors.rbs +64 -34
  210. data/sig/pg_eventstore/event.rbs +16 -2
  211. data/sig/pg_eventstore/event_deserializer.rbs +5 -10
  212. data/sig/pg_eventstore/event_global_index.rbs +60 -0
  213. data/sig/pg_eventstore/event_marker.rbs +9 -0
  214. data/sig/pg_eventstore/event_marker_index.rbs +12 -0
  215. data/sig/pg_eventstore/extensions/acts_as_configurable.rbs +29 -0
  216. data/sig/pg_eventstore/extensions/options_defaults.rbs +7 -0
  217. data/sig/pg_eventstore/feature_marker.rbs +10 -0
  218. data/sig/pg_eventstore/maintenance.rbs +12 -8
  219. data/sig/pg_eventstore/middleware/event_trace.rbs +14 -0
  220. data/sig/pg_eventstore/partition.rbs +2 -4
  221. data/sig/pg_eventstore/pg_connection.rbs +8 -0
  222. data/sig/pg_eventstore/queries/event_marker_queries.rbs +21 -0
  223. data/sig/pg_eventstore/queries/event_queries.rbs +4 -36
  224. data/sig/pg_eventstore/queries/events_global_index_queries.rbs +37 -0
  225. data/sig/pg_eventstore/queries/index_filtering_queries.rbs +50 -0
  226. data/sig/pg_eventstore/queries/links_resolver.rbs +5 -9
  227. data/sig/pg_eventstore/queries/maintenance_queries.rbs +12 -9
  228. data/sig/pg_eventstore/queries/partition_queries.rbs +32 -67
  229. data/sig/pg_eventstore/queries/replica_queries.rbs +31 -0
  230. data/sig/pg_eventstore/queries/streams_global_index_queries.rbs +39 -0
  231. data/sig/pg_eventstore/queries/transaction_queries.rbs +2 -0
  232. data/sig/pg_eventstore/queries.rbs +11 -21
  233. data/sig/pg_eventstore/query_builders/basic_filtering.rbs +10 -3
  234. data/sig/pg_eventstore/query_builders/event_markers_filtering.rbs +17 -0
  235. data/sig/pg_eventstore/query_builders/event_markers_index_filtering.rbs +69 -0
  236. data/sig/pg_eventstore/query_builders/event_subscription_positions_filtering.rbs +15 -0
  237. data/sig/pg_eventstore/query_builders/events_filtering_query.rbs +9 -51
  238. data/sig/pg_eventstore/query_builders/events_global_index_filtering.rbs +68 -0
  239. data/sig/pg_eventstore/query_builders/filters/collection.rbs +84 -0
  240. data/sig/pg_eventstore/query_builders/filters/event_type_filter.rbs +19 -0
  241. data/sig/pg_eventstore/query_builders/filters/filter_row.rbs +21 -0
  242. data/sig/pg_eventstore/query_builders/filters/marker_filter.rbs +13 -0
  243. data/sig/pg_eventstore/query_builders/filters/marker_filter_row.rbs +19 -0
  244. data/sig/pg_eventstore/query_builders/filters/stream_filter.rbs +24 -0
  245. data/sig/pg_eventstore/query_builders/index_based_events_filtering.rbs +60 -0
  246. data/sig/pg_eventstore/query_builders/partitions_filtering.rbs +29 -10
  247. data/sig/pg_eventstore/query_builders/read_cursor/stream_cursor.rbs +47 -0
  248. data/sig/pg_eventstore/query_builders/streams_global_index_filtering.rbs +27 -0
  249. data/sig/pg_eventstore/query_builders/subscription_events_filtering.rbs +26 -0
  250. data/sig/pg_eventstore/query_strategy/async.rbs +17 -0
  251. data/sig/pg_eventstore/query_strategy/foreground.rbs +11 -0
  252. data/sig/pg_eventstore/query_strategy.rbs +7 -0
  253. data/sig/pg_eventstore/raw_event.rbs +20 -0
  254. data/sig/pg_eventstore/sql_builder.rbs +32 -10
  255. data/sig/pg_eventstore/stream.rbs +10 -18
  256. data/sig/pg_eventstore/stream_global_index.rbs +14 -0
  257. data/sig/pg_eventstore/subscriptions/callback_handlers/events_processor_handlers.rbs +5 -4
  258. data/sig/pg_eventstore/subscriptions/callback_handlers/events_subscription_position_worker_handlers.rbs +9 -0
  259. data/sig/pg_eventstore/subscriptions/callback_handlers/subscription_feeder_handlers.rbs +17 -12
  260. data/sig/pg_eventstore/subscriptions/callback_handlers/subscription_runner_handlers.rbs +17 -6
  261. data/sig/pg_eventstore/subscriptions/event_subscription_position_queries.rbs +30 -0
  262. data/sig/pg_eventstore/subscriptions/events_processor.rbs +12 -5
  263. data/sig/pg_eventstore/subscriptions/events_processor_consumer/multiple.rbs +17 -0
  264. data/sig/pg_eventstore/subscriptions/events_processor_consumer/replica.rbs +17 -0
  265. data/sig/pg_eventstore/subscriptions/events_processor_consumer/single.rbs +17 -0
  266. data/sig/pg_eventstore/subscriptions/events_processor_consumer.rbs +14 -0
  267. data/sig/pg_eventstore/subscriptions/events_subscription_position_worker.rbs +28 -0
  268. data/sig/pg_eventstore/subscriptions/queries/subscription_queries.rbs +7 -39
  269. data/sig/pg_eventstore/subscriptions/replica_subscription_handler.rbs +33 -0
  270. data/sig/pg_eventstore/subscriptions/replica_subscription_runner.rbs +4 -0
  271. data/sig/pg_eventstore/subscriptions/subscription_feed_strategy/collection.rbs +14 -0
  272. data/sig/pg_eventstore/subscriptions/subscription_feed_strategy/index_read_strategy.rbs +23 -0
  273. data/sig/pg_eventstore/subscriptions/subscription_feed_strategy/replication_strategy.rbs +23 -0
  274. data/sig/pg_eventstore/subscriptions/subscription_feed_strategy.rbs +11 -0
  275. data/sig/pg_eventstore/subscriptions/subscription_feeder.rbs +13 -10
  276. data/sig/pg_eventstore/subscriptions/subscription_handler_performance.rbs +1 -1
  277. data/sig/pg_eventstore/subscriptions/subscription_runner.rbs +13 -2
  278. data/sig/pg_eventstore/subscriptions/subscription_runners_feeder.rbs +1 -8
  279. data/sig/pg_eventstore/subscriptions/subscriptions_lifecycle.rbs +4 -6
  280. data/sig/pg_eventstore/subscriptions/subscriptions_manager.rbs +29 -43
  281. data/sig/pg_eventstore/synchronized_array.rbs +4 -0
  282. data/sig/pg_eventstore/utils.rbs +10 -11
  283. data/sig/pg_eventstore/web/application.rbs +13 -3
  284. data/sig/pg_eventstore/web/paginator/base_collection.rbs +2 -0
  285. data/sig/pg_eventstore/web/paginator/event_types_collection.rbs +4 -0
  286. data/sig/pg_eventstore/web/paginator/events_collection.rbs +11 -11
  287. data/sig/pg_eventstore/web/paginator/helpers.rbs +6 -15
  288. data/sig/pg_eventstore/web/paginator/markers_collection.rbs +13 -0
  289. data/sig/pg_eventstore/web/paginator/stream_contexts_collection.rbs +4 -0
  290. data/sig/pg_eventstore/web/paginator/stream_names_collection.rbs +4 -0
  291. data/sig/pg_eventstore/web/paginator/streams_collection.rbs +30 -0
  292. data/sig/pg_eventstore.rbs +8 -26
  293. metadata +175 -20
  294. data/Dockerfile +0 -3
  295. data/lib/pg_eventstore/commands/all_stream_read_grouped.rb +0 -69
  296. data/lib/pg_eventstore/commands/regular_stream_read_grouped.rb +0 -31
  297. data/lib/pg_eventstore/subscriptions/queries/subscription_service_queries.rb +0 -78
  298. data/lib/pg_eventstore/web/views/home/partials/system_stream_filter.erb +0 -15
  299. data/sig/pg_eventstore/commands/all_stream_read_grouped.rbs +0 -16
  300. data/sig/pg_eventstore/commands/regular_stream_read_grouped.rbs +0 -8
  301. data/sig/pg_eventstore/subscriptions/queries/subscription_service_queries.rbs +0 -19
  302. data/sig/pg_eventstore/subscriptions/synchronized_array.rbs +0 -4
  303. /data/sig/interfaces/{_raw_event_handler.rbs → raw_event_handler.rbs} +0 -0
@@ -4,12 +4,10 @@ require 'digest/md5'
4
4
 
5
5
  module PgEventstore
6
6
  class Stream
7
- # @return [String] a stream prefix of the system stream
8
- SYSTEM_STREAM_PREFIX = '$'
9
7
  # @return [Integer]
10
8
  NON_EXISTING_STREAM_REVISION = -1
11
9
  # @return [Array<String>]
12
- KNOWN_SYSTEM_STREAMS = %w[$streams].freeze
10
+ KNOWN_SYSTEM_STREAMS = %w[].freeze
13
11
 
14
12
  class << self
15
13
  # Produces "all" stream instance. "all" stream does not represent any specific stream. Instead, it indicates that
@@ -20,12 +18,6 @@ module PgEventstore
20
18
  stream.instance_variable_set(:@all_stream, true)
21
19
  end
22
20
  end
23
-
24
- # @param name [String]
25
- # @return [PgEventstore::Stream]
26
- def system_stream(name)
27
- new(context: name, stream_name: '', stream_id: '')
28
- end
29
21
  end
30
22
 
31
23
  # @!attribute context
@@ -37,26 +29,31 @@ module PgEventstore
37
29
  # @!attribute stream_id
38
30
  # @return [String]
39
31
  attr_reader :stream_id
32
+ # @!attribute stream_revision
33
+ # @return [Integer, nil]
34
+ attr_reader :stream_revision
35
+ # @!attribute starting_position
36
+ # @return [Integer, nil]
37
+ attr_reader :starting_position
40
38
 
41
39
  # @param context [String]
42
40
  # @param stream_name [String]
43
41
  # @param stream_id [String]
44
- def initialize(context:, stream_name:, stream_id:)
42
+ # @param stream_revision [Integer, nil]
43
+ # @param starting_position [Integer, nil]
44
+ def initialize(context:, stream_name:, stream_id:, stream_revision: nil, starting_position: nil)
45
45
  @context = context
46
46
  @stream_name = stream_name
47
47
  @stream_id = stream_id
48
+ @stream_revision = stream_revision
49
+ @starting_position = starting_position
48
50
  end
49
51
 
50
52
  # @return [Boolean]
51
53
  def all_stream?
52
54
  !!@all_stream
53
55
  end
54
-
55
- # Determine whether a stream is reserved by `pg_eventstore`. You can't append events to such streams.
56
- # @return [Boolean]
57
- def system?
58
- all_stream? || context.start_with?(SYSTEM_STREAM_PREFIX)
59
- end
56
+ alias system? all_stream?
60
57
 
61
58
  # @return [Array]
62
59
  def deconstruct
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PgEventstore
4
+ # @!visibility private
5
+ class StreamGlobalIndex
6
+ include Extensions::OptionsExtension
7
+ include Extensions::OptionsDefaults
8
+
9
+ # @return [Integer]
10
+ INITIAL_STARTING_POSITION = -1
11
+
12
+ # @!attribute id
13
+ # @return [Integer]
14
+ attribute(:id)
15
+ # @!attribute partition_id
16
+ # @return [Integer]
17
+ attribute(:partition_id)
18
+ # @!attribute stream_id
19
+ # @return [String]
20
+ attribute(:stream_id)
21
+ # @!attribute stream_revision
22
+ # @return [Integer]
23
+ attribute(:stream_revision)
24
+ # @!attribute starting_position
25
+ # @return [Integer]
26
+ attribute(:starting_position)
27
+ end
28
+ end
@@ -6,25 +6,13 @@ module PgEventstore
6
6
  include Extensions::CallbackHandlersExtension
7
7
 
8
8
  class << self
9
+ # @param consumer [PgEventstore::EventsProcessorConsumer]
9
10
  # @param callbacks [PgEventstore::Callbacks]
10
- # @param handler [#call]
11
- # @param raw_events [Array<Hash>]
12
- # @param raw_events_cond [MonitorMixin::ConditionVariable]
11
+ # @param events_repository [PgEventstore::Chunks::Repository]
12
+ # @param repository_cond [MonitorMixin::ConditionVariable]
13
13
  # @return [void]
14
- def process_event(callbacks, handler, raw_events, raw_events_cond)
15
- raw_event = nil
16
- raw_events.synchronize do
17
- raw_events_cond.wait(0.5) if raw_events.empty?
18
- raw_event = raw_events.shift
19
- end
20
- return if raw_event.nil?
21
-
22
- callbacks.run_callbacks(:process, Utils.original_global_position(raw_event)) do
23
- handler.call(raw_event)
24
- rescue => exception
25
- raw_events.unshift(raw_event)
26
- raise Utils.wrap_exception(exception, global_position: Utils.original_global_position(raw_event))
27
- end
14
+ def consume_events(consumer, callbacks, events_repository, repository_cond)
15
+ consumer.call(callbacks, events_repository, repository_cond)
28
16
  end
29
17
 
30
18
  # @param callbacks [PgEventstore::Callbacks]
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PgEventstore
4
+ # @!visibility private
5
+ class EventsSubscriptionPositionWorkerHandlers
6
+ include Extensions::CallbackHandlersExtension
7
+
8
+ class << self
9
+ # @param event_subscription_position_queries [PgEventstore::EventSubscriptionPositionQueries]
10
+ # @param update_interval [Integer, Float]
11
+ # @return [void]
12
+ def assign_subscription_position(event_subscription_position_queries, update_interval)
13
+ affected_records = event_subscription_position_queries.assign_subscription_position
14
+ # In case if assigning subscription position process is locked by someone else or if we updated less than
15
+ # MAX_INDEX_RECORDS_TO_UPDATE_SUBSCRIPTION_POSITION number of records(which basically means we are on the edge
16
+ # of the table) - take some delay before the next attempt.
17
+ if affected_records.nil? ||
18
+ affected_records < EventSubscriptionPositionQueries::MAX_INDEX_RECORDS_TO_UPDATE_SUBSCRIPTION_POSITION
19
+ sleep update_interval
20
+ end
21
+ end
22
+
23
+ # @param event_subscription_position_queries [PgEventstore::EventSubscriptionPositionQueries]
24
+ # @param next_reindex_at [PgEventstore::EventsSubscriptionPositionWorker::ReindexTime]
25
+ # @return [void]
26
+ def reindex(event_subscription_position_queries, next_reindex_at)
27
+ return if next_reindex_at.time && next_reindex_at.time > Time.now
28
+
29
+ time = event_subscription_position_queries.reindex_unprocessed_positions
30
+ return unless time
31
+
32
+ next_reindex_at.time = time
33
+ end
34
+ end
35
+ end
36
+ end
@@ -85,6 +85,18 @@ module PgEventstore
85
85
  last_restarted_at: Time.now.utc, restart_count: subscriptions_set.restart_count + 1
86
86
  )
87
87
  end
88
+
89
+ # @param worker [PgEventstore::EventsSubscriptionPositionWorker]
90
+ # @return [void]
91
+ def start_events_subscription_position_worker(worker)
92
+ worker.start
93
+ end
94
+
95
+ # @param worker [PgEventstore::EventsSubscriptionPositionWorker]
96
+ # @return [void]
97
+ def stop_events_subscription_position_worker(worker)
98
+ worker.stop_async.wait_for_finish
99
+ end
88
100
  end
89
101
  end
90
102
  end
@@ -9,20 +9,22 @@ module PgEventstore
9
9
  # @param stats [PgEventstore::SubscriptionHandlerPerformance]
10
10
  # @param action [Proc]
11
11
  # @param _current_position [Integer]
12
+ # @param events_number [Integer]
12
13
  # @return [void]
13
- def track_exec_time(stats, action, _current_position)
14
- stats.track_exec_time { action.call }
14
+ def track_exec_time(stats, action, _current_position, events_number)
15
+ stats.track_exec_time(events_number) { action.call }
15
16
  end
16
17
 
17
18
  # @param subscription [PgEventstore::Subscription]
18
19
  # @param stats [PgEventstore::SubscriptionHandlerPerformance]
19
20
  # @param current_position [Integer]
21
+ # @param events_number [Integer]
20
22
  # @return [void]
21
- def update_subscription_stats(subscription, stats, current_position)
23
+ def update_subscription_stats(subscription, stats, current_position, events_number)
22
24
  subscription.update(
23
25
  average_event_processing_time: stats.average_event_processing_time,
24
26
  current_position:,
25
- total_processed_events: subscription.total_processed_events + 1
27
+ total_processed_events: subscription.total_processed_events + events_number
26
28
  )
27
29
  end
28
30
 
@@ -34,10 +36,12 @@ module PgEventstore
34
36
  end
35
37
 
36
38
  # @param subscription [PgEventstore::Subscription]
37
- # @param global_position [Integer]
39
+ # @param subscription_position [Integer]
38
40
  # @return [void]
39
- def update_subscription_chunk_stats(subscription, global_position)
40
- subscription.update(last_chunk_fed_at: Time.now.utc, last_chunk_greatest_position: global_position)
41
+ def update_subscription_chunk_stats(subscription, subscription_position)
42
+ return if subscription.last_chunk_greatest_position == subscription_position
43
+
44
+ subscription.update(last_chunk_fed_at: Time.now.utc, last_chunk_greatest_position: subscription_position)
41
45
  end
42
46
 
43
47
  # @param subscription [PgEventstore::Subscription]
@@ -52,6 +56,16 @@ module PgEventstore
52
56
  def update_subscription_state(subscription, state)
53
57
  subscription.update(state:)
54
58
  end
59
+
60
+ # @param subscription [PgEventstore::Subscription]
61
+ # @param global_position [Integer]
62
+ # @return [void]
63
+ def checkpoint(subscription, global_position)
64
+ return if subscription.current_position == subscription.last_chunk_greatest_position &&
65
+ subscription.current_position == global_position
66
+
67
+ subscription.update(current_position: global_position, last_chunk_greatest_position: global_position)
68
+ end
55
69
  end
56
70
  end
57
71
  end
@@ -10,14 +10,16 @@ module PgEventstore
10
10
  def_delegators :@basic_runner, :state, :start, :stop, :wait_for_finish, :stop_async, :restore, :running?,
11
11
  :within_state
12
12
 
13
- # @param handler [#call]
14
13
  # @param graceful_shutdown_timeout [Integer, Float] seconds. Determines how long to wait before force-shutdown
15
14
  # the runner when stopping it using #stop_async
15
+ # @param consumer [PgEventstore::EventsProcessorConsumer]
16
+ # @param events_repository [PgEventstore::Chunks::Repository]
16
17
  # @param recovery_strategies [Array<PgEventstore::RunnerRecoveryStrategy>]
17
- def initialize(handler, graceful_shutdown_timeout:, recovery_strategies: [])
18
- @handler = handler
19
- @raw_events = SynchronizedArray.new
20
- @raw_events_cond = @raw_events.new_cond
18
+ def initialize(graceful_shutdown_timeout:, consumer:, events_repository: Chunks::Repository.new,
19
+ recovery_strategies: [])
20
+ @consumer = consumer
21
+ @events_repository = events_repository
22
+ @repository_cond = @events_repository.new_cond
21
23
  @basic_runner = BasicRunner.new(
22
24
  run_interval: 0,
23
25
  async_shutdown_time: graceful_shutdown_timeout,
@@ -26,29 +28,27 @@ module PgEventstore
26
28
  attach_runner_callbacks
27
29
  end
28
30
 
29
- # @param raw_events [Array<Hash>]
31
+ # @param chunk [PgEventstore::Chunks::Chunk]
30
32
  # @return [void]
31
- def feed(raw_events)
32
- raise EmptyChunkFedError.new('Empty chunk was fed!') if raw_events.empty?
33
+ def feed(chunk)
34
+ raise EmptyChunkFedError.new('Empty chunk was fed!') if chunk.drained?
33
35
 
34
36
  within_state(:running) do
35
- callbacks.run_callbacks(:feed, Utils.original_global_position(raw_events.last))
36
- @raw_events.synchronize do
37
- @raw_events.push(*raw_events)
38
- @raw_events_cond.broadcast
39
- end
37
+ callbacks.run_callbacks(:feed, chunk.last.subscription_position)
38
+ @events_repository.add_chunk(chunk, condition: @repository_cond)
40
39
  end
41
40
  end
42
41
 
43
42
  # Number of unprocessed events which are currently in a queue
44
43
  # @return [Integer]
45
- def events_left_in_chunk
46
- @raw_events.size
44
+ def events_left_in_repo
45
+ @events_repository.size
47
46
  end
48
47
 
49
48
  # @return [void]
50
- def clear_chunk
51
- @raw_events.clear
49
+ def clear_events_repository
50
+ @events_repository.clear
51
+ @consumer.clear_unprocessed_events
52
52
  end
53
53
 
54
54
  private
@@ -56,7 +56,9 @@ module PgEventstore
56
56
  def attach_runner_callbacks
57
57
  @basic_runner.define_callback(
58
58
  :process_async, :before,
59
- EventsProcessorHandlers.setup_handler(:process_event, @callbacks, @handler, @raw_events, @raw_events_cond)
59
+ EventsProcessorHandlers.setup_handler(
60
+ :consume_events, @consumer, @callbacks, @events_repository, @repository_cond
61
+ )
60
62
  )
61
63
 
62
64
  @basic_runner.define_callback(
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PgEventstore
4
+ module EventsProcessorConsumer
5
+ # @!visibility private
6
+ class Multiple
7
+ include EventsProcessorConsumer
8
+
9
+ # @return [Float, Integer]
10
+ EVENTS_WAIT_TIMEOUT = 0.5
11
+
12
+ class << self
13
+ # @param handler [#call]
14
+ # @param deserializer [PgEventstore::EventDeserializer]
15
+ # @return [PgEventstore::EventsProcessorConsumer::Multiple]
16
+ def create_consumer(handler, deserializer)
17
+ raw_handler = ->(raw_events) { handler.call(raw_events.map(&deserializer.method(:deserialize))) }
18
+ new(raw_handler)
19
+ end
20
+ end
21
+
22
+ # @param handler [#call]
23
+ def initialize(handler)
24
+ @handler = handler
25
+ @last_unprocessed_events = nil
26
+ end
27
+
28
+ # @return [void]
29
+ def clear_unprocessed_events
30
+ @last_unprocessed_events = nil
31
+ end
32
+
33
+ # @param callbacks [PgEventstore::Callbacks]
34
+ # @param events_repository [PgEventstore::Chunks::Repository]
35
+ # @param repository_cond [MonitorMixin::ConditionVariable]
36
+ # @return [void]
37
+ def call(callbacks, events_repository, repository_cond)
38
+ events_to_process =
39
+ @last_unprocessed_events ||
40
+ events_repository.wait_and_consume(
41
+ entities_num: nil, timeout: EVENTS_WAIT_TIMEOUT, condition: repository_cond
42
+ )
43
+ return if events_to_process.empty?
44
+
45
+ if events_to_process.first.is_a?(Chunks::SubscriptionCheckpointChunk::Checkpoint)
46
+ callbacks.run_callbacks(:checkpoint, events_to_process.first.subscription_position)
47
+ return
48
+ end
49
+
50
+ callbacks.run_callbacks(:process, events_to_process.last.subscription_position, events_to_process.size) do
51
+ @handler.call(events_to_process.map(&:attributes))
52
+ rescue => exception
53
+ @last_unprocessed_events = events_to_process
54
+ raise Utils.wrap_exception(
55
+ exception, subscription_positions: events_to_process.map(&:subscription_position)
56
+ )
57
+ else
58
+ clear_unprocessed_events
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PgEventstore
4
+ module EventsProcessorConsumer
5
+ # @!visibility private
6
+ class Replica
7
+ include EventsProcessorConsumer
8
+
9
+ # @return [Float, Integer]
10
+ EVENTS_WAIT_TIMEOUT = 0.5
11
+
12
+ class << self
13
+ # @param config_name [Symbol]
14
+ # @param replica_config_name [Symbol]
15
+ # @return [PgEventstore::EventsProcessorConsumer::Replica]
16
+ def create_consumer(config_name, replica_config_name)
17
+ handler = ReplicaSubscriptionHandler.new(config_name, replica_config_name)
18
+ raw_handler = ->(events) { handler.call(events) }
19
+ new(raw_handler)
20
+ end
21
+ end
22
+
23
+ # @param handler [#call]
24
+ def initialize(handler)
25
+ @handler = handler
26
+ @last_unprocessed_events = nil
27
+ end
28
+
29
+ # @return [void]
30
+ def clear_unprocessed_events
31
+ @last_unprocessed_events = nil
32
+ end
33
+
34
+ # @param callbacks [PgEventstore::Callbacks]
35
+ # @param events_repository [PgEventstore::Chunks::Repository]
36
+ # @param repository_cond [MonitorMixin::ConditionVariable]
37
+ # @return [void]
38
+ def call(callbacks, events_repository, repository_cond)
39
+ events_to_process =
40
+ @last_unprocessed_events ||
41
+ events_repository.wait_and_consume(
42
+ entities_num: nil, timeout: EVENTS_WAIT_TIMEOUT, condition: repository_cond
43
+ )
44
+ return if events_to_process.empty?
45
+
46
+ if events_to_process.first.is_a?(Chunks::SubscriptionCheckpointChunk::Checkpoint)
47
+ callbacks.run_callbacks(:checkpoint, events_to_process.first.subscription_position)
48
+ return
49
+ end
50
+
51
+ callbacks.run_callbacks(:process, events_to_process.last.subscription_position, events_to_process.size) do
52
+ @handler.call(events_to_process)
53
+ rescue => exception
54
+ @last_unprocessed_events = events_to_process
55
+ raise Utils.wrap_exception(
56
+ exception,
57
+ subscription_position_range: [
58
+ events_to_process.first.subscription_position,
59
+ events_to_process.last.subscription_position,
60
+ ]
61
+ )
62
+ else
63
+ clear_unprocessed_events
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PgEventstore
4
+ module EventsProcessorConsumer
5
+ # @!visibility private
6
+ class Single
7
+ include EventsProcessorConsumer
8
+
9
+ # @return [Float, Integer]
10
+ EVENT_WAIT_TIMEOUT = 0.5
11
+
12
+ class << self
13
+ # @param handler [#call]
14
+ # @param deserializer [PgEventstore::EventDeserializer]
15
+ # @return [PgEventstore::EventsProcessorConsumer::Single]
16
+ def create_consumer(handler, deserializer)
17
+ raw_handler = ->(raw_event) { handler.call(deserializer.deserialize(raw_event)) }
18
+ new(raw_handler)
19
+ end
20
+ end
21
+
22
+ # @param handler [#call]
23
+ def initialize(handler)
24
+ @handler = handler
25
+ @last_unprocessed_event = nil
26
+ end
27
+
28
+ # @return [void]
29
+ def clear_unprocessed_events
30
+ @last_unprocessed_event = nil
31
+ end
32
+
33
+ # @param callbacks [PgEventstore::Callbacks]
34
+ # @param events_repository [PgEventstore::Chunks::Repository]
35
+ # @param repository_cond [MonitorMixin::ConditionVariable]
36
+ # @return [void]
37
+ def call(callbacks, events_repository, repository_cond)
38
+ raw_event =
39
+ @last_unprocessed_event ||
40
+ events_repository.wait_and_consume(
41
+ entities_num: 1, timeout: EVENT_WAIT_TIMEOUT, condition: repository_cond
42
+ ).first
43
+
44
+ return if raw_event.nil?
45
+
46
+ if raw_event.is_a?(Chunks::SubscriptionCheckpointChunk::Checkpoint)
47
+ callbacks.run_callbacks(:checkpoint, raw_event.subscription_position)
48
+ return
49
+ end
50
+
51
+ callbacks.run_callbacks(:process, raw_event.subscription_position, 1) do
52
+ @handler.call(raw_event.attributes)
53
+ rescue => exception
54
+ @last_unprocessed_event = raw_event
55
+ raise Utils.wrap_exception(exception, global_position: raw_event.subscription_position)
56
+ else
57
+ clear_unprocessed_events
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PgEventstore
4
+ # @!visibility private
5
+ module EventsProcessorConsumer
6
+ class << self
7
+ # @param in_batches [Boolean]
8
+ # @return [Class]
9
+ def consumer_class(in_batches)
10
+ return Multiple if in_batches
11
+
12
+ Single
13
+ end
14
+
15
+ def included(othermod)
16
+ othermod.extend(ClassMethods)
17
+ super
18
+ end
19
+ end
20
+
21
+ module ClassMethods
22
+ def create_consumer(handler, deserializer)
23
+ raise NotImplementedError
24
+ end
25
+ end
26
+
27
+ # @param callbacks [PgEventstore::Callbacks]
28
+ # @param repository [PgEventstore::Chunks::Repository]
29
+ # @param repository_cond [MonitorMixin::ConditionVariable]
30
+ # @return [void]
31
+ def call(callbacks, repository, repository_cond)
32
+ raise NotImplementedError
33
+ end
34
+
35
+ # @return [void]
36
+ def clear_unprocessed_events
37
+ raise NotImplementedError
38
+ end
39
+ end
40
+ end
41
+
42
+ require_relative 'events_processor_consumer/single'
43
+ require_relative 'events_processor_consumer/multiple'
44
+ require_relative 'events_processor_consumer/replica'
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PgEventstore
4
+ # @!visibility private
5
+ class EventsSubscriptionPositionWorker
6
+ extend Forwardable
7
+
8
+ attr_reader :config_name
9
+
10
+ def_delegators :@basic_runner, :start, :stop, :state, :stop_async, :wait_for_finish
11
+
12
+ class ReindexTime
13
+ include Extensions::OptionsExtension
14
+ include Extensions::OptionsDefaults
15
+
16
+ option(:time)
17
+ end
18
+
19
+ # @param config_name [Symbol]
20
+ def initialize(config_name)
21
+ @config_name = config_name
22
+ @basic_runner = BasicRunner.new(
23
+ run_interval: 0,
24
+ async_shutdown_time: 5,
25
+ recovery_strategies: [RunnerRecoveryStrategies::RestoreConnection.new(config_name)]
26
+ )
27
+ @next_reindex_at = ReindexTime.new
28
+ attach_runner_callbacks
29
+ end
30
+
31
+ private
32
+
33
+ # @return [void]
34
+ def attach_runner_callbacks
35
+ @basic_runner.define_callback(
36
+ :process_async, :before,
37
+ EventsSubscriptionPositionWorkerHandlers.setup_handler(
38
+ :assign_subscription_position,
39
+ event_subscription_position_queries,
40
+ config.events_subscription_position_update_interval
41
+ )
42
+ )
43
+ @basic_runner.define_callback(
44
+ :process_async, :before,
45
+ EventsSubscriptionPositionWorkerHandlers.setup_handler(
46
+ :reindex,
47
+ event_subscription_position_queries,
48
+ @next_reindex_at
49
+ )
50
+ )
51
+ end
52
+
53
+ # @return [PgEventstore::EventSubscriptionPositionQueries]
54
+ def event_subscription_position_queries
55
+ EventSubscriptionPositionQueries.new(connection)
56
+ end
57
+
58
+ # @return [PgEventstore::Connection]
59
+ def connection
60
+ PgEventstore.connection(config_name)
61
+ end
62
+
63
+ # @return [PgEventstore::Config]
64
+ def config
65
+ PgEventstore.config(config_name)
66
+ end
67
+ end
68
+ end