message_bus 3.3.8 → 4.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.eslintrc.js +1 -8
- data/.github/workflows/ci.yml +3 -1
- data/CHANGELOG +107 -46
- data/README.md +38 -55
- data/Rakefile +22 -22
- data/docker-compose.yml +1 -1
- data/lib/message_bus/backends/base.rb +9 -0
- data/lib/message_bus/backends/memory.rb +7 -0
- data/lib/message_bus/backends/postgres.rb +35 -9
- data/lib/message_bus/backends/redis.rb +18 -5
- data/lib/message_bus/client.rb +23 -22
- data/lib/message_bus/rack/middleware.rb +0 -6
- data/lib/message_bus/version.rb +1 -1
- data/lib/message_bus.rb +49 -72
- data/message_bus.gemspec +0 -2
- data/spec/lib/message_bus/backend_spec.rb +19 -5
- data/spec/lib/message_bus/multi_process_spec.rb +3 -2
- data/spec/lib/message_bus/rack/middleware_spec.rb +0 -48
- data/spec/lib/message_bus/timer_thread_spec.rb +1 -5
- data/spec/lib/message_bus_spec.rb +10 -2
- data/spec/performance/backlog.rb +80 -0
- data/spec/performance/publish.rb +36 -5
- data/spec/spec_helper.rb +1 -1
- metadata +4 -30
- data/assets/application.jsx +0 -121
- data/assets/babel.min.js +0 -25
- data/assets/react-dom.js +0 -19851
- data/assets/react.js +0 -3029
- data/examples/diagnostics/Gemfile +0 -6
- data/examples/diagnostics/config.ru +0 -22
- data/lib/message_bus/diagnostics.rb +0 -62
- data/lib/message_bus/rack/diagnostics.rb +0 -120
@@ -3,9 +3,9 @@
|
|
3
3
|
require_relative '../../spec_helper'
|
4
4
|
require 'message_bus'
|
5
5
|
|
6
|
-
describe
|
6
|
+
describe BACKEND_CLASS do
|
7
7
|
before do
|
8
|
-
@bus =
|
8
|
+
@bus = BACKEND_CLASS.new(test_config_for_backend(CURRENT_BACKEND))
|
9
9
|
end
|
10
10
|
|
11
11
|
after do
|
@@ -30,7 +30,7 @@ describe PUB_SUB_CLASS do
|
|
30
30
|
end
|
31
31
|
|
32
32
|
it "should initialize with max_backlog_size" do
|
33
|
-
|
33
|
+
BACKEND_CLASS.new({}, 2000).max_backlog_size.must_equal 2000
|
34
34
|
end
|
35
35
|
|
36
36
|
it "should truncate channels correctly" do
|
@@ -91,6 +91,22 @@ describe PUB_SUB_CLASS do
|
|
91
91
|
@bus.last_id("/foo").must_equal 1
|
92
92
|
end
|
93
93
|
|
94
|
+
it "should allow us to get multiple last_ids" do
|
95
|
+
@bus.last_ids("/foo", "/bar", "/foobar").must_equal [0, 0, 0]
|
96
|
+
|
97
|
+
@bus.publish("/foo", "one")
|
98
|
+
@bus.publish("/foo", "two")
|
99
|
+
@bus.publish("/foobar", "three")
|
100
|
+
|
101
|
+
@bus.last_ids("/foo", "/bar", "/foobar").must_equal(
|
102
|
+
[
|
103
|
+
@bus.last_id("/foo"),
|
104
|
+
@bus.last_id("/bar"),
|
105
|
+
@bus.last_id("/foobar")
|
106
|
+
]
|
107
|
+
)
|
108
|
+
end
|
109
|
+
|
94
110
|
it "can set backlog age" do
|
95
111
|
@bus.max_backlog_age = 1
|
96
112
|
|
@@ -294,8 +310,6 @@ describe PUB_SUB_CLASS do
|
|
294
310
|
end
|
295
311
|
|
296
312
|
it "should support clear_every setting" do
|
297
|
-
test_never :redis
|
298
|
-
|
299
313
|
@bus.clear_every = 5
|
300
314
|
@bus.max_global_backlog_size = 2
|
301
315
|
@bus.publish "/foo", "11"
|
@@ -3,7 +3,7 @@
|
|
3
3
|
require_relative '../../spec_helper'
|
4
4
|
require 'message_bus'
|
5
5
|
|
6
|
-
describe
|
6
|
+
describe BACKEND_CLASS do
|
7
7
|
def self.error!
|
8
8
|
@error = true
|
9
9
|
end
|
@@ -13,7 +13,7 @@ describe PUB_SUB_CLASS do
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def new_bus
|
16
|
-
|
16
|
+
BACKEND_CLASS.new(test_config_for_backend(CURRENT_BACKEND).merge(db: 10))
|
17
17
|
end
|
18
18
|
|
19
19
|
def work_it
|
@@ -91,6 +91,7 @@ describe PUB_SUB_CLASS do
|
|
91
91
|
end
|
92
92
|
|
93
93
|
bus.global_unsubscribe
|
94
|
+
bus.reset!
|
94
95
|
bus.destroy
|
95
96
|
end
|
96
97
|
end
|
@@ -142,54 +142,6 @@ describe MessageBus::Rack::Middleware do
|
|
142
142
|
end
|
143
143
|
end
|
144
144
|
|
145
|
-
describe "diagnostics" do
|
146
|
-
it "should return a 403 if an unauthorized user attempts to get at the _diagnostics path" do
|
147
|
-
get "/message-bus/_diagnostics"
|
148
|
-
last_response.status.must_equal 403
|
149
|
-
end
|
150
|
-
|
151
|
-
it "should get a 200 with html for an authorized user" do
|
152
|
-
def @bus.is_admin_lookup
|
153
|
-
proc { |_| true }
|
154
|
-
end
|
155
|
-
|
156
|
-
get "/message-bus/_diagnostics"
|
157
|
-
last_response.status.must_equal 200
|
158
|
-
end
|
159
|
-
|
160
|
-
describe "with an altered base_route" do
|
161
|
-
let(:base_route) { "/base/route/" }
|
162
|
-
|
163
|
-
it "should get a 200 with html for an authorized user" do
|
164
|
-
def @bus.is_admin_lookup
|
165
|
-
proc { |_| true }
|
166
|
-
end
|
167
|
-
|
168
|
-
get "/base/route/message-bus/_diagnostics"
|
169
|
-
last_response.status.must_equal 200
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
|
-
it "should get the script it asks for" do
|
174
|
-
def @bus.is_admin_lookup
|
175
|
-
proc { |_| true }
|
176
|
-
end
|
177
|
-
|
178
|
-
get "/message-bus/_diagnostics/assets/message-bus.js"
|
179
|
-
last_response.status.must_equal 200
|
180
|
-
last_response.content_type.must_equal "application/javascript;charset=UTF-8"
|
181
|
-
end
|
182
|
-
|
183
|
-
it "should return 404 for invalid assets path" do
|
184
|
-
def @bus.is_admin_lookup
|
185
|
-
proc { |_| true }
|
186
|
-
end
|
187
|
-
|
188
|
-
get "/message-bus/_diagnostics/assets/../Gemfile"
|
189
|
-
last_response.status.must_equal 404
|
190
|
-
end
|
191
|
-
end
|
192
|
-
|
193
145
|
describe "polling" do
|
194
146
|
before do
|
195
147
|
@bus.long_polling_enabled = false
|
@@ -52,10 +52,6 @@ describe MessageBus::TimerThread do
|
|
52
52
|
it "should call the error callback if something goes wrong" do
|
53
53
|
error = nil
|
54
54
|
|
55
|
-
@timer.queue do
|
56
|
-
boom
|
57
|
-
end
|
58
|
-
|
59
55
|
@timer.on_error do |e|
|
60
56
|
error = e
|
61
57
|
end
|
@@ -64,7 +60,7 @@ describe MessageBus::TimerThread do
|
|
64
60
|
boom
|
65
61
|
end
|
66
62
|
|
67
|
-
wait_for(
|
63
|
+
wait_for(100) do
|
68
64
|
error
|
69
65
|
end
|
70
66
|
|
@@ -37,6 +37,14 @@ describe MessageBus do
|
|
37
37
|
@bus.after_fork
|
38
38
|
end
|
39
39
|
|
40
|
+
it "destroying immediately after `after_fork` does not lock" do
|
41
|
+
10.times do
|
42
|
+
@bus.on
|
43
|
+
@bus.after_fork
|
44
|
+
@bus.destroy
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
40
48
|
describe "#base_route=" do
|
41
49
|
it "adds leading and trailing slashes" do
|
42
50
|
@bus.base_route = "my/base/route"
|
@@ -107,7 +115,7 @@ describe MessageBus do
|
|
107
115
|
@bus.publish("/chuck", norris: true)
|
108
116
|
@bus.publish("/chuck", norris: true)
|
109
117
|
|
110
|
-
@bus.
|
118
|
+
@bus.backend_instance.reset!
|
111
119
|
|
112
120
|
@bus.publish("/chuck", yeager: true)
|
113
121
|
|
@@ -125,7 +133,7 @@ describe MessageBus do
|
|
125
133
|
@bus.publish("/chuck", norris: true)
|
126
134
|
@bus.publish("/chuck", norris: true)
|
127
135
|
|
128
|
-
@bus.
|
136
|
+
@bus.backend_instance.expire_all_backlogs!
|
129
137
|
|
130
138
|
@bus.publish("/chuck", yeager: true)
|
131
139
|
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
$LOAD_PATH << File.join(File.dirname(__FILE__), '..', '..', 'lib')
|
4
|
+
require 'logger'
|
5
|
+
require 'benchmark'
|
6
|
+
require 'message_bus'
|
7
|
+
|
8
|
+
require_relative "../helpers"
|
9
|
+
|
10
|
+
backends = ENV['MESSAGE_BUS_BACKENDS'].split(",").map(&:to_sym)
|
11
|
+
channel = "/foo"
|
12
|
+
iterations = 10_000
|
13
|
+
results = []
|
14
|
+
|
15
|
+
puts "Running backlog benchmark with #{iterations} iterations on backends: #{backends.inspect}"
|
16
|
+
|
17
|
+
run_benchmark = lambda do |bm, backend|
|
18
|
+
bus = MessageBus::Instance.new
|
19
|
+
bus.configure(test_config_for_backend(backend))
|
20
|
+
|
21
|
+
bus.backend_instance.max_backlog_size = 100
|
22
|
+
bus.backend_instance.max_global_backlog_size = 1000
|
23
|
+
|
24
|
+
channel_names = 10.times.map { |i| "channel#{i}" }
|
25
|
+
|
26
|
+
100.times do |i|
|
27
|
+
channel_names.each do |ch|
|
28
|
+
bus.publish(ch, { message_number_is: i })
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
last_ids = channel_names.map { |ch| [ch, bus.last_id(ch)] }.to_h
|
33
|
+
|
34
|
+
1000.times do
|
35
|
+
# Warmup
|
36
|
+
client = MessageBus::Client.new(message_bus: bus)
|
37
|
+
channel_names.each { |ch| client.subscribe(ch, -1) }
|
38
|
+
client.backlog
|
39
|
+
end
|
40
|
+
|
41
|
+
bm.report("#{backend} - #backlog with no backlogs requested") do
|
42
|
+
iterations.times do
|
43
|
+
client = MessageBus::Client.new(message_bus: bus)
|
44
|
+
channel_names.each { |ch| client.subscribe(ch, -1) }
|
45
|
+
client.backlog
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
(0..5).each do |ch_i|
|
50
|
+
channels_with_messages = (ch_i) * 2
|
51
|
+
|
52
|
+
bm.report("#{backend} - #backlog when #{channels_with_messages}/10 channels have new messages") do
|
53
|
+
iterations.times do
|
54
|
+
client = MessageBus::Client.new(message_bus: bus)
|
55
|
+
channel_names.each_with_index do |ch, i|
|
56
|
+
client.subscribe(ch, last_ids[ch] + ((i < channels_with_messages) ? -1 : 0))
|
57
|
+
end
|
58
|
+
result = client.backlog
|
59
|
+
if result.length != channels_with_messages
|
60
|
+
raise "Result has #{result.length} messages. Expected #{channels_with_messages}"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
bus.reset!
|
67
|
+
bus.destroy
|
68
|
+
end
|
69
|
+
|
70
|
+
puts
|
71
|
+
|
72
|
+
Benchmark.benchmark(" duration\n", 60, "%10.2rs\n", "") do |bm|
|
73
|
+
backends.each do |backend|
|
74
|
+
run_benchmark.call(bm, backend)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
puts
|
78
|
+
results.each do |result|
|
79
|
+
puts result
|
80
|
+
end
|
data/spec/performance/publish.rb
CHANGED
@@ -9,7 +9,7 @@ require_relative "../helpers"
|
|
9
9
|
|
10
10
|
backends = ENV['MESSAGE_BUS_BACKENDS'].split(",").map(&:to_sym)
|
11
11
|
channel = "/foo"
|
12
|
-
iterations =
|
12
|
+
iterations = 100_000
|
13
13
|
results = []
|
14
14
|
|
15
15
|
puts "Running publication benchmark with #{iterations} iterations on backends: #{backends.inspect}"
|
@@ -32,8 +32,8 @@ benchmark_subscription_no_trimming = lambda do |bm, backend|
|
|
32
32
|
bus = MessageBus::Instance.new
|
33
33
|
bus.configure(test_config_for_backend(backend))
|
34
34
|
|
35
|
-
bus.
|
36
|
-
bus.
|
35
|
+
bus.backend_instance.max_backlog_size = iterations
|
36
|
+
bus.backend_instance.max_global_backlog_size = iterations
|
37
37
|
|
38
38
|
messages_received = 0
|
39
39
|
bus.after_fork
|
@@ -58,8 +58,35 @@ benchmark_subscription_with_trimming = lambda do |bm, backend|
|
|
58
58
|
bus = MessageBus::Instance.new
|
59
59
|
bus.configure(test_config_for_backend(backend))
|
60
60
|
|
61
|
-
bus.
|
62
|
-
bus.
|
61
|
+
bus.backend_instance.max_backlog_size = (iterations / 10)
|
62
|
+
bus.backend_instance.max_global_backlog_size = (iterations / 10)
|
63
|
+
|
64
|
+
messages_received = 0
|
65
|
+
bus.after_fork
|
66
|
+
bus.subscribe(channel) do |_message|
|
67
|
+
messages_received += 1
|
68
|
+
end
|
69
|
+
|
70
|
+
bm.report(test_title) do
|
71
|
+
iterations.times { bus.publish(channel, "Hello world") }
|
72
|
+
wait_for(60000) { messages_received == iterations }
|
73
|
+
end
|
74
|
+
|
75
|
+
results << "[#{test_title}]: #{iterations} messages sent, #{messages_received} received, rate of #{(messages_received.to_f / iterations.to_f) * 100}%"
|
76
|
+
|
77
|
+
bus.reset!
|
78
|
+
bus.destroy
|
79
|
+
end
|
80
|
+
|
81
|
+
benchmark_subscription_with_trimming_and_clear_every = lambda do |bm, backend|
|
82
|
+
test_title = "#{backend} - subscription with trimming and clear_every=50"
|
83
|
+
|
84
|
+
bus = MessageBus::Instance.new
|
85
|
+
bus.configure(test_config_for_backend(backend))
|
86
|
+
|
87
|
+
bus.backend_instance.max_backlog_size = (iterations / 10)
|
88
|
+
bus.backend_instance.max_global_backlog_size = (iterations / 10)
|
89
|
+
bus.backend_instance.clear_every = 50
|
63
90
|
|
64
91
|
messages_received = 0
|
65
92
|
bus.after_fork
|
@@ -96,6 +123,10 @@ Benchmark.bm(60) do |bm|
|
|
96
123
|
backends.each do |backend|
|
97
124
|
benchmark_subscription_with_trimming.call(bm, backend)
|
98
125
|
end
|
126
|
+
|
127
|
+
backends.each do |backend|
|
128
|
+
benchmark_subscription_with_trimming_and_clear_every.call(bm, backend)
|
129
|
+
end
|
99
130
|
end
|
100
131
|
puts
|
101
132
|
|
data/spec/spec_helper.rb
CHANGED
@@ -14,7 +14,7 @@ require_relative "helpers"
|
|
14
14
|
CURRENT_BACKEND = (ENV['MESSAGE_BUS_BACKEND'] || :redis).to_sym
|
15
15
|
|
16
16
|
require "message_bus/backends/#{CURRENT_BACKEND}"
|
17
|
-
|
17
|
+
BACKEND_CLASS = MessageBus::BACKENDS.fetch(CURRENT_BACKEND)
|
18
18
|
|
19
19
|
puts "Running with backend: #{CURRENT_BACKEND}"
|
20
20
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: message_bus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 4.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sam Saffron
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-02-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -282,13 +282,9 @@ files:
|
|
282
282
|
- LICENSE
|
283
283
|
- README.md
|
284
284
|
- Rakefile
|
285
|
-
- assets/application.jsx
|
286
|
-
- assets/babel.min.js
|
287
285
|
- assets/jquery-1.8.2.js
|
288
286
|
- assets/message-bus-ajax.js
|
289
287
|
- assets/message-bus.js
|
290
|
-
- assets/react-dom.js
|
291
|
-
- assets/react.js
|
292
288
|
- bench/codecs/all_codecs.rb
|
293
289
|
- bench/codecs/marshal.rb
|
294
290
|
- bench/codecs/packed_string.rb
|
@@ -306,8 +302,6 @@ files:
|
|
306
302
|
- examples/chat/config.ru
|
307
303
|
- examples/chat/docker_container/chat.yml
|
308
304
|
- examples/chat/docker_container/update_chat
|
309
|
-
- examples/diagnostics/Gemfile
|
310
|
-
- examples/diagnostics/config.ru
|
311
305
|
- examples/minimal/Gemfile
|
312
306
|
- examples/minimal/config.ru
|
313
307
|
- lib/message_bus.rb
|
@@ -321,13 +315,11 @@ files:
|
|
321
315
|
- lib/message_bus/codec/json.rb
|
322
316
|
- lib/message_bus/codec/oj.rb
|
323
317
|
- lib/message_bus/connection_manager.rb
|
324
|
-
- lib/message_bus/diagnostics.rb
|
325
318
|
- lib/message_bus/distributed_cache.rb
|
326
319
|
- lib/message_bus/http_client.rb
|
327
320
|
- lib/message_bus/http_client/channel.rb
|
328
321
|
- lib/message_bus/http_client/version.rb
|
329
322
|
- lib/message_bus/message.rb
|
330
|
-
- lib/message_bus/rack/diagnostics.rb
|
331
323
|
- lib/message_bus/rack/middleware.rb
|
332
324
|
- lib/message_bus/rack/thin_ext.rb
|
333
325
|
- lib/message_bus/rails/railtie.rb
|
@@ -352,6 +344,7 @@ files:
|
|
352
344
|
- spec/lib/message_bus/rack/middleware_spec.rb
|
353
345
|
- spec/lib/message_bus/timer_thread_spec.rb
|
354
346
|
- spec/lib/message_bus_spec.rb
|
347
|
+
- spec/performance/backlog.rb
|
355
348
|
- spec/performance/publish.rb
|
356
349
|
- spec/spec_helper.rb
|
357
350
|
- spec/support/jasmine-browser.json
|
@@ -381,23 +374,4 @@ rubygems_version: 3.1.6
|
|
381
374
|
signing_key:
|
382
375
|
specification_version: 4
|
383
376
|
summary: ''
|
384
|
-
test_files:
|
385
|
-
- spec/assets/SpecHelper.js
|
386
|
-
- spec/assets/message-bus.spec.js
|
387
|
-
- spec/fixtures/test/Gemfile
|
388
|
-
- spec/fixtures/test/config.ru
|
389
|
-
- spec/helpers.rb
|
390
|
-
- spec/integration/http_client_spec.rb
|
391
|
-
- spec/lib/fake_async_middleware.rb
|
392
|
-
- spec/lib/message_bus/assets/asset_encoding_spec.rb
|
393
|
-
- spec/lib/message_bus/backend_spec.rb
|
394
|
-
- spec/lib/message_bus/client_spec.rb
|
395
|
-
- spec/lib/message_bus/connection_manager_spec.rb
|
396
|
-
- spec/lib/message_bus/distributed_cache_spec.rb
|
397
|
-
- spec/lib/message_bus/multi_process_spec.rb
|
398
|
-
- spec/lib/message_bus/rack/middleware_spec.rb
|
399
|
-
- spec/lib/message_bus/timer_thread_spec.rb
|
400
|
-
- spec/lib/message_bus_spec.rb
|
401
|
-
- spec/performance/publish.rb
|
402
|
-
- spec/spec_helper.rb
|
403
|
-
- spec/support/jasmine-browser.json
|
377
|
+
test_files: []
|
data/assets/application.jsx
DELETED
@@ -1,121 +0,0 @@
|
|
1
|
-
'use strict';
|
2
|
-
|
3
|
-
class Process extends React.Component {
|
4
|
-
hup() {
|
5
|
-
fetch(
|
6
|
-
`/message-bus/_diagnostics/hup/${this.props.hostname}/${this.props.pid}`,
|
7
|
-
{
|
8
|
-
method: 'POST'
|
9
|
-
}
|
10
|
-
);
|
11
|
-
}
|
12
|
-
|
13
|
-
render() {
|
14
|
-
return (
|
15
|
-
<tr>
|
16
|
-
<td>{this.props.pid}</td>
|
17
|
-
<td>{this.props.full_path}</td>
|
18
|
-
<td>{this.props.hostname}</td>
|
19
|
-
<td>{this.props.uptime} secs</td>
|
20
|
-
<td><button onClick={this.hup.bind(this)}>HUP</button></td>
|
21
|
-
</tr>
|
22
|
-
);
|
23
|
-
}
|
24
|
-
};
|
25
|
-
|
26
|
-
class DiagnosticsApp extends React.Component {
|
27
|
-
constructor(props) {
|
28
|
-
super(props);
|
29
|
-
this.state = {processes: []};
|
30
|
-
}
|
31
|
-
|
32
|
-
componentDidMount() {
|
33
|
-
MessageBus.start();
|
34
|
-
this.ensureSubscribed();
|
35
|
-
}
|
36
|
-
|
37
|
-
discover() {
|
38
|
-
this.ensureSubscribed();
|
39
|
-
|
40
|
-
this.setState({discovering: true});
|
41
|
-
|
42
|
-
var _this = this;
|
43
|
-
fetch(
|
44
|
-
"/message-bus/_diagnostics/discover",
|
45
|
-
{
|
46
|
-
method: "POST"
|
47
|
-
}
|
48
|
-
).then(function() {
|
49
|
-
_this.setState({discovering: false})
|
50
|
-
});
|
51
|
-
}
|
52
|
-
|
53
|
-
ensureSubscribed() {
|
54
|
-
if (this.state.subscribed) { return; }
|
55
|
-
|
56
|
-
MessageBus.callbackInterval = 500;
|
57
|
-
|
58
|
-
MessageBus.subscribe(
|
59
|
-
"/_diagnostics/process-discovery",
|
60
|
-
this.updateProcess.bind(this)
|
61
|
-
);
|
62
|
-
|
63
|
-
this.setState({subscribed: true});
|
64
|
-
}
|
65
|
-
|
66
|
-
updateProcess(data) {
|
67
|
-
const _this = this;
|
68
|
-
const processes = this.state.processes.filter(function(process) {
|
69
|
-
return _this.processUniqueId(process) !== _this.processUniqueId(data);
|
70
|
-
});
|
71
|
-
this.setState({processes: processes.concat([data])});
|
72
|
-
}
|
73
|
-
|
74
|
-
processUniqueId(process) {
|
75
|
-
return process.hostname + process.pid;
|
76
|
-
}
|
77
|
-
|
78
|
-
render() {
|
79
|
-
let disabled = this.state.discovering ? "disabled" : null;
|
80
|
-
|
81
|
-
let _this = this;
|
82
|
-
let processes = this.state.processes.sort(function(a,b) {
|
83
|
-
return _this.processUniqueId(a) < _this.processUniqueId(b) ? -1 : 1;
|
84
|
-
});
|
85
|
-
|
86
|
-
return (
|
87
|
-
<div>
|
88
|
-
<header>
|
89
|
-
<h2>Message Bus Diagnostics</h2>
|
90
|
-
</header>
|
91
|
-
|
92
|
-
<div>
|
93
|
-
<button onClick={this.discover.bind(this)} disabled={disabled}>Discover Processes</button>
|
94
|
-
|
95
|
-
<table>
|
96
|
-
<thead>
|
97
|
-
<tr>
|
98
|
-
<td>pid</td>
|
99
|
-
<td>full_path</td>
|
100
|
-
<td>hostname</td>
|
101
|
-
<td>uptime</td>
|
102
|
-
<td></td>
|
103
|
-
</tr>
|
104
|
-
</thead>
|
105
|
-
|
106
|
-
<tbody>
|
107
|
-
{processes.map(function(process, index){
|
108
|
-
return <Process key={index} {...process} />;
|
109
|
-
})}
|
110
|
-
</tbody>
|
111
|
-
</table>
|
112
|
-
</div>
|
113
|
-
</div>
|
114
|
-
);
|
115
|
-
}
|
116
|
-
}
|
117
|
-
|
118
|
-
ReactDOM.render(
|
119
|
-
<DiagnosticsApp />,
|
120
|
-
document.getElementById('app')
|
121
|
-
);
|