waterdrop 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 68abb1be8f0558b53ff3cc1c8f29134e786b4c1c
4
+ data.tar.gz: 0031802410a38d242c0da4bbd74473a267852b67
5
+ SHA512:
6
+ metadata.gz: 1ca70187b5b3cc6559d48b276bc228b579cee0a0938c40656dd9158f74ae2094550b6e9059b1a4774188637fcda23fa2fed439b44a37537ffea89a73562746c4
7
+ data.tar.gz: 26c374cde1d74764d2def8933211b7a856a8f032bcd891342bc35121c5c10c0c1478d581834db9a3d9c4e0b9f26e63989c4b81315d21346eb01034b79184ebaf
data/.gitignore ADDED
@@ -0,0 +1,66 @@
1
+ # bundler state
2
+ /.bundle
3
+ /vendor/bundle/
4
+ /vendor/ruby/
5
+ /ruby/
6
+ app.god
7
+
8
+ # minimal Rails specific artifacts
9
+ db/*.sqlite3
10
+ /log/*
11
+ /tmp/*
12
+ *.gem
13
+ *.~
14
+
15
+ # various artifacts
16
+ **.war
17
+ *.rbc
18
+ *.sassc
19
+ .rspec
20
+ .redcar/
21
+ .capistrano/
22
+ .sass-cache
23
+ /config/god/sidekiq.rb
24
+ /config/puma.rb
25
+ /coverage.data
26
+ /coverage/
27
+ /doc/api/
28
+ /doc/app/
29
+ /doc/yard
30
+ /doc/features.html
31
+ /doc/specs.html
32
+ /spec/tmp/*
33
+ /cache
34
+ /capybara*
35
+ /capybara-*.html
36
+ /gems
37
+ /specifications
38
+ rerun.txt
39
+ pickle-email-*.html
40
+
41
+ # If you find yourself ignoring temporary files generated by your text editor
42
+ # or operating system, you probably want to add a global ignore instead:
43
+ # git config --global core.excludesfile ~/.gitignore_global
44
+ #
45
+ # Here are some files you may want to ignore globally:
46
+
47
+ # scm revert files
48
+ **.orig
49
+
50
+ # Mac finder artifacts
51
+ .DS_Store
52
+
53
+ # Netbeans project directory
54
+ /nbproject
55
+
56
+ # RubyMine project files
57
+ .idea
58
+
59
+ # Textmate project files
60
+ /*.tmproj
61
+
62
+ # vim artifacts
63
+ **.swp
64
+
65
+ # documentation
66
+ .yardoc
data/.ruby-gemset ADDED
@@ -0,0 +1 @@
1
+ waterdrop
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ ruby-2.2.2
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.5
4
+ - 2.2.2
5
+ script:
6
+ - bundle exec rake
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+ gem 'poseidon'
3
+ gem 'aspector'
4
+ gem 'polishgeeks-dev-tools'
data/Gemfile.lock ADDED
@@ -0,0 +1,191 @@
1
+ GEM
2
+ remote: https://rubygems.org/
3
+ specs:
4
+ abstract_type (0.0.7)
5
+ activemodel (4.2.3)
6
+ activesupport (= 4.2.3)
7
+ builder (~> 3.1)
8
+ activesupport (4.2.3)
9
+ i18n (~> 0.7)
10
+ json (~> 1.7, >= 1.7.7)
11
+ minitest (~> 5.1)
12
+ thread_safe (~> 0.3, >= 0.3.4)
13
+ tzinfo (~> 1.1)
14
+ adamantium (0.2.0)
15
+ ice_nine (~> 0.11.0)
16
+ memoizable (~> 0.4.0)
17
+ aspector (0.14.0)
18
+ ast (2.1.0)
19
+ astrolabe (1.3.1)
20
+ parser (~> 2.2)
21
+ axiom-types (0.1.1)
22
+ descendants_tracker (~> 0.0.4)
23
+ ice_nine (~> 0.11.0)
24
+ thread_safe (~> 0.3, >= 0.3.1)
25
+ brakeman (3.0.5)
26
+ erubis (~> 2.6)
27
+ fastercsv (~> 1.5)
28
+ haml (>= 3.0, < 5.0)
29
+ highline (~> 1.6.20)
30
+ multi_json (~> 1.2)
31
+ ruby2ruby (~> 2.1.1)
32
+ ruby_parser (~> 3.7.0)
33
+ sass (~> 3.0)
34
+ terminal-table (~> 1.4)
35
+ bson (3.2.1)
36
+ builder (3.2.2)
37
+ coderay (1.1.0)
38
+ coercible (1.0.0)
39
+ descendants_tracker (~> 0.0.1)
40
+ concord (0.1.5)
41
+ adamantium (~> 0.2.0)
42
+ equalizer (~> 0.0.9)
43
+ connection_pool (2.2.0)
44
+ descendants_tracker (0.0.4)
45
+ thread_safe (~> 0.3, >= 0.3.1)
46
+ diff-lcs (1.2.5)
47
+ docile (1.1.5)
48
+ equalizer (0.0.11)
49
+ erubis (2.7.0)
50
+ faker (1.5.0)
51
+ i18n (~> 0.5)
52
+ fastercsv (1.5.5)
53
+ flay (2.4.0)
54
+ ruby_parser (~> 3.0)
55
+ sexp_processor (~> 4.0)
56
+ flog (4.2.1)
57
+ ruby_parser (~> 3.1, > 3.1.0)
58
+ sexp_processor (~> 4.4)
59
+ haml (4.0.7)
60
+ tilt
61
+ haml-lint (0.13.0)
62
+ haml (~> 4.0)
63
+ rubocop (>= 0.25.0)
64
+ sysexits (~> 1.1)
65
+ highline (1.6.21)
66
+ i18n (0.7.0)
67
+ ice_nine (0.11.1)
68
+ json (1.8.3)
69
+ memoizable (0.4.2)
70
+ thread_safe (~> 0.3, >= 0.3.1)
71
+ method_source (0.8.2)
72
+ minitest (5.8.0)
73
+ mongoid (4.0.2)
74
+ activemodel (~> 4.0)
75
+ moped (~> 2.0.0)
76
+ origin (~> 2.1)
77
+ tzinfo (>= 0.3.37)
78
+ mongoid-rspec (2.2.0)
79
+ mongoid (~> 4.0.0)
80
+ rake
81
+ rspec (~> 3.1)
82
+ moped (2.0.7)
83
+ bson (~> 3.0)
84
+ connection_pool (~> 2.0)
85
+ optionable (~> 0.2.0)
86
+ multi_json (1.11.2)
87
+ optionable (0.2.0)
88
+ origin (2.1.1)
89
+ parser (2.2.2.6)
90
+ ast (>= 1.1, < 3.0)
91
+ polishgeeks-dev-tools (1.0.0)
92
+ brakeman
93
+ faker
94
+ haml-lint
95
+ mongoid-rspec
96
+ pry
97
+ rspec
98
+ rubocop
99
+ rubycritic (= 1.2.1)
100
+ shoulda
101
+ simplecov
102
+ timecop
103
+ yard
104
+ poseidon (0.0.5)
105
+ powerpack (0.1.1)
106
+ procto (0.0.2)
107
+ pry (0.10.1)
108
+ coderay (~> 1.1.0)
109
+ method_source (~> 0.8.1)
110
+ slop (~> 3.4)
111
+ rainbow (2.0.0)
112
+ rake (10.4.2)
113
+ reek (1.6.3)
114
+ parser (~> 2.2.0.pre.7)
115
+ rainbow (>= 1.99, < 3.0)
116
+ unparser (~> 0.2.2)
117
+ rspec (3.3.0)
118
+ rspec-core (~> 3.3.0)
119
+ rspec-expectations (~> 3.3.0)
120
+ rspec-mocks (~> 3.3.0)
121
+ rspec-core (3.3.2)
122
+ rspec-support (~> 3.3.0)
123
+ rspec-expectations (3.3.1)
124
+ diff-lcs (>= 1.2.0, < 2.0)
125
+ rspec-support (~> 3.3.0)
126
+ rspec-mocks (3.3.2)
127
+ diff-lcs (>= 1.2.0, < 2.0)
128
+ rspec-support (~> 3.3.0)
129
+ rspec-support (3.3.0)
130
+ rubocop (0.33.0)
131
+ astrolabe (~> 1.3)
132
+ parser (>= 2.2.2.5, < 3.0)
133
+ powerpack (~> 0.1)
134
+ rainbow (>= 1.99.1, < 3.0)
135
+ ruby-progressbar (~> 1.4)
136
+ ruby-progressbar (1.7.5)
137
+ ruby2ruby (2.1.4)
138
+ ruby_parser (~> 3.1)
139
+ sexp_processor (~> 4.0)
140
+ ruby_parser (3.7.1)
141
+ sexp_processor (~> 4.1)
142
+ rubycritic (1.2.1)
143
+ flay (= 2.4.0)
144
+ flog (= 4.2.1)
145
+ parser (>= 2.2.0, < 3.0)
146
+ reek (= 1.6.3)
147
+ ruby2ruby (>= 2.1.1, < 3.0)
148
+ virtus (~> 1.0)
149
+ sass (3.4.16)
150
+ sexp_processor (4.6.0)
151
+ shoulda (3.5.0)
152
+ shoulda-context (~> 1.0, >= 1.0.1)
153
+ shoulda-matchers (>= 1.4.1, < 3.0)
154
+ shoulda-context (1.2.1)
155
+ shoulda-matchers (2.8.0)
156
+ activesupport (>= 3.0.0)
157
+ simplecov (0.10.0)
158
+ docile (~> 1.1.0)
159
+ json (~> 1.8)
160
+ simplecov-html (~> 0.10.0)
161
+ simplecov-html (0.10.0)
162
+ slop (3.6.0)
163
+ sysexits (1.2.0)
164
+ terminal-table (1.5.2)
165
+ thread_safe (0.3.5)
166
+ tilt (2.0.1)
167
+ timecop (0.8.0)
168
+ tzinfo (1.2.2)
169
+ thread_safe (~> 0.1)
170
+ unparser (0.2.4)
171
+ abstract_type (~> 0.0.7)
172
+ adamantium (~> 0.2.0)
173
+ concord (~> 0.1.5)
174
+ diff-lcs (~> 1.2.5)
175
+ equalizer (~> 0.0.9)
176
+ parser (~> 2.2.2)
177
+ procto (~> 0.0.2)
178
+ virtus (1.0.5)
179
+ axiom-types (~> 0.1)
180
+ coercible (~> 1.0)
181
+ descendants_tracker (~> 0.0, >= 0.0.3)
182
+ equalizer (~> 0.0, >= 0.0.9)
183
+ yard (0.8.7.6)
184
+
185
+ PLATFORMS
186
+ ruby
187
+
188
+ DEPENDENCIES
189
+ aspector
190
+ polishgeeks-dev-tools
191
+ poseidon
data/MIT-LICENCE ADDED
@@ -0,0 +1,18 @@
1
+ Permission is hereby granted, free of charge, to any person obtaining
2
+ a copy of this software and associated documentation files (the
3
+ "Software"), to deal in the Software without restriction, including
4
+ without limitation the rights to use, copy, modify, merge, publish,
5
+ distribute, sublicense, and/or sell copies of the Software, and to
6
+ permit persons to whom the Software is furnished to do so, subject to
7
+ the following conditions:
8
+
9
+ The above copyright notice and this permission notice shall be
10
+ included in all copies or substantial portions of the Software.
11
+
12
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,147 @@
1
+ # WaterDrop
2
+
3
+ [![Build Status](https://travis-ci.org/karafka/waterdrop.png)](https://travis-ci.org/karafka/waterdrop)
4
+ [![Code Climate](https://codeclimate.com/github/karafka/waterdrop/badges/gpa.svg)](https://codeclimate.com/github/karafka/waterdrop)
5
+
6
+ Gem used to send events to Kafka in a standard and in an aspect way.
7
+
8
+ ## Installation
9
+
10
+ ```ruby
11
+ gem install waterdrop
12
+ ```
13
+
14
+ or add this to your Gemfile:
15
+
16
+ ```ruby
17
+ gem 'waterdrop'
18
+ ```
19
+
20
+ and run
21
+
22
+ ```
23
+ bundle install
24
+ ```
25
+
26
+ ## Setup
27
+
28
+ WaterDrop has following configuration options:
29
+
30
+ | Option | Value type | Description |
31
+ |-------------------------|---------------|--------------------------------|
32
+ | send_events | Boolean | Should we send events to Kafka |
33
+ | kafka_host | String | Kafka server host |
34
+ | kafka_ports | Array<String> | Kafka server ports |
35
+ | connection_pool_size | Integer | Kafka connection pool size |
36
+ | connection_pool_timeout | Integer | Kafka connection pool timeout |
37
+
38
+ To apply this configuration, you need to use a *setup* method:
39
+
40
+ ```ruby
41
+ WaterDrop.setup do |config|
42
+ config.send_events = true
43
+ config.connection_pool_size = 20
44
+ config.connection_pool_timeout = 1
45
+ config.kafka_ports = %w( 9092 )
46
+ config.kafka_host = 'localhost'
47
+ end
48
+ ```
49
+
50
+ This configuration can be placed in *config/initializers* and can vary based on the environment:
51
+
52
+ ```ruby
53
+ WaterDrop.setup do |config|
54
+ config.send_events = Rails.env.production?
55
+ config.connection_pool_size = 20
56
+ config.connection_pool_timeout = 1
57
+ config.kafka_ports = %w( 9092 )
58
+ config.kafka_host = Rails.env.production? ? 'prod-host' : 'localhost'
59
+ end
60
+ ```
61
+
62
+ ## Usage
63
+
64
+ ### Creating and sending standard events
65
+
66
+ To send Kafka messages, you don't need to use aspects, you can create and send events directly:
67
+
68
+ ```ruby
69
+ event = WaterDrop::Event.new('topic', 'message')
70
+ event.send!
71
+ ```
72
+
73
+ message that you want to send should be either castable to string or to json. If it can be casted to both, it will be casted to json.
74
+
75
+ ### Using aspects to handle events
76
+
77
+ WaterDrop uses [Aspector](https://github.com/gcao/aspector) to allow aspect oriented events hookup. If you need extensive details about aspector usage, please refer to the [examples](https://github.com/gcao/aspector/tree/master/examples) directory of this project.
78
+
79
+ In general aspects allows adding additional behavior to existing code without modifying the code itself. This way we can create and send events, without "polluting" the business logic with it.
80
+
81
+ All the WaterDrop aspects accept following parameters:
82
+
83
+ | Option | Value type | Description |
84
+ |-------------------------|-----------------------|----------------------------------------------|
85
+ | ClassName | Class | Class to which we want to hook |
86
+ | method: :method_name | Symbol, Array<Symbol> | Method (or methods) to which we want to hook |
87
+ | topic: 'karafka_topic' | String, Symbol | Kafka topic to which we will send the event |
88
+
89
+ There also a *message*, *after_message* and *before_message* proc parameter that will be evaluated in the methods object context.
90
+
91
+ #### Before aspects hookup
92
+
93
+ ```ruby
94
+ WaterDrop::Aspects::BeforeAspect.apply(
95
+ ClassName,
96
+ method: :run,
97
+ topic: 'karafka_topic',
98
+ message: -> { any_class_name_instance_method }
99
+ )
100
+ ```
101
+
102
+ now each time before you run:
103
+
104
+ ```ruby
105
+ ClassName.new.run
106
+ ```
107
+
108
+ an event with the given message will be send to Kafka.
109
+
110
+ #### After aspects hookup
111
+
112
+ ```ruby
113
+ WaterDrop::Aspects::AfterAspect.apply(
114
+ ClassName,
115
+ method: :run,
116
+ topic: 'karafka_topic',
117
+ message: ->(result) { "This is result of method run: #{result}" }
118
+ )
119
+ ```
120
+
121
+ now each time after you run:
122
+
123
+ ```ruby
124
+ ClassName.new.run
125
+ ```
126
+
127
+ an event with the given message will be send to Kafka.
128
+
129
+ #### Around aspects hookup
130
+
131
+ ```ruby
132
+ WaterDrop::Aspects::AroundAspect.apply(
133
+ ClassName,
134
+ method: :run,
135
+ topic: 'karafka_topic',
136
+ before_message: -> { any_class_name_instance_method },
137
+ after_message: ->(result) { "This is result of method run: #{result}" }
138
+ )
139
+ ```
140
+
141
+ now each time you run:
142
+
143
+ ```ruby
144
+ ClassName.new.run
145
+ ```
146
+
147
+ an event with the given message will be send before and after the method execution.
data/Rakefile ADDED
@@ -0,0 +1,18 @@
1
+ require 'bundler'
2
+ require 'bundler/gem_tasks'
3
+ require 'rake'
4
+ require 'polishgeeks-dev-tools'
5
+
6
+ PolishGeeks::DevTools.setup do |config|
7
+ config.brakeman = false
8
+ config.haml_lint = false
9
+ end
10
+
11
+ desc 'Self check using strike-dev-tools'
12
+ task :check do
13
+ PolishGeeks::DevTools::Runner.new.execute(
14
+ PolishGeeks::DevTools::Logger.new
15
+ )
16
+ end
17
+
18
+ task default: :check
data/lib/water_drop.rb ADDED
@@ -0,0 +1,53 @@
1
+ # External components
2
+ %w(
3
+ rake
4
+ rubygems
5
+ bundler
6
+ logger
7
+ pathname
8
+ json
9
+ poseidon
10
+ aspector
11
+ forwardable
12
+ connection_pool
13
+ ).each { |lib| require lib }
14
+
15
+ # Internal components
16
+
17
+ base_path = File.dirname(__FILE__) + '/water_drop'
18
+
19
+ %w(
20
+ version
21
+ pool
22
+ config
23
+ event
24
+ logger
25
+ aspects/base_aspect
26
+ aspects/formatter
27
+ aspects/after_aspect
28
+ aspects/around_aspect
29
+ aspects/before_aspect
30
+ ).each { |lib| require "#{base_path}/#{lib}" }
31
+
32
+ # WaterDrop library
33
+ module WaterDrop
34
+ class << self
35
+ attr_writer :logger
36
+
37
+ # @return [Logger] logger that we want to use
38
+ def logger
39
+ @logger ||= Logger.new
40
+ end
41
+
42
+ # Sets up the whole configuration
43
+ # @param [Block] block configuration block
44
+ def setup(&block)
45
+ Config.setup(&block)
46
+ end
47
+
48
+ # @return [WaterDrop::Config] config instance
49
+ def config
50
+ Config.config
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,18 @@
1
+ module WaterDrop
2
+ module Aspects
3
+ # After method execution aspect
4
+ # @example Apply after aspect to a method
5
+ # WaterDrop::Aspects::AfterAspect.apply(
6
+ # ClassName,
7
+ # method: :run,
8
+ # topic: 'karafka_topic',
9
+ # message: ->(result) { "This is result of method run: #{result}" }
10
+ # )
11
+ class AfterAspect < BaseAspect
12
+ after options[:method], interception_arg: true do |interception, result, *args|
13
+ options = interception.options
14
+ interception.aspect.handle(self, options, args, options[:message], result)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,21 @@
1
+ module WaterDrop
2
+ module Aspects
3
+ # Around method execution aspect
4
+ # @example Apply around aspect to a method
5
+ # WaterDrop::Aspects::AroundAspect.apply(
6
+ # ClassName,
7
+ # method: :run,
8
+ # topic: 'karafka_topic',
9
+ # before_message: -> { any_class_name_instance_method },
10
+ # after_message: ->(result) { "This is result of method run: #{result}" }
11
+ # )
12
+ class AroundAspect < BaseAspect
13
+ around options[:method], interception_arg: true do |interception, proxy, *args, &block|
14
+ options = interception.options
15
+ interception.aspect.handle(self, options, args, options[:before_message])
16
+ result = proxy.call(*args, &block)
17
+ interception.aspect.handle(self, options, args, options[:after_message], result)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,37 @@
1
+ module WaterDrop
2
+ # Aspects module which include all available aspects
3
+ module Aspects
4
+ # Base class for all aspects
5
+ class BaseAspect < ::Aspector::Base
6
+ default private_methods: true
7
+
8
+ # @param this is an instance on which we execute aspect (original method caller)
9
+ # @param [Hash] options aspect options
10
+ # @param [Array] args original method arguments
11
+ # @param [Block] message block which we evaluate to get a message that we will send
12
+ # @param result original method result
13
+ def handle(this, options, args, message, *result)
14
+ formatter = Formatter.new(
15
+ options,
16
+ args,
17
+ instance_run(this, result, message)
18
+ )
19
+
20
+ Event.new(options[:topic], formatter.message).send!
21
+ end
22
+
23
+ private
24
+
25
+ # Method used to change message block binding, so it will be evaluated
26
+ # in the caller instance context
27
+ # @param this is an instance on which we execute aspect (original method caller)
28
+ # @param result original method call result
29
+ # @param [Block] message block
30
+ def instance_run(this, result, message)
31
+ return this.instance_eval(&message) if message.parameters.empty?
32
+
33
+ this.instance_exec(result, message) { |res, block| block.call(res.first) }
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,18 @@
1
+ module WaterDrop
2
+ module Aspects
3
+ # Before method execution aspect
4
+ # @example Apply before aspect to a method
5
+ # WaterDrop::Aspects::BeforeAspect.apply(
6
+ # ClassName,
7
+ # method: :run,
8
+ # topic: 'karafka_topic',
9
+ # message: -> { any_class_name_instance_method }
10
+ # )
11
+ class BeforeAspect < BaseAspect
12
+ before options[:method], interception_arg: true do |interception, *args|
13
+ options = interception.options
14
+ interception.aspect.handle(self, options, args, options[:message])
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,25 @@
1
+ module WaterDrop
2
+ module Aspects
3
+ # Class used to format message that will be send from an aspect
4
+ class Formatter
5
+ # @param [Hash] options from an aspect
6
+ # @param [Array] args original method arguments
7
+ # @param result of execution of the method
8
+ def initialize(options, args, result)
9
+ @options = options
10
+ @args = args
11
+ @result = result
12
+ end
13
+
14
+ # @return [Hash] hash with formatted message that can be send
15
+ def message
16
+ {
17
+ topic: @options[:topic],
18
+ method: @options[:method],
19
+ message: @result,
20
+ args: @args
21
+ }
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,41 @@
1
+ module WaterDrop
2
+ # Configurator for setting up all options required by WaterDrop
3
+ class Config
4
+ class << self
5
+ attr_accessor :config
6
+ end
7
+
8
+ # Available options
9
+ # @option connection_pool_size [Fixnum] The number of connections to pool.
10
+ # @option connection_pool_timeout [Fixnum] Amount of time in seconds to wait for a connection
11
+ # if none currently available.
12
+ # @option kafka_ports [Array] the ports of kafka brokers
13
+ # @option kafka_host [String] the host of kafka server
14
+ # @option send_events [Boolean] boolean value to define whether events should be sent
15
+ #
16
+ OPTIONS = %i(
17
+ connection_pool_size
18
+ connection_pool_timeout
19
+ kafka_ports
20
+ kafka_host
21
+ send_events
22
+ )
23
+
24
+ OPTIONS.each do |attr_name|
25
+ attr_accessor attr_name
26
+
27
+ # @return [Boolean] is given command enabled
28
+ define_method :"#{attr_name}?" do
29
+ public_send(attr_name) == true
30
+ end
31
+ end
32
+
33
+ # Configurating method
34
+ def self.setup(&block)
35
+ self.config = new
36
+
37
+ block.call(config)
38
+ config.freeze
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,31 @@
1
+ module WaterDrop
2
+ # Event module which encapsulate single Kafka event logic and its delivery
3
+ class Event
4
+ attr_reader :topic, :message
5
+
6
+ # @param topic [String, Symbol] a topic to which we want to send a message
7
+ # @param message [Object] any object that can be serialized to a JSON string or
8
+ # that can be casted to a string
9
+ # @return [WaterDrop::Event] WaterDrop event instance
10
+ # @example Creating a new event
11
+ # WaterDrop::Event.new(topic, message)
12
+ def initialize(topic, message)
13
+ @topic = topic.to_s
14
+ @message = message.respond_to?(:to_json) ? message.to_json : message.to_s
15
+ end
16
+
17
+ # Sents a current event to Kafka
18
+ # @note Won't send any events if send_events config flag is set to false
19
+ # @example Set a message
20
+ # WaterDrop::Event.new(topic, message).send!
21
+ def send!
22
+ return true unless ::WaterDrop.config.send_events?
23
+
24
+ Pool.with do |producer|
25
+ producer.send_messages([
26
+ Poseidon::MessageToSend.new(topic, message)
27
+ ])
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,10 @@
1
+ module WaterDrop
2
+ # Null logger for karafka
3
+ # Is used when logger is not defined
4
+ class Logger
5
+ # Returns nil for any method call
6
+ def method_missing(*_args, &_block)
7
+ nil
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,24 @@
1
+ module WaterDrop
2
+ # Raw poseidon connection pool for WaterDrop events delivery
3
+ module Pool
4
+ extend SingleForwardable
5
+ # Delegate directly to pool
6
+ def_delegators :pool, :with
7
+
8
+ class << self
9
+ # @return [::ConnectionPool] connection pool instance that we can then use
10
+ def pool
11
+ @pool ||= ConnectionPool.new(
12
+ size: ::WaterDrop.config.connection_pool_size,
13
+ timeout: ::WaterDrop.config.connection_pool_timeout
14
+ ) do
15
+ addresses = ::WaterDrop.config.kafka_ports.map do |port|
16
+ "#{::WaterDrop.config.kafka_host}:#{port}"
17
+ end
18
+
19
+ Poseidon::Producer.new(addresses, object_id.to_s)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,5 @@
1
+ # WaterDrop library
2
+ module WaterDrop
3
+ # Current WaterDrop version
4
+ VERSION = '0.1.0'
5
+ end
data/waterdrop.gemspec ADDED
@@ -0,0 +1,25 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'rake'
4
+ require 'water_drop/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'waterdrop'
8
+ spec.version = ::WaterDrop::VERSION
9
+ spec.platform = Gem::Platform::RUBY
10
+ spec.authors = ['Maciej Mensfeld', 'Pavlo Vavruk']
11
+ spec.email = %w( maciej@mensfeld.pl pavlo.vavruk@gmail.com )
12
+ spec.homepage = ''
13
+ spec.summary = %q{ Kafka events with aspects made easy! }
14
+ spec.description = spec.summary
15
+ spec.license = 'MIT'
16
+
17
+ spec.add_dependency 'bundler', '~> 0'
18
+ spec.add_dependency 'rake', '~> 0'
19
+ spec.add_dependency 'aspector', '~> 0'
20
+ spec.add_dependency 'poseidon', '~> 0'
21
+
22
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(spec)/}) }
23
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
24
+ spec.require_paths = %w( lib )
25
+ end
metadata ADDED
@@ -0,0 +1,124 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: waterdrop
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Maciej Mensfeld
8
+ - Pavlo Vavruk
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2015-08-20 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: rake
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: aspector
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :runtime
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: poseidon
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - "~>"
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ description: Kafka events with aspects made easy!
71
+ email:
72
+ - maciej@mensfeld.pl
73
+ - pavlo.vavruk@gmail.com
74
+ executables: []
75
+ extensions: []
76
+ extra_rdoc_files: []
77
+ files:
78
+ - ".gitignore"
79
+ - ".ruby-gemset"
80
+ - ".ruby-version"
81
+ - ".travis.yml"
82
+ - Gemfile
83
+ - Gemfile.lock
84
+ - MIT-LICENCE
85
+ - README.md
86
+ - Rakefile
87
+ - lib/water_drop.rb
88
+ - lib/water_drop/aspects/after_aspect.rb
89
+ - lib/water_drop/aspects/around_aspect.rb
90
+ - lib/water_drop/aspects/base_aspect.rb
91
+ - lib/water_drop/aspects/before_aspect.rb
92
+ - lib/water_drop/aspects/formatter.rb
93
+ - lib/water_drop/config.rb
94
+ - lib/water_drop/event.rb
95
+ - lib/water_drop/logger.rb
96
+ - lib/water_drop/pool.rb
97
+ - lib/water_drop/version.rb
98
+ - waterdrop.gemspec
99
+ homepage: ''
100
+ licenses:
101
+ - MIT
102
+ metadata: {}
103
+ post_install_message:
104
+ rdoc_options: []
105
+ require_paths:
106
+ - lib
107
+ required_ruby_version: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ required_rubygems_version: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ requirements: []
118
+ rubyforge_project:
119
+ rubygems_version: 2.4.6
120
+ signing_key:
121
+ specification_version: 4
122
+ summary: Kafka events with aspects made easy!
123
+ test_files: []
124
+ has_rdoc: