io_daemonizer 5 → 6

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 +59 -4
  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: 9221b86c37a20ab3d79c7fb1fee60e9a7c74aa083d3aff30da43e755c9a02256
4
+ data.tar.gz: f0b41de14e06824a163ded73f2b70d45bc54c1c086ee8c2419b83af4d1ab3c58
5
5
  SHA512:
6
- metadata.gz: f531743fc395f854ed431ee7e2f283a206995df75367fe5fe871d8d7d1e238a482b0baf0ea132c8b384055377169870122e443c2840f51b2da092d25c2472dd2
7
- data.tar.gz: fe64289f1d5b86e12f52c157e46cb1d8e5d93ac9f95be18aa46e51f34a81f4a42f77a7ca0d193dc22fca2b0636f4f10349e342a97e6f3c0dd36d783ac1f2ee7b
6
+ metadata.gz: cbcfd15d8a147dc074f4003e7d1a6f2ee17979644220abb54044b740c7023f0f51bab528c395b38b053efb685abac807c4648387b9aa5c1e3cad0d0e45f0ef5f
7
+ data.tar.gz: 250baadd6ca2b943920408f431a66b5920f1655cfd44b4026f7c08409b23dcf9ad19972e2aae7f900e09268d4f9c472c33e80455a62ddf982e78751da9433f44
data/io_daemonizer.rb CHANGED
@@ -1,5 +1,6 @@
1
- # io_daemonizer v.5 https://github.com/joeyschoblaska/io_daemonizer
1
+ # io_daemonizer v.6 https://github.com/joeyschoblaska/io_daemonizer
2
2
 
3
+ require "json"
3
4
  require "shellwords"
4
5
  require "socket"
5
6
  require "stringio"
@@ -30,11 +31,14 @@ class IODaemonizer
30
31
  end
31
32
 
32
33
  def self.send_request(port:, args:)
34
+ consumer = LabeledIOConsumer.new
35
+
33
36
  TCPSocket.open("127.0.0.1", port) do |socket|
34
37
  socket.puts args.shelljoin
35
38
  socket.write $stdin.tty? ? "" : $stdin.read
36
39
  socket.close_write
37
- STDOUT.write(socket.read(4096)) until socket.eof?
40
+
41
+ consumer.write(socket.read) until socket.eof?
38
42
  end
39
43
  end
40
44
 
@@ -82,14 +86,65 @@ class IODaemonizer
82
86
  else
83
87
  IODaemonizer.redirect(
84
88
  stdin: StringIO.new(body.join),
85
- stdout: socket,
86
- stderr: socket
89
+ stdout: IOLabeler.new(1, socket, "stdout"),
90
+ stderr: IOLabeler.new(2, socket, "stderr")
87
91
  ) { @context.instance_exec args, &@run }
88
92
  end
89
93
  rescue => e
90
94
  socket.write e.inspect
95
+ raise e
91
96
  ensure
97
+ socket.close_write
92
98
  socket.close
93
99
  end
94
100
  end
101
+
102
+ class IOLabeler < IO
103
+ attr_reader :label
104
+
105
+ def initialize(fd, socket, label)
106
+ super(fd)
107
+ @socket = socket
108
+ @label = label
109
+ end
110
+
111
+ def write(chunk)
112
+ @socket.write({ @label => chunk }.to_json)
113
+ end
114
+
115
+ def reopen(io)
116
+ @label = io&.label || @label
117
+ end
118
+ end
119
+
120
+ class LabeledIOConsumer
121
+ def initialize
122
+ @buffer = ""
123
+ end
124
+
125
+ def write(chunk)
126
+ chunk.chars.each do |ch|
127
+ @buffer << ch
128
+ process_buffer
129
+ end
130
+ end
131
+
132
+ private
133
+
134
+ def process_buffer
135
+ parsed = JSON.parse(@buffer)
136
+ key = parsed.keys[0]
137
+ value = parsed.values[0]
138
+
139
+ case key
140
+ when "stdout"
141
+ $stdout.write(value)
142
+ when "stderr"
143
+ $stderr.write(value)
144
+ end
145
+
146
+ @buffer = ""
147
+ rescue JSON::ParserError
148
+ end
149
+ end
95
150
  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: '6'
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-07 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: []