fluq 0.7.5 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.travis.yml +3 -0
  4. data/Gemfile +12 -1
  5. data/Gemfile.lock +44 -8
  6. data/README.md +24 -6
  7. data/Rakefile +8 -1
  8. data/benchmark/socket.rb +13 -25
  9. data/examples/config/multi.rb +52 -0
  10. data/examples/config/simple.rb +15 -0
  11. data/fluq.gemspec +3 -3
  12. data/lib/fluq.rb +22 -16
  13. data/lib/fluq/cli.rb +3 -12
  14. data/lib/fluq/dsl.rb +2 -45
  15. data/lib/fluq/dsl/base.rb +11 -0
  16. data/lib/fluq/dsl/feed.rb +24 -0
  17. data/lib/fluq/dsl/root.rb +35 -0
  18. data/lib/fluq/event.rb +9 -28
  19. data/lib/fluq/feed.rb +40 -5
  20. data/lib/fluq/format.rb +6 -0
  21. data/lib/fluq/format/base.rb +42 -0
  22. data/lib/fluq/format/json.rb +17 -0
  23. data/lib/fluq/format/lines.rb +27 -0
  24. data/lib/fluq/format/msgpack.rb +28 -0
  25. data/lib/fluq/format/tsv.rb +19 -0
  26. data/lib/fluq/handler.rb +1 -1
  27. data/lib/fluq/handler/base.rb +11 -38
  28. data/lib/fluq/handler/log.rb +12 -14
  29. data/lib/fluq/handler/noop.rb +2 -0
  30. data/lib/fluq/input/base.rb +33 -29
  31. data/lib/fluq/input/socket.rb +46 -16
  32. data/lib/fluq/mixins.rb +2 -2
  33. data/lib/fluq/runner.rb +41 -0
  34. data/lib/fluq/testing.rb +5 -11
  35. data/lib/fluq/version.rb +1 -1
  36. data/lib/fluq/worker.rb +73 -0
  37. data/spec/fluq/dsl/feed_spec.rb +33 -0
  38. data/spec/fluq/dsl/root_spec.rb +20 -0
  39. data/spec/fluq/event_spec.rb +17 -12
  40. data/spec/fluq/feed_spec.rb +24 -0
  41. data/spec/fluq/format/base_spec.rb +9 -0
  42. data/spec/fluq/format/json_spec.rb +22 -0
  43. data/spec/fluq/format/lines_spec.rb +20 -0
  44. data/spec/fluq/format/msgpack_spec.rb +22 -0
  45. data/spec/fluq/format/tsv_spec.rb +21 -0
  46. data/spec/fluq/handler/base_spec.rb +7 -52
  47. data/spec/fluq/handler/log_spec.rb +11 -14
  48. data/spec/fluq/handler/{null_spec.rb → noop_spec.rb} +1 -3
  49. data/spec/fluq/input/base_spec.rb +48 -15
  50. data/spec/fluq/input/socket_spec.rb +34 -26
  51. data/spec/fluq/mixins/loggable_spec.rb +2 -2
  52. data/spec/fluq/runner_spec.rb +18 -0
  53. data/spec/fluq/worker_spec.rb +87 -0
  54. data/spec/fluq_spec.rb +1 -2
  55. data/spec/scenario/config/nested/feed1.rb +6 -0
  56. data/spec/scenario/config/test.rb +8 -2
  57. data/spec/spec_helper.rb +7 -26
  58. metadata +62 -62
  59. data/benchmark/logging.rb +0 -37
  60. data/examples/common.rb +0 -3
  61. data/examples/simple.rb +0 -5
  62. data/lib/fluq/buffer.rb +0 -6
  63. data/lib/fluq/buffer/base.rb +0 -51
  64. data/lib/fluq/buffer/file.rb +0 -68
  65. data/lib/fluq/feed/base.rb +0 -37
  66. data/lib/fluq/feed/json.rb +0 -28
  67. data/lib/fluq/feed/msgpack.rb +0 -27
  68. data/lib/fluq/feed/tsv.rb +0 -30
  69. data/lib/fluq/handler/null.rb +0 -4
  70. data/lib/fluq/input/socket/connection.rb +0 -41
  71. data/lib/fluq/mixins/logger.rb +0 -26
  72. data/lib/fluq/reactor.rb +0 -79
  73. data/spec/fluq/buffer/base_spec.rb +0 -21
  74. data/spec/fluq/buffer/file_spec.rb +0 -47
  75. data/spec/fluq/dsl_spec.rb +0 -43
  76. data/spec/fluq/feed/base_spec.rb +0 -15
  77. data/spec/fluq/feed/json_spec.rb +0 -27
  78. data/spec/fluq/feed/msgpack_spec.rb +0 -27
  79. data/spec/fluq/feed/tsv_spec.rb +0 -27
  80. data/spec/fluq/input/socket/connection_spec.rb +0 -35
  81. data/spec/fluq/mixins/logger_spec.rb +0 -25
  82. data/spec/fluq/reactor_spec.rb +0 -69
  83. data/spec/scenario/config/nested/common.rb +0 -3
@@ -0,0 +1,87 @@
1
+ require 'spec_helper'
2
+
3
+ describe FluQ::Worker do
4
+
5
+ class BadHandler < FluQ::Handler::Base
6
+ def filter(events)
7
+ events.reject! {|_| false }
8
+ end
9
+ end
10
+
11
+ let(:filtered) { event("filter" => true) }
12
+
13
+ def event(data = {})
14
+ FluQ::Event.new(data)
15
+ end
16
+
17
+ def events(num)
18
+ (0...num).map { event }
19
+ end
20
+
21
+ subject do
22
+ described_class.new "src", []
23
+ end
24
+
25
+ its(:wrapped_object) { should be_instance_of(described_class) }
26
+ its(:prefix) { should == "src" }
27
+ its(:handlers) { should have(:no).items }
28
+
29
+ it "should accept handlers" do
30
+ h1 = subject.add(FluQ::Handler::Test)
31
+ subject.should have(1).handlers
32
+ end
33
+
34
+ it "should process events" do
35
+ subject.add(FluQ::Handler::Test)
36
+ subject.add(FluQ::Handler::Test)
37
+ subject.process(events(1)).should be(true)
38
+ subject.handlers[0].should have(1).events
39
+ subject.handlers[1].should have(1).events
40
+ end
41
+
42
+ it "should prevent handlers from behaving badly" do
43
+ h1 = subject.add(BadHandler)
44
+ -> {
45
+ subject.process(events(1))
46
+ }.should raise_error(RuntimeError, /frozen/)
47
+ end
48
+
49
+ it "should skip filtered events" do
50
+ h1 = subject.add(FluQ::Handler::Test)
51
+ subject.process(events(2) + [filtered] + events(3)).should be(true)
52
+ h1.should have(5).events
53
+ end
54
+
55
+ it "should apply timeouts" do
56
+ h1 = subject.add(FluQ::Handler::Test, timeout: 0.001)
57
+ h1.events.stub(:concat).and_return {|*| sleep(0.1) }
58
+ -> {
59
+ subject.process events(1)
60
+ }.should raise_error(Timeout::Error)
61
+ end
62
+
63
+ it "should propagate handler crashes" do
64
+ h1 = subject.add(FluQ::Handler::Test)
65
+ h1.events.stub(:concat).and_raise("BOOM!")
66
+ -> {
67
+ subject.process events(1)
68
+ }.should raise_error(RuntimeError)
69
+ subject.inspect.should include("(FluQ::Worker) dead")
70
+ end
71
+
72
+ it "should execute handler timers" do
73
+ x = 0
74
+ h = subject.add(FluQ::Handler::Test)
75
+ h.timers.every(0.01) { x += 1 }
76
+ 20.times { break if x > 0; sleep(0.01) }
77
+ x.should > 0
78
+ end
79
+
80
+ it "should propagate handler timer crashes" do
81
+ h1 = subject.add(FluQ::Handler::Test)
82
+ h1.timers.every(0.01) { raise "BOOM!" }
83
+ 20.times { break if subject.inspect.include?("dead"); sleep(0.01) }
84
+ subject.inspect.should include("(FluQ::Worker) dead")
85
+ end
86
+
87
+ end
data/spec/fluq_spec.rb CHANGED
@@ -2,10 +2,9 @@ require 'spec_helper'
2
2
 
3
3
  describe FluQ do
4
4
 
5
- its(:env) { should == "test" }
6
5
  its(:root) { should be_instance_of(Pathname) }
7
6
  its(:logger) { should be_instance_of(Logger) }
8
7
  its("logger.level") { should == Logger::DEBUG }
9
8
  it { should respond_to(:logger=) }
10
9
 
11
- end
10
+ end
@@ -0,0 +1,6 @@
1
+ feed :feed1 do
2
+ input :socket do
3
+ bind 'tcp://localhost:7654'
4
+ end
5
+ handler :log
6
+ end
@@ -1,3 +1,9 @@
1
- import "nested/common.rb"
1
+ import "nested/feed1.rb"
2
+
3
+ feed :feed2 do
4
+ input :socket do
5
+ bind 'udp://localhost:7655'
6
+ end
7
+ handler :log
8
+ end
2
9
 
3
- handler :log
data/spec/spec_helper.rb CHANGED
@@ -1,37 +1,18 @@
1
- ENV['FLUQ_ENV'] ||= "test"
2
1
  ENV['FLUQ_ROOT'] ||= File.expand_path("../scenario/", __FILE__)
3
2
 
4
3
  require 'bundler/setup'
5
4
  require 'rspec'
6
- require 'fluq/testing'
5
+ require 'coveralls'
6
+ Coveralls.wear_merged!
7
7
 
8
+ require 'fluq/testing'
8
9
  FluQ.logger = Logger.new(FluQ.root.join("log", "fluq.log").to_s)
9
- FluQ::Testing.track_exceptions!
10
-
11
- $LOAD_PATH.unshift FluQ.root.join('lib')
12
- Random.srand(1234)
13
-
14
- module FluQ::SpecHelpers
15
-
16
- def self.included(base)
17
- super
18
- base.instance_eval do
19
- let(:reactor) { @_reactor ||= FluQ::Reactor.new }
20
- end
21
- end
22
-
23
- def with_reactor(&block)
24
- FluQ::Reactor.run do |reactor|
25
- @_reactor = reactor
26
- block.call(reactor)
27
- EM.stop
28
- end
29
- end
30
-
31
- end
10
+ require 'celluloid/rspec'
32
11
 
33
12
  RSpec.configure do |c|
34
- c.include FluQ::SpecHelpers
13
+ c.before :suite do
14
+ $LOAD_PATH.unshift FluQ.root.join('lib')
15
+ end
35
16
  c.after do
36
17
  FileUtils.rm_rf FluQ.root.join("tmp").to_s
37
18
  end
metadata CHANGED
@@ -1,125 +1,125 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluq
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.5
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Black Square Media
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-11-18 00:00:00.000000000 Z
11
+ date: 2014-01-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: msgpack
14
+ name: celluloid-io
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.5.0
19
+ version: 0.15.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.5.0
26
+ version: 0.15.0
27
27
  - !ruby/object:Gem::Dependency
28
- name: eventmachine-le
28
+ name: timed_lru
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '>='
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '>='
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: oj
42
+ name: multi_json
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '>='
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: 2.0.10
47
+ version: '0'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - '>='
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: 2.0.10
54
+ version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: timed_lru
56
+ name: rake
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - '>='
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
- type: :runtime
62
+ type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - '>='
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: rake
70
+ name: bundler
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - '>='
73
+ - - ">="
74
74
  - !ruby/object:Gem::Version
75
75
  version: '0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - '>='
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
- name: bundler
84
+ name: rspec
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - '>='
87
+ - - ">="
88
88
  - !ruby/object:Gem::Version
89
89
  version: '0'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - '>='
94
+ - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
- name: rspec
98
+ name: yard
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - '>='
101
+ - - ">="
102
102
  - !ruby/object:Gem::Version
103
103
  version: '0'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - '>='
108
+ - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
111
  - !ruby/object:Gem::Dependency
112
- name: yard
112
+ name: coveralls
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
- - - '>='
115
+ - - ">="
116
116
  - !ruby/object:Gem::Version
117
117
  version: '0'
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
- - - '>='
122
+ - - ">="
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0'
125
125
  description: The minimalistic stream processor
@@ -129,69 +129,69 @@ executables:
129
129
  extensions: []
130
130
  extra_rdoc_files: []
131
131
  files:
132
- - .gitignore
133
- - .travis.yml
132
+ - ".gitignore"
133
+ - ".travis.yml"
134
134
  - Gemfile
135
135
  - Gemfile.lock
136
136
  - MIT-LICENCE
137
137
  - README.md
138
138
  - Rakefile
139
- - benchmark/logging.rb
140
139
  - benchmark/socket.rb
141
140
  - bin/fluq-rb
142
- - examples/common.rb
143
- - examples/simple.rb
141
+ - examples/config/multi.rb
142
+ - examples/config/simple.rb
144
143
  - fluq.gemspec
145
144
  - lib/fluq.rb
146
- - lib/fluq/buffer.rb
147
- - lib/fluq/buffer/base.rb
148
- - lib/fluq/buffer/file.rb
149
145
  - lib/fluq/cli.rb
150
146
  - lib/fluq/dsl.rb
147
+ - lib/fluq/dsl/base.rb
148
+ - lib/fluq/dsl/feed.rb
151
149
  - lib/fluq/dsl/options.rb
150
+ - lib/fluq/dsl/root.rb
152
151
  - lib/fluq/error.rb
153
152
  - lib/fluq/event.rb
154
153
  - lib/fluq/feed.rb
155
- - lib/fluq/feed/base.rb
156
- - lib/fluq/feed/json.rb
157
- - lib/fluq/feed/msgpack.rb
158
- - lib/fluq/feed/tsv.rb
154
+ - lib/fluq/format.rb
155
+ - lib/fluq/format/base.rb
156
+ - lib/fluq/format/json.rb
157
+ - lib/fluq/format/lines.rb
158
+ - lib/fluq/format/msgpack.rb
159
+ - lib/fluq/format/tsv.rb
159
160
  - lib/fluq/handler.rb
160
161
  - lib/fluq/handler/base.rb
161
162
  - lib/fluq/handler/log.rb
162
- - lib/fluq/handler/null.rb
163
+ - lib/fluq/handler/noop.rb
163
164
  - lib/fluq/input.rb
164
165
  - lib/fluq/input/base.rb
165
166
  - lib/fluq/input/socket.rb
166
- - lib/fluq/input/socket/connection.rb
167
167
  - lib/fluq/mixins.rb
168
168
  - lib/fluq/mixins/loggable.rb
169
- - lib/fluq/mixins/logger.rb
170
- - lib/fluq/reactor.rb
169
+ - lib/fluq/runner.rb
171
170
  - lib/fluq/testing.rb
172
171
  - lib/fluq/url.rb
173
172
  - lib/fluq/version.rb
174
- - spec/fluq/buffer/base_spec.rb
175
- - spec/fluq/buffer/file_spec.rb
173
+ - lib/fluq/worker.rb
174
+ - spec/fluq/dsl/feed_spec.rb
176
175
  - spec/fluq/dsl/options_spec.rb
177
- - spec/fluq/dsl_spec.rb
176
+ - spec/fluq/dsl/root_spec.rb
178
177
  - spec/fluq/event_spec.rb
179
- - spec/fluq/feed/base_spec.rb
180
- - spec/fluq/feed/json_spec.rb
181
- - spec/fluq/feed/msgpack_spec.rb
182
- - spec/fluq/feed/tsv_spec.rb
178
+ - spec/fluq/feed_spec.rb
179
+ - spec/fluq/format/base_spec.rb
180
+ - spec/fluq/format/json_spec.rb
181
+ - spec/fluq/format/lines_spec.rb
182
+ - spec/fluq/format/msgpack_spec.rb
183
+ - spec/fluq/format/tsv_spec.rb
183
184
  - spec/fluq/handler/base_spec.rb
184
185
  - spec/fluq/handler/log_spec.rb
185
- - spec/fluq/handler/null_spec.rb
186
+ - spec/fluq/handler/noop_spec.rb
186
187
  - spec/fluq/input/base_spec.rb
187
- - spec/fluq/input/socket/connection_spec.rb
188
188
  - spec/fluq/input/socket_spec.rb
189
189
  - spec/fluq/mixins/loggable_spec.rb
190
- - spec/fluq/mixins/logger_spec.rb
191
- - spec/fluq/reactor_spec.rb
190
+ - spec/fluq/runner_spec.rb
192
191
  - spec/fluq/url_spec.rb
192
+ - spec/fluq/worker_spec.rb
193
193
  - spec/fluq_spec.rb
194
- - spec/scenario/config/nested/common.rb
194
+ - spec/scenario/config/nested/feed1.rb
195
195
  - spec/scenario/config/test.rb
196
196
  - spec/scenario/lib/fluq/handler/custom/test_handler.rb
197
197
  - spec/scenario/log/.gitkeep
@@ -206,17 +206,17 @@ require_paths:
206
206
  - lib
207
207
  required_ruby_version: !ruby/object:Gem::Requirement
208
208
  requirements:
209
- - - '>='
209
+ - - ">="
210
210
  - !ruby/object:Gem::Version
211
211
  version: 1.9.1
212
212
  required_rubygems_version: !ruby/object:Gem::Requirement
213
213
  requirements:
214
- - - '>='
214
+ - - ">="
215
215
  - !ruby/object:Gem::Version
216
216
  version: 1.8.0
217
217
  requirements: []
218
218
  rubyforge_project:
219
- rubygems_version: 2.0.3
219
+ rubygems_version: 2.2.1
220
220
  signing_key:
221
221
  specification_version: 4
222
222
  summary: FluQ
data/benchmark/logging.rb DELETED
@@ -1,37 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- $:.unshift(File.expand_path('../../lib', __FILE__))
4
-
5
- require 'bundler/setup'
6
- require 'fluq'
7
- require 'benchmark'
8
-
9
- ITER = 1_000
10
- SLICE = 1_000
11
-
12
- FileUtils.rm_rf FluQ.root.join("log/benchmark")
13
-
14
- events = (1..SLICE).map do
15
- FluQ::Event.new "a.b#{rand(4)}.c#{rand(10)}.d#{rand(100)}", Time.now.to_i, "k1" => "value", "k2" => "value", "k3" => "value"
16
- end
17
-
18
- handler = FluQ::Handler::Log.new FluQ::Reactor.new,
19
- path: "log/benchmark/%Y%m/%d/%H/%t.log",
20
- rewrite: lambda {|t| t.split(".")[1, 2].join("-") }
21
-
22
- puts "--> Started benchmark"
23
- processed = Benchmark.realtime do
24
- num = 0
25
- ITER.times do
26
- handler.on_events(events)
27
- num += SLICE
28
- if (num % 10_000).zero?
29
- puts "--> Processed : #{num}"
30
- end
31
- end
32
- end
33
-
34
- puts "--> Processed : #{events.size} in #{processed.round(1)}s"
35
- files = Dir[FluQ.root.join("log/benchmark/**/*.log").to_s]
36
- lines = `cat #{files.join(' ')} | wc -l`.strip
37
- puts "--> Fsynched : #{lines} lines"