procon_bypass_man 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/.circleci/config.yml +6 -6
- data/.rubocop.yml +4 -0
- data/.ruby-version +1 -1
- data/CHANGELOG.md +5 -0
- data/Gemfile.lock +1 -1
- data/README.md +15 -6
- data/Steepfile +0 -1
- data/docs/getting_started.md +48 -20
- data/docs/setup_raspi_by_mitamae.md +44 -2
- data/lib/procon_bypass_man/background/job_performer.rb +1 -2
- data/lib/procon_bypass_man/background/job_queue.rb +50 -0
- data/lib/procon_bypass_man/background/jobs/concerns/has_external_api_setting.rb +2 -2
- data/lib/procon_bypass_man/background/jobs/concerns/job_performable.rb +2 -2
- data/lib/procon_bypass_man/background/jobs/post_completed_remote_macro_job.rb +1 -1
- data/lib/procon_bypass_man/background/jobs/report_boot_job.rb +1 -1
- data/lib/procon_bypass_man/background/jobs/report_completed_upgrade_pbm_job.rb +1 -1
- data/lib/procon_bypass_man/background/jobs/report_error_job.rb +1 -1
- data/lib/procon_bypass_man/background/jobs/report_error_reload_config_job.rb +1 -1
- data/lib/procon_bypass_man/background/jobs/report_load_config_job.rb +1 -1
- data/lib/procon_bypass_man/background/jobs/report_procon_performance_measurements_job.rb +43 -0
- data/lib/procon_bypass_man/background/jobs/report_reload_config_job.rb +1 -1
- data/lib/procon_bypass_man/background/jobs/report_start_reboot_job.rb +1 -1
- data/lib/procon_bypass_man/background/jobs/sync_device_stats_job.rb +1 -1
- data/lib/procon_bypass_man/background.rb +2 -3
- data/lib/procon_bypass_man/bypass/bypass_command.rb +6 -15
- data/lib/procon_bypass_man/bypass/bypass_value.rb +6 -0
- data/lib/procon_bypass_man/bypass/procon_to_switch.rb +107 -0
- data/lib/procon_bypass_man/bypass/switch_to_procon.rb +64 -0
- data/lib/procon_bypass_man/bypass.rb +5 -110
- data/lib/procon_bypass_man/configuration.rb +15 -39
- data/lib/procon_bypass_man/device_connection/procon_setting_overrider.rb +12 -3
- data/lib/procon_bypass_man/procon/macro.rb +1 -1
- data/lib/procon_bypass_man/procon/performance_measurement/last_bypass_at.rb +17 -0
- data/lib/procon_bypass_man/procon/performance_measurement/measurement_collection.rb +9 -0
- data/lib/procon_bypass_man/procon/performance_measurement/measurements_summarizer.rb +84 -0
- data/lib/procon_bypass_man/procon/performance_measurement/procon_performance_span_transfer_job.rb +8 -0
- data/lib/procon_bypass_man/procon/performance_measurement/queue_over_process.rb +38 -0
- data/lib/procon_bypass_man/procon/performance_measurement/span_queue.rb +42 -0
- data/lib/procon_bypass_man/procon/performance_measurement/span_transfer_buffer.rb +39 -0
- data/lib/procon_bypass_man/procon/performance_measurement.rb +103 -0
- data/lib/procon_bypass_man/procon.rb +2 -1
- data/lib/procon_bypass_man/procon_display/bypass_hook.rb +4 -3
- data/lib/procon_bypass_man/remote_macro/queue_over_process.rb +26 -44
- data/lib/procon_bypass_man/remote_macro/remote_macro_object.rb +22 -24
- data/lib/procon_bypass_man/remote_macro/remote_macro_receiver.rb +1 -1
- data/lib/procon_bypass_man/remote_macro/remote_macro_sender.rb +1 -1
- data/lib/procon_bypass_man/remote_macro/task.rb +1 -5
- data/lib/procon_bypass_man/remote_macro/task_queue.rb +6 -10
- data/lib/procon_bypass_man/remote_pbm_action/commands/update_remote_pbm_action_status_command.rb +1 -1
- data/lib/procon_bypass_man/runner.rb +4 -10
- data/lib/procon_bypass_man/scheduler.rb +15 -6
- data/lib/procon_bypass_man/support/callbacks.rb +8 -4
- data/lib/procon_bypass_man/support/can_over_process.rb +60 -0
- data/lib/procon_bypass_man/support/gc.rb +8 -0
- data/lib/procon_bypass_man/support/http_client.rb +9 -6
- data/lib/procon_bypass_man/support/load_agv.rb +20 -0
- data/lib/procon_bypass_man/support/procon_performance_http_client.rb +7 -0
- data/lib/procon_bypass_man/support/retryable.rb +16 -0
- data/lib/procon_bypass_man/support/signal_handler.rb +1 -1
- data/lib/procon_bypass_man/version.rb +1 -1
- data/lib/procon_bypass_man/websocket/client.rb +2 -2
- data/lib/procon_bypass_man/worker.rb +32 -0
- data/lib/procon_bypass_man.rb +40 -10
- data/project_template/app.rb +4 -6
- data/project_template/app.rb.erb +4 -6
- data/sig/main.rbs +10 -52
- metadata +21 -8
- data/lib/procon_bypass_man/background/job_runner.rb +0 -45
- data/lib/procon_bypass_man/background/jobs/concerns/has_internal_api_setting.rb +0 -5
- data/lib/procon_bypass_man/background/jobs/report_pressed_buttons_job.rb +0 -15
- data/lib/procon_bypass_man/bypass/usb_hid_logger.rb +0 -43
- data/lib/procon_bypass_man/io_monitor.rb +0 -108
- data/lib/procon_bypass_man/support/server_pool.rb +0 -46
@@ -0,0 +1,42 @@
|
|
1
|
+
class ProconBypassMan::Procon::PerformanceMeasurement::SpanQueue
|
2
|
+
def initialize
|
3
|
+
@current_table = {} # 1つのスレッドからしか触らないのでlockはいらない
|
4
|
+
@measurement_collection_list = [] # main threadとjob worker threadから触るのでlockが必要
|
5
|
+
end
|
6
|
+
|
7
|
+
# @param [Array<PerformanceSpan>] spans
|
8
|
+
# bypassプロセスから呼ばれる. 実際に実行を行なっているのはmasterプロセス
|
9
|
+
def push(new_spans)
|
10
|
+
current_key = generate_bucket_key
|
11
|
+
|
12
|
+
if @current_table[current_key].nil?
|
13
|
+
if not @current_table.empty?
|
14
|
+
timestamp_key = @current_table.keys.first
|
15
|
+
spans = @current_table.values.first
|
16
|
+
# 本当ならmutexでlockする必要があるけど、正確性はいらないのでパフォーマンスを上げるためにlockしない
|
17
|
+
@measurement_collection_list.push(
|
18
|
+
ProconBypassMan::Procon::PerformanceMeasurement::MeasurementCollection.new(timestamp_key: timestamp_key, spans: spans)
|
19
|
+
)
|
20
|
+
end
|
21
|
+
|
22
|
+
@current_table = {}
|
23
|
+
@current_table[current_key] = []
|
24
|
+
@current_table[current_key].concat(new_spans)
|
25
|
+
else
|
26
|
+
@current_table[current_key].concat(new_spans)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# job workerから呼ばれる
|
31
|
+
# @return [ProconBypassMan::Procon::PerformanceMeasurement::MeasurementCollection]
|
32
|
+
def pop
|
33
|
+
@measurement_collection_list.pop
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
# 1分単位で次の値になる
|
39
|
+
def generate_bucket_key
|
40
|
+
Time.new.strftime("%Y-%m-%d %H:%M:00%:z")
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
class ProconBypassMan::Procon::PerformanceMeasurement::SpanTransferBuffer
|
2
|
+
include Singleton
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
@buff = []
|
6
|
+
end
|
7
|
+
|
8
|
+
# @param [Span]
|
9
|
+
# @return [void]
|
10
|
+
def push_and_run_block_if_buffer_over(value, &block)
|
11
|
+
push(value)
|
12
|
+
return unless buffer_over?
|
13
|
+
|
14
|
+
block.call(spans)
|
15
|
+
clear
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def spans
|
21
|
+
@buff
|
22
|
+
end
|
23
|
+
|
24
|
+
def clear
|
25
|
+
@buff.clear
|
26
|
+
end
|
27
|
+
|
28
|
+
def push(value)
|
29
|
+
@buff << value
|
30
|
+
end
|
31
|
+
|
32
|
+
def buffer_over?
|
33
|
+
@buff.length > max_buffer
|
34
|
+
end
|
35
|
+
|
36
|
+
def max_buffer
|
37
|
+
200
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
module ProconBypassMan::Procon::PerformanceMeasurement; end
|
2
|
+
|
3
|
+
require 'benchmark'
|
4
|
+
require 'procon_bypass_man/procon/performance_measurement/measurements_summarizer'
|
5
|
+
require 'procon_bypass_man/procon/performance_measurement/span_queue'
|
6
|
+
require 'procon_bypass_man/procon/performance_measurement/procon_performance_span_transfer_job'
|
7
|
+
require 'procon_bypass_man/procon/performance_measurement/span_transfer_buffer'
|
8
|
+
require 'procon_bypass_man/procon/performance_measurement/measurement_collection'
|
9
|
+
require 'procon_bypass_man/procon/performance_measurement/queue_over_process'
|
10
|
+
require 'procon_bypass_man/procon/performance_measurement/last_bypass_at'
|
11
|
+
|
12
|
+
module ProconBypassMan::Procon::PerformanceMeasurement
|
13
|
+
class PerformanceSpan
|
14
|
+
attr_accessor :time_taken, :succeed, :interval_from_previous_succeed, :gc_count, :gc_time
|
15
|
+
attr_reader :write_error_count, :read_error_count, :write_time, :read_time
|
16
|
+
|
17
|
+
def initialize
|
18
|
+
@write_error_count = 0
|
19
|
+
@read_error_count = 0
|
20
|
+
@time_taken = 0.0
|
21
|
+
@succeed = nil
|
22
|
+
@interval_from_previous_succeed = nil
|
23
|
+
@custom_metric = {}
|
24
|
+
@write_time = 0.0
|
25
|
+
@read_time = 0.0
|
26
|
+
@gc_time = 0.0
|
27
|
+
end
|
28
|
+
|
29
|
+
def record_read_error
|
30
|
+
@read_error_count += 1
|
31
|
+
end
|
32
|
+
|
33
|
+
def record_write_error
|
34
|
+
@write_error_count += 1
|
35
|
+
end
|
36
|
+
|
37
|
+
def record_write_time(&block)
|
38
|
+
result = nil
|
39
|
+
@write_time = Benchmark.realtime { result = block.call }
|
40
|
+
return result
|
41
|
+
end
|
42
|
+
|
43
|
+
def record_read_time(&block)
|
44
|
+
@read_time = Benchmark.realtime { block.call }
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# measureをして、measureの結果をためる
|
49
|
+
# @return [Boolean] 成功したか. テスト時に戻り値を使いたい
|
50
|
+
def self.measure(&bypass_process_block)
|
51
|
+
unless ProconBypassMan.config.enable_procon_performance_measurement?
|
52
|
+
bypass_process_block.call(PerformanceSpan.new)
|
53
|
+
return
|
54
|
+
end
|
55
|
+
|
56
|
+
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("3.1.0")
|
57
|
+
snapshot_gc_time = GC.stat(:time) / 1000.0
|
58
|
+
end
|
59
|
+
snapshot_gc_count = GC.count
|
60
|
+
span = PerformanceSpan.new
|
61
|
+
|
62
|
+
span.time_taken = Benchmark.realtime {
|
63
|
+
span.succeed = bypass_process_block.call(span)
|
64
|
+
}.floor(3)
|
65
|
+
|
66
|
+
if span.succeed
|
67
|
+
ProconBypassMan::Procon::PerformanceMeasurement::LastBypassAt.touch do |interval_from_previous_succeed|
|
68
|
+
span.interval_from_previous_succeed = interval_from_previous_succeed.floor(3)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
(GC.count - snapshot_gc_count).tap do |increased_gc_count|
|
73
|
+
span.gc_count = increased_gc_count
|
74
|
+
end
|
75
|
+
|
76
|
+
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("3.1.0")
|
77
|
+
((GC.stat(:time) / 1000.0) - snapshot_gc_time).tap do |increased_time|
|
78
|
+
span.gc_time = increased_time
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
ProconBypassMan::GC.stop_gc_in do
|
83
|
+
# measureするたびにperform_asyncしているとjob queueが詰まるのでbufferingしている
|
84
|
+
ProconBypassMan::Procon::PerformanceMeasurement::SpanTransferBuffer.instance.push_and_run_block_if_buffer_over(span) do |spans|
|
85
|
+
ProconBypassMan::ProconPerformanceSpanTransferJob.perform_async(spans.dup)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
return span.succeed
|
89
|
+
end
|
90
|
+
|
91
|
+
# @return [MeasurementCollection, NilClass]
|
92
|
+
# bypassしているプロセスから呼ばれる
|
93
|
+
def self.pop_measurement_collection
|
94
|
+
ProconBypassMan::Procon::PerformanceMeasurement::QueueOverProcess.pop
|
95
|
+
end
|
96
|
+
|
97
|
+
# @param [MeasurementCollection] spans
|
98
|
+
# @return [ProconBypassMan::Procon::PerformanceMeasurement::MeasurementsSummarizer::PerformanceMetric]
|
99
|
+
# jobから呼ばれる予定
|
100
|
+
def self.summarize(spans: )
|
101
|
+
ProconBypassMan::Procon::PerformanceMeasurement::MeasurementsSummarizer.new(spans: spans).summarize
|
102
|
+
end
|
103
|
+
end
|
@@ -7,8 +7,9 @@ class ProconBypassMan::Procon
|
|
7
7
|
require "procon_bypass_man/procon/value_objects/rumble_binary"
|
8
8
|
require "procon_bypass_man/procon/value_objects/binary"
|
9
9
|
require "procon_bypass_man/procon/value_objects/bypass_mode"
|
10
|
-
|
11
10
|
require "procon_bypass_man/procon/consts"
|
11
|
+
require "procon_bypass_man/procon/performance_measurement"
|
12
|
+
require "procon_bypass_man/procon/performance_measurement/queue_over_process"
|
12
13
|
require "procon_bypass_man/procon/mode_registry"
|
13
14
|
require "procon_bypass_man/procon/macro"
|
14
15
|
require "procon_bypass_man/procon/macro_registry"
|
@@ -1,11 +1,12 @@
|
|
1
1
|
module ProconBypassMan::ProconDisplay::BypassHook
|
2
2
|
include ProconBypassMan::Callbacks
|
3
3
|
|
4
|
-
define_callbacks :
|
4
|
+
define_callbacks :run
|
5
5
|
|
6
|
-
set_callback :
|
6
|
+
set_callback :run, :after, :write_procon_display_status
|
7
7
|
|
8
|
-
def
|
8
|
+
def write_procon_display_status
|
9
|
+
return unless bypass_value.binary
|
9
10
|
ProconBypassMan::ProconDisplay::Status.instance.current = bypass_value.binary.to_procon_reader.to_hash.dup
|
10
11
|
end
|
11
12
|
end
|
@@ -1,62 +1,44 @@
|
|
1
|
-
class ProconBypassMan::QueueOverProcess
|
2
|
-
|
3
|
-
|
4
|
-
@@drb_server = nil
|
5
|
-
@@drb_server_thread = nil
|
6
|
-
|
7
|
-
def self.start!
|
8
|
-
return unless ProconBypassMan.config.enable_remote_macro?
|
9
|
-
require 'drb/drb'
|
10
|
-
|
11
|
-
FileUtils.rm_rf(file_path) if File.exist?(file_path)
|
12
|
-
begin
|
13
|
-
@@drb_server = DRb.start_service(url, Queue.new, safe_level: 1)
|
14
|
-
rescue Errno::EADDRINUSE => e
|
15
|
-
ProconBypassMan.logger.error e
|
16
|
-
raise
|
17
|
-
end
|
18
|
-
|
19
|
-
@@drb_server_thread =
|
20
|
-
Thread.new do
|
21
|
-
DRb.thread.join
|
22
|
-
end
|
23
|
-
end
|
1
|
+
class ProconBypassMan::RemoteMacro::QueueOverProcess
|
2
|
+
extend ProconBypassMan::CanOverProcess
|
24
3
|
|
25
|
-
|
26
|
-
if @@drb_server
|
27
|
-
@@drb_server_thread.kill
|
28
|
-
@@drb_server.stop_service
|
29
|
-
end
|
30
|
-
end
|
4
|
+
include Singleton
|
31
5
|
|
32
|
-
|
33
|
-
return unless ProconBypassMan.config.enable_remote_macro?
|
6
|
+
attr_reader :distributed_queue
|
34
7
|
|
35
|
-
|
8
|
+
# @override
|
9
|
+
def self.enable?
|
10
|
+
ProconBypassMan.config.enable_remote_macro?
|
36
11
|
end
|
37
12
|
|
38
|
-
|
39
|
-
|
13
|
+
# @override
|
14
|
+
def self.distributed_class
|
15
|
+
Queue
|
16
|
+
end
|
40
17
|
|
41
|
-
|
18
|
+
# @override
|
19
|
+
def self.socket_file_path
|
20
|
+
"/tmp/procon_bypass_man_remote_macro_queue".freeze
|
42
21
|
end
|
43
22
|
|
44
|
-
def self.
|
45
|
-
return unless
|
23
|
+
def self.push(value)
|
24
|
+
return unless enable?
|
46
25
|
|
47
|
-
|
26
|
+
instance.distributed_queue.push(value)
|
48
27
|
end
|
49
28
|
|
50
|
-
|
51
|
-
|
52
|
-
|
29
|
+
def self.pop
|
30
|
+
return unless enable?
|
31
|
+
|
32
|
+
instance.distributed_queue.pop
|
53
33
|
end
|
54
34
|
|
55
|
-
def self.
|
56
|
-
|
35
|
+
def self.clear
|
36
|
+
return unless enable?
|
37
|
+
|
38
|
+
instance.distributed_queue.clear
|
57
39
|
end
|
58
40
|
|
59
41
|
def initialize
|
60
|
-
@
|
42
|
+
@distributed_queue = DRbObject.new_with_uri(self.class.socket_path)
|
61
43
|
end
|
62
44
|
end
|
@@ -1,30 +1,28 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
class NonSupportAction < ValidationError; end
|
1
|
+
class ProconBypassMan::RemoteMacro::RemoteMacroObject
|
2
|
+
# valueobjectがvalidatorの責務も持っている. 今度分離する
|
3
|
+
class ValidationError < StandardError; end
|
4
|
+
class MustBeNotNilError < ValidationError; end
|
5
|
+
class NonSupportAction < ValidationError; end
|
7
6
|
|
8
|
-
|
7
|
+
attr_accessor :name, :uuid, :steps
|
9
8
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
9
|
+
# @param [String] name
|
10
|
+
# @param [String] uuid
|
11
|
+
# @param [Array] steps
|
12
|
+
def initialize(name: , uuid:, steps: )
|
13
|
+
@name = name
|
14
|
+
@uuid = uuid
|
15
|
+
@steps = steps
|
16
|
+
freeze
|
17
|
+
end
|
19
18
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
end
|
19
|
+
# @raise [MustBeNotNilError]
|
20
|
+
# @raise [NonSupportAction]
|
21
|
+
# @return [void]
|
22
|
+
def validate!
|
23
|
+
self.uuid or raise MustBeNotNilError, "uuidは値が必須です"
|
24
|
+
unless self.steps.is_a?(Array)
|
25
|
+
raise ValidationError, "stepsは配列です"
|
28
26
|
end
|
29
27
|
end
|
30
28
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
class ProconBypassMan::RemoteMacroSender
|
2
2
|
def self.execute(name: , uuid: , steps: )
|
3
3
|
ProconBypassMan.logger.info "[remote macro][sender] name: #{name}, uuid: #{uuid}, steps: #{steps}"
|
4
|
-
ProconBypassMan::QueueOverProcess.push(
|
4
|
+
ProconBypassMan::RemoteMacro::QueueOverProcess.push(
|
5
5
|
ProconBypassMan::RemoteMacro::Task.new(name, uuid, steps)
|
6
6
|
)
|
7
7
|
end
|
@@ -1,13 +1,9 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
not empty?
|
6
|
-
end
|
1
|
+
class ProconBypassMan::RemoteMacro::TaskQueue < ::Queue
|
2
|
+
def present?
|
3
|
+
not empty?
|
4
|
+
end
|
7
5
|
|
8
|
-
|
9
|
-
|
10
|
-
end
|
11
|
-
end
|
6
|
+
def non_blocking_shift
|
7
|
+
present? && shift
|
12
8
|
end
|
13
9
|
end
|
data/lib/procon_bypass_man/remote_pbm_action/commands/update_remote_pbm_action_status_command.rb
CHANGED
@@ -10,7 +10,7 @@ module ProconBypassMan
|
|
10
10
|
def execute(to_status: )
|
11
11
|
ProconBypassMan::UpdateRemotePbmActionStatusHttpClient.new(
|
12
12
|
path: path,
|
13
|
-
|
13
|
+
server: ProconBypassMan.config.api_server,
|
14
14
|
).put(to_status: to_status)
|
15
15
|
end
|
16
16
|
|
@@ -1,8 +1,4 @@
|
|
1
|
-
require_relative "io_monitor"
|
2
|
-
|
3
1
|
class ProconBypassMan::Runner
|
4
|
-
class InterruptForRestart < StandardError; end
|
5
|
-
|
6
2
|
include ProconBypassMan::SignalHandler
|
7
3
|
|
8
4
|
def initialize(gadget: , procon: )
|
@@ -24,14 +20,12 @@ class ProconBypassMan::Runner
|
|
24
20
|
|
25
21
|
loop do
|
26
22
|
# NOTE メインプロセスではThreadをいくつか起動しているので念のためパフォーマンスを優先するためにforkしていく
|
27
|
-
child_pid = Kernel.fork
|
23
|
+
child_pid = Kernel.fork do
|
28
24
|
$will_terminate_token = false
|
29
|
-
|
30
|
-
ProconBypassMan::RemoteMacroReceiver.start!
|
31
|
-
ProconBypassMan::ProconDisplay::Server.start!
|
25
|
+
ProconBypassMan.after_fork_on_bypass_process
|
32
26
|
ProconBypassMan::BypassCommand.new(gadget: @gadget, procon: @procon).execute # ここでblockingする
|
33
27
|
next
|
34
|
-
|
28
|
+
end
|
35
29
|
|
36
30
|
begin
|
37
31
|
# TODO 子プロセスが消滅した時に、メインプロセスは生き続けてしまい、何もできなくなる問題がある
|
@@ -39,7 +33,7 @@ class ProconBypassMan::Runner
|
|
39
33
|
signal = readable_io.first[0].gets.strip
|
40
34
|
handle_signal(signal)
|
41
35
|
end
|
42
|
-
rescue InterruptForRestart
|
36
|
+
rescue ProconBypassMan::InterruptForRestart
|
43
37
|
ProconBypassMan::PrintMessageCommand.execute(text: "設定ファイルの再読み込みを開始します")
|
44
38
|
Process.kill("USR2", child_pid)
|
45
39
|
Process.wait
|
@@ -68,13 +68,22 @@ module ProconBypassMan
|
|
68
68
|
end
|
69
69
|
|
70
70
|
def self.register_schedules
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
71
|
+
if ProconBypassMan.config.has_api_server?
|
72
|
+
register(
|
73
|
+
schedule: Schedule.new(
|
74
|
+
klass: ProconBypassMan::SyncDeviceStatsJob,
|
75
|
+
args: [->{ ProconBypassMan::DeviceStatus.current }],
|
76
|
+
interval: 60,
|
77
|
+
)
|
76
78
|
)
|
77
|
-
|
79
|
+
register(
|
80
|
+
schedule: Schedule.new(
|
81
|
+
klass: ProconBypassMan::ReportProconPerformanceMeasurementsJob,
|
82
|
+
args: [->{ ProconBypassMan::Procon::PerformanceMeasurement.pop_measurement_collection }],
|
83
|
+
interval: 60,
|
84
|
+
)
|
85
|
+
)
|
86
|
+
end
|
78
87
|
end
|
79
88
|
|
80
89
|
# @param [Schedule] schedule
|
@@ -73,28 +73,32 @@ module ProconBypassMan
|
|
73
73
|
def run_callbacks(kind, &block)
|
74
74
|
chains = get_callbacks(kind) or raise("unknown callback")
|
75
75
|
if chains.nil? || chains.empty?
|
76
|
-
block.call
|
77
|
-
return
|
76
|
+
return block.call
|
78
77
|
end
|
79
78
|
|
80
79
|
chains[:before]&.each do |chain|
|
81
80
|
send chain.chain_method
|
82
81
|
end
|
83
|
-
block.call
|
82
|
+
result = block.call
|
84
83
|
chains[:after]&.each do |chain|
|
85
84
|
send chain.chain_method
|
86
85
|
end
|
86
|
+
|
87
|
+
return result
|
87
88
|
end
|
88
89
|
|
89
90
|
def get_callbacks(kind) # :nodoc:
|
90
91
|
# classに直接moduleをincludeしている場合
|
91
|
-
if defined?(self.class.__callbacks)
|
92
|
+
if defined?(self.class.__callbacks) && !self.class.respond_to?(:callbacks)
|
92
93
|
return self.class.__callbacks[kind.to_sym]
|
93
94
|
end
|
94
95
|
|
95
96
|
list = self.class.callbacks.flat_map { |callback_mod|
|
96
97
|
callback_mod.__callbacks && callback_mod.__callbacks[kind.to_sym]
|
97
98
|
}.compact
|
99
|
+
if(self.class.respond_to?(:__callbacks) && chain = self.class.__callbacks[kind.to_sym])
|
100
|
+
list << chain
|
101
|
+
end
|
98
102
|
table = {}
|
99
103
|
table[:before] = list.flat_map { |x| x[:before] }.compact
|
100
104
|
table[:after] = list.flat_map { |x| x[:after] }.compact
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'drb/drb'
|
2
|
+
|
3
|
+
# NOTE マスタープロセスでstart_distributed_object!をコールする必要がある
|
4
|
+
# forkをしたらそのさきでDRb.start_serviceをコールする必要がある
|
5
|
+
module ProconBypassMan::CanOverProcess
|
6
|
+
PROTOCOL = "drbunix".freeze
|
7
|
+
|
8
|
+
def self.extended(mod)
|
9
|
+
mod.singleton_class.attr_accessor :drb_server, :drb_server_thread
|
10
|
+
end
|
11
|
+
|
12
|
+
# @return [void]
|
13
|
+
def start_distributed_object!
|
14
|
+
return unless enable?
|
15
|
+
|
16
|
+
FileUtils.rm_rf(socket_file_path) if File.exist?(socket_file_path)
|
17
|
+
begin
|
18
|
+
self.drb_server = DRb.start_service(socket_path, distributed_class.new, safe_level: 1)
|
19
|
+
rescue Errno::EADDRINUSE => e
|
20
|
+
ProconBypassMan.logger.error e
|
21
|
+
raise
|
22
|
+
end
|
23
|
+
|
24
|
+
self.drb_server_thread =
|
25
|
+
Thread.new do
|
26
|
+
DRb.thread.join
|
27
|
+
end
|
28
|
+
end
|
29
|
+
alias start! start_distributed_object!
|
30
|
+
|
31
|
+
# @return [void]
|
32
|
+
def shutdown_distributed_object
|
33
|
+
if self.drb_server
|
34
|
+
self.drb_server_thread&.kill
|
35
|
+
self.drb_server_thread = nil
|
36
|
+
self.drb_server.stop_service
|
37
|
+
end
|
38
|
+
end
|
39
|
+
alias shutdown shutdown_distributed_object
|
40
|
+
|
41
|
+
# @return [Boolean]
|
42
|
+
def enable?
|
43
|
+
raise NotImplementedError
|
44
|
+
end
|
45
|
+
|
46
|
+
# @return [String]
|
47
|
+
def socket_file_path
|
48
|
+
raise NotImplementedError
|
49
|
+
end
|
50
|
+
|
51
|
+
# @return [any]
|
52
|
+
def distributed_class
|
53
|
+
raise NotImplementedError
|
54
|
+
end
|
55
|
+
|
56
|
+
# @return [String]
|
57
|
+
def socket_path
|
58
|
+
"#{PROTOCOL}:#{socket_file_path}".freeze
|
59
|
+
end
|
60
|
+
end
|
@@ -26,9 +26,9 @@ module ProconBypassMan
|
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
|
-
def initialize(path: ,
|
30
|
-
@
|
31
|
-
@uri = URI.parse("#{
|
29
|
+
def initialize(path: , server: , retry_on_connection_error: false)
|
30
|
+
@server = server
|
31
|
+
@uri = URI.parse("#{server}#{path}")
|
32
32
|
@retry_on_connection_error = retry_on_connection_error
|
33
33
|
end
|
34
34
|
|
@@ -76,14 +76,13 @@ module ProconBypassMan
|
|
76
76
|
return response.body
|
77
77
|
end
|
78
78
|
else
|
79
|
-
@server_pool.next!
|
80
79
|
ProconBypassMan.logger.error("#{@uri}から200以外(#{response.code})が帰ってきました. #{response.body}")
|
81
80
|
end
|
82
81
|
end
|
83
82
|
|
84
83
|
def handle_request
|
85
84
|
raise "need block" unless block_given?
|
86
|
-
if @
|
85
|
+
if @server.nil?
|
87
86
|
ProconBypassMan.logger.info('送信先が未設定なのでスキップしました')
|
88
87
|
return
|
89
88
|
end
|
@@ -94,6 +93,10 @@ module ProconBypassMan
|
|
94
93
|
sleep(10)
|
95
94
|
retry
|
96
95
|
end
|
96
|
+
rescue Timeout::Error
|
97
|
+
ProconBypassMan.logger.error(e)
|
98
|
+
sleep(10)
|
99
|
+
retry
|
97
100
|
rescue => e
|
98
101
|
puts e
|
99
102
|
ProconBypassMan.logger.error(e)
|
@@ -102,5 +105,5 @@ module ProconBypassMan
|
|
102
105
|
end
|
103
106
|
|
104
107
|
if $0 == __FILE__
|
105
|
-
ProconBypassMan::HttpClient.new(path: '/',
|
108
|
+
ProconBypassMan::HttpClient.new(path: '/', server: nil, retry_on_connection_error: false).get(response_body: '')
|
106
109
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module ProconBypassMan
|
2
|
+
class LoadAgv
|
3
|
+
PATH = '/proc/loadavg'
|
4
|
+
|
5
|
+
# @return [[Integer, Integer, Integer]]
|
6
|
+
def get
|
7
|
+
loadavg = get_proc_loadavg
|
8
|
+
loadavg =~ /^([0-9.]+)\s([0-9.]+)\s([0-9.]+)/
|
9
|
+
return [$1.to_f, $2.to_f, $3.to_f].join("-")
|
10
|
+
rescue Errno::ENOENT
|
11
|
+
""
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def get_proc_loadavg
|
17
|
+
File.read('/proc/loadavg')
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|