Language Implementation Guide - UltimatePea/UniversalLanguageInterface GitHub Wiki
This documentation is intended to be used as a guide to instruct the implementation of this Interface in different programming languages. Please refer to language specific guide if you want to use this interface.
The function that can be called must take a single string as argument and return a single string as result. It is up to the specific implementer on how the strings are encoded and decoded. It is recommended to use encodings like JSON pass complex data structure.
Calling Introduction
All calls are blocking for now. Async calls might be added in the future.
Calls are made via command line with three command line arguments.
-
--mode
-- eithersingle
,stream
. I will probably implementsingle
only as of 0.x ~ 1.0 release. I will bringstream
in 2.x. I plan to addserver
which accepts incoming function calls via network in 3.x versions. -
--input-pipe
-- the file path for caller -> callee unix named pipe. -
--output-pipe
-- the file path for callee -> caller unix named pipe.
Callee Responsibility
Callee will read input-pipe
for one line only. This line contains string in JSON format for the function the the caller intended to call. The JSON will look like the following
{
"name": "FUNCTION_NAME",
"args": "ARG_VALUE"
}
The callee will then call the function denoted by FUNCTION_NAME
with the argument list, and write to output-pipe
one line in the following JSON format.
{
"code":200,
"return_val":"RETURN_VAL_IN_STRING"
}
Note that all values (arguments, return value, function names) are strings.
If an error occurred during the calling, the callee should try its best not to crash the program but instead write the following JSON to output-pipe
.
{
"code":500,
"message":"ERROR_REASON"
}
Caller Responsibility
The caller is responsible for creating subprocess and necessary pipes.
Calling mode. Caller is handles calling mode differently for different programming languages. For compiled binary languages, caller will specify a single program name, e.g. (someprog/a.out
). For interpreted language, caller can accept interpreter name, e.g. (python3
) and a program file name, e.g. (uli_exposed.py
).
Due to the nature of blocking of opening FIFOs on unix, the procedure must be followed exactly to avoid stuck.
Steps:
- Caller Construct temporary FIFOs.
The recommended practice is to create a temporary directory under system temporary directory. Then use mkfifo
to create two fifo
s, inp
for caller -> callee communication and outp
for callee -> caller communication.
Please make sure security is handled properly here. Document any insecure operations using TODO
.
- Caller create and start a another process.
The starting process should be non blocking, to allow open files for constructed fifo
s.
- Caller opens
inp
inWriteMode
and write one line:
{
"name": "FUNCTION_NAME",
"args": "ARG_VALUE"
}
-
Caller opens
outp
inReadMode
-
Caller
join
to wait for the subprocess to finish. -
Caller read one line from
outp
and parse the output -
Caller check response code and make necessary actions.
-
Caller delete the temporary FIFO (
inp
,outp
) and the temporary directory. -
Caller returns the resulting object to the host program.
It is important to remove temporary directory for cleaning up
Note: the child process will stuck until both input and output pipes are open