evt-message_store-postgres 1.2.0.0 → 2.4.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 77c708beeefed6f49a2a8df231fc7d8bb84ef2dd75982dc602cb5b6893662869
4
- data.tar.gz: 3255fa00e94215b04d61fac3054ad4db43e64813c266232cf333e79345d7f49d
3
+ metadata.gz: d39147eb9243bc55ac8f717ea66848d8f52afa81e2765c65fbcb6d8790eddebd
4
+ data.tar.gz: c06dbbfd0bdf1755bba528431be09cdf6102e55895c6310f791ded9bdf6fe6f1
5
5
  SHA512:
6
- metadata.gz: 6b1e8f43a95d701db50f9c21964a52acebe8c435b11c91befb6a0e1c1cdf25b8a33f50d0457f1a4af0f34cfd6d426eb2bd918fef8c953af4deabd861a45ee0a4
7
- data.tar.gz: 5e63109d9eb4a60f9c2af6c50ee4adca1929fd224defbe558d47e96c5264ebb884553235cbf5962f9f3d1575fefa9f49ec58d10f4795143ba160a94a9dad67a4
6
+ metadata.gz: bc425933b84429dfcb09460747dd41b46e652da2b93dcad021759109c8756dcd8bf63b99b300d09200e364559e3220cf03e84e4746cbe8d4716409dac85ec765
7
+ data.tar.gz: a1834321e541d178d01a302b42c82d4d6f344fc51a47eaba2e6ffeecfaa1f63315e87f979de0c7d1edb3c405da6a5dd6309e8dbc23ac40f6ddfe72f3d6b2f4d2
@@ -15,7 +15,10 @@ require 'message_store/postgres/put'
15
15
  require 'message_store/postgres/write'
16
16
 
17
17
  require 'message_store/postgres/get'
18
+ require 'message_store/postgres/get/condition'
18
19
  require 'message_store/postgres/get/stream'
19
- require 'message_store/postgres/get/category'
20
20
  require 'message_store/postgres/get/stream/last'
21
+ require 'message_store/postgres/get/category'
22
+ require 'message_store/postgres/get/category/correlation'
23
+ require 'message_store/postgres/get/category/consumer_group'
21
24
  require 'message_store/postgres/read'
@@ -1,25 +1,7 @@
1
1
  module MessageStore
2
2
  module Postgres
3
3
  module Controls
4
- module Category
5
- def self.example(category: nil, randomize_category: nil)
6
- if randomize_category.nil?
7
- if !category.nil?
8
- randomize_category = false
9
- end
10
- end
11
-
12
- randomize_category = true if randomize_category.nil?
13
-
14
- category ||= 'test'
15
-
16
- if randomize_category
17
- category = "#{category}#{SecureRandom.hex(16)}XX"
18
- end
19
-
20
- category
21
- end
22
- end
4
+ Category = MessageStore::Controls::Category
23
5
  end
24
6
  end
25
7
  end
@@ -6,19 +6,19 @@ module MessageStore
6
6
  module MessageData
7
7
  module Write
8
8
  module List
9
- Entry = Struct.new(:stream_name, :message_data)
9
+ Entry = Struct.new(:stream_name, :category, :message_data)
10
10
 
11
- def self.get(instances: nil)
11
+ def self.get(instances: nil, stream_name: nil, category: nil)
12
12
  instances ||= 1
13
13
 
14
- stream_name = StreamName.example
15
-
16
14
  list = []
17
15
  instances.times do
18
- stream_name = Controls::StreamName.example
16
+ instance_stream_name = stream_name || StreamName.example(category: category)
17
+ instance_category = MessageStore::StreamName.get_category(instance_stream_name)
18
+
19
19
  write_message = Controls::MessageData::Write.example
20
20
 
21
- list << Entry.new(stream_name, write_message)
21
+ list << Entry.new(instance_stream_name, instance_category, write_message)
22
22
  end
23
23
 
24
24
  list
@@ -2,20 +2,21 @@ module MessageStore
2
2
  module Postgres
3
3
  module Controls
4
4
  module Put
5
- def self.call(instances: nil, stream_name: nil, message: nil, category: nil)
5
+ def self.call(instances: nil, stream_name: nil, message_data: nil, message: nil, category: nil)
6
6
  instances ||= 1
7
7
  stream_name ||= StreamName.example(category: category)
8
+ message_data ||= message
8
9
 
9
- message_specified = !message.nil?
10
+ message_specified = !message_data.nil?
10
11
 
11
- message ||= MessageData::Write.example
12
+ message_data ||= MessageData::Write.example
12
13
 
13
14
  position = nil
14
15
  instances.times do
15
- position = MessageStore::Postgres::Put.(message, stream_name)
16
+ position = MessageStore::Postgres::Put.(message_data, stream_name)
16
17
 
17
18
  unless message_specified
18
- message.id = MessageData::Write.id
19
+ message_data.id = MessageData::Write.id
19
20
  end
20
21
  end
21
22
 
@@ -4,14 +4,21 @@ module MessageStore
4
4
  def self.included(cls)
5
5
  cls.class_exec do
6
6
  include MessageStore::Get
7
+
7
8
  prepend Call
8
9
  prepend BatchSize
9
10
 
10
- extend SQLCommand
11
-
12
11
  dependency :session, Session
13
12
 
14
- initializer :stream_name, na(:batch_size), :condition
13
+ abstract :stream_name
14
+ abstract :sql_command
15
+ abstract :parameters
16
+ abstract :parameter_values
17
+ abstract :last_position
18
+ abstract :log_text
19
+
20
+ virtual :specialize_error
21
+ virtual :assure
15
22
  end
16
23
  end
17
24
 
@@ -21,40 +28,44 @@ module MessageStore
21
28
  end
22
29
  end
23
30
 
24
- def self.build(stream_name, batch_size: nil, session: nil, condition: nil)
31
+ def self.build(stream_name, **args)
25
32
  cls = specialization(stream_name)
26
-
27
- cls.new(stream_name, batch_size, condition).tap do |instance|
28
- instance.configure(session: session)
29
- end
33
+ cls.build(stream_name, **args)
30
34
  end
31
35
 
32
- def self.configure(receiver, stream_name, attr_name: nil, batch_size: nil, condition: nil, session: nil)
36
+ def self.configure(receiver, stream_name, **args)
37
+ attr_name = args.delete(:attr_name)
33
38
  attr_name ||= :get
34
- instance = build(stream_name, batch_size: batch_size, condition: condition, session: session)
35
- receiver.public_send "#{attr_name}=", instance
39
+
40
+ instance = build(stream_name, **args)
41
+ receiver.public_send("#{attr_name}=", instance)
36
42
  end
37
43
 
38
44
  def configure(session: nil)
39
- Session.configure self, session: session
45
+ Session.configure(self, session: session)
40
46
  end
41
47
 
42
- def self.call(stream_name, position: nil, batch_size: nil, condition: nil, session: nil)
43
- instance = build(stream_name, batch_size: batch_size, condition: condition, session: session)
48
+ def self.call(stream_name, **args)
49
+ position = args.delete(:position)
50
+ instance = build(stream_name, **args)
44
51
  instance.(position)
45
52
  end
46
53
 
47
54
  module Call
48
- def call(position)
49
- logger.trace(tag: :get) { "Getting message data (Stream Name: #{stream_name}, Position: #{position.inspect}, Batch Size: #{batch_size.inspect})" }
55
+ def call(position=nil, stream_name: nil)
56
+ position ||= self.class::Defaults.position
57
+
58
+ stream_name ||= self.stream_name
59
+
60
+ assure
50
61
 
51
- position ||= Defaults.position
62
+ logger.trace(tag: :get) { "Getting message data (#{log_text(stream_name, position)})" }
52
63
 
53
64
  result = get_result(stream_name, position)
54
65
 
55
66
  message_data = convert(result)
56
67
 
57
- logger.info(tag: :get) { "Finished getting message data (Count: #{message_data.length}, Stream Name: #{stream_name}, Position: #{position.inspect}, Batch Size: #{batch_size.inspect})" }
68
+ logger.info(tag: :get) { "Finished getting message data (Count: #{message_data.length}, #{log_text(stream_name, position)})" }
58
69
  logger.info(tags: [:data, :message_data]) { message_data.pretty_inspect }
59
70
 
60
71
  message_data
@@ -62,53 +73,60 @@ module MessageStore
62
73
  end
63
74
 
64
75
  def get_result(stream_name, position)
65
- logger.trace(tag: :get) { "Getting result (Stream Name: #{stream_name}, Position: #{position.inspect}, Batch Size: #{batch_size.inspect}, Condition: #{condition || '(none)'})" }
76
+ logger.trace(tag: :get) { "Getting result (#{log_text(stream_name, position)})" }
66
77
 
67
- sql_command = self.class.sql_command(stream_name, position, batch_size, condition)
78
+ parameter_values = parameter_values(stream_name, position)
68
79
 
69
- cond = Get.constrain_condition(condition)
70
-
71
- params = [
72
- stream_name,
73
- position,
74
- batch_size,
75
- cond
76
- ]
77
-
78
- result = session.execute(sql_command, params)
80
+ begin
81
+ result = session.execute(sql_command, parameter_values)
82
+ rescue PG::RaiseException => e
83
+ raise_error(e)
84
+ end
79
85
 
80
- logger.debug(tag: :get) { "Finished getting result (Count: #{result.ntuples}, Stream Name: #{stream_name}, Position: #{position.inspect}, Batch Size: #{batch_size.inspect}, Condition: #{condition || '(none)'})" }
86
+ logger.debug(tag: :get) { "Finished getting result (Count: #{result.ntuples}, #{log_text(stream_name, position)})" }
81
87
 
82
88
  result
83
89
  end
84
90
 
85
- def self.constrain_condition(condition)
86
- return nil if condition.nil?
91
+ def convert(result)
92
+ logger.trace(tag: :get) { "Converting result to message data (Result Count: #{result.ntuples})" }
93
+
94
+ message_data = result.map do |record|
95
+ Get.message_data(record)
96
+ end
87
97
 
88
- "(#{condition})"
98
+ logger.debug(tag: :get) { "Converted result to message data (Message Data Count: #{message_data.length})" }
99
+
100
+ message_data
89
101
  end
90
102
 
91
- module SQLCommand
92
- def sql_command(stream_name, position, batch_size, condition)
93
- parameters = '$1::varchar, $2::bigint, $3::bigint, $4::varchar'
94
- command_text(parameters)
95
- end
103
+ def self.message_data(record)
104
+ record['data'] = Get::Deserialize.data(record['data'])
105
+ record['metadata'] = Get::Deserialize.metadata(record['metadata'])
106
+ record['time'] = Get::Time.utc_coerced(record['time'])
107
+
108
+ MessageData::Read.build(record)
96
109
  end
97
110
 
98
- def convert(result)
99
- logger.trace(tag: :get) { "Converting result to message data (Result Count: #{result.ntuples})" }
111
+ def raise_error(pg_error)
112
+ error_message = Get.error_message(pg_error)
100
113
 
101
- message_data = result.map do |record|
102
- record['data'] = Deserialize.data(record['data'])
103
- record['metadata'] = Deserialize.metadata(record['metadata'])
104
- record['time'] = Time.utc_coerced(record['time'])
114
+ error = Condition.error(error_message)
105
115
 
106
- MessageData::Read.build(record)
116
+ if error.nil?
117
+ error = specialize_error(error_message)
107
118
  end
108
119
 
109
- logger.debug(tag: :get) { "Converted result to message data (Message Data Count: #{message_data.length})" }
120
+ if not error.nil?
121
+ logger.error { error_message }
122
+ raise error
123
+ end
110
124
 
111
- message_data
125
+ raise pg_error
126
+ end
127
+
128
+ def self.error_message(pg_error)
129
+ pg_error.message.gsub('ERROR:', '').strip
112
130
  end
113
131
 
114
132
  def self.specialization(stream_name)
@@ -138,10 +156,6 @@ module MessageStore
138
156
  end
139
157
 
140
158
  module Defaults
141
- def self.position
142
- 0
143
- end
144
-
145
159
  def self.batch_size
146
160
  1000
147
161
  end
@@ -2,15 +2,79 @@ module MessageStore
2
2
  module Postgres
3
3
  module Get
4
4
  class Category
5
+ Error = Class.new(RuntimeError)
6
+
5
7
  include Get
6
8
 
7
- def self.command_text(parameters)
9
+ initializer :category, na(:batch_size), :correlation, :consumer_group_member, :consumer_group_size, :condition
10
+ alias :stream_name :category
11
+
12
+ def self.call(category, position: nil, batch_size: nil, correlation: nil, consumer_group_member: nil, consumer_group_size: nil, condition: nil, session: nil)
13
+ instance = build(category, batch_size: batch_size, correlation: correlation, consumer_group_member: consumer_group_member, consumer_group_size: consumer_group_size, condition: condition, session: session)
14
+ instance.(position)
15
+ end
16
+
17
+ def self.build(category, batch_size: nil, correlation: nil, consumer_group_member: nil, consumer_group_size: nil, condition: nil, session: nil)
18
+ instance = new(category, batch_size, correlation, consumer_group_member, consumer_group_size, condition)
19
+ instance.configure(session: session)
20
+ instance
21
+ end
22
+
23
+ def self.configure(receiver, category, attr_name: nil, batch_size: nil, correlation: nil, consumer_group_member: nil, consumer_group_size: nil, condition: nil, session: nil)
24
+ attr_name ||= :get
25
+ instance = build(category, batch_size: batch_size, correlation: correlation, consumer_group_member: consumer_group_member, consumer_group_size: consumer_group_size, condition: condition, session: session)
26
+ receiver.public_send("#{attr_name}=", instance)
27
+ end
28
+
29
+ def sql_command
8
30
  "SELECT * FROM get_category_messages(#{parameters});"
9
31
  end
10
32
 
33
+ def parameters
34
+ '$1::varchar, $2::bigint, $3::bigint, $4::varchar, $5::bigint, $6::bigint, $7::varchar'
35
+ end
36
+
37
+ def parameter_values(category, position)
38
+ [
39
+ category,
40
+ position,
41
+ batch_size,
42
+ correlation,
43
+ consumer_group_member,
44
+ consumer_group_size,
45
+ condition
46
+ ]
47
+ end
48
+
11
49
  def last_position(batch)
12
50
  batch.last.global_position
13
51
  end
52
+
53
+ def specialize_error(error_message)
54
+ error = Correlation.error(error_message)
55
+
56
+ if error.nil?
57
+ error = ConsumerGroup.error(error_message)
58
+ end
59
+
60
+ error
61
+ end
62
+
63
+ def log_text(category, position)
64
+ "Category: #{category}, Position: #{position.inspect}, Batch Size: #{batch_size.inspect}, Correlation: #{correlation.inspect}, Consumer Group Member: #{consumer_group_member.inspect}, Consumer Group Size: #{consumer_group_size.inspect}, Condition: #{condition.inspect})"
65
+ end
66
+
67
+ def assure
68
+ if not MessageStore::StreamName.category?(category)
69
+ raise Error, "Must be a category (Stream Name: #{category})"
70
+ end
71
+ end
72
+
73
+ module Defaults
74
+ def self.position
75
+ 1
76
+ end
77
+ end
14
78
  end
15
79
  end
16
80
  end
@@ -0,0 +1,20 @@
1
+ module MessageStore
2
+ module Postgres
3
+ module Get
4
+ class Category
5
+ module ConsumerGroup
6
+ Error = Class.new(RuntimeError)
7
+
8
+ def self.error(error_message)
9
+ if error_message.start_with?('Consumer group size must not be less than 1') ||
10
+ error_message.start_with?('Consumer group member must be less than the group size') ||
11
+ error_message.start_with?('Consumer group member must not be less than 0') ||
12
+ error_message.start_with?('Consumer group member and size must be specified')
13
+ Error.new(error_message)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,17 @@
1
+ module MessageStore
2
+ module Postgres
3
+ module Get
4
+ class Category
5
+ module Correlation
6
+ Error = Class.new(RuntimeError)
7
+
8
+ def self.error(error_message)
9
+ if error_message.start_with?('Correlation must be a category')
10
+ Error.new(error_message)
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,15 @@
1
+ module MessageStore
2
+ module Postgres
3
+ module Get
4
+ module Condition
5
+ Error = Class.new(RuntimeError)
6
+
7
+ def self.error(error_message)
8
+ if error_message.start_with?('Retrieval with SQL condition is not activated')
9
+ Get::Condition::Error.new(error_message)
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -2,15 +2,65 @@ module MessageStore
2
2
  module Postgres
3
3
  module Get
4
4
  class Stream
5
+ Error = Class.new(RuntimeError)
6
+
5
7
  include Get
6
8
 
7
- def self.command_text(parameters)
9
+ initializer :stream_name, na(:batch_size), :condition
10
+
11
+ def self.call(stream_name, position: nil, batch_size: nil, condition: nil, session: nil)
12
+ instance = build(stream_name, batch_size: batch_size, condition: condition, session: session)
13
+ instance.(position)
14
+ end
15
+
16
+ def self.build(stream_name, batch_size: nil, condition: nil, session: nil)
17
+ instance = new(stream_name, batch_size, condition)
18
+ instance.configure(session: session)
19
+ instance
20
+ end
21
+
22
+ def self.configure(receiver, stream_name, attr_name: nil, batch_size: nil, condition: nil, session: nil)
23
+ attr_name ||= :get
24
+ instance = build(stream_name, batch_size: batch_size, condition: condition, session: session)
25
+ receiver.public_send("#{attr_name}=", instance)
26
+ end
27
+
28
+ def sql_command
8
29
  "SELECT * FROM get_stream_messages(#{parameters});"
9
30
  end
10
31
 
32
+ def parameters
33
+ '$1::varchar, $2::bigint, $3::bigint, $4::varchar'
34
+ end
35
+
36
+ def parameter_values(stream_name, position)
37
+ [
38
+ stream_name,
39
+ position,
40
+ batch_size,
41
+ condition
42
+ ]
43
+ end
44
+
11
45
  def last_position(batch)
12
46
  batch.last.position
13
47
  end
48
+
49
+ def log_text(stream_name, position)
50
+ "Stream Name: #{stream_name}, Position: #{position.inspect}, Batch Size: #{batch_size.inspect}, Condition: #{condition.inspect})"
51
+ end
52
+
53
+ def assure
54
+ if MessageStore::StreamName.category?(stream_name)
55
+ raise Error, "Must be a stream name (Category: #{stream_name})"
56
+ end
57
+ end
58
+
59
+ module Defaults
60
+ def self.position
61
+ 0
62
+ end
63
+ end
14
64
  end
15
65
  end
16
66
  end
@@ -31,11 +31,11 @@ module MessageStore
31
31
 
32
32
  sql_command = self.class.sql_command(stream_name)
33
33
 
34
- params = [
34
+ parameter_values = [
35
35
  stream_name
36
36
  ]
37
37
 
38
- result = session.execute(sql_command, params)
38
+ result = session.execute(sql_command, parameter_values)
39
39
 
40
40
  logger.debug(tag: :get) { "Finished getting result (Count: #{result.ntuples}, Stream: #{stream_name}" }
41
41
 
@@ -47,40 +47,18 @@ module MessageStore
47
47
  def self.sql_command(stream_name)
48
48
  parameters = '$1::varchar'
49
49
 
50
- "SELECT * FROM get_last_message(#{parameters});"
50
+ "SELECT * FROM get_last_stream_message(#{parameters});"
51
51
  end
52
52
 
53
53
  def convert(record)
54
54
  logger.trace(tag: :get) { "Converting record to message data" }
55
55
 
56
- record['data'] = Deserialize.data(record['data'])
57
- record['metadata'] = Deserialize.metadata(record['metadata'])
58
- record['time'] = Time.utc_coerced(record['time'])
59
-
60
- message_data = MessageData::Read.build(record)
56
+ message_data = Get.message_data(record)
61
57
 
62
58
  logger.debug(tag: :get) { "Converted record to message data" }
63
59
 
64
60
  message_data
65
61
  end
66
-
67
- module Deserialize
68
- def self.data(serialized_data)
69
- return nil if serialized_data.nil?
70
- Transform::Read.(serialized_data, :json, MessageData::Hash)
71
- end
72
-
73
- def self.metadata(serialized_metadata)
74
- return nil if serialized_metadata.nil?
75
- Transform::Read.(serialized_metadata, :json, MessageData::Hash)
76
- end
77
- end
78
-
79
- module Time
80
- def self.utc_coerced(local_time)
81
- Clock::UTC.coerce(local_time)
82
- end
83
- end
84
62
  end
85
63
  end
86
64
  end
@@ -5,7 +5,7 @@ module MessageStore
5
5
  include Log::Dependency
6
6
 
7
7
  dependency :session, Session
8
- dependency :identifier, Session
8
+ dependency :identifier, Identifier::UUID::RandomIdentifier dependency is corrected
9
9
 
10
10
  def self.build(session: nil)
11
11
  new.tap do |instance|
@@ -6,7 +6,7 @@ module MessageStore
6
6
  end
7
7
 
8
8
  def self.data_source
9
- Defaults.data_source || 'settings/message_store_postgres.json'
9
+ Defaults.data_source
10
10
  end
11
11
 
12
12
  def self.names
@@ -28,7 +28,7 @@ module MessageStore
28
28
 
29
29
  class Defaults
30
30
  def self.data_source
31
- ENV['MESSAGE_STORE_SETTINGS_PATH']
31
+ ENV['MESSAGE_STORE_SETTINGS_PATH'] || 'settings/message_store_postgres.json'
32
32
  end
33
33
  end
34
34
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: evt-message_store-postgres
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0.0
4
+ version: 2.4.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - The Eventide Project
8
8
  autorequire:
9
9
  bindir: scripts
10
10
  cert_chain: []
11
- date: 2019-11-01 00:00:00.000000000 Z
11
+ date: 2020-07-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: evt-message_store
@@ -25,7 +25,7 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: evt-message_store-postgres-database
28
+ name: evt-log
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
@@ -39,7 +39,7 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: evt-log
42
+ name: evt-settings
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
@@ -53,7 +53,7 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: evt-settings
56
+ name: message-db
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
@@ -137,6 +137,9 @@ files:
137
137
  - lib/message_store/postgres/controls/stream_name.rb
138
138
  - lib/message_store/postgres/get.rb
139
139
  - lib/message_store/postgres/get/category.rb
140
+ - lib/message_store/postgres/get/category/consumer_group.rb
141
+ - lib/message_store/postgres/get/category/correlation.rb
142
+ - lib/message_store/postgres/get/condition.rb
140
143
  - lib/message_store/postgres/get/stream.rb
141
144
  - lib/message_store/postgres/get/stream/last.rb
142
145
  - lib/message_store/postgres/log.rb
@@ -164,7 +167,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
164
167
  - !ruby/object:Gem::Version
165
168
  version: '0'
166
169
  requirements: []
167
- rubygems_version: 3.0.1
170
+ rubygems_version: 3.1.2
168
171
  signing_key:
169
172
  specification_version: 4
170
173
  summary: Message store implementation for PostgreSQL