Removing socket-based control connections for inter-process communication #48
Labels
No labels
bug
confirmed
critical
discussion
documentation
Doing
enhancement
suggestion
support
To Do
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: hazaar/hazaar-warlock#48
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
In the beginning, Warlock use PIPES for inter-process communication. Namely STDIN, STDOUT and STDERR. This worked perfectly on Linux/Unix machines, but developing on Windows machines was required and Windows has some serious issues with PIPES. The main issue is that they DO NOT work in non-blocking mode, meaning Warlock could not operate correctly. The other symptom of this was that data returned from a child process would not reach the parent until the pipe was closed and the process ended, meaning bi-directional real-time communication was not possible using PIPES on Windows.
So I switched to using TCP sockets for the control channel, but they appear to be pretty unreliable under PHP. Possibly due to some sort of resource management going on when the socket resource is lefts un-used for some time. This is most pronounced when the child process is doing some long-running task without communicating with the parent, so PHP seems to shut down the socket but doesn't notify the program until it attempts to use the socket. And then it notifies the program with a FATAL error and shuts it down.
Because of all this, I will be going back to using PIPES for inter-process communications and essentially ditching support for running Warlock on Windows.
HOWEVER!!!!
Windows 10 now has a cool feature called Windows Sub-system for Linux, which allows linux programs to run inside a Linux shell. I have already tested this and been able to start Warlock from a Windows CMD prompt using the included vendor binaries by executing the command:
From within a project folder. This should take care of windows development while allowing me to write code specifically tailored for Linux systems and achieve greater reliability and performance.
mentioned in merge request !21
created merge request !21 to address this issue
So I re-implemented pipes pretty easily, using the same technique as when I first created Warlock. That was to have the main loop use
socket_select
to monitor for data on the sockets and then an outside loop with zero wait time, to monitor for data on the pipes. This worked fine but introduced some potential lag on receiving data from a service because the main loop may have been waiting on sockets at the time, which is likely.The trick here was to convert everything over to using streams. This is possible in PHP using the
stream_socket_*
functions that allow sockets to be set up as streams. Then I replacedsocket_select
withstream_select
and gave it a list of streams to wait. After that it was as simple as treating pipes the same as sockets and adding them to the internal$this->sockets
array, which has now become$this->streams
for consistency. The end result is on main loop that waits for data on all connections, be it sockets or pipes, and immediate responsiveness and processing of received data.I have had this in a test environment for days now and everything appears to be working correctly. No changes are required to application code and it is full backwards compatible.
closed via merge request !21
mentioned in commit
d836f0a39a
changed milestone to %1