daemonizeProgram | shared void daemonizeProgram(void run(), Integer fd, String[] argumentsMap(String[] arguments, String? workingDirectory) = ..., Integer lengthSize = ..., Integer typeSize = 1, Integer? maximumStandardInput = null, Integer? maximumStandardOutput = null, Integer? maximumStandardError = null, Integer maximumPacketLength = ...) Turns a normal program (run() ) into a daemon
that runs one instance of the program per connection.
Only one instance of the program is run at a time,
to avoid interference between multiple instances via global state.
(However, the program needs to take care of resetting such state at the beginning or end itself.)
Parameters: run fd argumentsMap = arguments lengthSize = 2 typeSize = 1 maximumStandardInput = null maximumStandardOutput = null maximumStandardError = null maximumPacketLength = 256^lengthSize - 1
|
makeDaemonizeProgramInstance | shared [ReadCallback, SocketExceptionHandler]? makeDaemonizeProgramInstance(void run(), String[] argumentsMap(String[] arguments, String? workingDirectory) = ..., Integer lengthSize = ..., Integer typeSize = 1, Integer? maximumStandardInput = null, Integer? maximumStandardOutput = null, Integer? maximumStandardError = null, Integer maximumPacketLength = ...)(void write(ByteBuffer content, WriteCallback callback), void close()) Create an instance for start that runs a given program as daemon.
The socket protocol is packet-based,
with configurable lengthSize and typeSize .
Each connection understands the following packet types:
#00 (0): launch the program.
This must be the last packet;
any other packets after this one are an error.
#01 (1): add an argument.
The packet content is a single, UTF-8 encoded argument.
Upon launch, all received arguments are sent to argumentsMap()
(together with the working directory, if one was received ��� see below),
and the result (by default, the arguments themselves)
is made available to the program in arguments .
The mapping function may, for example, turn relative file paths in the arguments into absolute ones,
since the real working directory of the process is still the daemon working directory and cannot be changed.
#02 (2): set working directory.
The working directory, if set, will be passed to argumentsMap() along with all arguments
(otherwise, that argument will be null ).
This packet may only be sent at most once.
#03 (3): add standard input.
The packet content is added to a buffer which, upon launch,
is made available to the process as standard input via readLine and similar functions.
No encoding is specified;
language module functions producing text instead of bytes are themselves responsible for decoding the content,
just as with regular standard input.
(It is recommended to transfer text in UTF-8 encoding and ensure that the daemon process runs in a UTF-8 locale.)
Note that the JS backend does not support reading from standard input,
and this module does nothing to change that.
Once launched, the program runs to completion.
Afterwards, the following packet types may be sent:
#80 (128): connection closes.
The content is a 4-byte integer in network byte order,
indicating the exit code (exit ���s argument;
process.exit throws if called with a number that does not fit in four bytes),
or 0 if the run() function returned normally,
or 1 if the run() function threw an exception,
or #7FFFFFF0 (2147483632) if standard input was exceeded (see maximumStandardInput ),
or #7FFFFFF1 (2147483633) if standard output was exceeded (see maximumStandardOutput ),
or #7FFFFFF2 (2147483634) if standard error was exceeded (see maximumStandardError ).
A packet of this type is always sent on termination
(unless the packet-based protocol itself is violated),
and it is always the last packet;
the socket is closed once this packet has been sent.
#81 (129): standard output.
All standard output produced by the program via writeLine and similar functions
is stored in a buffer and finally sent in a packet of this type.
Boundaries between writes are not preserved.
(On the JVM backend, no encoding is specified, and the same advice as for standard input (#03 , see above) applies;
on the JS backend, the buffer is UTF-8 encoded.)
#82 (130): standard error.
Analogous to standard output (#81 , see above).
#83 (131): exception stacktrace.
If the program threw an exception,
a packet of this type is sent,
containing the UTF-8 encoded stack trace.
#90 (144): standard input too long.
This packet is sent when the a received standard input packet
bumps the total number of standard input bytes received
above the application-configured limit.
It contains that limit as a 4-byte integer in network byte order.
#91 (145): standard output too long.
This packet is sent when a write to standard output by the application
exceeds the application-configured limit.
It contains that limit as a 4-byte integer in network byte order.
#92 (146): standard error too long.
Analogous to standard output too long (#91 , see above).
Parameters: run The program being daemonized.
argumentsMap = arguments A mapping function that is applied to the arguments
before they are stored in arguments .
If a working directory packet has been sent,
that is set as the second argument.
This function can, for example,
change relative paths in the arguments to absolute ones
(relative to the passed working directory)
to ensure they are valid in the program
when it runs under the daemon���s working directory.
lengthSize = 2 The size of the packet length.
By default, a conservative size of 2 is chosen,
but I/O heavy programs may require larger sizes
(all output is sent in a single packet).
typeSize = 1 The size of the type length.
The default of 1 is sufficient for all understood types,
but a higher value may be desirable for alignment purpose.
maximumStandardInput = null The maximum number of bytes accepted on standard input.
If this is not null and is exceeded by some standard input packet,
the daemon sends ���standard input exceeded��� (#90 ) and ���exit��� (#80 ) packets
and then closes the connection.
(Truncating the input in a meaningful way, if desired,
is then the responsibility of the client program.)
maximumStandardOutput = null The maximum number of bytes accepted on standard output.
If this is not null and exceeded by some write to standard output,
an exception is immediately thrown.
If the run() function does not catch this error,
the program is terminated;
the daemon sends ���standard output exceeded��� (#91 ) and ���exit��� (#80 ) packets
and then closes the connection.
maximumStandardError = null The maximum number of bytes accepted on standard error.
If this is not null and exceeded by some write to standard error,
an exception is immediately thrown.
If the run() function does not catch this error,
the program is terminated;
the daemon sends ���standard error exceeded��� (#92 ) and ���exit��� (#80 ) packets
and then closes the connection.
maximumPacketLength = 256^lengthSize - 1
|