0

I have a client/server daemon in PHP, which forks per request. Processes A and B can talk using inter process communication (IPC) with the method described in socket_create_pair. However, if the request being handled by B forks again (into process C) to handle a long running task after B exits, C can only communicate on the original IPC pair to A until B exits (because A drops the socket when SIGCHLD is handled, and A really has no idea C exists).

A -> listening process
  B -> forked request process, will fork C
    C -> forked request continuing a long task as B returns "In progress..." to the user.
         (C can talk to A as long as B has not exited)

This is problematic because A manages some resources that can only be requested by IPC, and C naturally may end up causing an IPC request to A that blocks forever. Also, there is a risk of data corruption if B and C send any IPC at the same moment.

I've seen strategies for passing sockets between processes, but this doesn't seem to be possible in PHP's socket interface. I could use a non-paired socket listening on A that C can send requests to, but this is one way. Is there any other strategy in PHP to implement bidirectional IPC between A and C?

jimp
  • 16,999
  • 3
  • 27
  • 36
  • Why not simply let B continue to run and mediate communication between A and C? Alternatively you could fork less and use a task queue/scheduler to handle long-running and/or async tasks instead of trying to fork yourself to death. – Sammitch Dec 14 '17 at 21:10
  • If B doesn't end, A will not complete the response to the browser. The reason for an extra fork is just so the initial request (B) can immediately pass the work off and let it get started. A task queue will need to be poked and it would still have to hit the database/cache for all the data again. – jimp Dec 15 '17 at 00:04
  • I think that your question would be more answerable if you were to describe what you're actually doing and the constraints of doing it rather than the generalized version you currently have. I could suggest something that does what you want, but would really be the Z of the XY problem that it sounds like you're in the midst of right now. – Sammitch Dec 15 '17 at 00:12
  • I appreciate that, but I removed the details on purpose. It's just an internal HTTP service that forks per request received from authorized machines. I'm really not looking for a different solution. My code has led to the question regarding PHP's capabilities in this area (not XY). – jimp Dec 15 '17 at 04:38
  • Well, honestly the X sounds like "I've written a forking HTTP server in PHP" which is weird enough, the "double-forked, but not-backgrounded process that still needs to communicate with its grandparent" is another layer of strange, particularly in the context of an HTTP request. I honestly think you're painting yourself into a corner at the bottom of a hole you also want to dig even deeper. But if you're truly determined or I've misread the situation, then there's always: http://php.net/manual/en/function.posix-mkfifo.php – Sammitch Dec 15 '17 at 18:51
  • 1
    I didn't describe the situation, because I didn't want assumptions I must have a deeper problem. It's a mature code base, performing well, and actively maintained. I don't want to scrap it. A customer identified this issue and I just need to fix it to maintain stability. -- Thank you for taking the time to reply! I had forgotten about named pipes, but I think that will work. – jimp Dec 15 '17 at 22:37

0 Answers0