procon_bypass_man 0.1.23 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +13 -0
  3. data/.github/workflows/gitleacks.yml +12 -0
  4. data/.github/workflows/release.yml +1 -0
  5. data/.github/workflows/ruby.yml +1 -1
  6. data/CHANGELOG.md +20 -0
  7. data/Gemfile +6 -3
  8. data/Gemfile.lock +3 -3
  9. data/README.md +2 -2
  10. data/bin/generate_default_app +10 -0
  11. data/docs/getting_started.md +52 -7
  12. data/docs/setup_raspi.md +0 -1
  13. data/lib/procon_bypass_man/background/jobs/base_job.rb +1 -1
  14. data/lib/procon_bypass_man/background/jobs/concerns/{job_runnable.rb → job_performable.rb} +1 -1
  15. data/lib/procon_bypass_man/background.rb +1 -1
  16. data/lib/procon_bypass_man/buttons_setting_configuration/loader.rb +1 -1
  17. data/lib/procon_bypass_man/{commands → bypass}/bypass_command.rb +11 -19
  18. data/lib/procon_bypass_man/bypass/usb_hid_logger.rb +0 -1
  19. data/lib/procon_bypass_man/bypass.rb +9 -14
  20. data/lib/procon_bypass_man/commands/print_boot_message_command.rb +1 -2
  21. data/lib/procon_bypass_man/commands/send_error_command.rb +2 -2
  22. data/lib/procon_bypass_man/commands.rb +0 -3
  23. data/lib/procon_bypass_man/configuration.rb +22 -3
  24. data/lib/procon_bypass_man/device_connection/command.rb +28 -0
  25. data/lib/procon_bypass_man/{device_connector.rb → device_connection/executor.rb} +51 -38
  26. data/lib/procon_bypass_man/device_connection/output_report_generator.rb +42 -0
  27. data/lib/procon_bypass_man/device_connection/output_report_markerable.rb +28 -0
  28. data/lib/procon_bypass_man/device_connection/output_report_sub_command_table.rb +133 -0
  29. data/lib/procon_bypass_man/device_connection/output_report_watcher.rb +41 -0
  30. data/lib/procon_bypass_man/device_connection/pre_bypass.rb +67 -0
  31. data/lib/procon_bypass_man/device_connection/procon_setting_overrider.rb +78 -0
  32. data/lib/procon_bypass_man/device_connection/spoofing_output_report_watcher.rb +39 -0
  33. data/lib/procon_bypass_man/device_connection.rb +16 -0
  34. data/lib/procon_bypass_man/device_model.rb +17 -0
  35. data/lib/procon_bypass_man/io_monitor.rb +20 -1
  36. data/lib/procon_bypass_man/procon/macro_builder.rb +5 -3
  37. data/lib/procon_bypass_man/procon_display/bypass_hook.rb +11 -0
  38. data/lib/procon_bypass_man/procon_display/http_request.rb +31 -0
  39. data/lib/procon_bypass_man/procon_display/http_response.rb +23 -0
  40. data/lib/procon_bypass_man/procon_display/server.rb +33 -0
  41. data/lib/procon_bypass_man/procon_display/server_app.rb +17 -0
  42. data/lib/procon_bypass_man/procon_display/status.rb +20 -0
  43. data/lib/procon_bypass_man/procon_display.rb +11 -0
  44. data/lib/procon_bypass_man/{commands → remote_pbm_action/commands}/run_remote_pbm_action_dispatch_command.rb +0 -0
  45. data/lib/procon_bypass_man/remote_pbm_action/restore_pbm_setting.rb +7 -1
  46. data/lib/procon_bypass_man/remote_pbm_action.rb +1 -0
  47. data/lib/procon_bypass_man/runner.rb +4 -7
  48. data/lib/procon_bypass_man/support/callbacks.rb +68 -34
  49. data/lib/procon_bypass_man/support/never_exit_accidentally.rb +3 -3
  50. data/lib/procon_bypass_man/support/usb_device_controller.rb +2 -2
  51. data/lib/procon_bypass_man/support/yaml_loader.rb +12 -0
  52. data/lib/procon_bypass_man/version.rb +1 -1
  53. data/lib/procon_bypass_man/websocket/client.rb +1 -4
  54. data/lib/procon_bypass_man.rb +66 -41
  55. data/procon_bypass_man.gemspec +1 -1
  56. data/project_template/README.md +0 -5
  57. data/project_template/app.rb +24 -6
  58. data/project_template/app.rb.erb +64 -0
  59. data/project_template/lib/app_generator.rb +31 -0
  60. data/project_template/web.rb +1 -1
  61. data/sig/main.rbs +3 -3
  62. data/tmp/.keep +0 -0
  63. metadata +30 -8
  64. data/lib/procon_bypass_man/commands/connect_device_command.rb +0 -18
@@ -0,0 +1,11 @@
1
+ module ProconBypassMan::ProconDisplay::BypassHook
2
+ include ProconBypassMan::Callbacks
3
+
4
+ define_callbacks :send_procon_to_gadget
5
+
6
+ set_callback :send_procon_to_gadget, :after, :write_procon_display_Status
7
+
8
+ def write_procon_display_Status
9
+ ProconBypassMan::ProconDisplay::Status.instance.current = bypass_value.binary.to_procon_reader.to_hash.dup
10
+ end
11
+ end
@@ -0,0 +1,31 @@
1
+ module ProconBypassMan::ProconDisplay
2
+ # NOTE Support GET only
3
+ class HttpRequest
4
+ def self.parse(conn)
5
+ headers = {}
6
+ loop do
7
+ line = conn.gets("\n")&.strip
8
+ break if line.nil? || line.strip.empty?
9
+ key, value = line.split(/:\s/, 2)
10
+ headers[key] = value
11
+ end
12
+
13
+ new(headers)
14
+ end
15
+
16
+ def initialize(headers)
17
+ @headers = headers
18
+ end
19
+
20
+ def path
21
+ request_method_and_path = @headers.detect { |key, _value| key.start_with?("GET") }.first
22
+ if request_method_and_path =~ /(?:GET) ([^ ]+)/ && (path = $1)
23
+ return path
24
+ end
25
+ end
26
+
27
+ def to_hash
28
+ { "PATH" => path }
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,23 @@
1
+ module ProconBypassMan::ProconDisplay
2
+ class HttpResponse
3
+ def initialize(body, status: , format: "text/json")
4
+ @body = body&.to_json
5
+ @status = status
6
+ @format = format
7
+ end
8
+
9
+ def to_s
10
+ <<~EOH
11
+ HTTP/1.1 #{@status}
12
+ Content-Length: #{@body&.bytes&.size || 0}
13
+ Content-Type: #{@format}
14
+ Access-Control-Allow-Origin: *
15
+ Access-Control-Allow-Methods: GET
16
+ Access-Control-Allow-Private-Network:true
17
+ Connection: close
18
+
19
+ #{@body}
20
+ EOH
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,33 @@
1
+ require 'socket'
2
+
3
+ module ProconBypassMan::ProconDisplay
4
+ class Server
5
+ PORT = 9900
6
+
7
+ def self.start!
8
+ Thread.new do
9
+ new.start_with_foreground
10
+ end
11
+ end
12
+
13
+ def initialize
14
+ @server = TCPServer.new('0.0.0.0', PORT)
15
+ end
16
+
17
+ def start_with_foreground
18
+ loop do
19
+ conn = @server.accept
20
+ response = ServerApp.new(
21
+ HttpRequest.parse(conn).to_hash
22
+ ).call
23
+ conn.write(response)
24
+ conn.close
25
+ end
26
+ rescue Errno::EADDRINUSE => e
27
+ ProconBypassMan::SendErrorCommand.execute(error: e)
28
+ rescue => e
29
+ ProconBypassMan::SendErrorCommand.execute(error: e)
30
+ retry
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,17 @@
1
+ module ProconBypassMan::ProconDisplay
2
+ class ServerApp
3
+ def initialize(env)
4
+ @env = env
5
+ end
6
+
7
+ def call
8
+ case @env["PATH"]
9
+ when "/input"
10
+ response = ProconBypassMan::ProconDisplay::Status.instance.current
11
+ HttpResponse.new(response, status: 200).to_s
12
+ else
13
+ HttpResponse.new(nil, status: 404).to_s
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,20 @@
1
+ require 'singleton'
2
+
3
+ class ProconBypassMan::ProconDisplay::Status
4
+ include Singleton
5
+
6
+ # @return [Hash]
7
+ def current
8
+ @current || {}
9
+ end
10
+
11
+ # @return [void]
12
+ # @param [Hash] value
13
+ def current=(value)
14
+ if value.is_a?(Hash)
15
+ @current = value
16
+ else
17
+ @current = nil
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,11 @@
1
+ # 入力表示用
2
+
3
+ module ProconBypassMan::ProconDisplay
4
+ end
5
+
6
+ require "procon_bypass_man/procon_display/server"
7
+ require "procon_bypass_man/procon_display/server_app"
8
+ require "procon_bypass_man/procon_display/status"
9
+ require "procon_bypass_man/procon_display/http_response"
10
+ require "procon_bypass_man/procon_display/http_request"
11
+ require "procon_bypass_man/procon_display/bypass_hook"
@@ -17,7 +17,8 @@ module ProconBypassMan
17
17
  path: ProconBypassMan::ButtonsSettingConfiguration.instance.setting_path,
18
18
  content: setting,
19
19
  )
20
- ProconBypassMan.hot_reload!
20
+
21
+ hot_reload!
21
22
  end
22
23
 
23
24
  private
@@ -29,6 +30,11 @@ module ProconBypassMan
29
30
  def after_action_callback
30
31
  be_processed
31
32
  end
33
+
34
+ # @return [void]
35
+ def hot_reload!
36
+ Process.kill(:USR2, ProconBypassMan.pid)
37
+ end
32
38
  end
33
39
  end
34
40
  end
@@ -6,6 +6,7 @@ module ProconBypassMan
6
6
  require "procon_bypass_man/remote_pbm_action/stop_pbm_action"
7
7
  require "procon_bypass_man/remote_pbm_action/restore_pbm_setting.rb"
8
8
  require "procon_bypass_man/remote_pbm_action/commands/update_remote_pbm_action_status_command"
9
+ require "procon_bypass_man/remote_pbm_action/commands/run_remote_pbm_action_dispatch_command"
9
10
  require "procon_bypass_man/remote_pbm_action/value_objects/remote_pbm_action_object"
10
11
 
11
12
  ACTION_CHANGE_PBM_VERSION = "change_pbm_version"
@@ -8,8 +8,6 @@ class ProconBypassMan::Runner
8
8
  def initialize(gadget: , procon: )
9
9
  @gadget = gadget
10
10
  @procon = procon
11
-
12
- ProconBypassMan::PrintBootMessageCommand.execute
13
11
  end
14
12
 
15
13
  def run
@@ -30,6 +28,7 @@ class ProconBypassMan::Runner
30
28
  $will_terminate_token = false
31
29
  DRb.start_service if defined?(DRb)
32
30
  ProconBypassMan::RemoteMacroReceiver.start!
31
+ ProconBypassMan::ProconDisplay::Server.start!
33
32
  ProconBypassMan::BypassCommand.new(gadget: @gadget, procon: @procon).execute # ここでblockingする
34
33
  next
35
34
  }
@@ -41,9 +40,9 @@ class ProconBypassMan::Runner
41
40
  handle_signal(signal)
42
41
  end
43
42
  rescue InterruptForRestart
43
+ ProconBypassMan::PrintMessageCommand.execute(text: "設定ファイルの再読み込みを開始します")
44
44
  Process.kill("USR2", child_pid)
45
45
  Process.wait
46
- ProconBypassMan::PrintMessageCommand.execute(text: "Reloading config file")
47
46
  begin
48
47
  ProconBypassMan::ButtonsSettingConfiguration::Loader.reload_setting
49
48
  ProconBypassMan::SendReloadConfigEventCommand.execute
@@ -53,12 +52,10 @@ class ProconBypassMan::Runner
53
52
  end
54
53
  ProconBypassMan::PrintMessageCommand.execute(text: "バイパス処理を再開します")
55
54
  rescue Interrupt
55
+ puts
56
+ ProconBypassMan::PrintMessageCommand.execute(text: "処理を終了します")
56
57
  Process.kill("TERM", child_pid)
57
58
  Process.wait
58
- ProconBypassMan::PrintMessageCommand.execute(text: "処理を終了します")
59
- ProconBypassMan::UsbDeviceController.reset
60
- @gadget&.close
61
- @procon&.close
62
59
  break
63
60
  end
64
61
  end
@@ -1,21 +1,15 @@
1
1
  module ProconBypassMan
2
- module Callbacks
3
- class CallbacksChain
4
- attr_accessor :filter, :chain_method
5
- def initialize(filter: , chain_method: , block: )
6
- @filter = filter
7
- @chain_method = chain_method
8
- @block = block
9
- end
10
- end
2
+ module CallbacksRegisterable
3
+ attr_accessor :callbacks
11
4
 
12
- # TODO __callbacksをincludeしたクラス側で保持する. 今はnemespaceがない
13
- module M
14
- class << self
15
- attr_accessor :__callbacks
16
- end
5
+ def register_callback_module(mod)
6
+ self.callbacks ||= []
7
+ callbacks << mod
8
+ self.include(mod)
17
9
  end
10
+ end
18
11
 
12
+ module Callbacks
19
13
  module ClassMethods
20
14
  def define_callbacks(name)
21
15
  self.singleton_class.attr_accessor "_#{name}_callbacks"
@@ -29,8 +23,9 @@ module ProconBypassMan
29
23
  end
30
24
 
31
25
  def set_callback(kind, filter, chain_method, &block)
32
- ProconBypassMan::Callbacks::M.__callbacks ||= {}
33
- ProconBypassMan::Callbacks::M.__callbacks[kind] = CallbacksChain.new(
26
+ self.__callbacks ||= {}
27
+ self.__callbacks[kind] ||= CallbackChain.new
28
+ self.__callbacks[kind].append Callback.new(
34
29
  filter: filter,
35
30
  chain_method: chain_method,
36
31
  block: block,
@@ -38,33 +33,72 @@ module ProconBypassMan
38
33
  end
39
34
  end
40
35
 
36
+ def self.included(mod)
37
+ mod.singleton_class.attr_accessor :__callbacks
38
+ mod.extend(ClassMethods)
39
+ end
40
+
41
+ class CallbackChain
42
+ attr_accessor :callbacks
43
+
44
+ def initialize
45
+ self.callbacks = {}
46
+ end
47
+
48
+ def empty?
49
+ callbacks.empty?
50
+ end
51
+
52
+ def append(callback)
53
+ self.callbacks[callback.filter] ||= []
54
+ self.callbacks[callback.filter] << callback
55
+ end
56
+
57
+ def [](filter)
58
+ self.callbacks[filter]
59
+ end
60
+ end
61
+
62
+ class Callback
63
+ attr_accessor :filter, :chain_method
64
+
65
+ def initialize(filter: , chain_method: , block: )
66
+ @filter = filter
67
+ @chain_method = chain_method
68
+ @block = block
69
+ end
70
+ end
71
+
41
72
  # TODO haltしたらcallbackを止める
42
- # TODO 複数をチェインできるようにする
43
73
  def run_callbacks(kind, &block)
44
- chain = get_callbacks(kind) or raise("unknown callback")
45
- case chain.filter
46
- when :before
47
- send chain.chain_method
48
- block.call
49
- when :after
74
+ chains = get_callbacks(kind) or raise("unknown callback")
75
+ if chains.nil? || chains.empty?
50
76
  block.call
77
+ return
78
+ end
79
+
80
+ chains[:before]&.each do |chain|
81
+ send chain.chain_method
82
+ end
83
+ block.call
84
+ chains[:after]&.each do |chain|
51
85
  send chain.chain_method
52
- else
53
- raise("unknown filter")
54
86
  end
55
87
  end
56
88
 
57
- # def __run_callbacks__(name, &block)
58
- # puts "called"
59
- # end
60
-
61
89
  def get_callbacks(kind) # :nodoc:
62
- ProconBypassMan::Callbacks::M.__callbacks[kind.to_sym]
63
- end
90
+ # classに直接moduleをincludeしている場合
91
+ if defined?(self.class.__callbacks)
92
+ return self.class.__callbacks[kind.to_sym]
93
+ end
64
94
 
65
- def set_callbacks(name, callbacks) # :nodoc:
66
- send "_#{name}_callbacks=", callbacks
67
- ProconBypassMan::Callbacks::M.__callbacks[kind.to_sym] = callbacks
95
+ list = self.class.callbacks.flat_map { |callback_mod|
96
+ callback_mod.__callbacks && callback_mod.__callbacks[kind.to_sym]
97
+ }.compact
98
+ table = {}
99
+ table[:before] = list.flat_map { |x| x[:before] }.compact
100
+ table[:after] = list.flat_map { |x| x[:after] }.compact
101
+ table
68
102
  end
69
103
  end
70
104
  end
@@ -1,11 +1,11 @@
1
1
  module ProconBypassMan
2
2
  module NeverExitAccidentally
3
- def exit_if_allow(status)
3
+ def self.exit_if_allow_at_config
4
4
  if ProconBypassMan.never_exit_accidentally
5
- eternal_sleep
5
+ ProconBypassMan.eternal_sleep
6
6
  else
7
7
  yield if block_given?
8
- exit(status)
8
+ exit 1
9
9
  end
10
10
  end
11
11
  end
@@ -1,13 +1,13 @@
1
1
  class ProconBypassMan::UsbDeviceController
2
2
  class << self
3
- def reset
3
+ def reset(cooldown: 0.5)
4
4
  [ "echo > /sys/kernel/config/usb_gadget/procon/UDC",
5
5
  "ls /sys/class/udc > /sys/kernel/config/usb_gadget/procon/UDC",
6
6
  ].each do |shell|
7
7
  system shell
8
8
  ProconBypassMan.logger.debug { "[SHELL] #{shell}" }
9
9
  end
10
- sleep 0.5
10
+ sleep cooldown
11
11
  end
12
12
 
13
13
  def init
@@ -0,0 +1,12 @@
1
+ class ProconBypassMan::YamlLoader
2
+ # @param [String] path
3
+ # @return [Hash]
4
+ def self.load(path: )
5
+ YAML.load_file(path).tap do |y|
6
+ # 行末に空白があるとto_yamlしたときに改行コードがエスケープされてしまうのでstrip
7
+ y.transform_values do |v|
8
+ v.strip! if v.is_a?(String)
9
+ end
10
+ end
11
+ end
12
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ProconBypassMan
4
- VERSION = "0.1.23"
4
+ VERSION = "0.2.2"
5
5
  end
@@ -23,8 +23,7 @@ module ProconBypassMan
23
23
  ProconBypassMan.logger.info('websocket client: successfully connected in ProconBypassMan::Websocket::Client')
24
24
  }
25
25
  client.subscribed { |msg|
26
- ProconBypassMan.logger.info('websocket client: subscribed')
27
- puts({ event: :subscribed, msg: msg })
26
+ ProconBypassMan.logger.info("websocket client: subscribed(#{msg})")
28
27
  ProconBypassMan::SyncDeviceStatsJob.perform(ProconBypassMan::DeviceStatus.current)
29
28
  }
30
29
 
@@ -39,13 +38,11 @@ module ProconBypassMan
39
38
 
40
39
  client.disconnected {
41
40
  ProconBypassMan.logger.info('websocket client: disconnected!!')
42
- puts :disconnected
43
41
  client.reconnect!
44
42
  sleep 2
45
43
  }
46
44
  client.errored { |msg|
47
45
  ProconBypassMan.logger.error("websocket client: errored!!, #{msg}")
48
- puts :errored
49
46
  client.reconnect!
50
47
  sleep 2
51
48
  }
@@ -14,11 +14,14 @@ require "pbmenv"
14
14
  require_relative "procon_bypass_man/version"
15
15
  require_relative "procon_bypass_man/remote_pbm_action"
16
16
  require_relative "procon_bypass_man/remote_macro"
17
+
18
+ require_relative "procon_bypass_man/device_connection"
17
19
  require_relative "procon_bypass_man/support/usb_device_controller"
18
20
  require_relative "procon_bypass_man/support/device_procon_finder"
19
21
  require_relative "procon_bypass_man/support/device_mouse_finder"
20
22
  require_relative "procon_bypass_man/support/signal_handler"
21
23
  require_relative "procon_bypass_man/support/callbacks"
24
+ require_relative "procon_bypass_man/support/yaml_loader"
22
25
  require_relative "procon_bypass_man/support/yaml_writer"
23
26
  require_relative "procon_bypass_man/support/safe_timeout"
24
27
  require_relative "procon_bypass_man/support/compress_array"
@@ -33,16 +36,17 @@ require_relative "procon_bypass_man/support/server_pool"
33
36
  require_relative "procon_bypass_man/support/analog_stick_hypotenuse_tilting_power_scaler"
34
37
  require_relative "procon_bypass_man/support/never_exit_accidentally"
35
38
  require_relative "procon_bypass_man/support/cycle_sleep"
39
+ require_relative "procon_bypass_man/procon_display"
36
40
  require_relative "procon_bypass_man/background"
37
41
  require_relative "procon_bypass_man/commands"
38
42
  require_relative "procon_bypass_man/bypass"
39
- require_relative "procon_bypass_man/device_connector"
40
43
  require_relative "procon_bypass_man/device_status"
41
44
  require_relative "procon_bypass_man/runner"
42
45
  require_relative "procon_bypass_man/processor"
43
46
  require_relative "procon_bypass_man/configuration"
44
47
  require_relative "procon_bypass_man/buttons_setting_configuration"
45
48
  require_relative "procon_bypass_man/procon"
49
+ require_relative "procon_bypass_man/device_model"
46
50
  require_relative "procon_bypass_man/procon/button"
47
51
  require_relative "procon_bypass_man/procon/analog_stick_cap"
48
52
  require_relative "procon_bypass_man/procon/analog_stick_manipulator"
@@ -61,52 +65,59 @@ module ProconBypassMan
61
65
  extend ProconBypassMan::NeverExitAccidentally
62
66
 
63
67
  class CouldNotLoadConfigError < StandardError; end
64
- class EternalConnectionError < StandardError; end
68
+ class NotFoundProconError < StandardError; end
65
69
 
66
70
  # @return [void]
67
71
  def self.run(setting_path: nil)
68
- ProconBypassMan::Scheduler.start!
69
- ProconBypassMan::Background::JobRunner.start!
70
- ProconBypassMan::Websocket::Client.start!
71
- ProconBypassMan::QueueOverProcess.start!
72
-
73
72
  ProconBypassMan::PrintMessageCommand.execute(text: "PBMを起動しています")
74
73
  initialize_pbm
75
- ProconBypassMan::ButtonsSettingConfiguration::Loader.load(setting_path: setting_path)
76
- gadget, procon = ProconBypassMan::ConnectDeviceCommand.execute!
77
- Runner.new(gadget: gadget, procon: procon).run # ここでblockingする
78
- FileUtils.rm_rf(ProconBypassMan.pid_path)
79
- FileUtils.rm_rf(ProconBypassMan.digest_path)
80
- ProconBypassMan::QueueOverProcess.shutdown
81
- rescue ProconBypassMan::CouldNotLoadConfigError
82
- ProconBypassMan::SendErrorCommand.execute(error: "設定ファイルが不正です。設定ファイルの読み込みに失敗しました")
83
- ProconBypassMan::DeviceStatus.change_to_setting_syntax_error_and_shutdown!
84
- # TODO シグナルトラップをしていないのでUSR2を送ったときにプロセスが停止している. 明示的にハンドリングするべき.
85
- ProconBypassMan.exit_if_allow(1) do
86
- FileUtils.rm_rf(ProconBypassMan.pid_path)
87
- FileUtils.rm_rf(ProconBypassMan.digest_path)
88
- ProconBypassMan::QueueOverProcess.shutdown
74
+
75
+ begin
76
+ ProconBypassMan::ButtonsSettingConfiguration::Loader.load(setting_path: setting_path)
77
+ rescue ProconBypassMan::CouldNotLoadConfigError
78
+ ProconBypassMan::SendErrorCommand.execute(error: "設定ファイルが不正です。設定ファイルの読み込みに失敗しました")
79
+ ProconBypassMan::DeviceStatus.change_to_setting_syntax_error_and_shutdown!
80
+ # TODO シグナルトラップをしていないのでUSR2を送ったときにプロセスが停止している. 明示的にハンドリングするべき.
81
+ ProconBypassMan::NeverExitAccidentally.exit_if_allow_at_config do
82
+ terminate_pbm
83
+ end
84
+ return
89
85
  end
90
- rescue ProconBypassMan::ConnectDeviceCommand::NotFoundProconError
91
- ProconBypassMan::SendErrorCommand.execute(error: "プロコンが見つかりませんでした。")
92
- ProconBypassMan::DeviceStatus.change_to_procon_not_found_error!
93
- # TODO シグナルトラップをしていないのでUSR2を送ったときにプロセスが停止している. 明示的にハンドリングするべき.
94
- ProconBypassMan.exit_if_allow(1) do
95
- FileUtils.rm_rf(ProconBypassMan.pid_path)
96
- FileUtils.rm_rf(ProconBypassMan.digest_path)
97
- ProconBypassMan::QueueOverProcess.shutdown
86
+
87
+ begin
88
+ gadget, procon = ProconBypassMan::DeviceConnection::Command.execute!
89
+ rescue ProconBypassMan::DeviceConnection::NotFoundProconError
90
+ ProconBypassMan::SendErrorCommand.execute(error: "プロコンが見つかりませんでした。")
91
+ ProconBypassMan::DeviceStatus.change_to_procon_not_found_error!
92
+ # TODO シグナルトラップをしていないので以下の状態に、USR2を送ったときにプロセスが停止してしまう
93
+ ProconBypassMan::NeverExitAccidentally.exit_if_allow_at_config do
94
+ terminate_pbm
95
+ end
96
+ return
97
+ rescue ProconBypassMan::DeviceConnection::TimeoutError
98
+ ProconBypassMan::SendErrorCommand.execute(error: "接続の見込みがないのでsleepしまくります")
99
+ ProconBypassMan::DeviceStatus.change_to_connected_but_sleeping!
100
+ %w(TERM INT).each do |sig|
101
+ Kernel.trap(sig) { exit 0 }
102
+ end
103
+ Kernel.trap :USR2 do
104
+ exit 0 # TODO retryする
105
+ end
106
+ eternal_sleep
107
+ return
98
108
  end
99
- rescue ProconBypassMan::EternalConnectionError
100
- ProconBypassMan::SendErrorCommand.execute(error: "接続の見込みがないのでsleepしまくります")
101
- ProconBypassMan::DeviceStatus.change_to_connected_but_sleeping!
102
- FileUtils.rm_rf(ProconBypassMan.pid_path)
103
- eternal_sleep
109
+
110
+ ready_pbm
111
+ Runner.new(gadget: gadget, procon: procon).run # ここでblockingする
112
+ terminate_pbm
104
113
  end
105
114
 
115
+ # 実行ファイル(app.rb)から呼び出している
116
+ # @return [void]
106
117
  def self.configure(&block)
107
118
  @@configuration = ProconBypassMan::Configuration.new
108
119
  @@configuration.instance_eval(&block)
109
- @@configuration
120
+ nil
110
121
  end
111
122
 
112
123
  # @return [ProconBypassMan::Configuration]
@@ -123,20 +134,34 @@ module ProconBypassMan
123
134
  ProconBypassMan::IOMonitor.reset!
124
135
  end
125
136
 
137
+ # @return [void]
126
138
  def self.initialize_pbm
139
+ ProconBypassMan::Scheduler.start!
140
+ ProconBypassMan::Background::JobRunner.start!
141
+ ProconBypassMan::Websocket::Client.start!
142
+ ProconBypassMan::QueueOverProcess.start!
143
+
127
144
  ProconBypassMan::WriteDeviceIdCommand.execute
128
145
  ProconBypassMan::WriteSessionIdCommand.execute
129
- system("renice -n -20 -p #{$$}")
146
+ `renice -n -20 -p #{$$}`
130
147
  File.write(pid_path, $$)
131
148
  ProconBypassMan::DeviceStatus.change_to_running!
132
149
  end
133
150
 
134
- def self.eternal_sleep
135
- sleep(999999999)
151
+ def self.ready_pbm
152
+ ProconBypassMan::PrintBootMessageCommand.execute
153
+ ProconBypassMan::ReportLoadConfigJob.perform_async(ProconBypassMan.config.raw_setting)
154
+ end
155
+
156
+ # @return [void]
157
+ def self.terminate_pbm
158
+ FileUtils.rm_rf(ProconBypassMan.pid_path)
159
+ FileUtils.rm_rf(ProconBypassMan.digest_path)
160
+ ProconBypassMan::QueueOverProcess.shutdown
136
161
  end
137
162
 
138
- # @return [Void]
139
- def self.hot_reload!
140
- Process.kill(:USR2, pid)
163
+ # @return [void]
164
+ def self.eternal_sleep
165
+ sleep(999999999)
141
166
  end
142
167
  end
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
12
12
  spec.description = spec.summary
13
13
  spec.homepage = "https://github.com/splaplapla/procon_bypass_man"
14
14
  spec.license = "MIT"
15
- spec.required_ruby_version = Gem::Requirement.new(">= 3.0.0")
15
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.5.0")
16
16
 
17
17
  spec.metadata["homepage_uri"] = spec.homepage
18
18
  spec.metadata["source_code_uri"] = spec.homepage
@@ -1,6 +1,5 @@
1
1
  # Project Template
2
2
  * これらは https://github.com/splaplapla/pbmenv がinstallするときに配備するファイルです
3
- * pbm_webはオプショナルです
4
3
 
5
4
  ## systemdを使ってサービスに登録する方法
6
5
  systemctl enableした後は、次回のOS起動時にserviceも自動起動します
@@ -8,13 +7,9 @@ systemctl enableした後は、次回のOS起動時にserviceも自動起動し
8
7
  * pbm
9
8
  * sudo systemctl link /usr/share/pbm/current/systemd_units/pbm.service
10
9
  * sudo systemctl enable pbm.service
11
- * pbm_web
12
- * sudo systemctl link /usr/share/pbm/current/systemd_units/pbm_web.service
13
- * sudo systemctl enable pbm_web.service
14
10
 
15
11
  ## systemdを使ってサービスから解除する方法
16
12
  * sudo systemctl disable pbm.service
17
- * sudo systemctl disable pbm_web.service
18
13
 
19
14
  ### CheatSheet
20
15
  * systemctl daemon-reload