messaging 3.8.2 → 4.0.0.pre
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/.circleci/config.yml +6 -3
- data/.env +1 -1
- data/Gemfile +0 -7
- data/Gemfile.lock +104 -333
- data/bin/console +2 -3
- data/docker-compose.yml +1 -3
- data/lib/messaging/adapters/kafka.rb +1 -1
- data/lib/messaging/adapters/postgres/categories.rb +2 -2
- data/lib/messaging/adapters/postgres/category.rb +4 -0
- data/lib/messaging/adapters/postgres/consumer.rb +85 -0
- data/lib/messaging/adapters/postgres/create_lock.rb +28 -0
- data/lib/messaging/adapters/postgres/release_lock.rb +24 -0
- data/lib/messaging/adapters/postgres/serialized_message.rb +28 -0
- data/lib/messaging/adapters/postgres.rb +12 -0
- data/lib/messaging/config_23.rb +71 -0
- data/lib/messaging/consumer_supervisor.rb +1 -0
- data/lib/messaging/message.rb +2 -0
- data/lib/messaging/routing/message_matcher.rb +4 -0
- data/lib/messaging/routing/route.rb +4 -0
- data/lib/messaging/routing.rb +4 -0
- data/lib/messaging/routing_23.rb +97 -0
- data/lib/messaging/version.rb +1 -1
- data/lib/messaging.rb +17 -2
- data/messaging.gemspec +2 -3
- metadata +20 -29
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 04daa6dc85f15f5b160d49512f00a50d4fc378a8f597250ba07a5ea33955a26b
|
|
4
|
+
data.tar.gz: 45b51d553a5bc2b34381e553d741a5ba5c7e4cf4707ba5da727381fb73c8ca41
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a5f69b09408a3df46b9dc22f984c0588cc9276bfa530a5a86abc0d3759eba732fc596c4af5fa66f10d7f33a713723222460aa2c4ae0c3368625dbc8d6316fdee
|
|
7
|
+
data.tar.gz: fdf6cf4254e2cb44e255b41dde00b31edeec9c565e448fe000f6a63d0a2551a1ef766df4e96a268f01fb576a125d9b76a266e6996349d4c6f807b25c121e3ab8
|
data/.circleci/config.yml
CHANGED
|
@@ -8,12 +8,11 @@ orbs:
|
|
|
8
8
|
|
|
9
9
|
shared: &shared
|
|
10
10
|
docker:
|
|
11
|
-
|
|
12
|
-
- image: ghcr.io/bukowskis/base-image/development:ruby-2.7.6-v2
|
|
11
|
+
- image: ghcr.io/bukowskis/base-image/development:ruby-3.3.1-bookworm-v2
|
|
13
12
|
auth:
|
|
14
13
|
username: $GHCR_USER
|
|
15
14
|
password: $GHCR_PASSWORD
|
|
16
|
-
- image: cimg/postgres:
|
|
15
|
+
- image: cimg/postgres:16.1
|
|
17
16
|
environment:
|
|
18
17
|
- POSTGRES_HOST_AUTH_METHOD: trust
|
|
19
18
|
resource_class: large
|
|
@@ -49,6 +48,10 @@ jobs:
|
|
|
49
48
|
command: |
|
|
50
49
|
curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
|
51
50
|
chmod +x ./cc-test-reporter
|
|
51
|
+
- run:
|
|
52
|
+
name: Add postgres to hosts
|
|
53
|
+
command: |
|
|
54
|
+
tee -a /etc/hosts \<<<'127.0.0.1 postgres'
|
|
52
55
|
- run:
|
|
53
56
|
name: Database Setup
|
|
54
57
|
command: |
|
data/.env
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
PG_VERSION=
|
|
1
|
+
PG_VERSION=16
|
data/Gemfile
CHANGED
|
@@ -1,16 +1,9 @@
|
|
|
1
1
|
source 'https://rubygems.org'
|
|
2
2
|
|
|
3
|
-
git_source(:github) { |path| "https://github.com/#{path}.git" }
|
|
4
|
-
|
|
5
3
|
gem 'bootsnap', require: false
|
|
6
4
|
gem 'listen'
|
|
7
5
|
gem 'pg'
|
|
8
|
-
gem 'pry'
|
|
9
|
-
gem 'pry-rails'
|
|
10
6
|
gem 'railties'
|
|
11
7
|
gem 'sidekiq'
|
|
12
8
|
|
|
13
|
-
gem "github-pages", '203', group: :jekyll_plugins
|
|
14
|
-
gem "jekyll-include-cache", group: :jekyll_plugins
|
|
15
|
-
|
|
16
9
|
gemspec
|
data/Gemfile.lock
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
messaging (
|
|
4
|
+
messaging (4.0.0.pre)
|
|
5
5
|
activerecord
|
|
6
6
|
activesupport
|
|
7
7
|
after_transaction
|
|
8
8
|
concurrent-ruby (>= 1.0.2)
|
|
9
9
|
concurrent-ruby-ext (>= 1.0.2)
|
|
10
|
-
dry-configurable
|
|
10
|
+
dry-configurable
|
|
11
11
|
dry-container
|
|
12
12
|
dry-equalizer
|
|
13
13
|
dry-initializer
|
|
@@ -19,398 +19,169 @@ PATH
|
|
|
19
19
|
GEM
|
|
20
20
|
remote: https://rubygems.org/
|
|
21
21
|
specs:
|
|
22
|
-
actionpack (
|
|
23
|
-
actionview (=
|
|
24
|
-
activesupport (=
|
|
25
|
-
rack (~> 2.0)
|
|
22
|
+
actionpack (7.0.8)
|
|
23
|
+
actionview (= 7.0.8)
|
|
24
|
+
activesupport (= 7.0.8)
|
|
25
|
+
rack (~> 2.0, >= 2.2.4)
|
|
26
26
|
rack-test (>= 0.6.3)
|
|
27
27
|
rails-dom-testing (~> 2.0)
|
|
28
|
-
rails-html-sanitizer (~> 1.0, >= 1.0
|
|
29
|
-
actionview (
|
|
30
|
-
activesupport (=
|
|
28
|
+
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
|
29
|
+
actionview (7.0.8)
|
|
30
|
+
activesupport (= 7.0.8)
|
|
31
31
|
builder (~> 3.1)
|
|
32
32
|
erubi (~> 1.4)
|
|
33
33
|
rails-dom-testing (~> 2.0)
|
|
34
|
-
rails-html-sanitizer (~> 1.
|
|
35
|
-
activemodel (
|
|
36
|
-
activesupport (=
|
|
37
|
-
activerecord (
|
|
38
|
-
activemodel (=
|
|
39
|
-
activesupport (=
|
|
40
|
-
|
|
41
|
-
activesupport (5.2.4)
|
|
34
|
+
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
|
35
|
+
activemodel (7.0.8)
|
|
36
|
+
activesupport (= 7.0.8)
|
|
37
|
+
activerecord (7.0.8)
|
|
38
|
+
activemodel (= 7.0.8)
|
|
39
|
+
activesupport (= 7.0.8)
|
|
40
|
+
activesupport (7.0.8)
|
|
42
41
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
43
|
-
i18n (>=
|
|
44
|
-
minitest (
|
|
45
|
-
tzinfo (~>
|
|
46
|
-
addressable (2.8.1)
|
|
47
|
-
public_suffix (>= 2.0.2, < 6.0)
|
|
42
|
+
i18n (>= 1.6, < 2)
|
|
43
|
+
minitest (>= 5.1)
|
|
44
|
+
tzinfo (~> 2.0)
|
|
48
45
|
after_transaction (0.0.5)
|
|
49
46
|
activerecord
|
|
50
|
-
arel (9.0.0)
|
|
51
47
|
axiom-types (0.1.1)
|
|
52
48
|
descendants_tracker (~> 0.0.4)
|
|
53
49
|
ice_nine (~> 0.11.0)
|
|
54
50
|
thread_safe (~> 0.3, >= 0.3.1)
|
|
55
|
-
bootsnap (1.
|
|
56
|
-
msgpack (~> 1.
|
|
57
|
-
builder (3.
|
|
58
|
-
coderay (1.1.2)
|
|
51
|
+
bootsnap (1.18.3)
|
|
52
|
+
msgpack (~> 1.2)
|
|
53
|
+
builder (3.3.0)
|
|
59
54
|
coercible (1.0.0)
|
|
60
55
|
descendants_tracker (~> 0.0.1)
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
commonmarker (0.17.13)
|
|
67
|
-
ruby-enum (~> 0.5)
|
|
68
|
-
concurrent-ruby (1.1.10)
|
|
69
|
-
concurrent-ruby-ext (1.1.10)
|
|
70
|
-
concurrent-ruby (= 1.1.10)
|
|
71
|
-
connection_pool (2.2.2)
|
|
72
|
-
crass (1.0.5)
|
|
56
|
+
concurrent-ruby (1.3.3)
|
|
57
|
+
concurrent-ruby-ext (1.3.3)
|
|
58
|
+
concurrent-ruby (= 1.3.3)
|
|
59
|
+
connection_pool (2.4.1)
|
|
60
|
+
crass (1.0.6)
|
|
73
61
|
descendants_tracker (0.0.4)
|
|
74
62
|
thread_safe (~> 0.3, >= 0.3.1)
|
|
75
|
-
diff-lcs (1.
|
|
76
|
-
digest-crc (0.6.
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
docile (1.3.2)
|
|
63
|
+
diff-lcs (1.5.1)
|
|
64
|
+
digest-crc (0.6.5)
|
|
65
|
+
rake (>= 12.0.0, < 14.0.0)
|
|
66
|
+
docile (1.4.0)
|
|
80
67
|
dry-configurable (1.0.1)
|
|
81
68
|
dry-core (~> 1.0, < 2)
|
|
82
69
|
zeitwerk (~> 2.6)
|
|
83
70
|
dry-container (0.11.0)
|
|
84
71
|
concurrent-ruby (~> 1.0)
|
|
85
|
-
dry-core (1.0.
|
|
72
|
+
dry-core (1.0.1)
|
|
86
73
|
concurrent-ruby (~> 1.0)
|
|
87
74
|
zeitwerk (~> 2.6)
|
|
88
75
|
dry-equalizer (0.3.0)
|
|
89
76
|
dry-initializer (3.1.1)
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
ethon (0.16.0)
|
|
95
|
-
ffi (>= 1.15.0)
|
|
96
|
-
eventmachine (1.2.7)
|
|
97
|
-
execjs (2.8.1)
|
|
98
|
-
faraday (2.7.2)
|
|
99
|
-
faraday-net_http (>= 2.0, < 3.1)
|
|
100
|
-
ruby2_keywords (>= 0.0.4)
|
|
101
|
-
faraday-net_http (3.0.2)
|
|
102
|
-
ffi (1.15.5)
|
|
103
|
-
forwardable-extended (2.6.0)
|
|
104
|
-
gemoji (3.0.1)
|
|
105
|
-
github-pages (203)
|
|
106
|
-
github-pages-health-check (= 1.16.1)
|
|
107
|
-
jekyll (= 3.8.5)
|
|
108
|
-
jekyll-avatar (= 0.7.0)
|
|
109
|
-
jekyll-coffeescript (= 1.1.1)
|
|
110
|
-
jekyll-commonmark-ghpages (= 0.1.6)
|
|
111
|
-
jekyll-default-layout (= 0.1.4)
|
|
112
|
-
jekyll-feed (= 0.13.0)
|
|
113
|
-
jekyll-gist (= 1.5.0)
|
|
114
|
-
jekyll-github-metadata (= 2.12.1)
|
|
115
|
-
jekyll-mentions (= 1.5.1)
|
|
116
|
-
jekyll-optional-front-matter (= 0.3.2)
|
|
117
|
-
jekyll-paginate (= 1.1.0)
|
|
118
|
-
jekyll-readme-index (= 0.3.0)
|
|
119
|
-
jekyll-redirect-from (= 0.15.0)
|
|
120
|
-
jekyll-relative-links (= 0.6.1)
|
|
121
|
-
jekyll-remote-theme (= 0.4.1)
|
|
122
|
-
jekyll-sass-converter (= 1.5.2)
|
|
123
|
-
jekyll-seo-tag (= 2.6.1)
|
|
124
|
-
jekyll-sitemap (= 1.4.0)
|
|
125
|
-
jekyll-swiss (= 1.0.0)
|
|
126
|
-
jekyll-theme-architect (= 0.1.1)
|
|
127
|
-
jekyll-theme-cayman (= 0.1.1)
|
|
128
|
-
jekyll-theme-dinky (= 0.1.1)
|
|
129
|
-
jekyll-theme-hacker (= 0.1.1)
|
|
130
|
-
jekyll-theme-leap-day (= 0.1.1)
|
|
131
|
-
jekyll-theme-merlot (= 0.1.1)
|
|
132
|
-
jekyll-theme-midnight (= 0.1.1)
|
|
133
|
-
jekyll-theme-minimal (= 0.1.1)
|
|
134
|
-
jekyll-theme-modernist (= 0.1.1)
|
|
135
|
-
jekyll-theme-primer (= 0.5.4)
|
|
136
|
-
jekyll-theme-slate (= 0.1.1)
|
|
137
|
-
jekyll-theme-tactile (= 0.1.1)
|
|
138
|
-
jekyll-theme-time-machine (= 0.1.1)
|
|
139
|
-
jekyll-titles-from-headings (= 0.5.3)
|
|
140
|
-
jemoji (= 0.11.1)
|
|
141
|
-
kramdown (= 1.17.0)
|
|
142
|
-
liquid (= 4.0.3)
|
|
143
|
-
mercenary (~> 0.3)
|
|
144
|
-
minima (= 2.5.1)
|
|
145
|
-
nokogiri (>= 1.10.4, < 2.0)
|
|
146
|
-
rouge (= 3.13.0)
|
|
147
|
-
terminal-table (~> 1.4)
|
|
148
|
-
github-pages-health-check (1.16.1)
|
|
149
|
-
addressable (~> 2.3)
|
|
150
|
-
dnsruby (~> 1.60)
|
|
151
|
-
octokit (~> 4.0)
|
|
152
|
-
public_suffix (~> 3.0)
|
|
153
|
-
typhoeus (~> 1.3)
|
|
154
|
-
html-pipeline (2.14.3)
|
|
155
|
-
activesupport (>= 2)
|
|
156
|
-
nokogiri (>= 1.4)
|
|
157
|
-
http_parser.rb (0.8.0)
|
|
158
|
-
i18n (0.9.5)
|
|
77
|
+
equalizer (0.0.11)
|
|
78
|
+
erubi (1.12.0)
|
|
79
|
+
ffi (1.17.0)
|
|
80
|
+
i18n (1.14.5)
|
|
159
81
|
concurrent-ruby (~> 1.0)
|
|
160
82
|
ice_nine (0.11.2)
|
|
161
|
-
|
|
162
|
-
addressable (~> 2.4)
|
|
163
|
-
colorator (~> 1.0)
|
|
164
|
-
em-websocket (~> 0.5)
|
|
165
|
-
i18n (~> 0.7)
|
|
166
|
-
jekyll-sass-converter (~> 1.0)
|
|
167
|
-
jekyll-watch (~> 2.0)
|
|
168
|
-
kramdown (~> 1.14)
|
|
169
|
-
liquid (~> 4.0)
|
|
170
|
-
mercenary (~> 0.3.3)
|
|
171
|
-
pathutil (~> 0.9)
|
|
172
|
-
rouge (>= 1.7, < 4)
|
|
173
|
-
safe_yaml (~> 1.0)
|
|
174
|
-
jekyll-avatar (0.7.0)
|
|
175
|
-
jekyll (>= 3.0, < 5.0)
|
|
176
|
-
jekyll-coffeescript (1.1.1)
|
|
177
|
-
coffee-script (~> 2.2)
|
|
178
|
-
coffee-script-source (~> 1.11.1)
|
|
179
|
-
jekyll-commonmark (1.3.1)
|
|
180
|
-
commonmarker (~> 0.14)
|
|
181
|
-
jekyll (>= 3.7, < 5.0)
|
|
182
|
-
jekyll-commonmark-ghpages (0.1.6)
|
|
183
|
-
commonmarker (~> 0.17.6)
|
|
184
|
-
jekyll-commonmark (~> 1.2)
|
|
185
|
-
rouge (>= 2.0, < 4.0)
|
|
186
|
-
jekyll-default-layout (0.1.4)
|
|
187
|
-
jekyll (~> 3.0)
|
|
188
|
-
jekyll-feed (0.13.0)
|
|
189
|
-
jekyll (>= 3.7, < 5.0)
|
|
190
|
-
jekyll-gist (1.5.0)
|
|
191
|
-
octokit (~> 4.2)
|
|
192
|
-
jekyll-github-metadata (2.12.1)
|
|
193
|
-
jekyll (~> 3.4)
|
|
194
|
-
octokit (~> 4.0, != 4.4.0)
|
|
195
|
-
jekyll-include-cache (0.2.0)
|
|
196
|
-
jekyll (>= 3.7, < 5.0)
|
|
197
|
-
jekyll-mentions (1.5.1)
|
|
198
|
-
html-pipeline (~> 2.3)
|
|
199
|
-
jekyll (>= 3.7, < 5.0)
|
|
200
|
-
jekyll-optional-front-matter (0.3.2)
|
|
201
|
-
jekyll (>= 3.0, < 5.0)
|
|
202
|
-
jekyll-paginate (1.1.0)
|
|
203
|
-
jekyll-readme-index (0.3.0)
|
|
204
|
-
jekyll (>= 3.0, < 5.0)
|
|
205
|
-
jekyll-redirect-from (0.15.0)
|
|
206
|
-
jekyll (>= 3.3, < 5.0)
|
|
207
|
-
jekyll-relative-links (0.6.1)
|
|
208
|
-
jekyll (>= 3.3, < 5.0)
|
|
209
|
-
jekyll-remote-theme (0.4.1)
|
|
210
|
-
addressable (~> 2.0)
|
|
211
|
-
jekyll (>= 3.5, < 5.0)
|
|
212
|
-
rubyzip (>= 1.3.0)
|
|
213
|
-
jekyll-sass-converter (1.5.2)
|
|
214
|
-
sass (~> 3.4)
|
|
215
|
-
jekyll-seo-tag (2.6.1)
|
|
216
|
-
jekyll (>= 3.3, < 5.0)
|
|
217
|
-
jekyll-sitemap (1.4.0)
|
|
218
|
-
jekyll (>= 3.7, < 5.0)
|
|
219
|
-
jekyll-swiss (1.0.0)
|
|
220
|
-
jekyll-theme-architect (0.1.1)
|
|
221
|
-
jekyll (~> 3.5)
|
|
222
|
-
jekyll-seo-tag (~> 2.0)
|
|
223
|
-
jekyll-theme-cayman (0.1.1)
|
|
224
|
-
jekyll (~> 3.5)
|
|
225
|
-
jekyll-seo-tag (~> 2.0)
|
|
226
|
-
jekyll-theme-dinky (0.1.1)
|
|
227
|
-
jekyll (~> 3.5)
|
|
228
|
-
jekyll-seo-tag (~> 2.0)
|
|
229
|
-
jekyll-theme-hacker (0.1.1)
|
|
230
|
-
jekyll (~> 3.5)
|
|
231
|
-
jekyll-seo-tag (~> 2.0)
|
|
232
|
-
jekyll-theme-leap-day (0.1.1)
|
|
233
|
-
jekyll (~> 3.5)
|
|
234
|
-
jekyll-seo-tag (~> 2.0)
|
|
235
|
-
jekyll-theme-merlot (0.1.1)
|
|
236
|
-
jekyll (~> 3.5)
|
|
237
|
-
jekyll-seo-tag (~> 2.0)
|
|
238
|
-
jekyll-theme-midnight (0.1.1)
|
|
239
|
-
jekyll (~> 3.5)
|
|
240
|
-
jekyll-seo-tag (~> 2.0)
|
|
241
|
-
jekyll-theme-minimal (0.1.1)
|
|
242
|
-
jekyll (~> 3.5)
|
|
243
|
-
jekyll-seo-tag (~> 2.0)
|
|
244
|
-
jekyll-theme-modernist (0.1.1)
|
|
245
|
-
jekyll (~> 3.5)
|
|
246
|
-
jekyll-seo-tag (~> 2.0)
|
|
247
|
-
jekyll-theme-primer (0.5.4)
|
|
248
|
-
jekyll (> 3.5, < 5.0)
|
|
249
|
-
jekyll-github-metadata (~> 2.9)
|
|
250
|
-
jekyll-seo-tag (~> 2.0)
|
|
251
|
-
jekyll-theme-slate (0.1.1)
|
|
252
|
-
jekyll (~> 3.5)
|
|
253
|
-
jekyll-seo-tag (~> 2.0)
|
|
254
|
-
jekyll-theme-tactile (0.1.1)
|
|
255
|
-
jekyll (~> 3.5)
|
|
256
|
-
jekyll-seo-tag (~> 2.0)
|
|
257
|
-
jekyll-theme-time-machine (0.1.1)
|
|
258
|
-
jekyll (~> 3.5)
|
|
259
|
-
jekyll-seo-tag (~> 2.0)
|
|
260
|
-
jekyll-titles-from-headings (0.5.3)
|
|
261
|
-
jekyll (>= 3.3, < 5.0)
|
|
262
|
-
jekyll-watch (2.2.1)
|
|
263
|
-
listen (~> 3.0)
|
|
264
|
-
jemoji (0.11.1)
|
|
265
|
-
gemoji (~> 3.0)
|
|
266
|
-
html-pipeline (~> 2.2)
|
|
267
|
-
jekyll (>= 3.0, < 5.0)
|
|
268
|
-
json (2.3.0)
|
|
269
|
-
kramdown (1.17.0)
|
|
270
|
-
liquid (4.0.3)
|
|
271
|
-
listen (3.7.1)
|
|
83
|
+
listen (3.9.0)
|
|
272
84
|
rb-fsevent (~> 0.10, >= 0.10.3)
|
|
273
85
|
rb-inotify (~> 0.9, >= 0.9.10)
|
|
274
|
-
loofah (2.
|
|
86
|
+
loofah (2.22.0)
|
|
275
87
|
crass (~> 1.0.2)
|
|
276
|
-
nokogiri (>= 1.
|
|
277
|
-
mercenary (0.3.6)
|
|
88
|
+
nokogiri (>= 1.12.0)
|
|
278
89
|
meter (1.4.0)
|
|
279
90
|
useragent (~> 0.16.3)
|
|
280
|
-
method_object (1.
|
|
91
|
+
method_object (1.1.0)
|
|
281
92
|
dry-initializer
|
|
282
|
-
method_source (
|
|
283
|
-
mini_portile2 (2.8.
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
minitest (5.13.0)
|
|
289
|
-
msgpack (1.3.1)
|
|
290
|
-
nokogiri (1.13.10)
|
|
291
|
-
mini_portile2 (~> 2.8.0)
|
|
93
|
+
method_source (1.1.0)
|
|
94
|
+
mini_portile2 (2.8.7)
|
|
95
|
+
minitest (5.23.1)
|
|
96
|
+
msgpack (1.7.2)
|
|
97
|
+
nokogiri (1.16.5)
|
|
98
|
+
mini_portile2 (~> 2.8.2)
|
|
292
99
|
racc (~> 1.4)
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
method_source (~> 0.9.0)
|
|
302
|
-
pry-rails (0.3.9)
|
|
303
|
-
pry (>= 0.10.4)
|
|
304
|
-
public_suffix (3.1.1)
|
|
305
|
-
racc (1.6.2)
|
|
306
|
-
rack (2.0.7)
|
|
307
|
-
rack-protection (2.0.7)
|
|
308
|
-
rack
|
|
309
|
-
rack-test (1.1.0)
|
|
310
|
-
rack (>= 1.0, < 3)
|
|
311
|
-
rails-dom-testing (2.0.3)
|
|
312
|
-
activesupport (>= 4.2.0)
|
|
100
|
+
pg (1.5.6)
|
|
101
|
+
racc (1.8.0)
|
|
102
|
+
rack (2.2.9)
|
|
103
|
+
rack-test (2.1.0)
|
|
104
|
+
rack (>= 1.3)
|
|
105
|
+
rails-dom-testing (2.2.0)
|
|
106
|
+
activesupport (>= 5.0.0)
|
|
107
|
+
minitest
|
|
313
108
|
nokogiri (>= 1.6)
|
|
314
|
-
rails-html-sanitizer (1.
|
|
315
|
-
loofah (~> 2.
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
109
|
+
rails-html-sanitizer (1.6.0)
|
|
110
|
+
loofah (~> 2.21)
|
|
111
|
+
nokogiri (~> 1.14)
|
|
112
|
+
railties (7.0.8)
|
|
113
|
+
actionpack (= 7.0.8)
|
|
114
|
+
activesupport (= 7.0.8)
|
|
319
115
|
method_source
|
|
320
|
-
rake (>=
|
|
321
|
-
thor (
|
|
322
|
-
|
|
116
|
+
rake (>= 12.2)
|
|
117
|
+
thor (~> 1.0)
|
|
118
|
+
zeitwerk (~> 2.5)
|
|
119
|
+
rake (13.2.1)
|
|
323
120
|
rb-fsevent (0.11.2)
|
|
324
|
-
rb-inotify (0.
|
|
121
|
+
rb-inotify (0.11.1)
|
|
325
122
|
ffi (~> 1.0)
|
|
326
|
-
redis (
|
|
327
|
-
|
|
328
|
-
rspec (3.
|
|
329
|
-
rspec-core (~> 3.
|
|
330
|
-
rspec-expectations (~> 3.
|
|
331
|
-
rspec-mocks (~> 3.
|
|
332
|
-
rspec-core (3.
|
|
333
|
-
rspec-support (~> 3.
|
|
334
|
-
rspec-expectations (3.
|
|
123
|
+
redis-client (0.22.2)
|
|
124
|
+
connection_pool
|
|
125
|
+
rspec (3.13.0)
|
|
126
|
+
rspec-core (~> 3.13.0)
|
|
127
|
+
rspec-expectations (~> 3.13.0)
|
|
128
|
+
rspec-mocks (~> 3.13.0)
|
|
129
|
+
rspec-core (3.13.0)
|
|
130
|
+
rspec-support (~> 3.13.0)
|
|
131
|
+
rspec-expectations (3.13.0)
|
|
335
132
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
336
|
-
rspec-support (~> 3.
|
|
337
|
-
rspec-mocks (3.
|
|
133
|
+
rspec-support (~> 3.13.0)
|
|
134
|
+
rspec-mocks (3.13.1)
|
|
338
135
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
339
|
-
rspec-support (~> 3.
|
|
340
|
-
rspec-rails (
|
|
341
|
-
actionpack (>=
|
|
342
|
-
activesupport (>=
|
|
343
|
-
railties (>=
|
|
344
|
-
rspec-core (~> 3.
|
|
345
|
-
rspec-expectations (~> 3.
|
|
346
|
-
rspec-mocks (~> 3.
|
|
347
|
-
rspec-support (~> 3.
|
|
348
|
-
rspec-support (3.
|
|
349
|
-
ruby-enum (0.9.0)
|
|
350
|
-
i18n
|
|
136
|
+
rspec-support (~> 3.13.0)
|
|
137
|
+
rspec-rails (6.1.2)
|
|
138
|
+
actionpack (>= 6.1)
|
|
139
|
+
activesupport (>= 6.1)
|
|
140
|
+
railties (>= 6.1)
|
|
141
|
+
rspec-core (~> 3.13)
|
|
142
|
+
rspec-expectations (~> 3.13)
|
|
143
|
+
rspec-mocks (~> 3.13)
|
|
144
|
+
rspec-support (~> 3.13)
|
|
145
|
+
rspec-support (3.13.1)
|
|
351
146
|
ruby-kafka (1.5.0)
|
|
352
147
|
digest-crc
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
rb-fsevent (~> 0.9, >= 0.9.4)
|
|
360
|
-
rb-inotify (~> 0.9, >= 0.9.7)
|
|
361
|
-
sawyer (0.9.2)
|
|
362
|
-
addressable (>= 2.3.5)
|
|
363
|
-
faraday (>= 0.17.3, < 3)
|
|
364
|
-
sidekiq (5.2.7)
|
|
365
|
-
connection_pool (~> 2.2, >= 2.2.2)
|
|
366
|
-
rack (>= 1.5.0)
|
|
367
|
-
rack-protection (>= 1.5.0)
|
|
368
|
-
redis (>= 3.3.5, < 5)
|
|
369
|
-
simplecov (0.17.1)
|
|
148
|
+
sidekiq (7.2.4)
|
|
149
|
+
concurrent-ruby (< 2)
|
|
150
|
+
connection_pool (>= 2.3.0)
|
|
151
|
+
rack (>= 2.2.4)
|
|
152
|
+
redis-client (>= 0.19.0)
|
|
153
|
+
simplecov (0.22.0)
|
|
370
154
|
docile (~> 1.1)
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
simplecov-html (0.
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
terminal-table (1.8.0)
|
|
377
|
-
unicode-display_width (~> 1.1, >= 1.1.1)
|
|
378
|
-
thor (0.20.3)
|
|
155
|
+
simplecov-html (~> 0.11)
|
|
156
|
+
simplecov_json_formatter (~> 0.1)
|
|
157
|
+
simplecov-html (0.12.3)
|
|
158
|
+
simplecov_json_formatter (0.1.4)
|
|
159
|
+
thor (1.3.1)
|
|
379
160
|
thread_safe (0.3.6)
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
tzinfo (1.2.10)
|
|
383
|
-
thread_safe (~> 0.1)
|
|
384
|
-
unf (0.1.4)
|
|
385
|
-
unf_ext
|
|
386
|
-
unf_ext (0.0.8.2)
|
|
387
|
-
unicode-display_width (1.8.0)
|
|
161
|
+
tzinfo (2.0.6)
|
|
162
|
+
concurrent-ruby (~> 1.0)
|
|
388
163
|
useragent (0.16.10)
|
|
389
|
-
virtus (
|
|
164
|
+
virtus (1.0.5)
|
|
390
165
|
axiom-types (~> 0.1)
|
|
391
166
|
coercible (~> 1.0)
|
|
392
167
|
descendants_tracker (~> 0.0, >= 0.0.3)
|
|
393
|
-
|
|
168
|
+
equalizer (~> 0.0, >= 0.0.9)
|
|
169
|
+
zeitwerk (2.6.15)
|
|
394
170
|
|
|
395
171
|
PLATFORMS
|
|
396
172
|
ruby
|
|
397
173
|
|
|
398
174
|
DEPENDENCIES
|
|
399
175
|
bootsnap
|
|
400
|
-
bundler (~> 1.14)
|
|
401
|
-
github-pages (= 203)
|
|
402
|
-
jekyll-include-cache
|
|
403
176
|
listen
|
|
404
177
|
messaging!
|
|
405
178
|
pg
|
|
406
|
-
pry
|
|
407
|
-
pry-rails
|
|
408
179
|
railties
|
|
409
|
-
rake
|
|
180
|
+
rake
|
|
410
181
|
rspec (~> 3.0)
|
|
411
182
|
rspec-rails
|
|
412
183
|
sidekiq
|
|
413
184
|
simplecov
|
|
414
185
|
|
|
415
186
|
BUNDLED WITH
|
|
416
|
-
2.
|
|
187
|
+
2.5.10
|
data/bin/console
CHANGED
|
@@ -6,6 +6,5 @@ require "messaging"
|
|
|
6
6
|
# You can add fixtures and/or initialization code here to make experimenting
|
|
7
7
|
# with your gem easier. You can also use a different console, if you like.
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
Pry.start
|
|
9
|
+
require "irb"
|
|
10
|
+
IRB.start(__FILE__)
|
data/docker-compose.yml
CHANGED
|
@@ -15,7 +15,7 @@ x-shared: &shared
|
|
|
15
15
|
services:
|
|
16
16
|
runner:
|
|
17
17
|
<<: *shared
|
|
18
|
-
image: ghcr.io/bukowskis/base-image/development:ruby-
|
|
18
|
+
image: ghcr.io/bukowskis/base-image/development:ruby-3.3.1-bookworm-v2
|
|
19
19
|
stdin_open: true
|
|
20
20
|
tty: true
|
|
21
21
|
command: /bin/sh
|
|
@@ -24,8 +24,6 @@ services:
|
|
|
24
24
|
image: postgres:${PG_VERSION}
|
|
25
25
|
volumes:
|
|
26
26
|
- pg_data:/var/lib/postgresql/data
|
|
27
|
-
ports:
|
|
28
|
-
- 5432:5432
|
|
29
27
|
environment:
|
|
30
28
|
- POSTGRES_HOST_AUTH_METHOD=trust
|
|
31
29
|
|
|
@@ -37,7 +37,7 @@ module Messaging
|
|
|
37
37
|
# We have a specific logger for Ruby-Kafka as it
|
|
38
38
|
# is a bit more noisy than we would like.
|
|
39
39
|
kafka_logger = Messaging.logger.dup.tap { |logger| logger.level = Config.kafka.log_level }
|
|
40
|
-
|
|
40
|
+
::Kafka.new(**Config.kafka.client.to_h.merge(client_id: Config.app_name, logger: kafka_logger))
|
|
41
41
|
end
|
|
42
42
|
|
|
43
43
|
def self.register!
|
|
@@ -24,7 +24,7 @@ module Messaging
|
|
|
24
24
|
def create(name)
|
|
25
25
|
table_name = Category.table_name_for(name)
|
|
26
26
|
sql = <<~SQL
|
|
27
|
-
CREATE TABLE messaging.#{table_name}
|
|
27
|
+
CREATE TABLE IF NOT EXISTS messaging.#{table_name}
|
|
28
28
|
PARTITION OF messaging.messages FOR VALUES IN ('#{name}');
|
|
29
29
|
SQL
|
|
30
30
|
connection.execute sql
|
|
@@ -39,7 +39,7 @@ module Messaging
|
|
|
39
39
|
def create_and_partition_by_day(name)
|
|
40
40
|
table_name = Category.table_name_for(name)
|
|
41
41
|
sql = <<~SQL
|
|
42
|
-
CREATE TABLE messaging.#{table_name}
|
|
42
|
+
CREATE TABLE IF NOT EXISTS messaging.#{table_name}
|
|
43
43
|
PARTITION OF messaging.messages FOR VALUES IN ('#{name}')
|
|
44
44
|
PARTITION BY RANGE (created_at);
|
|
45
45
|
SQL
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
module Messaging
|
|
2
|
+
module Adapters
|
|
3
|
+
class Postgres
|
|
4
|
+
class Consumer < ActiveRecord::Base
|
|
5
|
+
include Messaging::Routing
|
|
6
|
+
|
|
7
|
+
self.table_name = 'messaging.consumers'
|
|
8
|
+
|
|
9
|
+
def self.latest_known_transaction_id
|
|
10
|
+
connection.select_value('select pg_snapshot_xmin(pg_current_snapshot())')
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def start
|
|
14
|
+
obtain_lock
|
|
15
|
+
refresh_latest_processed_transaction_id
|
|
16
|
+
|
|
17
|
+
Messaging.logger.info "[#{name}] Consumer started"
|
|
18
|
+
@running = true
|
|
19
|
+
process_messages
|
|
20
|
+
ensure
|
|
21
|
+
shutdown
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def stop
|
|
25
|
+
@running = false
|
|
26
|
+
save
|
|
27
|
+
Messaging.logger.info "[#{name}] Consumer stopping"
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def shutdown
|
|
31
|
+
Messaging.logger.info "[#{name}] Consumer stopped"
|
|
32
|
+
release_lock
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
def refresh_latest_processed_transaction_id
|
|
38
|
+
reload
|
|
39
|
+
return if last_processed_transaction_id.present?
|
|
40
|
+
|
|
41
|
+
self.last_processed_transaction_id = self.class.latest_known_transaction_id
|
|
42
|
+
save
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def process_messages
|
|
46
|
+
while @running do
|
|
47
|
+
messages = fetch_messages
|
|
48
|
+
messages.each do |message|
|
|
49
|
+
process_message(message)
|
|
50
|
+
end
|
|
51
|
+
save if messages.any?
|
|
52
|
+
pause_polling_for_5_s unless messages.any?
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def process_message(message)
|
|
57
|
+
Middleware.run(Config.consumer.middlewares, message) { handle message }
|
|
58
|
+
self.last_processed_position = message.global_position
|
|
59
|
+
self.last_processed_transaction_id = message.transaction_id
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def pause_polling_for_5_s
|
|
63
|
+
Messaging.logger.debug "[#{name}] No new messages. Sleeping"
|
|
64
|
+
sleep 5
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def fetch_messages
|
|
68
|
+
SerializedMessage.in_category(categories)
|
|
69
|
+
.with_transction_id_lower_than_any_currently_running_transaction
|
|
70
|
+
.newer_than(last_processed_transaction_id, last_processed_position)
|
|
71
|
+
.order(:id)
|
|
72
|
+
.limit(1000)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def obtain_lock
|
|
76
|
+
Messaging::Adapters::Postgres::CreateLock.(key: "#{app}-consumer-#{name}")
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def release_lock
|
|
80
|
+
Messaging::Adapters::Postgres::ReleaseLock.(key: "#{app}-consumer-#{name}")
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require 'method_object'
|
|
2
|
+
|
|
3
|
+
module Messaging
|
|
4
|
+
module Adapters
|
|
5
|
+
class Postgres
|
|
6
|
+
class CreateLock
|
|
7
|
+
include MethodObject
|
|
8
|
+
|
|
9
|
+
option :key
|
|
10
|
+
option :connection, default: -> { SerializedMessage.connection }
|
|
11
|
+
|
|
12
|
+
def call
|
|
13
|
+
connection.execute "SELECT pg_advisory_lock(#{lock_key});"
|
|
14
|
+
rescue ActiveRecord::QueryCanceled => e
|
|
15
|
+
Messaging.logger.debug "Locking failed, retrying in 5 seconds"
|
|
16
|
+
sleep 5
|
|
17
|
+
retry
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def lock_key
|
|
23
|
+
Zlib.crc32(key)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require 'method_object'
|
|
2
|
+
|
|
3
|
+
module Messaging
|
|
4
|
+
module Adapters
|
|
5
|
+
class Postgres
|
|
6
|
+
class ReleaseLock
|
|
7
|
+
include MethodObject
|
|
8
|
+
|
|
9
|
+
option :key
|
|
10
|
+
option :connection, default: -> { SerializedMessage.connection }
|
|
11
|
+
|
|
12
|
+
def call
|
|
13
|
+
connection.execute "SELECT pg_advisory_unlock(#{lock_key});"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
|
|
18
|
+
def lock_key
|
|
19
|
+
Zlib.crc32(key)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -6,17 +6,44 @@ module Messaging
|
|
|
6
6
|
|
|
7
7
|
attr_accessor :expected_version
|
|
8
8
|
|
|
9
|
+
def self.in_category(categories)
|
|
10
|
+
where(stream_category: Array(categories).map(&:to_s))
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.with_transction_id_lower_than_any_currently_running_transaction
|
|
14
|
+
where('transaction_id < pg_snapshot_xmin(pg_current_snapshot())')
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def self.newer_than(transaction_id, position)
|
|
18
|
+
where([
|
|
19
|
+
'transaction_id = (:transaction_id)::xid8 AND id > :position OR transaction_id > (:transaction_id)::xid8',
|
|
20
|
+
transaction_id: transaction_id.to_s,
|
|
21
|
+
position: position.to_i
|
|
22
|
+
])
|
|
23
|
+
end
|
|
24
|
+
|
|
9
25
|
# We override this AR method to make records retreived
|
|
10
26
|
# from scopes etc. be message objects of the corresponding
|
|
11
27
|
# message class instead of AR objects
|
|
12
28
|
#
|
|
13
29
|
# See https://api.rubyonrails.org/classes/ActiveRecord/Persistence/ClassMethods.html#method-i-instantiate
|
|
30
|
+
# Rails version < 6
|
|
14
31
|
def self.instantiate(attributes, *_args)
|
|
15
32
|
attributes['message_type'].constantize.new(
|
|
16
33
|
JSON.parse(attributes['data']).merge(stream_position: attributes['stream_position'])
|
|
17
34
|
)
|
|
18
35
|
end
|
|
19
36
|
|
|
37
|
+
# Rails version >= 6
|
|
38
|
+
def self.instantiate_instance_of(klas, attributes, column_types = {}, &block)
|
|
39
|
+
attributes['message_type'].constantize.new(
|
|
40
|
+
JSON.parse(attributes['data']).merge(
|
|
41
|
+
stream_position: attributes['stream_position'],
|
|
42
|
+
transaction_id: attributes['transaction_id'],
|
|
43
|
+
global_position: attributes['id'])
|
|
44
|
+
)
|
|
45
|
+
end
|
|
46
|
+
|
|
20
47
|
# Virtual setter for message so we can create a serialized message from a message
|
|
21
48
|
def message=(message)
|
|
22
49
|
self.data = message.attributes_as_json
|
|
@@ -42,6 +69,7 @@ module Messaging
|
|
|
42
69
|
end
|
|
43
70
|
|
|
44
71
|
def create_or_update(*args)
|
|
72
|
+
return super if readonly?
|
|
45
73
|
with_locked_stream do
|
|
46
74
|
set_stream_position
|
|
47
75
|
validate_expected_version!
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
require 'active_record'
|
|
2
2
|
require_relative 'postgres/serialized_message'
|
|
3
|
+
require_relative 'postgres/consumer'
|
|
4
|
+
|
|
3
5
|
require_relative 'postgres/advisory_transaction_lock'
|
|
6
|
+
require_relative 'postgres/create_lock'
|
|
7
|
+
require_relative 'postgres/release_lock'
|
|
4
8
|
|
|
5
9
|
require_relative 'postgres/store'
|
|
6
10
|
module Messaging
|
|
@@ -13,12 +17,19 @@ module Messaging
|
|
|
13
17
|
return if Adapters.key? :postgres
|
|
14
18
|
|
|
15
19
|
Adapters.register(:postgres, memoize: true) { Postgres.new }
|
|
20
|
+
Adapters::Consumer.register(:postgres, memoize: true) { Adapters[:postgres] }
|
|
16
21
|
Adapters::Store.register(:postgres, memoize: true) { Store.new }
|
|
22
|
+
Adapters::Dispatcher.register(:postgres, memoize: true) { ->(_) { } }
|
|
17
23
|
end
|
|
18
24
|
private_class_method :register!
|
|
19
25
|
|
|
20
26
|
register!
|
|
21
27
|
|
|
28
|
+
def create_consumer(name, **options)
|
|
29
|
+
Consumer.where(app: Messaging.config.app_name, name: name.to_s).first ||
|
|
30
|
+
Consumer.create(app: Messaging.config.app_name, name: name.to_s)
|
|
31
|
+
end
|
|
32
|
+
|
|
22
33
|
def create_messages_table
|
|
23
34
|
sql = <<~SQL
|
|
24
35
|
CREATE SCHEMA IF NOT EXISTS messaging;
|
|
@@ -26,6 +37,7 @@ module Messaging
|
|
|
26
37
|
|
|
27
38
|
CREATE TABLE messaging.messages (
|
|
28
39
|
id bigint DEFAULT nextval('messaging.messages_id_seq'::regclass) NOT NULL,
|
|
40
|
+
transaction_id xid8 DEFAULT pg_current_xact_id() NOT NULL,
|
|
29
41
|
uuid uuid NOT NULL,
|
|
30
42
|
stream character varying NOT NULL,
|
|
31
43
|
stream_position bigint NOT NULL,
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
if Dry::Configurable.respond_to?(:warn_on_setting_positional_default)
|
|
2
|
+
Dry::Configurable.warn_on_setting_constructor_block false
|
|
3
|
+
Dry::Configurable.warn_on_setting_positional_default false
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
module Messaging
|
|
7
|
+
class Config
|
|
8
|
+
extend ::Dry::Configurable
|
|
9
|
+
|
|
10
|
+
setting :app_name, 'messaging', reader: true
|
|
11
|
+
|
|
12
|
+
setting(:error_handlers, [], reader: true) { |value| Array(value) }
|
|
13
|
+
|
|
14
|
+
setting :background_job_handler, ->(message, handler_name) { handler_name.constantize.call(message) }, reader: true
|
|
15
|
+
|
|
16
|
+
setting :logger, Logger.new(STDOUT), reader: true
|
|
17
|
+
|
|
18
|
+
setting :consumer, reader: true do
|
|
19
|
+
setting :adapter, :kafka
|
|
20
|
+
setting(:middlewares, []) { |value| Array(value) }
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
setting :dispatcher, reader: true do
|
|
24
|
+
setting :adapter, :kafka
|
|
25
|
+
setting(:middlewares, []) { |value| Array(value) }
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
setting :message_store, reader: true do
|
|
29
|
+
setting :adapter, :postgres
|
|
30
|
+
setting(:middlewares, []) { |value| Array(value) }
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
setting :kafka, reader: true do
|
|
34
|
+
setting :log_level, :warn
|
|
35
|
+
setting :pause_timeout, 10
|
|
36
|
+
|
|
37
|
+
setting :client do
|
|
38
|
+
setting :seed_brokers, ['localhost:9092']
|
|
39
|
+
setting :connect_timeout
|
|
40
|
+
setting :socket_timeout
|
|
41
|
+
setting :ssl_ca_certs_from_system
|
|
42
|
+
setting :sasl_plain_username
|
|
43
|
+
setting :sasl_plain_password
|
|
44
|
+
setting :ssl_ca_cert, ENV['KAFKA_SSL_CA']
|
|
45
|
+
setting :ssl_client_cert, ENV['KAFKA_SSL_CERTIFICATE']
|
|
46
|
+
setting :ssl_client_cert_key, ENV['KAFKA_SSL_KEY']
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
setting :consumer do
|
|
50
|
+
setting :session_timeout, 30
|
|
51
|
+
setting :offset_commit_interval, 10
|
|
52
|
+
setting :offset_commit_threshold, 0
|
|
53
|
+
setting :heartbeat_interval, 10
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
setting :producer do
|
|
57
|
+
setting :max_queue_size, 5_000
|
|
58
|
+
setting :delivery_threshold, 10
|
|
59
|
+
setting :delivery_interval, 0.05
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
class << self
|
|
64
|
+
def setup
|
|
65
|
+
configure do |config|
|
|
66
|
+
yield(config)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
data/lib/messaging/message.rb
CHANGED
data/lib/messaging/routing.rb
CHANGED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
require 'messaging/routing/message_matcher'
|
|
2
|
+
require 'messaging/routing/route'
|
|
3
|
+
require 'messaging/routing/enqueued_route'
|
|
4
|
+
require 'messaging/routing/enqueue_message_handler'
|
|
5
|
+
|
|
6
|
+
module Messaging
|
|
7
|
+
module Routing
|
|
8
|
+
def self.included(base)
|
|
9
|
+
base.send :extend, ClassMethods
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
module ClassMethods
|
|
13
|
+
def definitions
|
|
14
|
+
@definitions ||= []
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def on(pattern, **options, &block)
|
|
18
|
+
definitions << { pattern: pattern, options: options, block: block }
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def new(*args, &block)
|
|
22
|
+
instance = allocate
|
|
23
|
+
|
|
24
|
+
# Pre-initialize
|
|
25
|
+
definitions.each do |definition|
|
|
26
|
+
instance.on(definition[:pattern], definition[:options], &definition[:block])
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
instance.send(:initialize, *args, &block)
|
|
30
|
+
instance
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Public: Sets up routes for the events that matches the given pattern
|
|
35
|
+
#
|
|
36
|
+
# pattern - Which messages to route. Can be a string, a regexp,
|
|
37
|
+
# a Message class, a module or anything that responds to call.
|
|
38
|
+
#
|
|
39
|
+
# call: - Any object that responds to call.
|
|
40
|
+
# Will be called immediately for matching messages.
|
|
41
|
+
#
|
|
42
|
+
# enqueue: - A constant that responds to call.
|
|
43
|
+
# Will be enqueued with Sidekiq for matching messages.
|
|
44
|
+
# Needs to be a constant that Sidekiq can serialize to a string
|
|
45
|
+
# and back again to a constant as you can't store procs in Redis.
|
|
46
|
+
#
|
|
47
|
+
# block - An optional block that will be called with each matching message.
|
|
48
|
+
#
|
|
49
|
+
#
|
|
50
|
+
# Examples
|
|
51
|
+
#
|
|
52
|
+
# Messaging.routes.draw do
|
|
53
|
+
# on 'Events::BidPlaced', call: NotifyOtherBidders
|
|
54
|
+
#
|
|
55
|
+
# on Events::BidPlaced, enqueue: NotifyOtherBidders
|
|
56
|
+
#
|
|
57
|
+
# on Events, do |event|
|
|
58
|
+
# puts event.inspect
|
|
59
|
+
# end
|
|
60
|
+
#
|
|
61
|
+
# on /.*Updated$/, enqueue: AuditChanges
|
|
62
|
+
#
|
|
63
|
+
# on ->(m) { m.topic == 'my-topic' }, call: DoSometing, enqueue: DoSomethingElseWithSidekiq
|
|
64
|
+
# end
|
|
65
|
+
#
|
|
66
|
+
def on(pattern = /.*/, call: nil, enqueue: nil, &block)
|
|
67
|
+
routes << Route.new(pattern, call) if call
|
|
68
|
+
routes << Route.new(pattern, block) if block_given?
|
|
69
|
+
routes << EnqueuedRoute.new(pattern, enqueue) if enqueue
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Internal: Handles the message with the matching subscribers
|
|
73
|
+
def handle(message, context = self)
|
|
74
|
+
routes.map { |route| route.call(message, context) }
|
|
75
|
+
message
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Internal: Used by Rails reloading in development.
|
|
79
|
+
def clear_routes!
|
|
80
|
+
@routes = Set.new
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
private
|
|
84
|
+
|
|
85
|
+
def routes
|
|
86
|
+
@routes ||= Set.new
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def topics
|
|
90
|
+
routes.flat_map(&:topics).map(&:to_s).uniq
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def categories
|
|
94
|
+
routes.flat_map(&:categories).map(&:to_s).uniq
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
data/lib/messaging/version.rb
CHANGED
data/lib/messaging.rb
CHANGED
|
@@ -5,14 +5,25 @@ require 'active_support'
|
|
|
5
5
|
require 'active_support/notifications'
|
|
6
6
|
require 'active_support/core_ext'
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
if RUBY_VERSION == '2.3.8'
|
|
9
|
+
require 'messaging/config_23'
|
|
10
|
+
else
|
|
11
|
+
require 'messaging/config'
|
|
12
|
+
end
|
|
13
|
+
|
|
9
14
|
require 'messaging/expected_version'
|
|
10
15
|
require 'messaging/instrumentation'
|
|
11
16
|
require 'messaging/meter'
|
|
12
17
|
require 'messaging/exception_handler'
|
|
13
18
|
require 'messaging/message'
|
|
14
19
|
require 'messaging/message/from_json'
|
|
15
|
-
|
|
20
|
+
|
|
21
|
+
if RUBY_VERSION == '2.3.8'
|
|
22
|
+
require 'messaging/routing_23'
|
|
23
|
+
else
|
|
24
|
+
require 'messaging/routing'
|
|
25
|
+
end
|
|
26
|
+
|
|
16
27
|
require 'messaging/routes'
|
|
17
28
|
require 'messaging/adapters'
|
|
18
29
|
require 'messaging/middleware'
|
|
@@ -91,6 +102,10 @@ module Messaging
|
|
|
91
102
|
message_store.messages_in_streams(*streams)
|
|
92
103
|
end
|
|
93
104
|
|
|
105
|
+
def self.all_messages
|
|
106
|
+
message_store.messages
|
|
107
|
+
end
|
|
108
|
+
|
|
94
109
|
def self.defined_messages
|
|
95
110
|
ObjectSpace.each_object(Class).select { |c| c.included_modules.include? Messaging::Message }
|
|
96
111
|
end
|
data/messaging.gemspec
CHANGED
|
@@ -24,7 +24,7 @@ Gem::Specification.new do |spec|
|
|
|
24
24
|
spec.add_dependency 'method_object'
|
|
25
25
|
spec.add_dependency 'concurrent-ruby', '>= 1.0.2'
|
|
26
26
|
spec.add_dependency 'concurrent-ruby-ext', '>= 1.0.2'
|
|
27
|
-
spec.add_dependency 'dry-configurable'
|
|
27
|
+
spec.add_dependency 'dry-configurable'
|
|
28
28
|
spec.add_dependency 'dry-container'
|
|
29
29
|
spec.add_dependency 'dry-equalizer'
|
|
30
30
|
spec.add_dependency 'dry-initializer'
|
|
@@ -32,8 +32,7 @@ Gem::Specification.new do |spec|
|
|
|
32
32
|
spec.add_dependency 'ruby-kafka', '>= 0.5.3'
|
|
33
33
|
spec.add_dependency 'virtus'
|
|
34
34
|
|
|
35
|
-
spec.add_development_dependency '
|
|
36
|
-
spec.add_development_dependency 'rake', '~> 10.0'
|
|
35
|
+
spec.add_development_dependency 'rake'
|
|
37
36
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
|
38
37
|
spec.add_development_dependency 'rspec-rails'
|
|
39
38
|
spec.add_development_dependency 'simplecov'
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: messaging
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 4.0.0.pre
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Bukowskis
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2024-07-03 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activerecord
|
|
@@ -98,16 +98,16 @@ dependencies:
|
|
|
98
98
|
name: dry-configurable
|
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
|
100
100
|
requirements:
|
|
101
|
-
- - "
|
|
101
|
+
- - ">="
|
|
102
102
|
- !ruby/object:Gem::Version
|
|
103
|
-
version:
|
|
103
|
+
version: '0'
|
|
104
104
|
type: :runtime
|
|
105
105
|
prerelease: false
|
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
|
107
107
|
requirements:
|
|
108
|
-
- - "
|
|
108
|
+
- - ">="
|
|
109
109
|
- !ruby/object:Gem::Version
|
|
110
|
-
version:
|
|
110
|
+
version: '0'
|
|
111
111
|
- !ruby/object:Gem::Dependency
|
|
112
112
|
name: dry-container
|
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -192,34 +192,20 @@ dependencies:
|
|
|
192
192
|
- - ">="
|
|
193
193
|
- !ruby/object:Gem::Version
|
|
194
194
|
version: '0'
|
|
195
|
-
- !ruby/object:Gem::Dependency
|
|
196
|
-
name: bundler
|
|
197
|
-
requirement: !ruby/object:Gem::Requirement
|
|
198
|
-
requirements:
|
|
199
|
-
- - "~>"
|
|
200
|
-
- !ruby/object:Gem::Version
|
|
201
|
-
version: '1.14'
|
|
202
|
-
type: :development
|
|
203
|
-
prerelease: false
|
|
204
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
205
|
-
requirements:
|
|
206
|
-
- - "~>"
|
|
207
|
-
- !ruby/object:Gem::Version
|
|
208
|
-
version: '1.14'
|
|
209
195
|
- !ruby/object:Gem::Dependency
|
|
210
196
|
name: rake
|
|
211
197
|
requirement: !ruby/object:Gem::Requirement
|
|
212
198
|
requirements:
|
|
213
|
-
- - "
|
|
199
|
+
- - ">="
|
|
214
200
|
- !ruby/object:Gem::Version
|
|
215
|
-
version: '
|
|
201
|
+
version: '0'
|
|
216
202
|
type: :development
|
|
217
203
|
prerelease: false
|
|
218
204
|
version_requirements: !ruby/object:Gem::Requirement
|
|
219
205
|
requirements:
|
|
220
|
-
- - "
|
|
206
|
+
- - ">="
|
|
221
207
|
- !ruby/object:Gem::Version
|
|
222
|
-
version: '
|
|
208
|
+
version: '0'
|
|
223
209
|
- !ruby/object:Gem::Dependency
|
|
224
210
|
name: rspec
|
|
225
211
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -262,7 +248,7 @@ dependencies:
|
|
|
262
248
|
- - ">="
|
|
263
249
|
- !ruby/object:Gem::Version
|
|
264
250
|
version: '0'
|
|
265
|
-
description:
|
|
251
|
+
description:
|
|
266
252
|
email:
|
|
267
253
|
- developers@bukowskis.com
|
|
268
254
|
executables:
|
|
@@ -302,6 +288,9 @@ files:
|
|
|
302
288
|
- lib/messaging/adapters/postgres/categories/row.rb
|
|
303
289
|
- lib/messaging/adapters/postgres/category.rb
|
|
304
290
|
- lib/messaging/adapters/postgres/category_with_partitions.rb
|
|
291
|
+
- lib/messaging/adapters/postgres/consumer.rb
|
|
292
|
+
- lib/messaging/adapters/postgres/create_lock.rb
|
|
293
|
+
- lib/messaging/adapters/postgres/release_lock.rb
|
|
305
294
|
- lib/messaging/adapters/postgres/serialized_message.rb
|
|
306
295
|
- lib/messaging/adapters/postgres/store.rb
|
|
307
296
|
- lib/messaging/adapters/postgres/stream.rb
|
|
@@ -314,6 +303,7 @@ files:
|
|
|
314
303
|
- lib/messaging/adapters/test/stream.rb
|
|
315
304
|
- lib/messaging/cli.rb
|
|
316
305
|
- lib/messaging/config.rb
|
|
306
|
+
- lib/messaging/config_23.rb
|
|
317
307
|
- lib/messaging/consumer_supervisor.rb
|
|
318
308
|
- lib/messaging/exception_handler.rb
|
|
319
309
|
- lib/messaging/expected_version.rb
|
|
@@ -333,13 +323,14 @@ files:
|
|
|
333
323
|
- lib/messaging/routing/enqueued_route.rb
|
|
334
324
|
- lib/messaging/routing/message_matcher.rb
|
|
335
325
|
- lib/messaging/routing/route.rb
|
|
326
|
+
- lib/messaging/routing_23.rb
|
|
336
327
|
- lib/messaging/sidekiq_worker.rb
|
|
337
328
|
- lib/messaging/version.rb
|
|
338
329
|
- messaging.gemspec
|
|
339
330
|
homepage: https://bukowskis.github.io/messaging/
|
|
340
331
|
licenses: []
|
|
341
332
|
metadata: {}
|
|
342
|
-
post_install_message:
|
|
333
|
+
post_install_message:
|
|
343
334
|
rdoc_options: []
|
|
344
335
|
require_paths:
|
|
345
336
|
- lib
|
|
@@ -354,8 +345,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
354
345
|
- !ruby/object:Gem::Version
|
|
355
346
|
version: '0'
|
|
356
347
|
requirements: []
|
|
357
|
-
rubygems_version: 3.
|
|
358
|
-
signing_key:
|
|
348
|
+
rubygems_version: 3.5.9
|
|
349
|
+
signing_key:
|
|
359
350
|
specification_version: 4
|
|
360
351
|
summary: A library for decoupling applications by using messaging to communicate between
|
|
361
352
|
components.
|