pheromone 0.4.5 → 0.5.0

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
  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