fwd 0.3.1 → 0.3.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.
- data/Gemfile.lock +1 -1
- data/benchmark/performance.rb +31 -25
- data/fwd.gemspec +1 -1
- data/lib/fwd/buffer.rb +5 -6
- data/lib/fwd/cli.rb +8 -5
- data/lib/fwd.rb +5 -3
- data/spec/fwd/buffer_spec.rb +5 -5
- data/spec/fwd/cli_spec.rb +1 -2
- data/spec/spec_helper.rb +1 -1
- metadata +1 -1
data/Gemfile.lock
CHANGED
data/benchmark/performance.rb
CHANGED
@@ -1,40 +1,46 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
require 'bundler/setup'
|
3
|
+
require 'pathname'
|
6
4
|
require 'benchmark'
|
7
|
-
require '
|
8
|
-
require '
|
5
|
+
require 'socket'
|
6
|
+
require 'fileutils'
|
9
7
|
|
10
8
|
root = Pathname.new(File.expand_path('../..', __FILE__))
|
11
|
-
|
12
|
-
FileUtils.
|
9
|
+
tmp = root.join("tmp/benchmark")
|
10
|
+
FileUtils.rm_rf tmp
|
11
|
+
FileUtils.mkdir_p tmp
|
13
12
|
|
14
|
-
|
15
|
-
|
16
|
-
|
13
|
+
OUT = tmp.join('out.txt')
|
14
|
+
FWD = fork { exec "#{root}/bin/fwd-rb --flush 10000:2 -F tcp://0.0.0.0:7291 --path #{tmp} -v" }
|
15
|
+
NCC = fork { exec "nc -vlp 7291 > #{OUT}" }
|
17
16
|
|
18
|
-
|
19
|
-
|
20
|
-
|
17
|
+
at_exit do
|
18
|
+
Process.kill(:TERM, FWD)
|
19
|
+
Process.kill(:TERM, NCC)
|
21
20
|
end
|
22
|
-
|
21
|
+
|
22
|
+
sleep(3)
|
23
|
+
|
24
|
+
EVENTS = 10_000_000
|
25
|
+
LENGTH = 100
|
26
|
+
DATA = "A" * LENGTH
|
27
|
+
|
28
|
+
ds = Benchmark.realtime do
|
23
29
|
sock = TCPSocket.new "127.0.0.1", 7289
|
24
30
|
EVENTS.times { sock.write DATA }
|
25
31
|
sock.close
|
26
32
|
end
|
27
33
|
|
28
|
-
|
29
|
-
|
30
|
-
|
34
|
+
rs = Benchmark.realtime do
|
35
|
+
while OUT.size < EVENTS * LENGTH
|
36
|
+
sleep(1)
|
37
|
+
puts "--> Written : #{(OUT.size / 1024.0 / 1024.0).round(1)}M of #{(EVENTS * LENGTH / 1024.0 / 1024.0).round(1)}M"
|
38
|
+
end
|
31
39
|
end
|
32
40
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
puts "Written #{(OUTF.size / 1024.0 / 1024.0).round(1)}M"
|
40
|
-
end
|
41
|
+
sleep(3)
|
42
|
+
puts "--> Dispatched in : #{ds.round(1)}s"
|
43
|
+
puts "--> Completed in : #{(ds + rs).round(1)}s"
|
44
|
+
puts "--> FWD RSS : #{(`ps -o rss= -p #{FWD}`.to_f / 1024).round(1)}M"
|
45
|
+
puts "--> Processed : #{EVENTS} events"
|
46
|
+
puts "--> Written : #{(OUT.size / 1024.0 / 1024.0).round(1)}M"
|
data/fwd.gemspec
CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |s|
|
|
9
9
|
s.name = File.basename(__FILE__, '.gemspec')
|
10
10
|
s.summary = "fwd >>"
|
11
11
|
s.description = "The minimalistic stream forwarder"
|
12
|
-
s.version = "0.3.
|
12
|
+
s.version = "0.3.2"
|
13
13
|
|
14
14
|
s.authors = ["Black Square Media"]
|
15
15
|
s.email = "info@blacksquaremedia.com"
|
data/lib/fwd/buffer.rb
CHANGED
@@ -2,7 +2,7 @@ class Fwd::Buffer
|
|
2
2
|
extend Forwardable
|
3
3
|
def_delegators :core, :root, :prefix, :logger
|
4
4
|
|
5
|
-
|
5
|
+
MAX_LIMIT = 64 * 1024 * 1024 # 64M
|
6
6
|
attr_reader :core, :interval, :rate, :count, :limit, :timer, :fd
|
7
7
|
|
8
8
|
# Constructor
|
@@ -11,7 +11,7 @@ class Fwd::Buffer
|
|
11
11
|
@core = core
|
12
12
|
@interval = (core.opts[:flush_interval] || 60).to_i
|
13
13
|
@rate = (core.opts[:flush_rate] || 10_000).to_i
|
14
|
-
@limit =
|
14
|
+
@limit = [core.opts[:buffer_limit].to_i, MAX_LIMIT].reject(&:zero?).min
|
15
15
|
@count = 0
|
16
16
|
|
17
17
|
reschedule!
|
@@ -37,8 +37,7 @@ class Fwd::Buffer
|
|
37
37
|
|
38
38
|
# @return [Boolean] true if flush is due
|
39
39
|
def flush?
|
40
|
-
|
41
|
-
(@rate > 0 && @count >= @rate) || (@limit > 0 && @fd.size >= @limit)
|
40
|
+
@rate > 0 && @count >= @rate
|
42
41
|
end
|
43
42
|
|
44
43
|
# (Force) rotate buffer file
|
@@ -46,7 +45,7 @@ class Fwd::Buffer
|
|
46
45
|
return if @fd && @fd.size.zero?
|
47
46
|
|
48
47
|
if @fd
|
49
|
-
logger.debug { "
|
48
|
+
logger.debug { "Rotating #{File.basename(@fd.path)}, #{@fd.size / 1024} kB" }
|
50
49
|
FileUtils.mv(@fd.path, @fd.path.sub(/\.open$/, ".closed"))
|
51
50
|
end
|
52
51
|
|
@@ -56,7 +55,7 @@ class Fwd::Buffer
|
|
56
55
|
|
57
56
|
# @return [Boolean] true if rotation is due
|
58
57
|
def rotate?
|
59
|
-
@fd.nil? || @fd.size
|
58
|
+
@fd.nil? || @fd.size >= @limit
|
60
59
|
rescue Errno::ENOENT
|
61
60
|
false
|
62
61
|
end
|
data/lib/fwd/cli.rb
CHANGED
@@ -32,13 +32,12 @@ class Fwd::CLI < Hash
|
|
32
32
|
update forward: uris.map {|uri| URI.parse(uri).to_s }
|
33
33
|
end
|
34
34
|
|
35
|
-
o.on("-f", "--flush
|
35
|
+
o.on("-f", "--flush M:N",
|
36
36
|
"Flush after an interval of N seconds, " <<
|
37
37
|
"or after receiving M messages, " <<
|
38
|
-
"
|
39
|
-
"
|
40
|
-
|
41
|
-
update flush_limit: l.to_i, flush_rate: m.to_i, flush_interval: n.to_i
|
38
|
+
"Default: 10000:60") do |values|
|
39
|
+
m,n = values.split(":").map(&:to_i)
|
40
|
+
update flush_rate: m.to_i, flush_interval: n.to_i
|
42
41
|
end
|
43
42
|
|
44
43
|
o.on("--path PATH", "Root path for storage. Default: ./tmp") do |path|
|
@@ -49,6 +48,10 @@ class Fwd::CLI < Hash
|
|
49
48
|
update prefix: prefix
|
50
49
|
end
|
51
50
|
|
51
|
+
o.on("-v", "--verbose", "Enable verbose logging.") do |_|
|
52
|
+
Fwd.logger.level = Logger::DEBUG
|
53
|
+
end
|
54
|
+
|
52
55
|
o.separator ""
|
53
56
|
o.on_tail("-h", "--help", "Show this message") do
|
54
57
|
puts o
|
data/lib/fwd.rb
CHANGED
@@ -17,7 +17,9 @@ class Fwd
|
|
17
17
|
|
18
18
|
# [Logger] logger instance
|
19
19
|
def logger
|
20
|
-
@logger ||= ::Logger.new(STDOUT)
|
20
|
+
@logger ||= ::Logger.new(STDOUT).tap do |l|
|
21
|
+
l.level = ::Logger::INFO
|
22
|
+
end
|
21
23
|
end
|
22
24
|
|
23
25
|
end
|
@@ -43,8 +45,8 @@ class Fwd
|
|
43
45
|
# @option opts [String] prefix buffer file prefix
|
44
46
|
# @option opts [URI] bind the endpoint to listen to
|
45
47
|
# @option opts [Array<URI>] forward the endpoints to forward to
|
46
|
-
# @option opts [Integer]
|
47
|
-
# @option opts [Integer] flush_rate flush after
|
48
|
+
# @option opts [Integer] buffer_limit limit buffer files to N bytes
|
49
|
+
# @option opts [Integer] flush_rate flush after N messages
|
48
50
|
# @option opts [Integer] flush_interval flush after N seconds
|
49
51
|
def initialize(opts = {})
|
50
52
|
@bind = URI.parse(opts[:bind] || "tcp://0.0.0.0:7289")
|
data/spec/fwd/buffer_spec.rb
CHANGED
@@ -39,6 +39,11 @@ describe Fwd::Buffer do
|
|
39
39
|
before { buffer }
|
40
40
|
subject { lambda { buffer.rotate! } }
|
41
41
|
|
42
|
+
it 'should trigger when buffer limit is reached' do
|
43
|
+
lambda { buffer.concat("x" * 2048) }.should_not change { buffer.fd.path }
|
44
|
+
lambda { buffer.concat("x") }.should change { buffer.fd.path }
|
45
|
+
end
|
46
|
+
|
42
47
|
describe "when changed" do
|
43
48
|
before { buffer.concat("x" * 1024) }
|
44
49
|
|
@@ -67,11 +72,6 @@ describe Fwd::Buffer do
|
|
67
72
|
lambda { subject.concat("x") }.should change { subject.count }.from(19).to(0)
|
68
73
|
end
|
69
74
|
|
70
|
-
it 'should trigger when flush limit is reached' do
|
71
|
-
subject.concat("x" * 1024)
|
72
|
-
lambda { subject.concat("x" * 1024) }.should change { subject.count }.from(1).to(0)
|
73
|
-
end
|
74
|
-
|
75
75
|
it 'should reset count' do
|
76
76
|
3.times { subject.concat("x") }
|
77
77
|
lambda { subject.flush! }.should change { subject.count }.from(3).to(0)
|
data/spec/fwd/cli_spec.rb
CHANGED
@@ -8,7 +8,7 @@ describe Fwd::CLI do
|
|
8
8
|
"--prefix", "prefix",
|
9
9
|
"--bind", "tcp://127.0.0.1:7289",
|
10
10
|
"--forward", "tcp://1.2.3.4:1234,tcp://1.2.3.5:1235",
|
11
|
-
"--flush", "
|
11
|
+
"--flush", "1200:90",
|
12
12
|
]
|
13
13
|
end
|
14
14
|
|
@@ -17,7 +17,6 @@ describe Fwd::CLI do
|
|
17
17
|
its([:prefix]) { should == "prefix" }
|
18
18
|
its([:bind]) { should == "tcp://127.0.0.1:7289" }
|
19
19
|
its([:forward]) { should == ["tcp://1.2.3.4:1234", "tcp://1.2.3.5:1235"] }
|
20
|
-
its([:flush_limit]) { should == 30 }
|
21
20
|
its([:flush_rate]) { should == 1200 }
|
22
21
|
its([:flush_interval]) { should == 90 }
|
23
22
|
its(:core) { should be_instance_of(Fwd) }
|
data/spec/spec_helper.rb
CHANGED