io_daemonizer 5 → 7.2

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.
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: []