From dfcfcf2b10381f82ad2c3562a9fe0bf092f18b83 Mon Sep 17 00:00:00 2001 From: jiikko Date: Sat, 27 May 2023 23:14:22 +0900 Subject: [PATCH] =?UTF-8?q?=E3=82=A2=E3=82=A6=E3=83=88=E3=83=A9=E3=82=A4?= =?UTF-8?q?=E3=83=B3=E3=82=92=E5=AE=9F=E8=A3=85=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/procon_bypass_man.rb | 1 + .../bypass/bypass_command.rb | 5 +++-- .../bypass/procon_to_switch.rb | 13 ++++++++---- .../procon_display/server.rb | 2 -- .../procon_display/server2.rb | 21 +++++++++++++++++++ lib/procon_bypass_man/runner.rb | 7 ++++++- .../support/simple_tcp_server.rb | 2 -- .../support/simple_tcp_server_spec.rb | 3 +-- 8 files changed, 41 insertions(+), 13 deletions(-) create mode 100644 lib/procon_bypass_man/procon_display/server2.rb diff --git a/lib/procon_bypass_man.rb b/lib/procon_bypass_man.rb index 023499bcf..ce7d55d7d 100644 --- a/lib/procon_bypass_man.rb +++ b/lib/procon_bypass_man.rb @@ -13,6 +13,7 @@ require "ext/module" require "resolv-replace" require "pbmenv" +require 'socket' require "blue_green_process" require_relative "procon_bypass_man/version" diff --git a/lib/procon_bypass_man/bypass/bypass_command.rb b/lib/procon_bypass_man/bypass/bypass_command.rb index efccf2883..2740fc023 100644 --- a/lib/procon_bypass_man/bypass/bypass_command.rb +++ b/lib/procon_bypass_man/bypass/bypass_command.rb @@ -5,9 +5,10 @@ module WILL_TERMINATE_TOKEN RESTART = :restart end - def initialize(gadget: , procon: ) + def initialize(gadget: , procon: , write_pipe: ) @gadget = gadget @procon = procon + @write_pipe = write_pipe end def execute @@ -51,7 +52,7 @@ def execute # procon => gadget # シビア t2 = Thread.new do - bypass = ProconBypassMan::Bypass::ProconToSwitch.new(gadget: @gadget, procon: @procon) + bypass = ProconBypassMan::Bypass::ProconToSwitch.new(gadget: @gadget, procon: @procon, pipe: @write_pipe) process = BlueGreenProcess.new(worker_instance: bypass, max_work: 1000) loop do if $will_terminate_token diff --git a/lib/procon_bypass_man/bypass/procon_to_switch.rb b/lib/procon_bypass_man/bypass/procon_to_switch.rb index be432375e..44bd59f8a 100644 --- a/lib/procon_bypass_man/bypass/procon_to_switch.rb +++ b/lib/procon_bypass_man/bypass/procon_to_switch.rb @@ -3,10 +3,8 @@ require "procon_bypass_man/bypass/bypass_command" class ProconBypassMan::Bypass::ProconToSwitch - extend ProconBypassMan::CallbacksRegisterable include ProconBypassMan::Callbacks - class CouldNotReadFromProconError < StandardError; end class CouldNotWriteToSwitchError < StandardError; end define_callbacks :work @@ -15,11 +13,12 @@ class CouldNotWriteToSwitchError < StandardError; end # マルチプロセス化したので一旦無効にする # register_callback_module(ProconBypassMan::ProconDisplay::BypassHook) - attr_accessor :gadget, :procon, :bypass_value + attr_accessor :gadget, :procon, :bypass_value, :display_input_pipe - def initialize(gadget: , procon: ) + def initialize(gadget: , procon: , pipe: ) self.gadget = gadget self.procon = procon + self.display_input_pipe = pipe end # @raise [Errno::EIO, Errno::ENODEV, Errno::EPROTO, IOError, Errno::ESHUTDOWN, Errno::ETIMEDOUT] @@ -36,6 +35,12 @@ def work(*) begin return(false) if will_terminate? raw_output = self.procon.read_nonblock(64) + + begin + display_input_pipe.write_nonblock("#{raw_output}\n") if display_input_pipe + rescue IO::EAGAINWaitWritable # pipeのバッファが溢れたらこれが発生する + end + rescue IO::EAGAINWaitReadable sleep(0.002) retry diff --git a/lib/procon_bypass_man/procon_display/server.rb b/lib/procon_bypass_man/procon_display/server.rb index c1941f0f8..d44ff5d5c 100644 --- a/lib/procon_bypass_man/procon_display/server.rb +++ b/lib/procon_bypass_man/procon_display/server.rb @@ -1,5 +1,3 @@ -require 'socket' - module ProconBypassMan::ProconDisplay class Server PORT = 9900 diff --git a/lib/procon_bypass_man/procon_display/server2.rb b/lib/procon_bypass_man/procon_display/server2.rb new file mode 100644 index 000000000..65f4f799d --- /dev/null +++ b/lib/procon_bypass_man/procon_display/server2.rb @@ -0,0 +1,21 @@ +module ProconBypassMan::ProconDisplay::Server2 < SimpleTCPServer + def self.run(read_pipe) + server = new('0.0.0.0', 8000, read_pipe) + server.start_server + server.run + end + + def initialize(host, port, read_pipe) + super(host, port) + @read_pipe = read_pipe + end + + # TODO: バッファリングしたい + def receive_data(socket, _data) + # TODO: IO::EAGAINWaitReadableが起きるまでread_pipe.read_nonblock(1024)を実行する。改行未満の部分を捨てる。取得しまくったら200ms分の履歴を返す + pipe_data = @read_pipe.gets + puts pipe_data + # TODO: HTTP形式で返す + socket.puts(pipe_data) + end +end diff --git a/lib/procon_bypass_man/runner.rb b/lib/procon_bypass_man/runner.rb index 1adb9c053..b7eff63a4 100644 --- a/lib/procon_bypass_man/runner.rb +++ b/lib/procon_bypass_man/runner.rb @@ -22,7 +22,12 @@ def run ProconBypassMan.logger.info "[BYPASS] BYPASSプロセスを起動します" $will_terminate_token = false ProconBypassMan.run_on_after_fork_of_bypass_process - ProconBypassMan::BypassCommand.new(gadget: @gadget, procon: @procon).execute # ここでblockingする + + read_pipe, write_pipe = IO.pipe + Thread.start { ProconBypassMan::ProconDisplay::Server2.run(read_pipe) } + + ProconBypassMan::BypassCommand.new(gadget: @gadget, procon: @procon, write_pipe: write_pipe).execute # ここでblockingする + next end diff --git a/lib/procon_bypass_man/support/simple_tcp_server.rb b/lib/procon_bypass_man/support/simple_tcp_server.rb index 0650f7f9e..b195b7591 100644 --- a/lib/procon_bypass_man/support/simple_tcp_server.rb +++ b/lib/procon_bypass_man/support/simple_tcp_server.rb @@ -1,5 +1,3 @@ -require 'socket' - class SimpleTCPServer def initialize(host, port) @host = host diff --git a/spec/lib/procon_bypass_man/support/simple_tcp_server_spec.rb b/spec/lib/procon_bypass_man/support/simple_tcp_server_spec.rb index f4cfe6102..c108ca8eb 100644 --- a/spec/lib/procon_bypass_man/support/simple_tcp_server_spec.rb +++ b/spec/lib/procon_bypass_man/support/simple_tcp_server_spec.rb @@ -1,5 +1,4 @@ -require 'socket' -require 'procon_bypass_man/support/simple_tcp_server' +require "spec_helper" describe SimpleTCPServer do let(:host) { 'localhost' }