pheromone 0.0.2
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 +7 -0
- data/CODE_OF_CONDUCT.md +49 -0
- data/README.md +211 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/pheromone/options_validator.rb +58 -0
- data/lib/pheromone/setup/waterdrop.rb +7 -0
- data/lib/pheromone/version.rb +3 -0
- data/lib/pheromone.rb +98 -0
- metadata +164 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8a1139f6f89ed56b3c6403f3ec53e6e484129306
|
4
|
+
data.tar.gz: 6d57ed3461f221dbb859e909c78843b1996d249a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: db3e5e83ddfb4dd2f95ee7502fc958dcad89d38754ff901c8b3894b37503a6021bbeb7e68e1f55dad3fc34279017da71bb34adbc50611e4713bec2c0ed34be32
|
7
|
+
data.tar.gz: 64cba76f28557a3cdb5672ef29539a5c21650a9cebc42e1edabe7419f13ac554d280946db82de90b6194375f7d38e9357d3c99a74de5a9733c1984d72709abbf
|
data/CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# Contributor Code of Conduct
|
2
|
+
|
3
|
+
As contributors and maintainers of this project, and in the interest of
|
4
|
+
fostering an open and welcoming community, we pledge to respect all people who
|
5
|
+
contribute through reporting issues, posting feature requests, updating
|
6
|
+
documentation, submitting pull requests or patches, and other activities.
|
7
|
+
|
8
|
+
We are committed to making participation in this project a harassment-free
|
9
|
+
experience for everyone, regardless of level of experience, gender, gender
|
10
|
+
identity and expression, sexual orientation, disability, personal appearance,
|
11
|
+
body size, race, ethnicity, age, religion, or nationality.
|
12
|
+
|
13
|
+
Examples of unacceptable behavior by participants include:
|
14
|
+
|
15
|
+
* The use of sexualized language or imagery
|
16
|
+
* Personal attacks
|
17
|
+
* Trolling or insulting/derogatory comments
|
18
|
+
* Public or private harassment
|
19
|
+
* Publishing other's private information, such as physical or electronic
|
20
|
+
addresses, without explicit permission
|
21
|
+
* Other unethical or unprofessional conduct
|
22
|
+
|
23
|
+
Project maintainers have the right and responsibility to remove, edit, or
|
24
|
+
reject comments, commits, code, wiki edits, issues, and other contributions
|
25
|
+
that are not aligned to this Code of Conduct, or to ban temporarily or
|
26
|
+
permanently any contributor for other behaviors that they deem inappropriate,
|
27
|
+
threatening, offensive, or harmful.
|
28
|
+
|
29
|
+
By adopting this Code of Conduct, project maintainers commit themselves to
|
30
|
+
fairly and consistently applying these principles to every aspect of managing
|
31
|
+
this project. Project maintainers who do not follow or enforce the Code of
|
32
|
+
Conduct may be permanently removed from the project team.
|
33
|
+
|
34
|
+
This code of conduct applies both within project spaces and in public spaces
|
35
|
+
when an individual is representing the project or its community.
|
36
|
+
|
37
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
38
|
+
reported by contacting a project maintainer at ankitagupta12391@gmail.com. All
|
39
|
+
complaints will be reviewed and investigated and will result in a response that
|
40
|
+
is deemed necessary and appropriate to the circumstances. Maintainers are
|
41
|
+
obligated to maintain confidentiality with regard to the reporter of an
|
42
|
+
incident.
|
43
|
+
|
44
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
45
|
+
version 1.3.0, available at
|
46
|
+
[http://contributor-covenant.org/version/1/3/0/][version]
|
47
|
+
|
48
|
+
[homepage]: http://contributor-covenant.org
|
49
|
+
[version]: http://contributor-covenant.org/version/1/3/0/
|
data/README.md
ADDED
@@ -0,0 +1,211 @@
|
|
1
|
+
# Pheromone
|
2
|
+
|
3
|
+
`pheromone` provides a utility function to easily send `ActiveRecord` updates to Kafka.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'pheromone'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle install
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install pheromone
|
20
|
+
|
21
|
+
## Waterdrop Setup
|
22
|
+
|
23
|
+
Pheromone depends on `waterdrop` to send messages to Kafka. `waterdrop` settings can be added by following the Setup step on [waterdrop](https://github.com/karafka/waterdrop/blob/master/README.md)
|
24
|
+
|
25
|
+
WaterDrop has following configuration options:
|
26
|
+
|
27
|
+
| Option | Value type | Description |
|
28
|
+
|-------------------------|---------------|----------------------------------|
|
29
|
+
| send_messages | Boolean | Should we send messages to Kafka |
|
30
|
+
| kafka.hosts | Array<String> | Kafka servers hosts with ports |
|
31
|
+
| connection_pool_size | Integer | Kafka connection pool size |
|
32
|
+
| connection_pool_timeout | Integer | Kafka connection pool timeout |
|
33
|
+
| raise_on_failure | Boolean | Should we raise an exception when we cannot send message to Kafka - if false will silently ignore failures (will just ignore them) |
|
34
|
+
|
35
|
+
To apply this configuration, you need to use a *setup* method:
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
WaterDrop.setup do |config|
|
39
|
+
config.send_messages = true
|
40
|
+
config.connection_pool_size = 20
|
41
|
+
config.connection_pool_timeout = 1
|
42
|
+
config.kafka.hosts = ['localhost:9092']
|
43
|
+
config.raise_on_failure = true
|
44
|
+
end
|
45
|
+
```
|
46
|
+
|
47
|
+
This configuration can be placed in *config/initializers* and can vary based on the environment:
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
WaterDrop.setup do |config|
|
51
|
+
config.send_messages = Rails.env.production?
|
52
|
+
config.connection_pool_size = 20
|
53
|
+
config.connection_pool_timeout = 1
|
54
|
+
config.kafka.hosts = [Rails.env.production? ? 'prod-host:9091' : 'localhost:9092']
|
55
|
+
config.raise_on_failure = Rails.env.production?
|
56
|
+
end
|
57
|
+
```
|
58
|
+
|
59
|
+
## Usage
|
60
|
+
|
61
|
+
### 1. Supported events
|
62
|
+
#### 1.a. To send messages for model `create` event, add the following lines to your ActiveRecord model
|
63
|
+
|
64
|
+
```
|
65
|
+
class PublishableModel < ActiveRecord::Base
|
66
|
+
include Pheromone
|
67
|
+
publish message_options: [
|
68
|
+
{
|
69
|
+
event_types: [:create],
|
70
|
+
topic: :topic1,
|
71
|
+
message: ->(obj) { { name: obj.name } }
|
72
|
+
}
|
73
|
+
]
|
74
|
+
end
|
75
|
+
```
|
76
|
+
|
77
|
+
#### 1.b. To send messages for model `update` event, specify `update` in the `event_types` array:
|
78
|
+
|
79
|
+
```
|
80
|
+
class PublishableModel < ActiveRecord::Base
|
81
|
+
include Pheromone
|
82
|
+
publish message_options: [
|
83
|
+
{
|
84
|
+
event_types: [:update],
|
85
|
+
topic: :topic1,
|
86
|
+
message: ->(obj) { { name: obj.name } }
|
87
|
+
}
|
88
|
+
]
|
89
|
+
end
|
90
|
+
```
|
91
|
+
|
92
|
+
Messages can be published for multiple event types by defining `events_types: [:create, :update]`.
|
93
|
+
|
94
|
+
### 2. Supported message formats
|
95
|
+
|
96
|
+
#### 2.a. Using a proc in `message`
|
97
|
+
|
98
|
+
```
|
99
|
+
class PublishableModel < ActiveRecord::Base
|
100
|
+
include Pheromone
|
101
|
+
publish message_options: [
|
102
|
+
{
|
103
|
+
event_types: [:create],
|
104
|
+
topic: :topic1,
|
105
|
+
message: ->(obj) { { name: obj.name } }
|
106
|
+
}
|
107
|
+
]
|
108
|
+
end
|
109
|
+
```
|
110
|
+
|
111
|
+
#### 2.a. Using a defined function in `message`
|
112
|
+
|
113
|
+
```
|
114
|
+
class PublishableModel < ActiveRecord::Base
|
115
|
+
include Pheromone
|
116
|
+
publish message_options: [
|
117
|
+
{
|
118
|
+
event_types: [:update],
|
119
|
+
topic: :topic1,
|
120
|
+
message: message
|
121
|
+
}
|
122
|
+
]
|
123
|
+
|
124
|
+
def message
|
125
|
+
{ name: self.name }
|
126
|
+
end
|
127
|
+
end
|
128
|
+
```
|
129
|
+
|
130
|
+
### 3. Sending messages conditionally
|
131
|
+
|
132
|
+
#### 3.a. Using a proc in `if`
|
133
|
+
|
134
|
+
```
|
135
|
+
class PublishableModel < ActiveRecord::Base
|
136
|
+
include Pheromone
|
137
|
+
publish message_options: [
|
138
|
+
{
|
139
|
+
event_types: [:update],
|
140
|
+
topic: :topic1,
|
141
|
+
message: message,
|
142
|
+
if: ->(data) { data.condition },
|
143
|
+
}
|
144
|
+
]
|
145
|
+
|
146
|
+
def message
|
147
|
+
{ name: self.name }
|
148
|
+
end
|
149
|
+
end
|
150
|
+
```
|
151
|
+
#### 3.b. Using a defined function in `if`
|
152
|
+
|
153
|
+
```
|
154
|
+
class PublishableModel < ActiveRecord::Base
|
155
|
+
include Pheromone
|
156
|
+
publish message_options: [
|
157
|
+
{
|
158
|
+
event_types: [:update],
|
159
|
+
topic: :topic1,
|
160
|
+
message: message,
|
161
|
+
if: pre_condition
|
162
|
+
}
|
163
|
+
]
|
164
|
+
|
165
|
+
def pre_condition
|
166
|
+
name.present?
|
167
|
+
end
|
168
|
+
|
169
|
+
def message
|
170
|
+
{ name: self.name }
|
171
|
+
end
|
172
|
+
end
|
173
|
+
```
|
174
|
+
|
175
|
+
### 4. Specifying the topic
|
176
|
+
|
177
|
+
The kafka topic can be specified in the `topic` option to `publish`. To publish to `topic_test`, use the following:
|
178
|
+
|
179
|
+
|
180
|
+
```
|
181
|
+
class PublishableModel < ActiveRecord::Base
|
182
|
+
include Pheromone
|
183
|
+
publish message_options: [
|
184
|
+
{
|
185
|
+
event_types: [:create],
|
186
|
+
topic: :topic_test,
|
187
|
+
message: ->(obj) { { name: obj.name } }
|
188
|
+
}
|
189
|
+
]
|
190
|
+
end
|
191
|
+
```
|
192
|
+
|
193
|
+
|
194
|
+
## Development
|
195
|
+
|
196
|
+
After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
197
|
+
|
198
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
199
|
+
|
200
|
+
## Contributing
|
201
|
+
|
202
|
+
This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
203
|
+
|
204
|
+
|
205
|
+
## License
|
206
|
+
|
207
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
208
|
+
|
209
|
+
=======
|
210
|
+
# pheromone
|
211
|
+
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "pheromone"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
# validate message options provided to publish method in Publishable concern
|
2
|
+
class OptionsValidator
|
3
|
+
ACCEPTED_EVENT_TYPES = [:create, :update].freeze
|
4
|
+
|
5
|
+
def initialize(message_options)
|
6
|
+
@errors = {}
|
7
|
+
@message_options = message_options
|
8
|
+
end
|
9
|
+
|
10
|
+
def validate
|
11
|
+
validate_message_options
|
12
|
+
return @errors if @errors.present?
|
13
|
+
validate_topic
|
14
|
+
validate_event_types
|
15
|
+
validate_message_attributes
|
16
|
+
@errors
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def validate_message_options
|
22
|
+
return if @message_options.is_a?(Array)
|
23
|
+
add_error_message(:message_options, 'Message options should be an array')
|
24
|
+
end
|
25
|
+
|
26
|
+
def validate_topic
|
27
|
+
return if @message_options.all? { |options| options[:topic].present? }
|
28
|
+
add_error_message(:topic, 'Topic name missing')
|
29
|
+
end
|
30
|
+
|
31
|
+
# :reek:FeatureEnvy
|
32
|
+
def validate_event_types
|
33
|
+
return if @message_options.all? do |options|
|
34
|
+
event_types = options[:event_types]
|
35
|
+
next true unless event_types
|
36
|
+
event_types.present? &&
|
37
|
+
event_types.is_a?(Array) &&
|
38
|
+
(event_types - ACCEPTED_EVENT_TYPES).empty?
|
39
|
+
end
|
40
|
+
|
41
|
+
add_error_message(
|
42
|
+
:event_types,
|
43
|
+
"Event types must be a non-empty array with types #{ACCEPTED_EVENT_TYPES.join(',')}"
|
44
|
+
)
|
45
|
+
end
|
46
|
+
|
47
|
+
def validate_message_attributes
|
48
|
+
return if @message_options.all? do |options|
|
49
|
+
options[:serializer].present? || options[:message].present?
|
50
|
+
end
|
51
|
+
|
52
|
+
add_error_message(:message_attributes, 'Either serializer or message should be specified')
|
53
|
+
end
|
54
|
+
|
55
|
+
def add_error_message(key, value)
|
56
|
+
@errors.merge!(key => value)
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
WaterDrop.setup do |config|
|
2
|
+
config.send_messages = true
|
3
|
+
config.connection_pool_size = ENV['KAFKA_CONNECTION_POOL_SIZE'] || 20
|
4
|
+
config.connection_pool_timeout = ENV['KAFKA_CONNECTION_POOL_TIMEOUT'] || 1
|
5
|
+
config.kafka.hosts = (ENV['KAFKA_HOSTS'] || '').split(',')
|
6
|
+
config.raise_on_failure = true
|
7
|
+
end
|
data/lib/pheromone.rb
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'pheromone/version'
|
2
|
+
require 'pheromone/options_validator'
|
3
|
+
require 'active_support'
|
4
|
+
|
5
|
+
# Usage: For publishing messages to kafka, include this concern
|
6
|
+
# in the model and then add
|
7
|
+
#
|
8
|
+
# include Publishable
|
9
|
+
# publish message_options: [
|
10
|
+
# {
|
11
|
+
# topic: :topic1,
|
12
|
+
# event_types: [:create, :update],
|
13
|
+
# message: { a: 1, b: 2 }
|
14
|
+
# },....
|
15
|
+
# ]
|
16
|
+
#
|
17
|
+
# Each entry in message_options will be registered as a potential
|
18
|
+
# message to be published to kafka on the after_commit hook of the
|
19
|
+
# including model. message_options can take an optional if: key which
|
20
|
+
# accepts either a callback or an instance method name - which can be
|
21
|
+
# used to decide if the message should be published or not.
|
22
|
+
#
|
23
|
+
# To control how the model is serialized before being published to kafka
|
24
|
+
# either provide a Serializer via the `serializer` key or a callback or instance
|
25
|
+
# method name via the `message` key
|
26
|
+
|
27
|
+
module Pheromone
|
28
|
+
extend ActiveSupport::Concern
|
29
|
+
|
30
|
+
# class methods for the model including Publishable
|
31
|
+
module ClassMethods
|
32
|
+
def publish(message_options:)
|
33
|
+
errors = OptionsValidator.new(message_options).validate
|
34
|
+
raise "Errors: #{errors}" unless errors.empty?
|
35
|
+
__send__(:after_commit, proc { dispatch_messages(message_options: message_options) })
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def dispatch_messages(message_options:)
|
40
|
+
message_options.each do |options|
|
41
|
+
next unless check_conditions(options)
|
42
|
+
begin
|
43
|
+
send_message(options)
|
44
|
+
rescue => error
|
45
|
+
puts error
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def check_conditions(options)
|
53
|
+
condition_callback = options[:if]
|
54
|
+
return check_event(options) unless condition_callback
|
55
|
+
call_proc_or_instance_method(condition_callback)
|
56
|
+
end
|
57
|
+
|
58
|
+
def check_event(options)
|
59
|
+
options[:event_types].any? { |event| event == current_event }
|
60
|
+
end
|
61
|
+
|
62
|
+
def send_message(options)
|
63
|
+
WaterDrop::Message.new(
|
64
|
+
options[:topic],
|
65
|
+
message_meta_data.merge!(blob: message_blob(options)).to_json
|
66
|
+
).send!
|
67
|
+
end
|
68
|
+
|
69
|
+
def message_meta_data
|
70
|
+
{
|
71
|
+
event: current_event,
|
72
|
+
entity: self.class.name,
|
73
|
+
timestamp: Time.now
|
74
|
+
}
|
75
|
+
end
|
76
|
+
|
77
|
+
def current_event
|
78
|
+
id_previously_changed? ? :create : :update
|
79
|
+
end
|
80
|
+
|
81
|
+
def message_blob(options)
|
82
|
+
message = options[:message]
|
83
|
+
return call_proc_or_instance_method(message) if message
|
84
|
+
# options[:serializer].new(self, options[:serializer_options] || {}).serializable_object
|
85
|
+
end
|
86
|
+
|
87
|
+
# This method has the :reek:ManualDispatch smell,
|
88
|
+
# which is difficult to avoid since it handles
|
89
|
+
# either a lambda/Proc or a named method from the including
|
90
|
+
# class.
|
91
|
+
def call_proc_or_instance_method(proc_or_symbol)
|
92
|
+
return proc_or_symbol.call(self) if proc_or_symbol.respond_to?(:call)
|
93
|
+
unless respond_to? proc_or_symbol
|
94
|
+
raise "Method #{proc_or_symbol} not found for #{self.class.name}"
|
95
|
+
end
|
96
|
+
__send__(proc_or_symbol)
|
97
|
+
end
|
98
|
+
end
|
metadata
ADDED
@@ -0,0 +1,164 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: pheromone
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ankita Gupta
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-05-16 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '5.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '5.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: activerecord
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '5.0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '5.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: waterdrop
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.3.2.1
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.3.2.1
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: bundler
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.12'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.12'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: timecop
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0.8'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0.8'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rake
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rspec-rails
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '3.5'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '3.5'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: with_model
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '1.2'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '1.2'
|
125
|
+
description: Sends messages to kafka using different formats and strategies
|
126
|
+
email:
|
127
|
+
- ankitagupta12391@gmail.com
|
128
|
+
executables: []
|
129
|
+
extensions: []
|
130
|
+
extra_rdoc_files: []
|
131
|
+
files:
|
132
|
+
- CODE_OF_CONDUCT.md
|
133
|
+
- README.md
|
134
|
+
- bin/console
|
135
|
+
- bin/setup
|
136
|
+
- lib/pheromone.rb
|
137
|
+
- lib/pheromone/options_validator.rb
|
138
|
+
- lib/pheromone/setup/waterdrop.rb
|
139
|
+
- lib/pheromone/version.rb
|
140
|
+
homepage: https://github.com/ankitagupta12/pheromone
|
141
|
+
licenses:
|
142
|
+
- MIT
|
143
|
+
metadata: {}
|
144
|
+
post_install_message:
|
145
|
+
rdoc_options: []
|
146
|
+
require_paths:
|
147
|
+
- lib
|
148
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
154
|
+
requirements:
|
155
|
+
- - ">="
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: '0'
|
158
|
+
requirements: []
|
159
|
+
rubyforge_project:
|
160
|
+
rubygems_version: 2.6.7
|
161
|
+
signing_key:
|
162
|
+
specification_version: 4
|
163
|
+
summary: Transmits messages to kafka from active record
|
164
|
+
test_files: []
|