Removing socket-based control connections for inter-process communication #48

Closed
opened 2019-05-16 02:07:43 +00:00 by jamie · 7 comments
jamie commented 2019-05-16 02:07:43 +00:00 (Migrated from git.hazaar.io)

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:

wsl vendor/bin/warlock

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.

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: ``` wsl vendor/bin/warlock ``` 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.
jamie commented 2019-05-16 06:56:34 +00:00 (Migrated from git.hazaar.io)

mentioned in merge request !21

mentioned in merge request !21
jamie commented 2019-05-16 06:56:34 +00:00 (Migrated from git.hazaar.io)

created merge request !21 to address this issue

created merge request !21 to address this issue
jamie commented 2019-05-23 23:31:12 +00:00 (Migrated from git.hazaar.io)

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 replaced socket_select with stream_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.

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 replaced `socket_select` with `stream_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.
jamie commented 2019-05-28 01:09:30 +00:00 (Migrated from git.hazaar.io)

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.

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.
jamie commented 2019-05-28 01:10:25 +00:00 (Migrated from git.hazaar.io)

closed via merge request !21

closed via merge request !21
jamie commented 2019-05-28 01:10:25 +00:00 (Migrated from git.hazaar.io)

mentioned in commit d836f0a39a

mentioned in commit d836f0a39a28b65170a187c97939cb1d6eacf383
jamie commented 2019-05-28 02:07:15 +00:00 (Migrated from git.hazaar.io)

changed milestone to %1

changed milestone to %1
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: hazaar/hazaar-warlock#48
No description provided.