Reputation: 303
I want to make a synchronous call to a Port in Erlang. That is, to send some input to a running OS process connected through a Port and get its output directly, not using messages.
There is a port_call
function which is said to do that. However, the documentation says that the function parameters and return value are driver-dependent. I couldn't find any information about the driver which is used when a Port is opened the usual way, for example, by open_port({spawn, 'cat'}, [binary])
.
I am coming from Elixir and the problem that I'm trying to solve is concurrently using a Port where a single external process is continuously running, taking input from and returning output to many VM processes (like a database).
I was looking for a mechanism in both Elixir and Erlang to guarantee that, if a Port is used asynchronously, its responses are delivered exactly to those processes that sent the corresponding requests.
It looks like the solution that Erlang suggests is to call receive
immediately after a command
message is sent to the Port (probably relying on the fact that message ordering is guaranteed in Erlang), but this technique can't be used with Elixir's GenServer, since it advises against it.
If there was a way to 'set a cookie' on a message to the Port and then get it back when it responds, it would be possible to match the response to the request, but I see no way doing that with Erlang at the moment.
The only solution I see is to add a decorator to the OS process which would pass this cookie from request to response, but it seems ugly.
I must be missing something here since both languages are very mature.
Upvotes: 4
Views: 221
Reputation: 20024
Have a look at erlexec
. It's much more flexible and capable than the built-in driver, and it might provide what you're looking for. For example, its documentation specifically provides examples for running OS commands synchronously.
Upvotes: 2