hubbado-idempotence-reservation 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 9bac8d6a56f3ecf2241b64c925acc2c7351eef692a7f3aa58f7899739decc189
4
+ data.tar.gz: d685f8f302b9f0b5465de6d36cb2eec7df82412b9ee54be2751dc27f187eb566
5
+ SHA512:
6
+ metadata.gz: 580a113f600505e7cc24190c957fc15158f4e99b4e2828110de0347a192acd565bb085b8caa4261c4ee299bac8cd4327f208a6abbdbae0816a97cba2df810cdb
7
+ data.tar.gz: 4dfccb048328a36cee84c0dedaf05a5f760201b3f8a186b0c157be8c4ed00543b029bdd1afdd1c38517864536c51fbcadd0dbc43007218b514d763916403b5c5
@@ -0,0 +1,5 @@
1
+ module Idempotence
2
+ module Controls
3
+ Message = Messaging::Controls::Message
4
+ end
5
+ end
@@ -0,0 +1,15 @@
1
+ module Idempotence
2
+ module Controls
3
+ Metadata = Messaging::Controls::Metadata
4
+
5
+ module Metadata::Reserved
6
+ def self.example
7
+ metadata = Metadata::Random.example
8
+
9
+ metadata.local_properties[Reservation::METADATA_NAME] = :value
10
+
11
+ metadata
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,4 @@
1
+ require 'messaging/controls'
2
+
3
+ require "idempotence/reservation/controls/message"
4
+ require "idempotence/reservation/controls/metadata"
@@ -0,0 +1,128 @@
1
+ module Idempotence
2
+ class Reservation
3
+ include Log::Dependency
4
+
5
+ METADATA_NAME = :reserved
6
+
7
+ dependency :write, Messaging::Postgres::Write
8
+
9
+ configure :reservation
10
+
11
+ def self.call(message, idempotence_key, session: nil)
12
+ instance = build(session: session)
13
+ instance.(message, idempotence_key)
14
+ end
15
+
16
+ def self.build(session: nil)
17
+ instance = new
18
+ instance.configure(session: session)
19
+ instance
20
+ end
21
+
22
+ def configure(session: nil)
23
+ Messaging::Postgres::Write.configure(self, session: session)
24
+ end
25
+
26
+ def call(message, idempotence_key, &block)
27
+ logger.trace(
28
+ "Handling reservation idempotence for message #{message.class.name} #{message.metadata.global_position}",
29
+ tag: :reservation
30
+ )
31
+
32
+ if reserved?(message)
33
+ handle_reserved_message(message, &block)
34
+ else
35
+ reserve_message(message, idempotence_key)
36
+ end
37
+
38
+ logger.info(
39
+ "Handled reservation idempotence for #{message.class.name} #{message.metadata.global_position}",
40
+ tag: :reservation
41
+ )
42
+ end
43
+
44
+ def handle_reserved_message(message, &block)
45
+ logger.trace(
46
+ "Handling reserved message #{message.class.name} #{message.metadata.global_position}",
47
+ tag: :reservation
48
+ )
49
+
50
+ yield message
51
+
52
+ logger.info(
53
+ "Handled reserved message #{message.class.name} #{message.metadata.global_position}",
54
+ tag: :reservation
55
+ )
56
+ end
57
+
58
+ private
59
+
60
+ def reserved?(message)
61
+ !!message.metadata.get_local_property(METADATA_NAME)
62
+ end
63
+
64
+ def reserve_message(message, idempotence_key)
65
+ logger.trace(
66
+ "Reserving #{message.class.name} #{message.metadata.global_position}, Idempotence Key: #{idempotence_key}",
67
+ tag: :reservation
68
+ )
69
+
70
+ reservation_message = message.class.follow(message)
71
+ reservation_message.metadata.set_local_property(METADATA_NAME, message.id)
72
+ origin_stream_name = message.metadata.stream_name
73
+
74
+ category = Messaging::StreamName.get_category(origin_stream_name)
75
+ origin_ids = Messaging::StreamName.get_ids(origin_stream_name)
76
+
77
+ ids = origin_ids + [idempotence_key]
78
+
79
+ stream_name = MessageStore::StreamName.stream_name(category, ids)
80
+
81
+ result = Try.(MessageStore::ExpectedVersion::Error) do
82
+ write.initial(reservation_message, stream_name)
83
+ end
84
+
85
+ if result
86
+ logger.info(
87
+ "Reserved #{message.class.name} #{message.metadata.global_position}, Idempotence Key: #{idempotence_key}",
88
+ tag: :reservation
89
+ )
90
+ else
91
+ log_ignore(message, stream_name)
92
+ end
93
+ end
94
+
95
+ def log_ignore(message, stream_name)
96
+ logger.info(
97
+ "#{message.class.name} #{message.metadata.global_position} ignored, output stream #{stream_name} exists",
98
+ tags: %i[reservation ignored]
99
+ )
100
+ end
101
+
102
+ module Substitute
103
+ def self.build
104
+ Reservation.new
105
+ end
106
+
107
+ class Reservation
108
+ attr_reader :message
109
+ attr_reader :idempotence_key
110
+
111
+ def call(m, i_key, &block)
112
+ @message = m
113
+ @idempotence_key = i_key
114
+
115
+ yield message
116
+ end
117
+
118
+ def message?(value)
119
+ message == value
120
+ end
121
+
122
+ def idempotence_key?(value)
123
+ idempotence_key == value
124
+ end
125
+ end
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,8 @@
1
+ require "messaging/postgres"
2
+ require "message_store"
3
+ require "try"
4
+ require "log"
5
+ require "configure"; Configure.activate
6
+ require "dependency"; Dependency.activate
7
+
8
+ require "idempotence/reservation/reservation"
metadata ADDED
@@ -0,0 +1,181 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hubbado-idempotence-reservation
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Alfonso Uceda
8
+ - Sam Stickland
9
+ - Alexander Repnikov
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2023-03-29 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: evt-messaging-postgres
17
+ requirement: !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - ">="
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ version: '0'
29
+ - !ruby/object:Gem::Dependency
30
+ name: evt-message_store
31
+ requirement: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - ">="
34
+ - !ruby/object:Gem::Version
35
+ version: '0'
36
+ type: :runtime
37
+ prerelease: false
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: '0'
43
+ - !ruby/object:Gem::Dependency
44
+ name: evt-configure
45
+ requirement: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
50
+ type: :runtime
51
+ prerelease: false
52
+ version_requirements: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ - !ruby/object:Gem::Dependency
58
+ name: evt-dependency
59
+ requirement: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
64
+ type: :runtime
65
+ prerelease: false
66
+ version_requirements: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ - !ruby/object:Gem::Dependency
72
+ name: evt-try
73
+ requirement: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ type: :runtime
79
+ prerelease: false
80
+ version_requirements: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ - !ruby/object:Gem::Dependency
86
+ name: evt-log
87
+ requirement: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ type: :runtime
93
+ prerelease: false
94
+ version_requirements: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ - !ruby/object:Gem::Dependency
100
+ name: hubbado-style
101
+ requirement: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ type: :development
107
+ prerelease: false
108
+ version_requirements: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ version: '0'
113
+ - !ruby/object:Gem::Dependency
114
+ name: test_bench
115
+ requirement: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ type: :development
121
+ prerelease: false
122
+ version_requirements: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ - !ruby/object:Gem::Dependency
128
+ name: debug
129
+ requirement: !ruby/object:Gem::Requirement
130
+ requirements:
131
+ - - ">="
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ type: :development
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ requirements:
138
+ - - ">="
139
+ - !ruby/object:Gem::Version
140
+ version: '0'
141
+ description:
142
+ email:
143
+ - alfonso@hubbado.com
144
+ - sam@hubbado.com
145
+ - aleksander.repnikov@gmail.com
146
+ executables: []
147
+ extensions: []
148
+ extra_rdoc_files: []
149
+ files:
150
+ - lib/idempotence/reservation.rb
151
+ - lib/idempotence/reservation/controls.rb
152
+ - lib/idempotence/reservation/controls/message.rb
153
+ - lib/idempotence/reservation/controls/metadata.rb
154
+ - lib/idempotence/reservation/reservation.rb
155
+ homepage: https://github.com/hubbado/hubbado-idempotence-reservation
156
+ licenses:
157
+ - MIT
158
+ metadata:
159
+ homepage_uri: https://github.com/hubbado/hubbado-idempotence-reservation
160
+ source_code_uri: https://github.com/hubbado/hubbado-idempotence-reservation
161
+ github_repo: https://github.com/hubbado/hubbado-idempotence-reservation
162
+ post_install_message:
163
+ rdoc_options: []
164
+ require_paths:
165
+ - lib
166
+ required_ruby_version: !ruby/object:Gem::Requirement
167
+ requirements:
168
+ - - ">="
169
+ - !ruby/object:Gem::Version
170
+ version: 2.4.0
171
+ required_rubygems_version: !ruby/object:Gem::Requirement
172
+ requirements:
173
+ - - ">="
174
+ - !ruby/object:Gem::Version
175
+ version: '0'
176
+ requirements: []
177
+ rubygems_version: 3.4.7
178
+ signing_key:
179
+ specification_version: 4
180
+ summary: Idempotence library to handle reservation pattern in eventide toolkit
181
+ test_files: []