io_daemonizer 5 → 7.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/io_daemonizer.rb +56 -9
  3. metadata +4 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 80b48adc5074a3057dd995bd6111fffcaecaf14436d94aa781c822eef10fd95b
4
- data.tar.gz: 1f816e2e331f8132844a4fcc1a8da7731d4d08d70165f89ac34c3f985a969466
3
+ metadata.gz: b77913ca0b5c285bb8a710fd00053a24866b53573ba9c41bb16ed602e31b38c4
4
+ data.tar.gz: 547656ffb02c86efcc71e61fc880b2123c107ec6db9b2f1096a7f1cef295ec70
5
5
  SHA512:
6
- metadata.gz: f531743fc395f854ed431ee7e2f283a206995df75367fe5fe871d8d7d1e238a482b0baf0ea132c8b384055377169870122e443c2840f51b2da092d25c2472dd2
7
- data.tar.gz: fe64289f1d5b86e12f52c157e46cb1d8e5d93ac9f95be18aa46e51f34a81f4a42f77a7ca0d193dc22fca2b0636f4f10349e342a97e6f3c0dd36d783ac1f2ee7b
6
+ metadata.gz: 6fd051362f2c045038893605755df28027058bc6207a9e7c59f2637061b8dc38887677575303403430d5acc78480ac571bb2a30cc826cbc27c6d42e99ad7baff
7
+ data.tar.gz: 2b83f413fa0cdbf040844263e5b0ac0e6a0feb2f3742bd77cc796bc310cfcea7b40823ee8941462a3c2a9283e1d2043b22b14175b94287b86da5dfa8bf39f21c
data/io_daemonizer.rb CHANGED
@@ -1,5 +1,6 @@
1
- # io_daemonizer v.5 https://github.com/joeyschoblaska/io_daemonizer
1
+ # io_daemonizer v.7.2 https://github.com/joeyschoblaska/io_daemonizer
2
2
 
3
+ require "json"
3
4
  require "shellwords"
4
5
  require "socket"
5
6
  require "stringio"
@@ -18,9 +19,7 @@ class IODaemonizer
18
19
  send_request(port: port, args: ARGV)
19
20
  rescue Errno::ECONNREFUSED => e
20
21
  raise(e) unless autostart
21
- daemon = Daemon.new(port: port, setup: setup, run: run)
22
- daemon.setup
23
- fork { daemon.start }
22
+ Daemon.run(port: port, setup: setup, run: run, fork: true)
24
23
  sleep 0.1
25
24
  send_request(port: port, args: ARGV)
26
25
  end
@@ -30,11 +29,14 @@ class IODaemonizer
30
29
  end
31
30
 
32
31
  def self.send_request(port:, args:)
32
+ consumer = LabeledIOConsumer.new
33
+
33
34
  TCPSocket.open("127.0.0.1", port) do |socket|
34
35
  socket.puts args.shelljoin
35
36
  socket.write $stdin.tty? ? "" : $stdin.read
36
37
  socket.close_write
37
- STDOUT.write(socket.read(4096)) until socket.eof?
38
+
39
+ consumer.write(socket.read) until socket.eof?
38
40
  end
39
41
  end
40
42
 
@@ -48,10 +50,10 @@ class IODaemonizer
48
50
  end
49
51
 
50
52
  class Daemon
51
- def self.run(port:, setup:, run:)
53
+ def self.run(port:, setup:, run:, fork: false)
52
54
  daemon = new(port: port, setup: setup, run: run)
53
55
  daemon.setup
54
- daemon.start
56
+ fork ? Kernel.fork { daemon.start } : daemon.start
55
57
  end
56
58
 
57
59
  def initialize(port:, setup:, run:)
@@ -82,14 +84,59 @@ class IODaemonizer
82
84
  else
83
85
  IODaemonizer.redirect(
84
86
  stdin: StringIO.new(body.join),
85
- stdout: socket,
86
- stderr: socket
87
+ stdout: IOLabeler.new(1, socket, "stdout"),
88
+ stderr: IOLabeler.new(2, socket, "stderr")
87
89
  ) { @context.instance_exec args, &@run }
88
90
  end
89
91
  rescue => e
90
92
  socket.write e.inspect
93
+ raise e
91
94
  ensure
95
+ socket.close_write
92
96
  socket.close
93
97
  end
94
98
  end
99
+
100
+ class IOLabeler < IO
101
+ attr_reader :label
102
+
103
+ def initialize(fd, socket, label)
104
+ super(fd)
105
+ @socket = socket
106
+ @label = label
107
+ end
108
+
109
+ def write(chunk)
110
+ @socket.write({ @label => chunk }.to_json)
111
+ end
112
+
113
+ def reopen(io)
114
+ @label = io&.label || @label
115
+ end
116
+ end
117
+
118
+ class LabeledIOConsumer
119
+ def initialize
120
+ @buffer = ""
121
+ end
122
+
123
+ def write(chunk)
124
+ chunk.chars.each do |ch|
125
+ @buffer << ch
126
+ process_buffer if ch == "}"
127
+ end
128
+ end
129
+
130
+ private
131
+
132
+ def process_buffer
133
+ parsed = JSON.parse(@buffer)
134
+
135
+ $stdout.write(parsed["stdout"]) if parsed["stdout"]
136
+ $stderr.write(parsed["stderr"]) if parsed["stderr"]
137
+
138
+ @buffer = ""
139
+ rescue JSON::ParserError
140
+ end
141
+ end
95
142
  end
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: io_daemonizer
3
3
  version: !ruby/object:Gem::Version
4
- version: '5'
4
+ version: '7.2'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joey Schoblaska
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-09-06 00:00:00.000000000 Z
11
+ date: 2022-09-08 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description: Wrap a Ruby script that speaks IO in a daemon so that you only pay the
14
- startup overhead once.
13
+ description: Wrap a Ruby script that speaks stdio in a daemon so that you only pay
14
+ the startup overhead once.
15
15
  email: joey.schoblaska@gmail.com
16
16
  executables: []
17
17
  extensions: []