Skip to content

Commit 211a5af

Browse files
mancvsotakase1121
andauthored
Addednotes on process API write (#31)
* Update child-processes.md * Rearrange and rephrase into a proper section --------- Co-authored-by: takase1121 <20792268+takase1121@users.noreply.github.com>
1 parent d338764 commit 211a5af

File tree

1 file changed

+53
-0
lines changed

1 file changed

+53
-0
lines changed

docs/developer-guide/using-libraries/child-processes.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,59 @@ print(proc:read_stdout())
180180
print(proc:read_stderr())
181181
```
182182

183+
### Writing data to a process
184+
185+
If the child process is created with the correct input mode,
186+
you can write to the standard input of the process with `process:write()`.
187+
188+
```lua
189+
function process:write(data: string): integer|nil, string|nil end
190+
```
191+
192+
The function accepts a byte string containing the data to write,
193+
and returns the number of bytes successfully written.
194+
If it encounters an error, it will return nil and an error message.
195+
196+
The function is asynchronous and will return immediately, even when data is not written.
197+
As such, the number of bytes written may be less than the number of bytes in the input.
198+
You should handle this by chunking the data manually and implement exponetial backoff.
199+
200+
```lua
201+
---Writes data asynchronously to a process, with chunking and exponetial backoff.
202+
---The exponetial backoff will only work when calling this function inside a thread created with core.add_thread().
203+
---adapted from https://github.com/lite-xl/lite-xl-lsp/blob/b2523423b34712dd5cefc5d7ee6f7a500f4ac2ed/server.lua#L907
204+
---
205+
---@param proc process The child process to write to.
206+
---@param data string The data to write.
207+
---@return boolean success
208+
---@return string error
209+
local function write_data(proc, data)
210+
local failures, data_len = 0, #data
211+
local written, errmsg = proc:write(data)
212+
local total_written = written or 0
213+
214+
while total_written < data_len and not errmsg do
215+
written, errmsg = proc:write(data:sub(total_written + 1))
216+
total_written = total_written + (written or 0)
217+
218+
if (not written or written <= 0) and not errmsg and coroutine.running() then
219+
-- with each consecutive fail the yield timeout is increased by 5ms
220+
coroutine.yield((failures * 5) / 1000)
221+
222+
failures = failures + 1
223+
if failures > 19 then -- after ~1000ms we error out
224+
errmsg = "maximum amount of consecutive failures reached"
225+
break
226+
end
227+
else
228+
failures = 0
229+
end
230+
end
231+
232+
return total_written == data_len, errmsg
233+
end
234+
```
235+
183236
### Waiting for a child process
184237

185238
You might want to wait for a child process to end.

0 commit comments

Comments
 (0)