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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b4cb86ee9ef9fea14e1e9993705fd6684472dfd8
4
- data.tar.gz: 421982c3b033d1778bcf8e9f4ee7ceec4c039e18
3
+ metadata.gz: 3e21ddb46a7940af3aa6428f01c768b484c8cd08
4
+ data.tar.gz: e25484b58e3f22a92d4829c17c850d45e6207273
5
5
  SHA512:
6
- metadata.gz: 192c520604afdabf44a96ab535ce14f3c2a7408d9684670a2986a9d7dfbac8f1e6cfe937a45b8a14c6502a5597a907117b58892f499f44e5855b9a6418fb3f84
7
- data.tar.gz: e3c87d8c40b5475097c05eeba2fe19348d16a83a50e17aef41c2e27d3be309eee090b517b2c9e938a44f965ab630c8a61e8f8b628942f76ad5c6f22a722fa931
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(full_message).format,
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 full_message
24
- @metadata.merge!(
25
- timestamp: Time.now,
26
- blob: @blob
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
- message.send!
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
- SUPPORTED_MESSAGE_FORMATS = [:json].freeze
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 Pheromone.config.message_format == :json
13
- convert_to_time_format.to_json
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 convert_to_time_format
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
- producer_options: options[:producer_options]
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)
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Pheromone
3
- VERSION = '0.4.5'.freeze
3
+ VERSION = '0.5.0'.freeze
4
4
  end
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.5
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-03-28 00:00:00.000000000 Z
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: '1.2'
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: '1.2'
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