procon_bypass_man 0.3.7 → 0.3.8
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/.github/workflows/gitleacks.yml +1 -1
- data/.github/workflows/release.yml +1 -1
- data/.github/workflows/ruby.yml +2 -2
- data/CHANGELOG.md +6 -0
- data/Gemfile.lock +2 -2
- data/README.md +2 -2
- data/bin/console +0 -3
- data/docs/getting_started.md +25 -2
- data/lib/procon_bypass_man/commands/print_boot_message_command.rb +3 -2
- data/lib/procon_bypass_man/configuration.rb +25 -14
- data/lib/procon_bypass_man/external_input/boot_message.rb +21 -0
- data/lib/procon_bypass_man/external_input/channels/base.rb +10 -0
- data/lib/procon_bypass_man/external_input/channels/serial_port_channel.rb +9 -1
- data/lib/procon_bypass_man/external_input/channels/tcpip_channel.rb +131 -0
- data/lib/procon_bypass_man/external_input/channels.rb +1 -1
- data/lib/procon_bypass_man/external_input.rb +5 -9
- data/lib/procon_bypass_man/support/forever.rb +51 -0
- data/lib/procon_bypass_man/support/proccess_cheacker.rb +14 -0
- data/lib/procon_bypass_man/support/retryable.rb +2 -1
- data/lib/procon_bypass_man/support/simple_tcp_server.rb +63 -0
- data/lib/procon_bypass_man/support/watchdog.rb +23 -0
- data/lib/procon_bypass_man/support/web_connectivity_checker.rb +4 -2
- data/lib/procon_bypass_man/version.rb +1 -1
- data/lib/procon_bypass_man/websocket/client.rb +11 -9
- data/lib/procon_bypass_man.rb +11 -4
- data/project_template/app.rb +2 -1
- data/project_template/app.rb.erb +2 -2
- data/sig/main.rbs +2 -2
- metadata +8 -5
- data/lib/procon_bypass_man/external_input/channels/tcpip.rb +0 -16
- data/lib/procon_bypass_man/websocket/forever.rb +0 -47
- data/lib/procon_bypass_man/websocket/watchdog.rb +0 -19
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1933db5fe8c39267f980712a5477a457277cdd3ce9148a81966c1e1d818805e8
|
|
4
|
+
data.tar.gz: 404ce5c7ada74a92afb5abf2b2f583c3fe1c87bbc4d3ae2372e0ff3f961d9245
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: eeeb32ff42fc02d2b40b19be2a1eba55a9fc5ffc6a3f08af47b4ed86bb67edba60dc7ef409f892ba9ef21953a349abda01a28d04f4a4f99f0032382a68c2f904
|
|
7
|
+
data.tar.gz: 811f537dd6ea2659678911678022c02734a2a21ef099d7ed140067a56e88edf0fabc4aec8264c052e8e8e9759c54085a17ab7a72c668a338560250b880395e2f
|
data/.github/workflows/ruby.yml
CHANGED
|
@@ -16,10 +16,10 @@ jobs:
|
|
|
16
16
|
timeout-minutes: 5
|
|
17
17
|
strategy:
|
|
18
18
|
matrix:
|
|
19
|
-
ruby-version: ['3.0.1', '3.
|
|
19
|
+
ruby-version: ['3.0', '3.1', '3.2']
|
|
20
20
|
|
|
21
21
|
steps:
|
|
22
|
-
- uses: actions/checkout@
|
|
22
|
+
- uses: actions/checkout@v3
|
|
23
23
|
- name: Set up Ruby
|
|
24
24
|
# To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
|
|
25
25
|
# change this to (see https://github.com/ruby/setup-ruby#versioning):
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
## [0.3.8] 2023-05-03
|
|
2
|
+
* TCP/IP経由でPBMに入力ができるようになりました
|
|
3
|
+
* 多重起動ができないようにしました
|
|
4
|
+
* pbm-cloudとの連携時に、pbmenvを使っているかの判定を修正しました
|
|
5
|
+
* actioncable(websocket)serverのURLをpbm-cloudから取得するようにしました
|
|
6
|
+
|
|
1
7
|
## [0.3.7] 2023-04-06
|
|
2
8
|
* PBM-Cloudと連携しているかをbootメッセージに表示ようになりました
|
|
3
9
|
* シリアルポート経由でPBMに入力ができるようになりました
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
procon_bypass_man (0.3.
|
|
4
|
+
procon_bypass_man (0.3.8)
|
|
5
5
|
action_cable_client
|
|
6
6
|
blue_green_process (= 0.1.4.2)
|
|
7
7
|
pbmenv (>= 0.1.11)
|
|
@@ -38,7 +38,7 @@ GEM
|
|
|
38
38
|
parallel (1.21.0)
|
|
39
39
|
parser (3.0.3.2)
|
|
40
40
|
ast (~> 2.4.1)
|
|
41
|
-
pbmenv (0.1.
|
|
41
|
+
pbmenv (0.1.12)
|
|
42
42
|
pry (0.14.1)
|
|
43
43
|
coderay (~> 1.1)
|
|
44
44
|
method_source (~> 1.0)
|
data/README.md
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
https://user-images.githubusercontent.com/1664497/171327108-f12f56a5-fc36-48da-95a5-65e976553a20.mov
|
|
13
13
|
|
|
14
|
-
##
|
|
14
|
+
## 必要なハードウェア
|
|
15
15
|
* Nintendo Switch Proコントローラー
|
|
16
16
|
* Switch本体とドック
|
|
17
17
|
* Raspberry Pi4 (Raspberry Pi OS)
|
|
@@ -38,7 +38,7 @@ https://user-images.githubusercontent.com/1664497/171327108-f12f56a5-fc36-48da-9
|
|
|
38
38
|
* レイヤーを切り替える方法は?
|
|
39
39
|
* 設定ファイルに記述している `prefix_keys_for_changing_layer`の後ろにあるキーを同時押しながら、十字キーのどれかを押すことで任意のレイヤーに切り替わります
|
|
40
40
|
* このツールでできることは?
|
|
41
|
-
* キーリマップ, 連射,
|
|
41
|
+
* キーリマップ, 連射, マクロ, 外部ツールからの入力
|
|
42
42
|
* リマップは1つのキーを別のキーに割り当てます
|
|
43
43
|
* 連射中には特定のキーの入力を無視したり、複数のキーをトリガーに連射することができます
|
|
44
44
|
* どうしてsudoが必要なの?
|
data/bin/console
CHANGED
data/docs/getting_started.md
CHANGED
|
@@ -18,7 +18,8 @@
|
|
|
18
18
|
* [設定ファイルの書き方がわからない、エラーが起きるとき](#設定ファイルの書き方がわからない、エラーが起きるとき)
|
|
19
19
|
* [procon_bypass_manのアップグレード方法](#procon_bypass_manのアップグレード方法)
|
|
20
20
|
* [procon_bypass_man_cloudについて](#procon_bypass_man_cloudについて)
|
|
21
|
-
* [
|
|
21
|
+
* [シリアルポート連携](#シリアルポート連携)
|
|
22
|
+
* [TCPIP連携](#TCPIP連携)
|
|
22
23
|
* [最適化について](#最適化について)
|
|
23
24
|
|
|
24
25
|
## はじめに
|
|
@@ -252,10 +253,32 @@ procon_bypass_man_cloudとの接続が完了後、Raspberry Piを起動時にpro
|
|
|
252
253
|
|
|
253
254
|
セットアップ方法は https://pbm-cloud.jiikko.com/faq に書いています。
|
|
254
255
|
|
|
255
|
-
##
|
|
256
|
+
## シリアルポート連携
|
|
256
257
|
* [ラズベリーパイのシリアルポート(GPIO)へ書き込んでPBM経由してSwitchへ入力をする方法](/docs/setting/integration_external_input_serial_port.md)
|
|
257
258
|
* [ラズベリーパイのシリアルポート(GPIO)に書き込むフォーマットについて](/docs/setting/integration_external_input_serial_port_format.md)
|
|
258
259
|
|
|
260
|
+
## TCPIP連携
|
|
261
|
+
procon_bypass_man: 0.3.8 からTCP/IP経由で入力ができるようになりました。
|
|
262
|
+
書き込みフォーマットはJSONのみに対応しています。JSONの詳細な仕様については [ラズベリーパイのシリアルポート(GPIO)に書き込むフォーマットについて](/docs/setting/integration_external_input_serial_port_format.md) を参照してください。
|
|
263
|
+
|
|
264
|
+
次は、PBM側の設定方法についてです。app.rbに以下の行を追加すると、連携するためのTCPサーバを起動するようになります。
|
|
265
|
+
|
|
266
|
+
```diff
|
|
267
|
+
+ config.external_input_channels = [
|
|
268
|
+
+ ProconBypassMan::ExternalInput::Channels::TCPIPChannel.new(port: 9000),
|
|
269
|
+
+ ]
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
クライアント側のサンプル実装は次の通りです。これを実行するとAボタンを入力します。
|
|
273
|
+
|
|
274
|
+
```ruby
|
|
275
|
+
socket = TCPSocket.new('ras1.local', 9000)
|
|
276
|
+
json = { buttons: [:a] }.to_json
|
|
277
|
+
message = "#{json}\r\n"
|
|
278
|
+
socket.write(message)
|
|
279
|
+
puts socket.gets
|
|
280
|
+
```
|
|
281
|
+
|
|
259
282
|
## 最適化について
|
|
260
283
|
本稿では、Rubyの最適化について書きます。上級者向けです。適用しなくても普通に動きますが、逆に適用したことで何らかのケースで遅くなる場合があるかもしれません。
|
|
261
284
|
|
|
@@ -10,7 +10,7 @@ class ProconBypassMan::PrintBootMessageCommand
|
|
|
10
10
|
@table[:pid_path] = ProconBypassMan.pid_path
|
|
11
11
|
@table[:setting_path] = ProconBypassMan::ButtonsSettingConfiguration.instance.setting_path
|
|
12
12
|
@table[:uptime_from_boot] = ProconBypassMan::Uptime.from_boot
|
|
13
|
-
@table[:use_pbmenv] =
|
|
13
|
+
@table[:use_pbmenv] = ProconBypassMan.root.start_with?(Pbmenv::PBM_DIR)
|
|
14
14
|
@table[:session_id] = ProconBypassMan.session_id
|
|
15
15
|
@table[:device_id] = ProconBypassMan.device_id
|
|
16
16
|
@table[:never_exit_accidentally] = ProconBypassMan.config.never_exit_accidentally
|
|
@@ -34,7 +34,8 @@ class ProconBypassMan::PrintBootMessageCommand
|
|
|
34
34
|
ProconBypassMan::VERSION: #{@table[:pbm_version]}
|
|
35
35
|
RUBY_VERSION: #{@table[:ruby_version]}
|
|
36
36
|
Pbmenv::VERSION: #{@table[:pbmenv_version]}
|
|
37
|
-
PBM-Cloud Integration: #{ProconBypassMan::WebConnectivityChecker.new(ProconBypassMan.config.api_server)}
|
|
37
|
+
PBM-Cloud Integration: #{ProconBypassMan::WebConnectivityChecker.new(ProconBypassMan.config.api_server, ProconBypassMan.config.current_ws_server_url)}
|
|
38
|
+
ExternalInput Integration: #{ProconBypassMan::ExternalInput::BootMessage.new(channels: ProconBypassMan::ExternalInput.channels)}
|
|
38
39
|
pid: #{@table[:pid]}
|
|
39
40
|
root: #{@table[:root_path]}
|
|
40
41
|
pid_path: #{@table[:pid_path]}
|
|
@@ -19,9 +19,11 @@ class ProconBypassMan::Configuration
|
|
|
19
19
|
@@pid_path ||= File.expand_path("#{root}/pbm_pid", __dir__).freeze
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
-
# @return [Integer]
|
|
22
|
+
# @return [Integer, nil]
|
|
23
23
|
def pid
|
|
24
24
|
File.read(pid_path).to_i
|
|
25
|
+
rescue Errno::ENOENT
|
|
26
|
+
nil
|
|
25
27
|
end
|
|
26
28
|
|
|
27
29
|
def digest_path
|
|
@@ -70,6 +72,7 @@ class ProconBypassMan::Configuration
|
|
|
70
72
|
if defined?(@root)
|
|
71
73
|
@root
|
|
72
74
|
else
|
|
75
|
+
ProconBypassMan.logger.warn 'root pathが未設定です'
|
|
73
76
|
File.expand_path('..', __dir__ || ".").freeze
|
|
74
77
|
end
|
|
75
78
|
end
|
|
@@ -126,22 +129,30 @@ class ProconBypassMan::Configuration
|
|
|
126
129
|
end
|
|
127
130
|
|
|
128
131
|
# @return [String, NilClass]
|
|
129
|
-
def
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
132
|
+
def current_ws_server_url
|
|
133
|
+
return @current_ws_server_url if defined?(@current_ws_server_url)
|
|
134
|
+
return unless api_server
|
|
135
|
+
|
|
136
|
+
response_json = ProconBypassMan::HttpClient.new(server: api_server, path: '/api/v1/configuration').get
|
|
137
|
+
ws_server_url = response_json&.fetch("ws_server_url", nil)
|
|
138
|
+
|
|
139
|
+
begin
|
|
140
|
+
uri = URI.parse(ws_server_url)
|
|
141
|
+
if uri.scheme == 'ws'
|
|
142
|
+
@current_ws_server_url = uri.to_s
|
|
143
|
+
return @current_ws_server_url
|
|
144
|
+
elsif uri.scheme == 'wss' # NOTE: SSL_CTX_use_certificate: ee key too small (OpenSSL::SSL::SSLError) が起きるので
|
|
145
|
+
uri.scheme = 'ws'
|
|
146
|
+
@current_ws_server_url = uri.to_s
|
|
147
|
+
return @current_ws_server_url
|
|
133
148
|
else
|
|
134
|
-
|
|
149
|
+
ProconBypassMan.logger.warn { "#{ws_server_url} is invalid." }
|
|
150
|
+
return nil
|
|
135
151
|
end
|
|
152
|
+
rescue URI::InvalidURIError => e
|
|
153
|
+
ProconBypassMan.logger.warn { "#{ws_server_url} is invalid. #{e}" }
|
|
154
|
+
nil
|
|
136
155
|
end
|
|
137
|
-
rescue URI::InvalidURIError
|
|
138
|
-
nil
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
# @return [String, NilClass]
|
|
142
|
-
def current_ws_server_url
|
|
143
|
-
return unless current_ws_server
|
|
144
|
-
"#{current_ws_server}/websocket/"
|
|
145
156
|
end
|
|
146
157
|
|
|
147
158
|
# @return [Boolean]
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ProconBypassMan
|
|
4
|
+
module ExternalInput
|
|
5
|
+
class BootMessage
|
|
6
|
+
# @return [ProconBypassMan::ExternalInput::Channels::Base]
|
|
7
|
+
def initialize(channels: )
|
|
8
|
+
@channels = channels
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# @return [String]
|
|
12
|
+
def to_s
|
|
13
|
+
if @channels.nil? or @channels.empty?
|
|
14
|
+
return 'DISABLE'
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
@channels.map(&:display_name_for_boot_message).join(', ')
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -6,6 +6,16 @@ module ProconBypassMan
|
|
|
6
6
|
def read
|
|
7
7
|
raise NotImplementedError
|
|
8
8
|
end
|
|
9
|
+
|
|
10
|
+
# @return [void]
|
|
11
|
+
def shutdown
|
|
12
|
+
raise NotImplementedError
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# @return [String]
|
|
16
|
+
def display_name_for_boot_message
|
|
17
|
+
raise NotImplementedError
|
|
18
|
+
end
|
|
9
19
|
end
|
|
10
20
|
end
|
|
11
21
|
end
|
|
@@ -14,7 +14,7 @@ module ProconBypassMan
|
|
|
14
14
|
data_bits = 8
|
|
15
15
|
stop_bits = 1
|
|
16
16
|
parity = SerialPort::NONE
|
|
17
|
-
@serial_port= SerialPort.new(device_path, baud_rate, data_bits, stop_bits, parity)
|
|
17
|
+
@serial_port = SerialPort.new(device_path, baud_rate, data_bits, stop_bits, parity)
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
# @return [String, NilClass]
|
|
@@ -42,6 +42,14 @@ module ProconBypassMan
|
|
|
42
42
|
end
|
|
43
43
|
chunks.first
|
|
44
44
|
end
|
|
45
|
+
|
|
46
|
+
def shutdown
|
|
47
|
+
# no-op
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def display_name_for_boot_message
|
|
51
|
+
'SerialPort'
|
|
52
|
+
end
|
|
45
53
|
end
|
|
46
54
|
end
|
|
47
55
|
end
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
module ProconBypassMan
|
|
2
|
+
module ExternalInput
|
|
3
|
+
module Channels
|
|
4
|
+
class TCPIPChannel < Base
|
|
5
|
+
class ShutdownSignal < StandardError; end
|
|
6
|
+
|
|
7
|
+
class AppServer < SimpleTCPServer
|
|
8
|
+
@command_queue = Queue.new
|
|
9
|
+
|
|
10
|
+
class << self
|
|
11
|
+
attr_accessor :command_queue
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def post_init
|
|
15
|
+
ProconBypassMan.logger.info { "[ExternalInput][TCPIPChannel] A client has connected" }
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def unbind
|
|
19
|
+
ProconBypassMan.logger.info { "[ExternalInput][TCPIPChannel] A client has disconnected" }
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# @return [String]
|
|
23
|
+
def receive_data(client, data)
|
|
24
|
+
case data
|
|
25
|
+
when /^{/
|
|
26
|
+
self.class.command_queue.push(data)
|
|
27
|
+
client.write("OK\n")
|
|
28
|
+
return
|
|
29
|
+
when /^\n/
|
|
30
|
+
if self.class.command_queue.empty?
|
|
31
|
+
client.write("EMPTY\n")
|
|
32
|
+
return
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
data = self.class.command_queue.pop
|
|
36
|
+
client.write("#{data}\n")
|
|
37
|
+
return
|
|
38
|
+
else
|
|
39
|
+
client.write("Unknown command\n")
|
|
40
|
+
return
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def initialize(port: )
|
|
46
|
+
@port = port
|
|
47
|
+
super()
|
|
48
|
+
|
|
49
|
+
begin
|
|
50
|
+
@server = AppServer.new('0.0.0.0', @port)
|
|
51
|
+
rescue Errno::EADDRINUSE # NOTE: Address already in use - bind(2) for "0.0.0.0" port XXXX
|
|
52
|
+
ProconBypassMan::SendErrorCommand.execute(error: "[ExternalInput][TCPIPChannel] 起動に失敗しました。#{e.message}")
|
|
53
|
+
@server_thread = Thread.start {}
|
|
54
|
+
return
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# NOTE: masterプロセスで起動する
|
|
58
|
+
@server_thread = Thread.start do
|
|
59
|
+
begin
|
|
60
|
+
loop do
|
|
61
|
+
@server.start_server
|
|
62
|
+
@server.run
|
|
63
|
+
end
|
|
64
|
+
rescue Errno::EPIPE, EOFError, Errno::ECONNRESET => e
|
|
65
|
+
ProconBypassMan::SendErrorCommand.execute(error: "[ExternalInput][TCPIPChannel] #{e.message}(#{e})")
|
|
66
|
+
sleep(5)
|
|
67
|
+
|
|
68
|
+
@server.shutdown
|
|
69
|
+
retry
|
|
70
|
+
rescue ShutdownSignal => e
|
|
71
|
+
ProconBypassMan::SendErrorCommand.execute(error: "[ExternalInput][TCPIPChannel] ShutdownSignalを受け取りました。終了します。")
|
|
72
|
+
@server.shutdown
|
|
73
|
+
rescue => e
|
|
74
|
+
ProconBypassMan::SendErrorCommand.execute(error: "[ExternalInput][TCPIPChannel] #{e.message}(#{e})")
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# NOTE: bypassプロセスから呼ばれ、masterプロセスへ繋ぐ
|
|
80
|
+
# @return [String, NilClass]
|
|
81
|
+
def read
|
|
82
|
+
@socket ||= TCPSocket.new('0.0.0.0', @port)
|
|
83
|
+
read_command = "\n"
|
|
84
|
+
@socket.write(read_command)
|
|
85
|
+
response = @socket.gets&.strip
|
|
86
|
+
# ProconBypassMan.logger.debug { "Received: #{response}" }
|
|
87
|
+
|
|
88
|
+
case response
|
|
89
|
+
when /^{/
|
|
90
|
+
return response
|
|
91
|
+
when /^EMPTY/, ''
|
|
92
|
+
return nil
|
|
93
|
+
else
|
|
94
|
+
ProconBypassMan.logger.warn { "[ExternalInput][TCPIPChannel] Unknown response(#{response}, codepoints: #{response.codepoints})" }
|
|
95
|
+
return nil
|
|
96
|
+
end
|
|
97
|
+
rescue Errno::EPIPE, EOFError => e
|
|
98
|
+
@socket = nil
|
|
99
|
+
sleep(10)
|
|
100
|
+
ProconBypassMan.logger.error { "[ExternalInput][TCPIPChannel] #{e.message}!!!!!!!(#{e})" }
|
|
101
|
+
retry
|
|
102
|
+
rescue => e
|
|
103
|
+
@socket = nil
|
|
104
|
+
ProconBypassMan.logger.error { "[ExternalInput][TCPIPChannel] #{e.message} が起きました(#{e})" }
|
|
105
|
+
return nil
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def shutdown
|
|
109
|
+
ProconBypassMan.logger.info { "[ExternalInput][TCPIPChannel] shutdown" }
|
|
110
|
+
@server_thread.raise(ShutdownSignal)
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def alive_server?
|
|
114
|
+
return false if not @server_thread.alive?
|
|
115
|
+
|
|
116
|
+
begin
|
|
117
|
+
TCPSocket.new('0.0.0.0', @port).close
|
|
118
|
+
rescue Errno::ECONNREFUSED, Errno::ECONNRESET
|
|
119
|
+
return false
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
true
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def display_name_for_boot_message
|
|
126
|
+
"TCPIP(port: #{@port})"
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
@@ -4,25 +4,20 @@ module ProconBypassMan
|
|
|
4
4
|
module ExternalInput
|
|
5
5
|
class ParseError < StandardError; end
|
|
6
6
|
|
|
7
|
-
@@channels = nil
|
|
8
|
-
|
|
9
7
|
# @return [Array<ProconBypassMan::ExternalInput::Channels::Base>]
|
|
10
8
|
def self.channels
|
|
11
|
-
@@channels
|
|
9
|
+
@@channels ||= ProconBypassMan.config.external_input_channels
|
|
12
10
|
end
|
|
13
11
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
@@channels = ProconBypassMan.config.external_input_channels
|
|
12
|
+
def self.shutdown
|
|
13
|
+
channels.each(&:shutdown)
|
|
17
14
|
end
|
|
18
15
|
|
|
19
16
|
# @return [NilClass, String]
|
|
20
17
|
# NOTE: 外部入力からのreadがボトルネックになるなら、Concurrent::Futureを使ってプロコンからの読み出しと並列化することを検討する
|
|
21
18
|
def self.read
|
|
22
|
-
raise '外部入力が未初期化です' if @@channels.nil?
|
|
23
|
-
|
|
24
19
|
value = nil
|
|
25
|
-
|
|
20
|
+
channels.each do |channel|
|
|
26
21
|
value = channel.read
|
|
27
22
|
break if value
|
|
28
23
|
end
|
|
@@ -33,3 +28,4 @@ end
|
|
|
33
28
|
|
|
34
29
|
require "procon_bypass_man/external_input/external_data"
|
|
35
30
|
require "procon_bypass_man/external_input/channels.rb"
|
|
31
|
+
require "procon_bypass_man/external_input/boot_message"
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
module ProconBypassMan
|
|
2
|
+
class Forever
|
|
3
|
+
# 動作確認方法
|
|
4
|
+
# - 10秒ごとにrefreshするのでタイムアウトは起きない
|
|
5
|
+
# - ProconBypassMan::Forever.run { |watchdog| loop { puts(:hi); sleep(10); watchdog.active! } }
|
|
6
|
+
# - タイムアウトが起きること
|
|
7
|
+
# - ProconBypassMan::Forever.run { |watchdog| loop { puts(:hi); sleep(10); } }
|
|
8
|
+
def self.run(&block)
|
|
9
|
+
loop do
|
|
10
|
+
new.run(&block)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# @return [void]
|
|
15
|
+
def run(&block)
|
|
16
|
+
raise(ArgumentError, "need a block") unless block_given?
|
|
17
|
+
|
|
18
|
+
thread, watchdog = work_one(callable: block)
|
|
19
|
+
wait_and_kill_if_outdated(thread, watchdog)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# @param [Proc] callable
|
|
23
|
+
# @return [Array<Thread, ProconBypassMan::Watchdog>]
|
|
24
|
+
def work_one(callable: )
|
|
25
|
+
watchdog = ProconBypassMan::Watchdog.new
|
|
26
|
+
thread = Thread.start do
|
|
27
|
+
callable.call(watchdog)
|
|
28
|
+
rescue => e
|
|
29
|
+
ProconBypassMan.logger.error("[Forever] #{e.full_message}")
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
return [thread, watchdog]
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# @param [ProconBypassMan::Watchdog] watchdog
|
|
36
|
+
# @param [Thread] thread
|
|
37
|
+
# @return [void]
|
|
38
|
+
def wait_and_kill_if_outdated(thread, watchdog)
|
|
39
|
+
loop do
|
|
40
|
+
if watchdog.outdated?
|
|
41
|
+
watchdog.active!
|
|
42
|
+
ProconBypassMan.logger.error("watchdog timeout!!")
|
|
43
|
+
thread.kill
|
|
44
|
+
return
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
sleep(10)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
module ProconBypassMan
|
|
2
2
|
class Retryable
|
|
3
|
-
def self.retryable(tries: , retried: 0, on_no_retry: [], log_label: nil)
|
|
3
|
+
def self.retryable(tries: , retried: 0, on_no_retry: [], log_label: nil, interval_on_retry: 0)
|
|
4
4
|
return yield(retried)
|
|
5
5
|
rescue *on_no_retry
|
|
6
6
|
raise
|
|
@@ -11,6 +11,7 @@ module ProconBypassMan
|
|
|
11
11
|
retried = retried + 1
|
|
12
12
|
ProconBypassMan.logger.debug "[Retryable]#{log_label && "[#{log_label}]"} #{e}が起きました。retryします。#{retried} / #{tries}"
|
|
13
13
|
|
|
14
|
+
sleep(interval_on_retry)
|
|
14
15
|
retry
|
|
15
16
|
end
|
|
16
17
|
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
require 'socket'
|
|
2
|
+
|
|
3
|
+
class SimpleTCPServer
|
|
4
|
+
def initialize(host, port)
|
|
5
|
+
@host = host
|
|
6
|
+
@port = port
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def start_server
|
|
10
|
+
@connections = []
|
|
11
|
+
@server = TCPServer.new(@host, @port)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def run
|
|
15
|
+
loop do
|
|
16
|
+
timeout = 5 # 5秒のタイムアウト
|
|
17
|
+
readable, _ = IO.select(@connections + [@server], nil, nil, timeout)
|
|
18
|
+
next if readable.nil? # timeoutを迎えるとnilになる
|
|
19
|
+
|
|
20
|
+
readable.each do |socket|
|
|
21
|
+
if socket == @server
|
|
22
|
+
client = @server.accept
|
|
23
|
+
post_init
|
|
24
|
+
@connections << client
|
|
25
|
+
else
|
|
26
|
+
data = socket.gets
|
|
27
|
+
if data.nil?
|
|
28
|
+
@connections.delete(socket)
|
|
29
|
+
unbind
|
|
30
|
+
socket.close
|
|
31
|
+
else
|
|
32
|
+
receive_data(socket, data)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
rescue Errno::EBADF, IOError => e
|
|
37
|
+
unbind
|
|
38
|
+
@connections = []
|
|
39
|
+
@server.close
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def shutdown
|
|
44
|
+
@server.close
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# @return [Integer]
|
|
48
|
+
def connections_size
|
|
49
|
+
@connections.size
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def post_init
|
|
53
|
+
# Override this method
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def receive_data(socket, data)
|
|
57
|
+
# Override this method
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def unbind
|
|
61
|
+
# Override this method
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module ProconBypassMan
|
|
2
|
+
class Watchdog
|
|
3
|
+
def initialize(timeout: 100)
|
|
4
|
+
@timeout = timeout
|
|
5
|
+
active!
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
# @return [Boolean]
|
|
9
|
+
def outdated?
|
|
10
|
+
@time < Time.now
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# @return [Time]
|
|
14
|
+
def time
|
|
15
|
+
@time
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# @return [void]
|
|
19
|
+
def active!
|
|
20
|
+
@time = Time.now + @timeout
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
class ProconBypassMan::WebConnectivityChecker
|
|
2
2
|
# @param [String, NilClass] url
|
|
3
|
-
|
|
3
|
+
# @param [String, NilClass] ws_url
|
|
4
|
+
def initialize(url, ws_url)
|
|
4
5
|
@url = url
|
|
6
|
+
@ws_url = ws_url
|
|
5
7
|
end
|
|
6
8
|
|
|
7
9
|
# @return [String]
|
|
@@ -11,7 +13,7 @@ class ProconBypassMan::WebConnectivityChecker
|
|
|
11
13
|
end
|
|
12
14
|
|
|
13
15
|
if alive?
|
|
14
|
-
return "ENABLE (#{@url})"
|
|
16
|
+
return "ENABLE (#{@url}, #{@ws_url})"
|
|
15
17
|
else
|
|
16
18
|
return "UNREACHABLE (#{@url})"
|
|
17
19
|
end
|
|
@@ -7,11 +7,13 @@ module ProconBypassMan
|
|
|
7
7
|
return unless ProconBypassMan.config.enable_ws?
|
|
8
8
|
|
|
9
9
|
Thread.start do
|
|
10
|
-
Forever.run
|
|
10
|
+
ProconBypassMan::Forever.run do |watchdog|
|
|
11
|
+
run(watchdog: watchdog)
|
|
12
|
+
end
|
|
11
13
|
end
|
|
12
14
|
end
|
|
13
15
|
|
|
14
|
-
def self.run
|
|
16
|
+
def self.run(watchdog: )
|
|
15
17
|
EventMachine.run do
|
|
16
18
|
client = ActionCableClient.new(
|
|
17
19
|
ProconBypassMan.config.current_ws_server_url, {
|
|
@@ -20,15 +22,15 @@ module ProconBypassMan
|
|
|
20
22
|
)
|
|
21
23
|
|
|
22
24
|
client.connected {
|
|
23
|
-
ProconBypassMan.logger.info('
|
|
25
|
+
ProconBypassMan.logger.info('[WebsocketClient] successfully connected in ProconBypassMan::Websocket::Client')
|
|
24
26
|
}
|
|
25
27
|
client.subscribed { |msg|
|
|
26
|
-
ProconBypassMan.logger.info("
|
|
28
|
+
ProconBypassMan.logger.info("[WebsocketClient] subscribed(#{msg})")
|
|
27
29
|
ProconBypassMan::SyncDeviceStatsJob.perform(ProconBypassMan::DeviceStatus.current)
|
|
28
30
|
}
|
|
29
31
|
|
|
30
32
|
client.received do |data|
|
|
31
|
-
ProconBypassMan.logger.info('
|
|
33
|
+
ProconBypassMan.logger.info('[WebsocketClient] received!!')
|
|
32
34
|
ProconBypassMan.logger.info(data)
|
|
33
35
|
|
|
34
36
|
dispatch(data: data, client: client)
|
|
@@ -37,20 +39,20 @@ module ProconBypassMan
|
|
|
37
39
|
end
|
|
38
40
|
|
|
39
41
|
client.disconnected {
|
|
40
|
-
ProconBypassMan.logger.info('
|
|
42
|
+
ProconBypassMan.logger.info('[WebsocketClient] disconnected!!')
|
|
41
43
|
client.reconnect!
|
|
42
44
|
sleep 2
|
|
43
45
|
}
|
|
44
46
|
client.errored { |msg|
|
|
45
|
-
ProconBypassMan.logger.error("
|
|
47
|
+
ProconBypassMan.logger.error("[WebsocketClient] errored!!, #{msg}")
|
|
46
48
|
client.reconnect!
|
|
47
49
|
sleep 2
|
|
48
50
|
}
|
|
49
51
|
client.pinged { |msg|
|
|
50
|
-
|
|
52
|
+
watchdog.active!
|
|
51
53
|
|
|
52
54
|
ProconBypassMan.cache.fetch key: 'ws_pinged', expires_in: 10 do
|
|
53
|
-
ProconBypassMan.logger.info('
|
|
55
|
+
ProconBypassMan.logger.info('[WebsocketClient] pinged!!')
|
|
54
56
|
ProconBypassMan.logger.info(msg)
|
|
55
57
|
end
|
|
56
58
|
}
|
data/lib/procon_bypass_man.rb
CHANGED
|
@@ -42,6 +42,10 @@ require_relative "procon_bypass_man/support/can_over_process"
|
|
|
42
42
|
require_relative "procon_bypass_man/support/retryable"
|
|
43
43
|
require_relative "procon_bypass_man/support/renice_command"
|
|
44
44
|
require_relative "procon_bypass_man/support/web_connectivity_checker"
|
|
45
|
+
require_relative "procon_bypass_man/support/watchdog"
|
|
46
|
+
require_relative "procon_bypass_man/support/forever"
|
|
47
|
+
require_relative "procon_bypass_man/support/simple_tcp_server"
|
|
48
|
+
require_relative "procon_bypass_man/support/proccess_cheacker"
|
|
45
49
|
require_relative "procon_bypass_man/procon_display"
|
|
46
50
|
require_relative "procon_bypass_man/background"
|
|
47
51
|
require_relative "procon_bypass_man/commands"
|
|
@@ -61,8 +65,6 @@ require_relative "procon_bypass_man/scheduler"
|
|
|
61
65
|
require_relative "procon_bypass_man/plugins"
|
|
62
66
|
require_relative "procon_bypass_man/worker"
|
|
63
67
|
require_relative "procon_bypass_man/websocket/client"
|
|
64
|
-
require_relative "procon_bypass_man/websocket/watchdog"
|
|
65
|
-
require_relative "procon_bypass_man/websocket/forever"
|
|
66
68
|
require_relative "procon_bypass_man/external_input"
|
|
67
69
|
require_relative "procon_bypass_man/remote_action"
|
|
68
70
|
|
|
@@ -124,8 +126,6 @@ module ProconBypassMan
|
|
|
124
126
|
return
|
|
125
127
|
end
|
|
126
128
|
|
|
127
|
-
ProconBypassMan::ExternalInput.prepare_channels
|
|
128
|
-
|
|
129
129
|
ready_pbm
|
|
130
130
|
Runner.new(gadget: gadget, procon: procon).run # ここでblockingする
|
|
131
131
|
terminate_pbm
|
|
@@ -161,6 +161,12 @@ module ProconBypassMan
|
|
|
161
161
|
|
|
162
162
|
# @return [void]
|
|
163
163
|
def self.initialize_pbm
|
|
164
|
+
if ProconBypassMan.pid && ProconBypassMan::ProcessChecker.running?(ProconBypassMan.pid)
|
|
165
|
+
ProconBypassMan::SendErrorCommand.execute(error: "別のプロセスでPBMがすでに起動中なので処理を停止します。")
|
|
166
|
+
raise 'テスト実行中でここに入ると調査が面倒なのでエラーにします' if ENV['PBM_ENV'] == 'test'
|
|
167
|
+
exit 1
|
|
168
|
+
end
|
|
169
|
+
|
|
164
170
|
ProconBypassMan::ReniceCommand.change_priority(to: :low, pid: $$)
|
|
165
171
|
ProconBypassMan::Background::JobQueue.start!
|
|
166
172
|
ProconBypassMan::Websocket::Client.start!
|
|
@@ -211,6 +217,7 @@ module ProconBypassMan
|
|
|
211
217
|
ProconBypassMan::RemoteAction::QueueOverProcess.shutdown
|
|
212
218
|
ProconBypassMan::Procon::PerformanceMeasurement::QueueOverProcess.shutdown
|
|
213
219
|
self.worker&.shutdown
|
|
220
|
+
ProconBypassMan::ExternalInput.shutdown
|
|
214
221
|
end
|
|
215
222
|
|
|
216
223
|
# @return [void]
|
data/project_template/app.rb
CHANGED
|
@@ -12,7 +12,7 @@ begin
|
|
|
12
12
|
gemfile do
|
|
13
13
|
source 'https://rubygems.org'
|
|
14
14
|
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
|
|
15
|
-
gem 'procon_bypass_man', '0.3.
|
|
15
|
+
gem 'procon_bypass_man', '0.3.8'
|
|
16
16
|
# uncomment if you want to use master branch
|
|
17
17
|
# gem 'procon_bypass_man', github: 'splaplapla/procon_bypass_man', branch: 'master'
|
|
18
18
|
# uncomment if you want to use serial communication feature
|
|
@@ -57,6 +57,7 @@ ProconBypassMan.configure do |config|
|
|
|
57
57
|
# シリアル通信やTCP/IP経由で入力するときに設定してください
|
|
58
58
|
# config.external_input_channels = [
|
|
59
59
|
# ProconBypassMan::ExternalInput::Channels::SerialPortChannel.new(device_path: '/dev/serial0', baud_rate: 9600),
|
|
60
|
+
# ProconBypassMan::ExternalInput::Channels::TCPIPChannel.new(port: 9000),
|
|
60
61
|
# ]
|
|
61
62
|
end
|
|
62
63
|
|
data/project_template/app.rb.erb
CHANGED
|
@@ -12,7 +12,7 @@ begin
|
|
|
12
12
|
gemfile do
|
|
13
13
|
source 'https://rubygems.org'
|
|
14
14
|
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
|
|
15
|
-
gem 'procon_bypass_man', '0.3.
|
|
15
|
+
gem 'procon_bypass_man', '0.3.8'
|
|
16
16
|
# uncomment if you want to use master branch
|
|
17
17
|
# gem 'procon_bypass_man', github: 'splaplapla/procon_bypass_man', branch: 'master'
|
|
18
18
|
# uncomment if you want to use serial communication feature
|
|
@@ -62,7 +62,7 @@ ProconBypassMan.configure do |config|
|
|
|
62
62
|
# シリアル通信やTCP/IP経由で入力するときに設定してください
|
|
63
63
|
# config.external_input_channels = [
|
|
64
64
|
# ProconBypassMan::ExternalInput::Channels::SerialPortChannel.new(device_path: '/dev/serial0', baud_rate: 9600),
|
|
65
|
-
|
|
65
|
+
# ProconBypassMan::ExternalInput::Channels::TCPIPChannel.new(port: 9000),
|
|
66
66
|
# ]
|
|
67
67
|
end
|
|
68
68
|
|
data/sig/main.rbs
CHANGED
|
@@ -210,7 +210,7 @@ class ProconBypassMan::Configuration
|
|
|
210
210
|
|
|
211
211
|
def current_ws_server: () -> (String | nil)
|
|
212
212
|
|
|
213
|
-
def current_ws_server_url: () ->
|
|
213
|
+
def current_ws_server_url: () -> (String | nil)
|
|
214
214
|
|
|
215
215
|
def enable_ws?: () -> bool
|
|
216
216
|
|
|
@@ -577,7 +577,7 @@ module ProconBypassMan
|
|
|
577
577
|
@retry_on_connection_error: false
|
|
578
578
|
|
|
579
579
|
def initialize: (path: String, server: untyped, ?retry_on_connection_error: false) -> void
|
|
580
|
-
def get: ->
|
|
580
|
+
def get: -> Hash[untyped, untyped]?
|
|
581
581
|
def post: (request_body: untyped) -> nil
|
|
582
582
|
def put: (request_body: untyped) -> nil
|
|
583
583
|
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: procon_bypass_man
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.3.
|
|
4
|
+
version: 0.3.8
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- jiikko
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2023-
|
|
11
|
+
date: 2023-05-02 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: pbmenv
|
|
@@ -180,10 +180,11 @@ files:
|
|
|
180
180
|
- lib/procon_bypass_man/device_status.rb
|
|
181
181
|
- lib/procon_bypass_man/ephemeral_configuration.rb
|
|
182
182
|
- lib/procon_bypass_man/external_input.rb
|
|
183
|
+
- lib/procon_bypass_man/external_input/boot_message.rb
|
|
183
184
|
- lib/procon_bypass_man/external_input/channels.rb
|
|
184
185
|
- lib/procon_bypass_man/external_input/channels/base.rb
|
|
185
186
|
- lib/procon_bypass_man/external_input/channels/serial_port_channel.rb
|
|
186
|
-
- lib/procon_bypass_man/external_input/channels/
|
|
187
|
+
- lib/procon_bypass_man/external_input/channels/tcpip_channel.rb
|
|
187
188
|
- lib/procon_bypass_man/external_input/external_data.rb
|
|
188
189
|
- lib/procon_bypass_man/plugin/splatoon2/macro/charge_tansan_bomb.rb
|
|
189
190
|
- lib/procon_bypass_man/plugin/splatoon2/macro/dasei_cancel.rb
|
|
@@ -276,10 +277,12 @@ files:
|
|
|
276
277
|
- lib/procon_bypass_man/support/cycle_sleep.rb
|
|
277
278
|
- lib/procon_bypass_man/support/device_mouse_finder.rb
|
|
278
279
|
- lib/procon_bypass_man/support/device_procon_finder.rb
|
|
280
|
+
- lib/procon_bypass_man/support/forever.rb
|
|
279
281
|
- lib/procon_bypass_man/support/http_client.rb
|
|
280
282
|
- lib/procon_bypass_man/support/load_agv.rb
|
|
281
283
|
- lib/procon_bypass_man/support/never_exit_accidentally.rb
|
|
282
284
|
- lib/procon_bypass_man/support/on_memory_cache.rb
|
|
285
|
+
- lib/procon_bypass_man/support/proccess_cheacker.rb
|
|
283
286
|
- lib/procon_bypass_man/support/procon_performance_http_client.rb
|
|
284
287
|
- lib/procon_bypass_man/support/remote_macro_http_client.rb
|
|
285
288
|
- lib/procon_bypass_man/support/renice_command.rb
|
|
@@ -287,16 +290,16 @@ files:
|
|
|
287
290
|
- lib/procon_bypass_man/support/retryable.rb
|
|
288
291
|
- lib/procon_bypass_man/support/safe_timeout.rb
|
|
289
292
|
- lib/procon_bypass_man/support/send_device_stats_http_client.rb
|
|
293
|
+
- lib/procon_bypass_man/support/simple_tcp_server.rb
|
|
290
294
|
- lib/procon_bypass_man/support/update_remote_pbm_job_status_http_client.rb
|
|
291
295
|
- lib/procon_bypass_man/support/uptime.rb
|
|
292
296
|
- lib/procon_bypass_man/support/usb_device_controller.rb
|
|
297
|
+
- lib/procon_bypass_man/support/watchdog.rb
|
|
293
298
|
- lib/procon_bypass_man/support/web_connectivity_checker.rb
|
|
294
299
|
- lib/procon_bypass_man/support/yaml_loader.rb
|
|
295
300
|
- lib/procon_bypass_man/support/yaml_writer.rb
|
|
296
301
|
- lib/procon_bypass_man/version.rb
|
|
297
302
|
- lib/procon_bypass_man/websocket/client.rb
|
|
298
|
-
- lib/procon_bypass_man/websocket/forever.rb
|
|
299
|
-
- lib/procon_bypass_man/websocket/watchdog.rb
|
|
300
303
|
- lib/procon_bypass_man/worker.rb
|
|
301
304
|
- procon_bypass_man.gemspec
|
|
302
305
|
- project_template/README.md
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
# TODO: 実装する
|
|
2
|
-
# module ProconBypassMan
|
|
3
|
-
# module ExternalInput
|
|
4
|
-
# module Channels
|
|
5
|
-
# class TCPIP < Base
|
|
6
|
-
# def initialize(port: )
|
|
7
|
-
# super()
|
|
8
|
-
# # TODO: ここでTCPサーバを起動する(port)
|
|
9
|
-
# end
|
|
10
|
-
#
|
|
11
|
-
# def read
|
|
12
|
-
# end
|
|
13
|
-
# end
|
|
14
|
-
# end
|
|
15
|
-
# end
|
|
16
|
-
# end
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
module ProconBypassMan
|
|
2
|
-
module Websocket
|
|
3
|
-
class Forever
|
|
4
|
-
# 動作確認方法
|
|
5
|
-
# - 10秒ごとにrefreshするのでタイムアウトは起きない
|
|
6
|
-
# - ProconBypassMan::Websocket::Forever.run { loop { puts(:hi); sleep(10); ProconBypassMan::Websocket::Watchdog.active! } }
|
|
7
|
-
# - タイムアウトが起きること
|
|
8
|
-
# - ProconBypassMan::Websocket::Forever.run { puts(:hi); sleep(3000); }
|
|
9
|
-
# - ブロックを1回評価するとThreadが死ぬので100秒後にタイムアウトが起きること
|
|
10
|
-
# - ProconBypassMan::Websocket::Forever.run { puts(:hi); sleep(10); ProconBypassMan::Websocket::Watchdog.active! }
|
|
11
|
-
def self.run(&block)
|
|
12
|
-
loop do
|
|
13
|
-
new.run(&block)
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def run(&block)
|
|
18
|
-
raise("need a block") unless block_given?
|
|
19
|
-
|
|
20
|
-
ws_thread = work_one(callable: block)
|
|
21
|
-
wait_and_kill_if_outdated(ws_thread)
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
# @return [Thread]
|
|
25
|
-
def work_one(callable: )
|
|
26
|
-
Thread.start do
|
|
27
|
-
callable.call
|
|
28
|
-
rescue => e
|
|
29
|
-
ProconBypassMan.logger.error("websocket client with forever: #{e.full_message}")
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def wait_and_kill_if_outdated(thread)
|
|
34
|
-
loop do
|
|
35
|
-
if Watchdog.outdated?
|
|
36
|
-
Watchdog.active!
|
|
37
|
-
ProconBypassMan.logger.error("watchdog timeout!!")
|
|
38
|
-
thread.kill
|
|
39
|
-
return
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
sleep(10)
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
end
|