nexia_worker_roulette 0.2.2 → 0.2.3
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 +4 -4
- data/lib/worker_roulette/batch_size.rb +18 -0
- data/lib/worker_roulette/monkey_patches.rb +9 -0
- data/lib/worker_roulette/queue_depth.rb +15 -0
- data/lib/worker_roulette/queue_latency.rb +32 -0
- data/lib/worker_roulette/queue_metric_tracker.rb +71 -0
- data/lib/worker_roulette/stat_calculator.rb +24 -0
- data/lib/worker_roulette/tradesman.rb +2 -0
- data/lib/worker_roulette/version.rb +1 -1
- data/lib/worker_roulette.rb +7 -10
- data/spec/integration/evented_worker_roulette_spec.rb +4 -4
- data/spec/integration/worker_roulette_spec.rb +5 -5
- data/spec/unit/{queue_latency_tracker_spec.rb → queue_latency_spec.rb} +9 -25
- data/spec/unit/queue_metric_tracker_spec.rb +71 -0
- data/spec/unit/readlock_spec.rb +4 -4
- data/spec/unit/stat_calculator_spec.rb +32 -0
- metadata +15 -6
- data/lib/worker_roulette/queue_latency_tracker.rb +0 -48
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 53d36e15910ce2db5cd63152496ee34dfa5c9b0f
|
4
|
+
data.tar.gz: 28376e7730e8e6fbe960f53a9936897307bc1bc8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aef9594153c398471a13a261e673a442d085c670c3782a17c673112ec4ffbfe55cf309fbfce5e746af8a66bbdb8ed629e71ca836d1fb160f6cc9b49b1088761e
|
7
|
+
data.tar.gz: 79cfc9c99a374508c56b2783d180f170671723530eccea31f6de1a8bd8dc7e19160e6b87dd1708b8eb3b68e96e03f32df40d9efa7d8052ca6e5a79ee21e0ec8f
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require_relative "queue_metric_tracker"
|
2
|
+
|
3
|
+
module WorkerRoulette
|
4
|
+
class BatchSize
|
5
|
+
include ::QueueMetricTracker
|
6
|
+
|
7
|
+
def track(sender, work_orders, _remaining)
|
8
|
+
return unless enabled?
|
9
|
+
|
10
|
+
batch_size = work_orders.length
|
11
|
+
return if batch_size == 0
|
12
|
+
|
13
|
+
if value = calculate_stats(:batch_size, batch_size)
|
14
|
+
tracker_send(message("batch_size", channel(sender), value))
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require_relative "queue_metric_tracker"
|
2
|
+
|
3
|
+
module WorkerRoulette
|
4
|
+
class QueueDepth
|
5
|
+
include ::QueueMetricTracker
|
6
|
+
|
7
|
+
def track(sender, work_orders, remaining)
|
8
|
+
return unless enabled?
|
9
|
+
|
10
|
+
if value = calculate_stats(:queue_depth, remaining)
|
11
|
+
tracker_send(message("queue_depth", channel(sender), value))
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module WorkerRoulette
|
2
|
+
module QueueLatency
|
3
|
+
GRANULARITY = 1_000_000
|
4
|
+
|
5
|
+
class Foreman
|
6
|
+
def process(work_order, _channel)
|
7
|
+
work_order['headers'].merge!(
|
8
|
+
"queued_at" => (Time.now.to_f * GRANULARITY).to_i) if work_order.is_a?(Hash) && work_order["headers"]
|
9
|
+
work_order
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class Tradesman
|
14
|
+
include QueueMetricTracker
|
15
|
+
|
16
|
+
def process(work_order, channel)
|
17
|
+
send_latency(work_order["headers"]["queued_at"], channel)
|
18
|
+
work_order
|
19
|
+
end
|
20
|
+
|
21
|
+
def send_latency(queued_at, channel)
|
22
|
+
return unless queued_at
|
23
|
+
|
24
|
+
latency_ns = (Time.now.to_f * GRANULARITY).to_i - queued_at
|
25
|
+
|
26
|
+
if value = calculate_stats(:queue_latency, latency_ns / 1000.0)
|
27
|
+
tracker_send(message("queue_latency(ms)", channel, value))
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module QueueMetricTracker
|
2
|
+
def tracker_send(msg)
|
3
|
+
UDPSocket.new.send(msg, 0, config[:metric_host][:host_ip], config[:metric_host][:host_port])
|
4
|
+
end
|
5
|
+
|
6
|
+
def granularity
|
7
|
+
config[:granularity] || 100
|
8
|
+
end
|
9
|
+
|
10
|
+
def calculate_stats(stat_name, value)
|
11
|
+
calculator(stat_name).add(value)
|
12
|
+
end
|
13
|
+
|
14
|
+
def calculator(stat_name)
|
15
|
+
QueueMetricTracker.calculators[stat_name] ||= QueueMetricTracker::StatCalculator.new(granularity)
|
16
|
+
end
|
17
|
+
|
18
|
+
def channel(sender)
|
19
|
+
(sender.split ":").first
|
20
|
+
end
|
21
|
+
|
22
|
+
def config
|
23
|
+
QueueMetricTracker.config
|
24
|
+
end
|
25
|
+
|
26
|
+
def message(label, channel, value)
|
27
|
+
"#{label},server_name=#{config[:server_name]},channel=#{channel} value=#{value} #{(Time.now.to_f * 1_000_000_000).to_i}"
|
28
|
+
end
|
29
|
+
|
30
|
+
def enabled?
|
31
|
+
return false unless config && config[:metrics]
|
32
|
+
|
33
|
+
klass = self.class.to_s.split("::").last.underscore.to_sym
|
34
|
+
config[:metrics][klass] rescue false
|
35
|
+
end
|
36
|
+
|
37
|
+
class << self
|
38
|
+
attr_reader :config, :calculators
|
39
|
+
def configure(options)
|
40
|
+
@calculators = {}
|
41
|
+
@config = {
|
42
|
+
server_name: options[:server_name],
|
43
|
+
granularity: options[:granularity],
|
44
|
+
metric_host: {
|
45
|
+
host_ip: ip_address(options[:metric_host]),
|
46
|
+
host_port: options[:metric_host_port]
|
47
|
+
}
|
48
|
+
}
|
49
|
+
@config.merge!({
|
50
|
+
metrics: options[:metrics]
|
51
|
+
}) if options[:metrics]
|
52
|
+
end
|
53
|
+
|
54
|
+
def included(tracker)
|
55
|
+
@trackers ||= []
|
56
|
+
@trackers << tracker
|
57
|
+
end
|
58
|
+
|
59
|
+
def track_all(options)
|
60
|
+
@trackers.each do |tracker_class|
|
61
|
+
tracker = tracker_class.new
|
62
|
+
tracker.track(*options) if tracker.respond_to?(:track)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def ip_address(server_name)
|
67
|
+
server_name == "localhost" ? "127.0.0.1" : Resolv.new.getaddress(server_name).to_s
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module QueueMetricTracker
|
2
|
+
class StatCalculator
|
3
|
+
attr_accessor :count, :sum, :granularity
|
4
|
+
|
5
|
+
def initialize(granularity = 100)
|
6
|
+
@granularity = granularity
|
7
|
+
@sum = 0
|
8
|
+
@count = 0
|
9
|
+
end
|
10
|
+
|
11
|
+
def add(value)
|
12
|
+
@sum += value
|
13
|
+
@count += 1
|
14
|
+
|
15
|
+
if @count == granularity
|
16
|
+
value = @sum / granularity
|
17
|
+
@sum = @count = 0
|
18
|
+
return value
|
19
|
+
end
|
20
|
+
|
21
|
+
return nil
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -134,6 +134,8 @@ module WorkerRoulette
|
|
134
134
|
work_orders = results[1]
|
135
135
|
@remaining_jobs = results[2]
|
136
136
|
@last_sender = sender_key.split(':').last
|
137
|
+
|
138
|
+
QueueMetricTracker.track_all(results) if work_orders.any?
|
137
139
|
work = work_orders.map { |wo| preprocess(WorkerRoulette.load(wo), channel) }
|
138
140
|
callback.call work if callback
|
139
141
|
work
|
data/lib/worker_roulette.rb
CHANGED
@@ -67,21 +67,22 @@ module WorkerRoulette
|
|
67
67
|
|
68
68
|
@preprocessors = []
|
69
69
|
|
70
|
-
|
70
|
+
configure_queue_tracker(config.delete(:metric_tracker))
|
71
71
|
end
|
72
72
|
|
73
|
-
def
|
73
|
+
def configure_queue_tracker(config)
|
74
74
|
return unless config
|
75
75
|
|
76
|
-
|
76
|
+
QueueMetricTracker.configure(
|
77
77
|
{
|
78
78
|
server_name: `hostname`.chomp,
|
79
|
-
|
80
|
-
|
79
|
+
metric_host: config[:metric_host],
|
80
|
+
metric_host_port: config[:metric_host_port],
|
81
|
+
metrics: config[:metrics]
|
81
82
|
}
|
82
83
|
)
|
83
84
|
|
84
|
-
preprocessors <<
|
85
|
+
preprocessors << QueueLatency
|
85
86
|
end
|
86
87
|
|
87
88
|
def foreman(sender, namespace = nil)
|
@@ -112,10 +113,6 @@ module WorkerRoulette
|
|
112
113
|
|
113
114
|
private
|
114
115
|
|
115
|
-
def ip_address(server_name)
|
116
|
-
server_name == "localhost" ? "127.0.0.1" : Resolv::DNS.new.getaddress(server_name).to_s
|
117
|
-
end
|
118
|
-
|
119
116
|
def new_redis
|
120
117
|
if @evented
|
121
118
|
require 'eventmachine'
|
@@ -12,13 +12,13 @@ module WorkerRoulette
|
|
12
12
|
let(:foreman_work_order) { Hash["payload" => "foreman"] }
|
13
13
|
let(:work_orders_with_headers) { default_headers.merge({ "payload" => work_orders }) }
|
14
14
|
let(:jsonized_work_orders_with_headers) { [WorkerRoulette.dump(work_orders_with_headers)] }
|
15
|
-
let(:
|
15
|
+
let(:metric_tracker) {
|
16
16
|
{
|
17
|
-
|
18
|
-
|
17
|
+
metric_host: "localhost",
|
18
|
+
metric_host_port: 7777
|
19
19
|
}
|
20
20
|
}
|
21
|
-
let(:worker_roulette) { WorkerRoulette.start(evented: true,
|
21
|
+
let(:worker_roulette) { WorkerRoulette.start(evented: true, metric_tracker: metric_tracker) }
|
22
22
|
let(:redis) { Redis.new(worker_roulette.redis_config) }
|
23
23
|
|
24
24
|
before do
|
@@ -14,8 +14,8 @@ module WorkerRoulette
|
|
14
14
|
let(:foreman_work_order) { Hash['payload' => "foreman"] }
|
15
15
|
let(:work_orders_with_headers) { default_headers.merge({ 'payload' => work_orders }) }
|
16
16
|
let(:jsonized_work_orders_with_headers) { [WorkerRoulette.dump(work_orders_with_headers)] }
|
17
|
-
let(:worker_roulette) { WorkerRoulette.start(evented: false,
|
18
|
-
let(:
|
17
|
+
let(:worker_roulette) { WorkerRoulette.start(evented: false, metric_tracker: metric_tracker) }
|
18
|
+
let(:metric_tracker) { nil }
|
19
19
|
|
20
20
|
let(:redis) { Redis.new(worker_roulette.redis_config) }
|
21
21
|
|
@@ -153,10 +153,10 @@ module WorkerRoulette
|
|
153
153
|
context "when latency tracker is enabled" do
|
154
154
|
let(:default_headers) { Hash["headers" => { "sender" => sender, "queued_at" => (queued_at.to_f * 1_000_000).to_i }] }
|
155
155
|
let(:queued_at) { 1234567 }
|
156
|
-
let(:
|
156
|
+
let(:metric_tracker) {
|
157
157
|
{
|
158
|
-
|
159
|
-
|
158
|
+
metric_host: "localhost",
|
159
|
+
metric_host_port: 7777
|
160
160
|
}
|
161
161
|
}
|
162
162
|
|
@@ -1,25 +1,6 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
|
-
module
|
4
|
-
describe ".configure" do
|
5
|
-
let(:source_config) { { logstash_server_ip: ip, logstash_port: port, server_name: server_name } }
|
6
|
-
let(:ip) { "1.2.3.4" }
|
7
|
-
let(:port) { 123 }
|
8
|
-
let(:server_name) { "server.example" }
|
9
|
-
|
10
|
-
|
11
|
-
it "stores the configuration" do
|
12
|
-
QueueLatencyTracker.configure(source_config)
|
13
|
-
|
14
|
-
expect(QueueLatencyTracker.config).to eq({
|
15
|
-
logstash: {
|
16
|
-
server_ip: ip,
|
17
|
-
port: port },
|
18
|
-
server_name: server_name
|
19
|
-
})
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
3
|
+
module WorkerRoulette::QueueLatency
|
23
4
|
describe Foreman do
|
24
5
|
describe "#process" do
|
25
6
|
let(:channel) { "a_channel" }
|
@@ -39,7 +20,7 @@ module QueueLatencyTracker
|
|
39
20
|
describe Tradesman do
|
40
21
|
describe "#process" do
|
41
22
|
let(:queued_at) { 1234567 * GRANULARITY }
|
42
|
-
let(:
|
23
|
+
let(:host) { "a_metric_host" }
|
43
24
|
let(:ip) { "1.2.3.4" }
|
44
25
|
let(:port) { 123 }
|
45
26
|
let(:latency) { 123.432 }
|
@@ -47,15 +28,18 @@ module QueueLatencyTracker
|
|
47
28
|
let(:channel) { "a_channel" }
|
48
29
|
let(:headers) { { "queued_at" => queued_at } }
|
49
30
|
let(:raw_work_order) { { "headers" => headers, "payload" => "aPayload" } }
|
50
|
-
let(:
|
51
|
-
let(:config) { {
|
31
|
+
let(:metric_config) { { host_ip: ip, host_port: port } }
|
32
|
+
let(:config) { { metric_host: metric_config, server_name: server_name } }
|
33
|
+
let(:expected_msg) { "queue_latency(ms),server_name=server.example,channel=a_channel value=123.432 1234690432000000" }
|
52
34
|
|
53
|
-
before { allow(
|
35
|
+
before { allow(QueueMetricTracker).to receive(:config).and_return(config) }
|
54
36
|
before { allow(Time).to receive(:now).and_return(queued_at / GRANULARITY + latency) }
|
55
37
|
before { allow_any_instance_of(UDPSocket).to receive(:send) }
|
38
|
+
before { allow_any_instance_of(QueueMetricTracker).to receive(:calculate_stats).and_return(latency) }
|
39
|
+
before { allow(QueueMetricTracker).to receive(:ipaddress).and_return(ip) }
|
56
40
|
|
57
41
|
it "passes the right json to logstash_send" do
|
58
|
-
expect_any_instance_of(UDPSocket).to receive(:send).with(
|
42
|
+
expect_any_instance_of(UDPSocket).to receive(:send).with(expected_msg, 0, ip, port)
|
59
43
|
|
60
44
|
subject.process(raw_work_order, channel)
|
61
45
|
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
module QueueMetricTracker
|
4
|
+
describe QueueMetricTracker do
|
5
|
+
let(:host) { "localhost" }
|
6
|
+
let(:port) { 123 }
|
7
|
+
let(:granularity) { 3 }
|
8
|
+
let(:ip) { "1.2.3.4" }
|
9
|
+
let(:server_name) { "server.example" }
|
10
|
+
let(:source_config) { {
|
11
|
+
metric_host: host,
|
12
|
+
metric_host_port: port,
|
13
|
+
server_name: server_name,
|
14
|
+
granularity: granularity
|
15
|
+
}
|
16
|
+
}
|
17
|
+
|
18
|
+
describe ".configure" do
|
19
|
+
it "stores the configuration" do
|
20
|
+
allow(QueueMetricTracker).to receive(:ip_address).and_return(ip)
|
21
|
+
QueueMetricTracker.configure(source_config)
|
22
|
+
|
23
|
+
expect(QueueMetricTracker.config).to eq({
|
24
|
+
metric_host: {
|
25
|
+
host_ip: ip,
|
26
|
+
host_port: port },
|
27
|
+
server_name: server_name,
|
28
|
+
granularity: granularity
|
29
|
+
})
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "#enabled?" do
|
34
|
+
let(:config) { {} }
|
35
|
+
subject(:metric) { WorkerRoulette::BatchSize }
|
36
|
+
subject(:metric_object) { metric.new }
|
37
|
+
|
38
|
+
before { QueueMetricTracker.configure(source_config.merge(config)) }
|
39
|
+
|
40
|
+
context "when the config is nil" do
|
41
|
+
it "returns false" do
|
42
|
+
expect(metric_object.enabled?).to be_falsey
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context "when the config has no metrics defined" do
|
47
|
+
let(:config) { { metrics: {}} }
|
48
|
+
|
49
|
+
it "returns false" do
|
50
|
+
expect(metric_object.enabled?).to be_falsey
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context "when the metric is false" do
|
55
|
+
let(:config) { { metrics: { :batch_size => false } } }
|
56
|
+
|
57
|
+
it "returns false" do
|
58
|
+
expect(metric_object.enabled?).to be_falsey
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context "when the metric is true" do
|
63
|
+
let(:config) { { metrics: { :batch_size => true }} }
|
64
|
+
|
65
|
+
it "returns true" do
|
66
|
+
expect(metric_object.enabled?).to be_truthy
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
data/spec/unit/readlock_spec.rb
CHANGED
@@ -2,13 +2,13 @@ require "spec_helper"
|
|
2
2
|
|
3
3
|
module WorkerRoulette
|
4
4
|
describe "Read Lock" do
|
5
|
-
let(:
|
5
|
+
let(:metric_tracker) {
|
6
6
|
{
|
7
|
-
|
8
|
-
|
7
|
+
metric_host: "localhost",
|
8
|
+
metric_host_port: 7777
|
9
9
|
}
|
10
10
|
}
|
11
|
-
let(:worker_roulette) { WorkerRoulette.start(evented: false,
|
11
|
+
let(:worker_roulette) { WorkerRoulette.start(evented: false, metric_tracker: metric_tracker) }
|
12
12
|
let(:redis) { Redis.new(worker_roulette.redis_config) }
|
13
13
|
let(:sender) { "katie_80" }
|
14
14
|
let(:work_orders) { "hello" }
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
module QueueMetricTracker
|
4
|
+
describe StatCalculator do
|
5
|
+
let(:granularity) { 10 }
|
6
|
+
let(:default_granularity) { 100 }
|
7
|
+
subject(:calculator) { described_class }
|
8
|
+
|
9
|
+
it "responds to new with a granularity" do
|
10
|
+
expect(calculator.new(granularity).granularity).to eq(granularity)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "granularity defaults to a value" do
|
14
|
+
expect(calculator.new().granularity).to eq(default_granularity)
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "#add" do
|
18
|
+
let(:granularity) { 3 }
|
19
|
+
let(:value1) { 4 }
|
20
|
+
let(:value2) { 3 }
|
21
|
+
let(:value3) { 8 }
|
22
|
+
let(:average) { 5 }
|
23
|
+
subject(:calculator) { described_class.new(granularity) }
|
24
|
+
|
25
|
+
it "calculates average of N values" do
|
26
|
+
expect(subject.add(value1)).to be_nil
|
27
|
+
expect(subject.add(value2)).to be_nil
|
28
|
+
expect(subject.add(value3)).to eq(average)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nexia_worker_roulette
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Paul Saieg
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2015-
|
13
|
+
date: 2015-08-03 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: oj
|
@@ -211,10 +211,15 @@ files:
|
|
211
211
|
- README.md
|
212
212
|
- Rakefile
|
213
213
|
- lib/worker_roulette.rb
|
214
|
+
- lib/worker_roulette/batch_size.rb
|
214
215
|
- lib/worker_roulette/foreman.rb
|
215
216
|
- lib/worker_roulette/lua.rb
|
217
|
+
- lib/worker_roulette/monkey_patches.rb
|
216
218
|
- lib/worker_roulette/preprocessor.rb
|
217
|
-
- lib/worker_roulette/
|
219
|
+
- lib/worker_roulette/queue_depth.rb
|
220
|
+
- lib/worker_roulette/queue_latency.rb
|
221
|
+
- lib/worker_roulette/queue_metric_tracker.rb
|
222
|
+
- lib/worker_roulette/stat_calculator.rb
|
218
223
|
- lib/worker_roulette/tradesman.rb
|
219
224
|
- lib/worker_roulette/version.rb
|
220
225
|
- spec/benchmark/irb_demo_runner.rb
|
@@ -226,8 +231,10 @@ files:
|
|
226
231
|
- spec/unit/evented_readlock_spec.rb
|
227
232
|
- spec/unit/lua_spec.rb
|
228
233
|
- spec/unit/preprocessor_spec.rb
|
229
|
-
- spec/unit/
|
234
|
+
- spec/unit/queue_latency_spec.rb
|
235
|
+
- spec/unit/queue_metric_tracker_spec.rb
|
230
236
|
- spec/unit/readlock_spec.rb
|
237
|
+
- spec/unit/stat_calculator_spec.rb
|
231
238
|
- worker_roulette.gemspec
|
232
239
|
homepage: https://github.com/nexiahome/worker_roulette
|
233
240
|
licenses: []
|
@@ -248,7 +255,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
248
255
|
version: '0'
|
249
256
|
requirements: []
|
250
257
|
rubyforge_project:
|
251
|
-
rubygems_version: 2.4.
|
258
|
+
rubygems_version: 2.4.5
|
252
259
|
signing_key:
|
253
260
|
specification_version: 4
|
254
261
|
summary: Pub Sub Queue for Redis that ensures ordered processing
|
@@ -262,5 +269,7 @@ test_files:
|
|
262
269
|
- spec/unit/evented_readlock_spec.rb
|
263
270
|
- spec/unit/lua_spec.rb
|
264
271
|
- spec/unit/preprocessor_spec.rb
|
265
|
-
- spec/unit/
|
272
|
+
- spec/unit/queue_latency_spec.rb
|
273
|
+
- spec/unit/queue_metric_tracker_spec.rb
|
266
274
|
- spec/unit/readlock_spec.rb
|
275
|
+
- spec/unit/stat_calculator_spec.rb
|
@@ -1,48 +0,0 @@
|
|
1
|
-
module QueueLatencyTracker
|
2
|
-
GRANULARITY = 1_000_000
|
3
|
-
|
4
|
-
class Foreman
|
5
|
-
def process(work_order, _channel)
|
6
|
-
work_order['headers'].merge!(
|
7
|
-
"queued_at" => (Time.now.to_f * GRANULARITY).to_i) if work_order.is_a?(Hash) && work_order["headers"]
|
8
|
-
work_order
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
class Tradesman
|
13
|
-
def process(work_order, channel)
|
14
|
-
send_latency(work_order["headers"]["queued_at"], channel)
|
15
|
-
work_order
|
16
|
-
end
|
17
|
-
|
18
|
-
def send_latency(queued_at, channel)
|
19
|
-
latency_ns = (Time.now.to_f * GRANULARITY).to_i - queued_at
|
20
|
-
logstash_send(latency_json(latency_ns / 1000.0, channel))
|
21
|
-
end
|
22
|
-
|
23
|
-
def logstash_send(json)
|
24
|
-
UDPSocket.new.send(json, 0, config[:logstash][:server_ip], config[:logstash][:port])
|
25
|
-
end
|
26
|
-
|
27
|
-
def latency_json(latency_ms, channel)
|
28
|
-
%({"server_name":"#{config[:server_name]}","queue_latency (ms)":#{latency_ms},"channel":"#{channel}"})
|
29
|
-
end
|
30
|
-
|
31
|
-
def config
|
32
|
-
QueueLatencyTracker.config
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
class << self
|
37
|
-
attr_reader :config
|
38
|
-
def configure(config)
|
39
|
-
@config = {
|
40
|
-
logstash: {
|
41
|
-
server_ip: config[:logstash_server_ip],
|
42
|
-
port: config[:logstash_port] },
|
43
|
-
server_name: config[:server_name]
|
44
|
-
}
|
45
|
-
end
|
46
|
-
|
47
|
-
end
|
48
|
-
end
|