monsoon-droplet 1.0.0 → 1.1.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: 7e6232ff9dd488d25b28e378d87905d90a8e80bf
4
- data.tar.gz: 6628745f73d30cc0c87cb5d19c916fc9a4f38e3e
3
+ metadata.gz: 71c6d61b46942b8e4b68c0e52742786e9d6d5809
4
+ data.tar.gz: 220a3aafa400bd53007a7472008eaf4051d9b951
5
5
  SHA512:
6
- metadata.gz: fb6209b101d0aa6437d9b90fba8e215f2f8d81439ec9754b5a1ecd8b35c93e19523e2c1dee06ecca4be7ce7073fc43aabf5e709e983b880edf5ad81045733e4f
7
- data.tar.gz: 16ba8785319d604cf311db264f70cb00abc1482314b58f34d97f70831d2e7688827aaf9672c8e26131ba30fe39bd620b867342b1c9ce218e09073746449728d2
6
+ metadata.gz: c4d7e57af9b1e1f02e71ea69fe87003fe4bb90f53303709c18fbbc8be45ab59572c13cd272ad1f03e38e5b0188ad8922e56e4d05dcea867ac0302171a7cfb945
7
+ data.tar.gz: f61e8e456527c79551542091ccf7f94dbc75b68ca6abe2f098c6ff773b084c864e361fff65541ef22bdc9d045b0c2d70f0747ca27f3ab7f00743ad09c88177a7
data/README.md CHANGED
@@ -32,17 +32,18 @@ require 'monsoon/streams/kinesis'
32
32
  require 'monsoon/streams/console'
33
33
 
34
34
  Monsoon.versions_schema = {
35
- "analytics": {
36
- "1.0.0": ["user_id", "event_type", "timestamp", "data"],
37
- "1.0.1": ["user_id", "event_type", "timestamp", "data"],
38
- "1.1.0": ["user_id", "event_type", "timestamp", "data", "resource_id"],
39
- "2.0.0": ["event_type", "timestamp", "data", "resource_id"]
40
- },
41
- "transcodes": {
42
- "1.0.0": ["filename", "status"],
43
- "2.0.0": ["filename", "sources"]
35
+ "transcodes" => {
36
+ "download_complete" => {
37
+ "1.0" => ["filename", "media_id"],
38
+ "2.0" => ["url", "media_id"]
39
+ },
40
+ "transcode_complete" => {
41
+ "1.1" => ["filename", "media_id"],
42
+ "2.0" => ["media_id", "status"]
43
+ }
44
44
  }
45
45
  }
46
+ Monsoon.default_stream = 'transcodes'
46
47
 
47
48
  # if using the Kinesis stream...
48
49
  ENV['AWS_ACCESS_KEY_ID'] = "YOUR AWS ACCESS KEY"
@@ -60,39 +61,43 @@ require 'monsoon/streams/kinesis'
60
61
 
61
62
  This will add the built-in AWS Kinesis adapter. `monsoon/streams/console` is also built-in for testing by writing your streams to STDOUT.
62
63
 
63
- You can write your own stream adapter by creating a class that implements `#put_records(stream_name, records_array)` and then add it to Monsoon with `Monsoon.streams << YourNewAdapter.new`. See `Monsoon::Streams::Console` for an example.
64
+ You can write your own stream adapter by creating a class that implements `#put_records(stream_name, records_array, options_hsh = {})` and then add it to Monsoon with `Monsoon.streams << YourNewAdapter.new`. See `Monsoon::Streams::Console` for an example.
64
65
 
65
66
  Monsoon will send your messages to all added streams by default.
66
67
 
68
+ Note on Kinesis Stream: Kinesis requires a partition key when streaming a message. Monsoon will look for a `partition_key` in your droplet's `options` hash. If no `partition_key` is provided, Monsoon will default to partitioning on the event name or droplet version. If neither of those are available, Monsoon will send everything to the `monsoon` partition.
69
+
67
70
  ### Versions Schema
68
71
 
69
- To auto-generate versioned copies of your message, configure Monsoon with your versions schema. This is just a hash of stream names and keys that tells Monsoon, given a stream name, here's a list of versions we support and the keys each version should include in its message. For example, if you have the following schema defined:
72
+ To auto-generate versioned copies of your message, configure Monsoon with your versions schema. This is just a hash of stream names and keys that tells Monsoon, given a stream name and event name, here's a list of versions we support and the keys each version should include in its message. For example, if you have the following schema defined:
70
73
 
71
74
  ```ruby
72
75
  Monsoon.versions_schema = {
73
- "analytics": {
74
- "1.0.0": ["user_id", "event_type", "timestamp", "data"],
75
- "1.0.1": ["user_id", "event_type", "timestamp", "data"],
76
- "1.1.0": ["user_id", "event_type", "timestamp", "data", "resource_id"],
77
- "2.0.0": ["event_type", "timestamp", "data", "resource_id"]
78
- },
79
- "transcodes": {
80
- "1.0.0": ["filename", "status"],
81
- "2.0.0": ["filename", "sources"]
76
+ "transcodes" => {
77
+ "download_complete" => {
78
+ "1.0" => ["filename", "media_id"],
79
+ "2.0" => ["url", "media_id"]
80
+ },
81
+ "transcode_complete" => {
82
+ "1.1" => ["filename", "media_id"],
83
+ "2.0" => ["media_id", "status"]
84
+ }
82
85
  }
83
86
  }
84
87
  ```
85
88
 
86
- and you want to send the message `{user_id: 1, event_type: 'play', timestamp: 23, data: 'some other data', resource_id: 10}` to your `analytics` stream, Monsoon will automatically generate 4 versions of your message for each defined version. The versioned message will only include the keys needed for that version, as well as 2 new keys: 'droplet_version' and 'droplet_deprecated'. `droplet_version` tells the receiving client which version they're reading, and `version_deprecated` is true if there is a newer version defined in the schema.
89
+ and you want to send the message `{stream: 'transcodes', event: 'download_complete', filename: 'my_movie.mp4', media_id: 5, url: 'example.com/my_movie.mp4'}`, Monsoon will automatically generate 2 versions of your message for each defined version (1.0 and 2.0). The versioned message will only include the keys needed for that version, as well as 2 new keys: 'droplet_version' and 'droplet_deprecated'. `droplet_version` tells the receiving client which version they're reading, and `version_deprecated` is true if there is a newer version defined in the schema.
90
+
91
+ If the original message does not include all of the keys needed for an older version (e.g., `filename` is left out in the above example), then Monsoon will only send the versions it has the data for (e.g., it will only send v2.0).
87
92
 
88
- If the original message does not include all of the keys needed for an older version (e.g., `user_id` is left out in the above example), then Abacus will only send the versions it has the data for (e.g., it will only send v2.0+ for the 'analytics' stream).
93
+ Since many apps will only use 1 stream, you can also set `Monsoon.default_stream` to avoid passing the `stream` key with each message.
89
94
 
90
95
  ### Droplets
91
96
 
92
97
  To send a message after you've configured Monsoon, just create a new Droplet and stream it:
93
98
 
94
99
  ```ruby
95
- droplet = Monsoon::Droplet.new("analytics", {user_id: 1, event_type: 'play', timestamp: 23, data: 'some other data', resource_id: 10})
100
+ droplet = Monsoon::Droplet.new({stream: 'transcodes', event: 'download_complete', filename: 'my_movie.mp4', media_id: 5, url: 'example.com/my_movie.mp4'})
96
101
  droplet.stream
97
102
  ```
98
103
 
@@ -106,7 +111,7 @@ Droplets can also take a hash with the following options:
106
111
  `#stream` can also take an optional stream adapter (any object that implements `#put_records`) to only stream to that adapter. For example:
107
112
 
108
113
  ```ruby
109
- droplet = Monsoon::Droplet.new("my_stream", {user_id: 1, event_type: 'play', timestamp: 23}, {versioning: :skip})
114
+ droplet = Monsoon::Droplet.new({stream: 'transcodes', event: 'download_complete', media_id: 5, url: 'example.com/my_movie.mp4'}, {versioning: :skip})
110
115
  droplet.stream(YourNewAdapter.new)
111
116
  ```
112
117
 
@@ -5,6 +5,7 @@ require 'monsoon/droplet'
5
5
  module Monsoon
6
6
  @@streams = []
7
7
  @@versions_schema = {}
8
+ @@default_stream = nil
8
9
 
9
10
  def self.streams
10
11
  @@streams
@@ -21,4 +22,12 @@ module Monsoon
21
22
  def self.versions_schema=(versions_schema)
22
23
  @@versions_schema = versions_schema
23
24
  end
25
+
26
+ def self.default_stream
27
+ @@default_stream
28
+ end
29
+
30
+ def self.default_stream=(stream_name)
31
+ @@default_stream = stream_name
32
+ end
24
33
  end
@@ -6,21 +6,23 @@ module Monsoon
6
6
  attr_reader :data
7
7
 
8
8
  # new - creates a droplet
9
- # stream_name - name of the stream to write to (required)
10
9
  # data - hash of data to write to stream (required)
11
10
  # options - optional hash
12
11
  # :versioning => can be :skip, :enforce, or nil
13
12
  # :skip will ignore the versions schema and write the data exactly as passed
14
13
  # :enforce will require using the schema and will write nothing if unable to version
15
14
  # nil will try to write versioned droplets and fallback to raw data (default)
15
+ # :partition_key => the partition key to use for kinesis
16
16
  #
17
17
  # @example
18
- # Monsoon::Droplet.new('analytics', {user_id: 3, event_type: 'play'}, {versioning: :enforce})
19
- def initialize(stream_name, raw_data, options = {})
20
- @stream_name = stream_name
18
+ # Monsoon::Droplet.new({stream: 'transcodes', event: 'download_complete', filename: 'my_movie.mp4', media_id: 5, url: 'example.com/my_movie.mp4'}, {versioning: :enforce})
19
+ def initialize(raw_data, options = {})
20
+ @stream_name = raw_data.delete(:stream) || raw_data.delete('stream') || Monsoon.default_stream
21
+ raise ArgumentError, "stream not specified" unless @stream_name
22
+ @event = raw_data[:event] || raw_data['event']
21
23
  @options = options
22
24
  @raw_data = raw_data
23
- @data = VersionsSchema.new(@stream_name).get_droplets(@raw_data) unless @options[:versioning] == :skip
25
+ @data = VersionsSchema.new(@stream_name, @event).get_droplets(@raw_data) unless @options[:versioning] == :skip
24
26
  @data = [@raw_data] if blank? && @options[:versioning] != :enforce
25
27
  end
26
28
 
@@ -28,11 +30,11 @@ module Monsoon
28
30
  # streamer - (optional) stream adapter instance to limit which adapter is used (adapter must implement `#put_records`)
29
31
  #
30
32
  # @example
31
- # droplet = Monsoon::Droplet.new('analytics', {user_id: 3, event_type: 'play'})
33
+ # droplet = Monsoon::Droplet.new({stream: 'transcodes', event: 'download_complete', filename: 'my_movie.mp4', media_id: 5, url: 'example.com/my_movie.mp4'})
32
34
  # droplet.stream(Monsoon::Streams::Console.new)
33
35
  def stream(streamer = false)
34
36
  return if blank?
35
- streamer ? streamer.put_records(@stream_name, @data) : Monsoon.streams.each {|s| stream(s) }
37
+ streamer ? streamer.put_records(@stream_name, @data, @options) : Monsoon.streams.each {|s| stream(s) }
36
38
  end
37
39
 
38
40
  def blank?
@@ -3,7 +3,7 @@ require 'json'
3
3
  module Monsoon
4
4
  module Streams
5
5
  class Console
6
- def put_records(stream, records)
6
+ def put_records(stream, records, options = {})
7
7
  records.each do |r|
8
8
  puts "Streaming to #{stream}: #{JSON.pretty_generate(r)}"
9
9
  end
@@ -7,11 +7,11 @@ module Monsoon
7
7
  @client = Aws::Kinesis::Client.new
8
8
  end
9
9
 
10
- def put_records(stream, records)
10
+ def put_records(stream, records, options = {})
11
11
  data = records.map do |r|
12
12
  {
13
13
  data: JSON.generate(r),
14
- partition_key: 'monsoon'
14
+ partition_key: options[:partition_key] || r['event'] || r[:event] || r['droplet_version'] || 'monsoon'
15
15
  }
16
16
  end
17
17
  @client.put_records(records: data, stream_name: stream)
@@ -1,3 +1,3 @@
1
1
  module Monsoon
2
- VERSION = '1.0.0'
2
+ VERSION = '1.1.0'
3
3
  end
@@ -1,15 +1,17 @@
1
1
  module Monsoon
2
2
  class VersionsSchema
3
3
  attr_reader :stream
4
+ attr_reader :event
4
5
 
5
- def initialize(stream)
6
+ def initialize(stream, event)
6
7
  @stream = stream
8
+ @event = event
7
9
  end
8
10
 
9
11
  def get_droplets(record)
10
12
  return if record.nil?
11
13
 
12
- schema.map do |version, keys|
14
+ event_schema.map do |version, keys|
13
15
  symbolized_keys = keys.map(&:to_sym)
14
16
  # Only keep the record keys that are defined in this version's schema
15
17
  versioned_record = record.select{|k,v| symbolized_keys.include?(k.to_sym)}
@@ -18,7 +20,8 @@ module Monsoon
18
20
  # add versioning metadata
19
21
  versioned_record.merge({
20
22
  'droplet_version' => version.to_s,
21
- 'droplet_deprecated' => deprecated?(version)
23
+ 'droplet_deprecated' => deprecated?(version),
24
+ 'event' => @event
22
25
  }) if versioned_record.keys.length == keys.length # make sure we got all the keys for this version
23
26
  end.compact
24
27
  end
@@ -28,13 +31,19 @@ module Monsoon
28
31
  end
29
32
 
30
33
  def versions
31
- schema.keys
34
+ event_schema.keys
32
35
  end
33
36
 
34
37
  private
35
38
 
36
- def schema
37
- @schema ||= Monsoon.versions_schema[@stream.to_sym] || Monsoon.versions_schema[@stream.to_s] || {}
39
+ def stream_schema
40
+ return {} unless @stream
41
+ @stream_schema ||= Monsoon.versions_schema[@stream.to_sym] || Monsoon.versions_schema[@stream.to_s] || {}
42
+ end
43
+
44
+ def event_schema
45
+ return {} unless @event
46
+ @event_schema ||= stream_schema[@event.to_sym] || stream_schema[@event.to_s] || {}
38
47
  end
39
48
  end
40
49
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: monsoon-droplet
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Neil Gupta
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-10 00:00:00.000000000 Z
11
+ date: 2016-03-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk