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
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PgEventstore
4
+ module Commands
5
+ # @!visibility private
6
+ class ReadStreams < AbstractCommand
7
+ # @param options [Hash] request options
8
+ # @option options [String] :direction
9
+ # @option options [Integer] :from_position
10
+ # @option options [Integer] :max_count
11
+ # @return [Array<PgEventstore::Stream>]
12
+ def call(options: {})
13
+ indexes = queries.streams_global_index.streams_global_index(options)
14
+ queries.streams_global_index.resolve_indexes(indexes)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PgEventstore
4
+ module Commands
5
+ # @!visibility private
6
+ class ReadStreamsPaginated < AbstractCommand
7
+ # @param options [Hash] request options
8
+ # @option options [String] :direction
9
+ # @option options [Integer] :from_position
10
+ # @option options [Integer] :max_count
11
+ # @return [Enumerator]
12
+ def call(options: {})
13
+ Enumerator.new do |yielder|
14
+ next_position = nil
15
+ loop do
16
+ options = options.merge(from_position: next_position) if next_position
17
+ indexes = queries.streams_global_index.streams_global_index(options)
18
+ streams = queries.streams_global_index.resolve_indexes(indexes)
19
+ yielder << streams if streams.any?
20
+ if end_reached?(streams, options[:max_count] || QueryBuilders::StreamsGlobalIndexFiltering::DEFAULT_LIMIT)
21
+ raise StopIteration
22
+ end
23
+
24
+ next_position = calc_next_position(indexes, options[:direction])
25
+ raise StopIteration if next_position <= 0
26
+ end
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ # @param streams [Array<PgEventstore::Stream>]
33
+ # @param max_count [Integer]
34
+ # @return [Boolean]
35
+ def end_reached?(streams, max_count)
36
+ streams.size < max_count
37
+ end
38
+
39
+ # @param indexes [Array<PgEventstore::StreamGlobalIndex>]
40
+ # @param direction [String, Symbol, nil]
41
+ # @return [Integer]
42
+ def calc_next_position(indexes, direction)
43
+ return indexes.last.starting_position + 1 if forwards?(direction)
44
+
45
+ indexes.last.starting_position - 1
46
+ end
47
+
48
+ # @param direction [String, Symbol, nil]
49
+ # @return [Boolean]
50
+ def forwards?(direction)
51
+ QueryBuilders::StreamsGlobalIndexFiltering::SQL_DIRECTIONS[direction] ==
52
+ QueryBuilders::StreamsGlobalIndexFiltering::SQL_DIRECTIONS[:asc]
53
+ end
54
+ end
55
+ end
56
+ end
@@ -5,14 +5,14 @@ module PgEventstore
5
5
  # @!visibility private
6
6
  class RegularStreamReadPaginated < AbstractCommand
7
7
  # @see PgEventstore::Commands::Read for docs
8
- def call(stream, options: {})
8
+ def call(stream, deserializer:, options: {})
9
9
  Enumerator.new do |yielder|
10
10
  next_revision = nil
11
11
  loop do
12
12
  options = options.merge(from_revision: next_revision) if next_revision
13
- events = read_cmd.call(stream, options:)
13
+ events = read_cmd.call(stream, deserializer:, options:)
14
14
  yielder << events if events.any?
15
- if end_reached?(events, options[:max_count] || QueryBuilders::EventsFiltering::DEFAULT_LIMIT)
15
+ if end_reached?(events, options[:max_count] || QueryBuilders::EventsGlobalIndexFiltering::DEFAULT_LIMIT)
16
16
  raise StopIteration
17
17
  end
18
18
 
@@ -43,7 +43,7 @@ module PgEventstore
43
43
  # @param direction [String, Symbol, nil]
44
44
  # @return [Boolean]
45
45
  def forwards?(direction)
46
- QueryBuilders::EventsFiltering::SQL_DIRECTIONS[direction] == QueryBuilders::EventsFiltering::SQL_DIRECTIONS[:asc]
46
+ QueryBuilders::BasicFiltering::SQL_DIRECTIONS[direction] == QueryBuilders::BasicFiltering::SQL_DIRECTIONS[:asc]
47
47
  end
48
48
 
49
49
  # @return [PgEventstore::Commands::Read]
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PgEventstore
4
+ module Commands
5
+ module RevisionCheck
6
+ # @!visibility private
7
+ class CurrentRevision
8
+ class StreamRevision
9
+ include Extensions::OptionsExtension
10
+ include Extensions::OptionsDefaults
11
+
12
+ # @!attribute revision
13
+ # @return [Integer]
14
+ attribute(:revision)
15
+ end
16
+
17
+ class EventTypeRevisions
18
+ include Extensions::OptionsExtension
19
+ include Extensions::OptionsDefaults
20
+
21
+ # @!attribute revisions
22
+ # @return [Array<PgEventstore::EventsGlobalIndex::RevisionCheckRepr>]
23
+ attribute(:revisions)
24
+ end
25
+
26
+ class << self
27
+ # @param stream [PgEventstore::Stream]
28
+ # @param stream_revision [Integer]
29
+ # @param expected_revision [ExpectedRevision::StreamRevision, ExpectedRevision::EventTypeRevisions, nil]
30
+ # @param index_filtering_queries [PgEventstore::IndexFilteringQueries]
31
+ # @return [CurrentRevision::StreamRevision, CurrentRevision::EventTypeRevisions, nil]
32
+ def build(stream, stream_revision, expected_revision, index_filtering_queries)
33
+ case expected_revision
34
+ in ExpectedRevision::StreamRevision
35
+ StreamRevision.new(revision: stream_revision)
36
+ in ExpectedRevision::EventTypeRevisions
37
+ indexes = index_filtering_queries.fetch_indexes_for_revision_validation(
38
+ stream, expected_revision.revisions
39
+ )
40
+ EventTypeRevisions.new(revisions: indexes)
41
+ in NilClass
42
+ # do nothing
43
+ else
44
+ raise ArgumentError, "Unsupported expected revision #{expected_revision.inspect}."
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PgEventstore
4
+ module Commands
5
+ module RevisionCheck
6
+ # @!visibility private
7
+ class EventTypeRevisionsComparison
8
+ class << self
9
+ # @param current_revision [Integer]
10
+ # @param expected_revision [Symbol, Integer]
11
+ # @param expected_markers [Array<String>, nil]
12
+ # @param event_type [String, Symbol]
13
+ # @return [PgEventstore::WrongExpectedTypesRevisionError::Verdict, nil]
14
+ def verdict(current_revision, expected_revision, expected_markers: nil, event_type: :any)
15
+ return if expected_revision == :any
16
+
17
+ verdict_sym =
18
+ case [current_revision, expected_revision]
19
+ in [Event::NON_EXISTING_EVENT_REVISION, Integer]
20
+ :event_is_absent
21
+ in [Integer, Integer]
22
+ :event_revision_does_not_match unless current_revision == expected_revision
23
+ in [Integer, Symbol]
24
+ if current_revision == Event::NON_EXISTING_EVENT_REVISION && expected_revision == :event_exists
25
+ :event_is_absent
26
+ elsif current_revision > Event::NON_EXISTING_EVENT_REVISION && expected_revision == :no_event
27
+ :event_is_present
28
+ end
29
+ else
30
+ Utils.missing_implementation!([current_revision, expected_revision])
31
+ end
32
+ return unless verdict_sym
33
+
34
+ WrongExpectedTypesRevisionError::Verdict.new(
35
+ verdict: verdict_sym,
36
+ event_type:,
37
+ current_revision:,
38
+ expected_revision:,
39
+ expected_markers:
40
+ )
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,135 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PgEventstore
4
+ module Commands
5
+ module RevisionCheck
6
+ # @!visibility private
7
+ class ExpectedRevision
8
+ class StreamRevision
9
+ include Extensions::OptionsExtension
10
+ include Extensions::OptionsDefaults
11
+
12
+ # @!attribute revision
13
+ # @return [Symbol, Integer]
14
+ attribute(:revision)
15
+ end
16
+
17
+ class EventTypeRevision
18
+ include Extensions::OptionsExtension
19
+ include Extensions::OptionsDefaults
20
+
21
+ # @!attribute expected_revision
22
+ # @return [Symbol, Integer]
23
+ attribute(:expected_revision)
24
+ # @!attribute event_type
25
+ # @return [String, nil]
26
+ attribute(:event_type)
27
+ # @!attribute sequence_number
28
+ # @return [Integer]
29
+ attribute(:sequence_number)
30
+ end
31
+
32
+ class EventTypeRevisionWithMarkers
33
+ include Extensions::OptionsExtension
34
+ include Extensions::OptionsDefaults
35
+
36
+ # @!attribute expected_revision
37
+ # @return [Symbol, Integer]
38
+ attribute(:expected_revision)
39
+ # @!attribute event_type
40
+ # @return [String, nil]
41
+ attribute(:event_type)
42
+ # @!attribute markers
43
+ # @return [Array<String>]
44
+ attribute(:markers)
45
+ # @!attribute sequence_number
46
+ # @return [Integer]
47
+ attribute(:sequence_number)
48
+ end
49
+
50
+ class MarkersRevision
51
+ include Extensions::OptionsExtension
52
+ include Extensions::OptionsDefaults
53
+
54
+ # @!attribute expected_revision
55
+ # @return [Symbol, Integer]
56
+ attribute(:expected_revision)
57
+ # @!attribute markers
58
+ # @return [Array<String>]
59
+ attribute(:markers)
60
+ # @!attribute sequence_number
61
+ # @return [Integer]
62
+ attribute(:sequence_number)
63
+ end
64
+
65
+ class EventTypeRevisions
66
+ include Extensions::OptionsExtension
67
+ include Extensions::OptionsDefaults
68
+
69
+ # @!attribute revisions
70
+ # @return [Array<EventTypeRevision, EventTypeRevisionWithMarkers, MarkersRevision>]
71
+ attribute(:revisions)
72
+ end
73
+
74
+ class << self
75
+ # @param expected_revision [Symbol, Integer, Hash]
76
+ # @return [ExpectedRevision::StreamRevision, ExpectedRevision::EventTypeRevisions, nil]
77
+ def build(expected_revision)
78
+ case expected_revision
79
+ in Integer | Symbol
80
+ StreamRevision.new(revision: expected_revision)
81
+ in Hash
82
+ revisions = expected_revision.map.with_index do |(key, value), index|
83
+ case [key, value]
84
+ # { 'Foo' => 1 }, { 'Foo' => :any }, etc
85
+ in [String, Integer | Symbol]
86
+ EventTypeRevision.new(event_type: key, expected_revision: value, sequence_number: index)
87
+ # { 'Foo' => { expected_revision: 1, markers: ['foo'] } },
88
+ # { 'Foo' => { expected_revision: :any, markers: ['foo'] } }, etc
89
+ in [String, Hash]
90
+ markers = extract_markers(value)
91
+ expected_revision = extract_expected_revision(value)
92
+ EventTypeRevisionWithMarkers.new(
93
+ event_type: key, expected_revision:, markers:, sequence_number: index
94
+ )
95
+ # { any: => { expected_revision: 1, markers: ['foo'] } },
96
+ # { any: => { expected_revision: :any, markers: ['foo'] } }, etc
97
+ in [:any, Hash]
98
+ markers = extract_markers(value)
99
+ expected_revision = extract_expected_revision(value)
100
+ MarkersRevision.new(expected_revision:, markers:, sequence_number: index)
101
+ else
102
+ nil
103
+ end
104
+ end.compact
105
+ EventTypeRevisions.new(revisions:)
106
+ in NilClass
107
+ # do nothing
108
+ else
109
+ raise ArgumentError, "Unsupported :expected_revision #{expected_revision.inspect} option."
110
+ end
111
+ end
112
+
113
+ private
114
+
115
+ # @param hash [Hash]
116
+ # @return [Symbol, Integer]
117
+ def extract_expected_revision(hash)
118
+ hash in { expected_revision: Symbol | Integer => expected_revision }
119
+ expected_revision ||
120
+ raise(ArgumentError, "Unsupported expected revision #{hash[:expected_revision].inspect} value.")
121
+ end
122
+
123
+ # @param hash [Hash]
124
+ # @return [Array<String>]
125
+ def extract_markers(hash)
126
+ markers = hash[:markers]&.grep(String)
127
+ raise ArgumentError, "Unsupported markers: #{hash[:markers].inspect}." if markers.nil? || markers.empty?
128
+
129
+ markers
130
+ end
131
+ end
132
+ end
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,98 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'expected_revision'
4
+ require_relative 'current_revision'
5
+ require_relative 'event_type_revisions_comparison'
6
+ require_relative 'stream_revision_comparison'
7
+
8
+ module PgEventstore
9
+ module Commands
10
+ module RevisionCheck
11
+ # @!visibility private
12
+ class StreamRevisionCheck
13
+ class << self
14
+ # @param current_revision [CurrentRevision::StreamRevision, CurrentRevision::EventTypeRevisions, nil]
15
+ # @param expected_revision [ExpectedRevision::StreamRevision, ExpectedRevision::EventTypeRevisions, nil]
16
+ # @param stream [PgEventstore::Stream]
17
+ # @return [void]
18
+ def assert_eq!(current_revision, expected_revision, stream)
19
+ case [current_revision, expected_revision]
20
+ in [_, NilClass]
21
+ # do nothing. We don't have expected revision
22
+ in [CurrentRevision::StreamRevision, ExpectedRevision::StreamRevision]
23
+ verdict = StreamRevisionComparison.verdict(current_revision.revision, expected_revision.revision)
24
+ if verdict
25
+ raise WrongExpectedRevisionError.new(
26
+ revision: current_revision.revision,
27
+ expected_revision: expected_revision.revision,
28
+ stream:,
29
+ verdict:
30
+ )
31
+ end
32
+ in [CurrentRevision::EventTypeRevisions, ExpectedRevision::EventTypeRevisions]
33
+ verdicts = []
34
+ rev_check_indexes = current_revision.revisions.to_h { [_1.sequence_number, _1] }
35
+ expected_revision.revisions.each do |revision|
36
+ index = find_index(revision, rev_check_indexes)
37
+ verdict =
38
+ case revision
39
+ when ExpectedRevision::EventTypeRevision
40
+ EventTypeRevisionsComparison.verdict(
41
+ index.stream_revision,
42
+ revision.expected_revision,
43
+ event_type: revision.event_type
44
+ )
45
+ when ExpectedRevision::EventTypeRevisionWithMarkers
46
+ EventTypeRevisionsComparison.verdict(
47
+ index.stream_revision,
48
+ revision.expected_revision,
49
+ expected_markers: revision.markers,
50
+ event_type: revision.event_type
51
+ )
52
+ when ExpectedRevision::MarkersRevision
53
+ EventTypeRevisionsComparison.verdict(
54
+ index.stream_revision,
55
+ revision.expected_revision,
56
+ expected_markers: revision.markers
57
+ )
58
+ else
59
+ Utils.missing_implementation!(revision)
60
+ end
61
+ verdicts.push(verdict) if verdict
62
+ end
63
+ raise WrongExpectedTypesRevisionError.new(stream:, verdicts:) if verdicts.any?
64
+ else
65
+ Utils.missing_implementation!([current_revision, expected_revision])
66
+ end
67
+ end
68
+
69
+ private
70
+
71
+ # @param expected_revision [ExpectedRevision::EventTypeRevision,
72
+ # ExpectedRevision::EventTypeRevisionWithMarkers, ExpectedRevision::MarkersRevision]
73
+ # @param rev_check_indexes [Hash<Integer, PgEventstore::EventGlobalIndex::RevisionCheckRepr>]
74
+ # @return [PgEventstore::EventGlobalIndex::RevisionCheckRepr]
75
+ def find_index(expected_revision, rev_check_indexes)
76
+ from_dictionary = rev_check_indexes[expected_revision.sequence_number]
77
+ return from_dictionary if from_dictionary
78
+
79
+ case expected_revision
80
+ when ExpectedRevision::EventTypeRevision
81
+ EventGlobalIndex::RevisionCheckRepr.new(
82
+ sequence_number: expected_revision.sequence_number, stream_revision: Event::NON_EXISTING_EVENT_REVISION
83
+ )
84
+ when ExpectedRevision::EventTypeRevisionWithMarkers, ExpectedRevision::MarkersRevision
85
+ EventGlobalIndex::RevisionCheckRepr.new(
86
+ sequence_number: expected_revision.sequence_number,
87
+ stream_revision: Event::NON_EXISTING_EVENT_REVISION,
88
+ marker: Event::SYSTEM_SYMBOL
89
+ )
90
+ else
91
+ Utils.missing_implementation!(expected_revision)
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PgEventstore
4
+ module Commands
5
+ module RevisionCheck
6
+ # @!visibility private
7
+ class StreamRevisionComparison
8
+ class << self
9
+ # @param current_revision [Integer]
10
+ # @param expected_revision [Integer, Symbol]
11
+ # @return [Symbol]
12
+ def verdict(current_revision, expected_revision)
13
+ return if expected_revision == :any
14
+
15
+ case [current_revision, expected_revision]
16
+ in [Stream::NON_EXISTING_STREAM_REVISION, Integer]
17
+ :expected_to_have_stream_with_given_revision
18
+ in [Integer, Integer]
19
+ :unmatched_stream_revision unless current_revision == expected_revision
20
+ in [Integer, Symbol]
21
+ if current_revision == Stream::NON_EXISTING_STREAM_REVISION && expected_revision == :stream_exists
22
+ return :expected_to_have_stream
23
+ end
24
+
25
+ if current_revision > Stream::NON_EXISTING_STREAM_REVISION && expected_revision == :no_stream
26
+ :expected_not_to_have_stream
27
+ end
28
+ else
29
+ raise ArgumentError
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PgEventstore
4
+ module Commands
5
+ # @!visibility private
6
+ class StreamRevision < AbstractCommand
7
+ # @param stream [PgEventstore::Stream]
8
+ # @return [Integer]
9
+ def call(stream)
10
+ queries.streams_global_index.stream_revision(stream) || Stream::NON_EXISTING_STREAM_REVISION
11
+ end
12
+ end
13
+ end
14
+ end
@@ -5,14 +5,14 @@ module PgEventstore
5
5
  # @!visibility private
6
6
  class SystemStreamReadPaginated < AbstractCommand
7
7
  # @see PgEventstore::Commands::Read for docs
8
- def call(stream, options: {})
8
+ def call(stream, deserializer:, options: {})
9
9
  Enumerator.new do |yielder|
10
10
  next_position = nil
11
11
  loop do
12
12
  options = options.merge(from_position: next_position) if next_position
13
- events = read_cmd.call(stream, options:)
13
+ events = read_cmd.call(stream, deserializer:, options:)
14
14
  yielder << events if events.any?
15
- if end_reached?(events, options[:max_count] || QueryBuilders::EventsFiltering::DEFAULT_LIMIT)
15
+ if end_reached?(events, options[:max_count] || QueryBuilders::EventsGlobalIndexFiltering::DEFAULT_LIMIT)
16
16
  raise StopIteration
17
17
  end
18
18
 
@@ -43,7 +43,7 @@ module PgEventstore
43
43
  # @param direction [String, Symbol, nil]
44
44
  # @return [Boolean]
45
45
  def forwards?(direction)
46
- QueryBuilders::EventsFiltering::SQL_DIRECTIONS[direction] == QueryBuilders::EventsFiltering::SQL_DIRECTIONS[:asc]
46
+ QueryBuilders::BasicFiltering::SQL_DIRECTIONS[direction] == QueryBuilders::BasicFiltering::SQL_DIRECTIONS[:asc]
47
47
  end
48
48
 
49
49
  # @return [PgEventstore::Commands::Read]
@@ -5,11 +5,13 @@ require_relative 'commands/event_modifiers/prepare_link_event'
5
5
  require_relative 'commands/event_modifiers/prepare_regular_event'
6
6
  require_relative 'commands/append'
7
7
  require_relative 'commands/read'
8
- require_relative 'commands/regular_stream_read_grouped'
9
- require_relative 'commands/all_stream_read_grouped'
8
+ require_relative 'commands/read_grouped'
9
+ require_relative 'commands/read_streams'
10
+ require_relative 'commands/read_streams_paginated'
10
11
  require_relative 'commands/regular_stream_read_paginated'
11
12
  require_relative 'commands/system_stream_read_paginated'
12
13
  require_relative 'commands/multiple'
13
14
  require_relative 'commands/link_to'
14
15
  require_relative 'commands/delete_stream'
15
16
  require_relative 'commands/delete_event'
17
+ require_relative 'commands/stream_revision'
@@ -1,10 +1,27 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PgEventstore
4
- class Config
5
- include Extensions::OptionsExtension
4
+ class Config < BasicConfig
5
+ module NodeRole
6
+ # @return [Symbol]
7
+ STANDALONE = :standalone
8
+ # @return [Symbol]
9
+ PRIMARY = :primary
10
+ # @return [Symbol]
11
+ REPLICA = :replica
6
12
 
7
- attr_reader :name
13
+ class << self
14
+ # @return [Array<Symbol>]
15
+ def writable
16
+ [STANDALONE, PRIMARY]
17
+ end
18
+
19
+ # @return [Array<Symbol>]
20
+ def maintainable
21
+ [STANDALONE]
22
+ end
23
+ end
24
+ end
8
25
 
9
26
  # @!attribute pg_uri
10
27
  # @return [String] PostgreSQL connection URI docs
@@ -55,16 +72,20 @@ module PgEventstore
55
72
  # @!attribute subscription_graceful_shutdown_timeout
56
73
  # @return [Integer] the number of seconds to wait until force-shutdown the subscription during the stop process
57
74
  option(:subscription_graceful_shutdown_timeout) { 15 }
58
-
59
- # @param name [Symbol] config's name. Its value matches the appropriate key in PgEventstore.config hash
60
- def initialize(name:, **options)
61
- super
62
- @name = name
63
- end
75
+ # @!attribute events_subscription_position_update_interval
76
+ # @return [Float, Integer] events subscription position update interval
77
+ option(:events_subscription_position_update_interval) { 0.2 }
78
+ # @!attribute eventstore_role
79
+ # @return [Symbol] the role of this node
80
+ option(:eventstore_role) { NodeRole::STANDALONE }
81
+ # @!attribute max_events_to_replicate
82
+ # @return [Integer] max number of events to replicate at a time
83
+ option(:max_events_to_replicate) { 10_000 }
64
84
 
65
85
  # Computes a value for usage in PgEventstore::Connection
66
86
  # @return [Hash]
67
87
  def connection_options
88
+ puts "DEPRECATED: Config##{__method__} will be removed in next major version with no replacement"
68
89
  { uri: pg_uri, pool_size: connection_pool_size, pool_timeout: connection_pool_timeout }
69
90
  end
70
91
  end
@@ -31,17 +31,22 @@ module PgEventstore
31
31
  end
32
32
 
33
33
  # A shorthand from ConnectionPool#with.
34
- # @yieldparam connection [PG::Connection] PostgreSQL connection instance
34
+ # @yieldparam connection [PgEventstore::PgConnection] PostgreSQL connection instance
35
35
  # @return [Object] a value of a given block
36
36
  def with(&)
37
37
  should_retry = true
38
38
  @pool.with do |conn|
39
39
  yield conn
40
40
  rescue PG::ConnectionBad, PG::UnableToSend
41
+ unless should_retry
42
+ # Connection is broken. We should throw it away
43
+ @pool.discard_current_connection
44
+ raise
45
+ end
46
+
41
47
  # Recover a connection after fork or when we lost a connection to PostgreSQL. We retry only once and without any
42
48
  # delay.
43
49
  conn.sync_reset
44
- raise unless should_retry
45
50
 
46
51
  should_retry = false
47
52
  retry
@@ -53,6 +58,20 @@ module PgEventstore
53
58
  @pool.shutdown(&:close)
54
59
  end
55
60
 
61
+ # Restore connection after shutdown by re-initializing connection pool
62
+ # @return [void]
63
+ def establish_connection
64
+ @pool = nil
65
+ init_pool
66
+ end
67
+
68
+ # @return [void]
69
+ def discard_current_connection
70
+ @pool.discard_current_connection do |conn|
71
+ conn.close unless conn.finished?
72
+ end
73
+ end
74
+
56
75
  private
57
76
 
58
77
  # @return [ConnectionPool]