pheromone 0.4.5 → 0.5.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 +4 -4
- data/README.md +68 -0
- data/lib/pheromone/messaging/message.rb +15 -7
- data/lib/pheromone/messaging/message_dispatcher.rb +8 -6
- data/lib/pheromone/messaging/message_formatter.rb +17 -5
- data/lib/pheromone/method_invoker.rb +2 -2
- data/lib/pheromone/publishable.rb +5 -2
- data/lib/pheromone/version.rb +1 -1
- data/pheromone.gemspec +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3e21ddb46a7940af3aa6428f01c768b484c8cd08
|
4
|
+
data.tar.gz: e25484b58e3f22a92d4829c17c850d45e6207273
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d222ca050b37759c2a85d3d5aff1d3e3a95a29fdf741dc916762cde97ed95ce67632fe443c1eafaf74e5771fc6dbdab7e2d9def782f8129f108d4da142fade11
|
7
|
+
data.tar.gz: 6b18b8348d1a54b2e5a9b3b4c9e87ccb85aebba4908c7a03b5378c305bc18e9dbc91ab07113348ed3da0a56274ff97eb57cefefa98166d8b268aad4a838c110d
|
data/README.md
CHANGED
@@ -383,6 +383,74 @@ The Kafka message will have the original metadata in addition to the new fields:
|
|
383
383
|
|
384
384
|
As seen above `timestamp` will be added automatically to the main attributes along with the message metadata. The actual message will be encapsulated inside a key called `blob`.
|
385
385
|
|
386
|
+
### 9. Encoding messages
|
387
|
+
|
388
|
+
`pheromone` allows encoding messages using custom encoders. Encoders can be specified by simply specifying a proc to encode the message in any given format.
|
389
|
+
|
390
|
+
`publish` takes the `encoder` and `message_format` as options for encoding to be specified. Encoder is called with the entire message object and performs encoding on this message.
|
391
|
+
|
392
|
+
```
|
393
|
+
publish(
|
394
|
+
[
|
395
|
+
{
|
396
|
+
topic: :test_topic,
|
397
|
+
event_types: [:update, :create],
|
398
|
+
serializer: TestSerializer,
|
399
|
+
message_format: :with_encoding,
|
400
|
+
encoder: ->(message) { avro.encode(message, schema_name: 'test') },
|
401
|
+
if: ->(object) { object.should_publish_status_update? }
|
402
|
+
}
|
403
|
+
]
|
404
|
+
)
|
405
|
+
```
|
406
|
+
|
407
|
+
## Message Contents
|
408
|
+
|
409
|
+
In versions before `< 0.5`, the metadata keys were present at the top-most level, and the message itself was embedded inside the key `blob`.
|
410
|
+
|
411
|
+
The message published to Kafka looks like this:
|
412
|
+
```
|
413
|
+
{
|
414
|
+
event: 'create',
|
415
|
+
entity: 'KlassName',
|
416
|
+
timestamp: '2015-07-14T02:10:00.000Z',
|
417
|
+
blob: {
|
418
|
+
message_contents: 'message_contents'
|
419
|
+
}
|
420
|
+
}
|
421
|
+
```
|
422
|
+
From `0.5` version onwards, the message format looks like this:
|
423
|
+
```
|
424
|
+
{
|
425
|
+
metadata: {
|
426
|
+
event: 'create',
|
427
|
+
entity: 'KlassName',
|
428
|
+
timestamp: '2015-07-14T02:10:00.000Z'
|
429
|
+
}
|
430
|
+
blob: {
|
431
|
+
message_contents: 'message_contents'
|
432
|
+
}
|
433
|
+
}
|
434
|
+
```
|
435
|
+
`event`, `entity`, and `timestamp` are determined and added by `pheromone`. `timestamp` will be in UTC by default and will use `timezone_format` value specified in `config/initializers/pheromone.rb`. Contents of `metadata` can be modified by using these [guidelines](https://github.com/ankitagupta12/pheromone#7-specifying-message-metadata). Message contents are placed under the key `blob`.
|
436
|
+
|
437
|
+
In order to use the format with `blob` embedded inside `metadata`, specify option `embed_blob` as `true` inside `publish` options like this:
|
438
|
+
|
439
|
+
```
|
440
|
+
publish(
|
441
|
+
[
|
442
|
+
{
|
443
|
+
topic: :test_topic,
|
444
|
+
event_types: [:update, :create],
|
445
|
+
serializer: TestSerializer,
|
446
|
+
message_format: :with_encoding,
|
447
|
+
embed_blob: true
|
448
|
+
encoder: ->(message) { avro.encode(message, schema_name: 'test') },
|
449
|
+
if: ->(object) { object.should_publish_status_update? }
|
450
|
+
}
|
451
|
+
]
|
452
|
+
)
|
453
|
+
```
|
386
454
|
## Testing
|
387
455
|
|
388
456
|
#### RSpec
|
@@ -2,29 +2,37 @@
|
|
2
2
|
module Pheromone
|
3
3
|
module Messaging
|
4
4
|
class Message
|
5
|
-
def initialize(topic:, blob:, metadata: {}, options: {})
|
5
|
+
def initialize(topic:, blob:, metadata: {}, options: {}, encoder:, message_format:, embed_blob:)
|
6
6
|
@topic = topic
|
7
7
|
@blob = blob
|
8
8
|
@options = options || {}
|
9
9
|
@metadata = metadata || {}
|
10
|
+
@encoder = encoder
|
11
|
+
@message_format = message_format
|
12
|
+
@embed_blob = embed_blob
|
10
13
|
end
|
11
14
|
|
12
15
|
attr_reader :topic, :blob, :options, :metadata
|
13
16
|
|
14
17
|
def send!
|
15
18
|
WaterDrop::SyncProducer.call(
|
16
|
-
MessageFormatter.new(
|
19
|
+
MessageFormatter.new(
|
20
|
+
message,
|
21
|
+
@encoder,
|
22
|
+
@message_format
|
23
|
+
).format,
|
17
24
|
{ topic: topic.to_s }.merge!(options)
|
18
25
|
)
|
19
26
|
end
|
20
27
|
|
21
28
|
private
|
22
29
|
|
23
|
-
def
|
24
|
-
@
|
25
|
-
|
26
|
-
|
27
|
-
|
30
|
+
def message
|
31
|
+
if @embed_blob
|
32
|
+
@metadata.merge!(blob: @blob)
|
33
|
+
else
|
34
|
+
{ metadata: @metadata, blob: @blob }
|
35
|
+
end
|
28
36
|
end
|
29
37
|
end
|
30
38
|
end
|
@@ -17,7 +17,12 @@ module Pheromone
|
|
17
17
|
def dispatch
|
18
18
|
return unless Pheromone.enabled?
|
19
19
|
if @dispatch_method == :sync
|
20
|
-
|
20
|
+
Message.new(
|
21
|
+
message_body.merge!(
|
22
|
+
encoder: @message_parameters[:encoder],
|
23
|
+
message_format: @message_parameters[:message_format]
|
24
|
+
)
|
25
|
+
).send!
|
21
26
|
elsif @dispatch_method == :async
|
22
27
|
send_message_asynchronously
|
23
28
|
end
|
@@ -36,16 +41,13 @@ module Pheromone
|
|
36
41
|
end
|
37
42
|
end
|
38
43
|
|
39
|
-
def message
|
40
|
-
Message.new(message_body)
|
41
|
-
end
|
42
|
-
|
43
44
|
def message_body
|
44
45
|
{
|
45
46
|
topic: @message_parameters[:topic],
|
46
47
|
blob: @message_parameters[:blob],
|
47
48
|
metadata: @message_parameters[:metadata],
|
48
|
-
options: @message_parameters[:producer_options] || {}
|
49
|
+
options: @message_parameters[:producer_options] || {},
|
50
|
+
embed_blob: @message_parameters[:embed_blob]
|
49
51
|
}
|
50
52
|
end
|
51
53
|
|
@@ -2,15 +2,23 @@ require 'pheromone/exceptions/unsupported_message_format'
|
|
2
2
|
module Pheromone
|
3
3
|
module Messaging
|
4
4
|
class MessageFormatter
|
5
|
-
|
5
|
+
include Pheromone::MethodInvoker
|
6
|
+
SUPPORTED_MESSAGE_FORMATS = [:json, :with_encoding].freeze
|
6
7
|
|
7
|
-
def initialize(message)
|
8
|
+
def initialize(message, encoder, format)
|
8
9
|
@message = message
|
10
|
+
@encoder = encoder
|
11
|
+
@message_format = format
|
9
12
|
end
|
10
13
|
|
11
14
|
def format
|
12
|
-
if
|
13
|
-
|
15
|
+
if message_format == :json
|
16
|
+
message_with_time_conversion.to_json
|
17
|
+
elsif message_format == :with_encoding
|
18
|
+
call_proc_or_instance_method(
|
19
|
+
@encoder,
|
20
|
+
message_with_time_conversion.with_indifferent_access
|
21
|
+
)
|
14
22
|
elsif !SUPPORTED_MESSAGE_FORMATS.include?(Pheromone.config.message_format)
|
15
23
|
raise Pheromone::Exceptions::UnsupportedMessageFormat.new
|
16
24
|
end
|
@@ -18,8 +26,12 @@ module Pheromone
|
|
18
26
|
|
19
27
|
private
|
20
28
|
|
29
|
+
def message_format
|
30
|
+
@message_format || Pheromone.config.message_format
|
31
|
+
end
|
32
|
+
|
21
33
|
# recursively converts time to the timezone set in configuration
|
22
|
-
def
|
34
|
+
def message_with_time_conversion
|
23
35
|
deep_transform_values!(@message) do |value|
|
24
36
|
if value.is_a? Time
|
25
37
|
value.in_time_zone(Pheromone.config.timezone)
|
@@ -6,8 +6,8 @@ module Pheromone
|
|
6
6
|
# which is difficult to avoid since it handles
|
7
7
|
# either a lambda/Proc or a named method from the including
|
8
8
|
# class.
|
9
|
-
def call_proc_or_instance_method(proc_or_symbol)
|
10
|
-
return proc_or_symbol.call(self) if proc_or_symbol.respond_to?(:call)
|
9
|
+
def call_proc_or_instance_method(proc_or_symbol, argument = nil)
|
10
|
+
return proc_or_symbol.call(argument || self) if proc_or_symbol.respond_to?(:call)
|
11
11
|
unless respond_to? proc_or_symbol
|
12
12
|
raise "Method #{proc_or_symbol} not found for #{self.class.name}"
|
13
13
|
end
|
@@ -86,7 +86,10 @@ module Pheromone
|
|
86
86
|
topic: options[:topic],
|
87
87
|
blob: message_blob(options),
|
88
88
|
metadata: message_meta_data(options, current_event),
|
89
|
-
|
89
|
+
encoder: options[:encoder],
|
90
|
+
message_format: options[:message_format],
|
91
|
+
producer_options: options[:producer_options],
|
92
|
+
embed_blob: options[:embed_blob]
|
90
93
|
},
|
91
94
|
dispatch_method: options[:dispatch_method] || :sync
|
92
95
|
).dispatch
|
@@ -94,7 +97,7 @@ module Pheromone
|
|
94
97
|
|
95
98
|
def message_meta_data(options, current_event)
|
96
99
|
metadata = options[:metadata]
|
97
|
-
default_metadata = { event: current_event, entity: self.class.name }
|
100
|
+
default_metadata = { event: current_event.to_s, entity: self.class.name, timestamp: Time.now }
|
98
101
|
return default_metadata if metadata.blank?
|
99
102
|
provided_metadata = metadata.is_a?(Hash) ? metadata : call_proc_or_instance_method(metadata)
|
100
103
|
default_metadata.merge!(provided_metadata)
|
data/lib/pheromone/version.rb
CHANGED
data/pheromone.gemspec
CHANGED
@@ -33,5 +33,5 @@ Gem::Specification.new do |spec|
|
|
33
33
|
spec.add_development_dependency 'sidekiq'
|
34
34
|
spec.add_development_dependency 'sqlite3'
|
35
35
|
spec.add_development_dependency 'timecop', '~> 0.8'
|
36
|
-
spec.add_development_dependency 'with_model', '~> 1.2'
|
36
|
+
spec.add_development_dependency 'with_model', '~> 1.2.1'
|
37
37
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pheromone
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ankita Gupta
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-06-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: active_model_serializers
|
@@ -184,14 +184,14 @@ dependencies:
|
|
184
184
|
requirements:
|
185
185
|
- - "~>"
|
186
186
|
- !ruby/object:Gem::Version
|
187
|
-
version:
|
187
|
+
version: 1.2.1
|
188
188
|
type: :development
|
189
189
|
prerelease: false
|
190
190
|
version_requirements: !ruby/object:Gem::Requirement
|
191
191
|
requirements:
|
192
192
|
- - "~>"
|
193
193
|
- !ruby/object:Gem::Version
|
194
|
-
version:
|
194
|
+
version: 1.2.1
|
195
195
|
description: Sends messages to kafka using different formats and strategies
|
196
196
|
email:
|
197
197
|
- ankitagupta12391@gmail.com
|