Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Child processes #389

Merged
merged 33 commits into from
Oct 31, 2024
Merged

Child processes #389

merged 33 commits into from
Oct 31, 2024

Conversation

simonhamp
Copy link
Member

@simonhamp simonhamp commented Oct 20, 2024

@simonhamp simonhamp marked this pull request as draft October 21, 2024 12:06
@simonhamp simonhamp marked this pull request as ready for review October 29, 2024 19:06
simonhamp and others added 3 commits October 29, 2024 19:10
- ChildProcess instances can be used to interact with a process
- get, all and restart are piped up
@simonhamp simonhamp merged commit fcdcc06 into main Oct 31, 2024
2 of 23 checks passed
@simonhamp simonhamp deleted the feature/child-processes branch October 31, 2024 13:07
@XbNz
Copy link
Contributor

XbNz commented Nov 17, 2024

Hey @simonhamp,

I was following this conversation and wasn't able to deduce whether you guys managed to come up with a proper inter-process communication mechanism.

My use case is that I'm listening to the native: channel in a Livewire component:

#[On('native:'.SomeCustomEvent::class)]
final class SomeCustomEvent implements ShouldBroadcastNow
{
    use Dispatchable;
    use InteractsWithSockets;

    public function broadcastOn(): array
    {
        return [
            new Channel('nativephp'),
        ];
    }
}

This works great when the event is dispatched from a queue worker (::dispatchSync() and ::dispatch(). However, when the event is fired from within a child process, it does not seem to hit my Livewire method. The only alternative to this would be polling with something like wire:poll, which isn't ideal.

I do see that you've had to implement some custom JavaScript to fire the (4?) pre-defined events dedicated to child processes:

    proc.stdout.on('data', (data) => {
        notifyLaravel('events', {
            event: 'Native\\Laravel\\Events\\ChildProcess\\MessageReceived',
            payload: {
                alias,
                data: data.toString(),
            }
        });
    });
    proc.stderr.on('data', (data) => {
        console.error('Error received from process [' + alias + ']:', data.toString());
        notifyLaravel('events', {
            event: 'Native\\Laravel\\Events\\ChildProcess\\ErrorReceived',
            payload: {
                alias,
                data: data.toString(),
            }
        });
    });
    proc.on('spawn', () => {
        console.log('Process [' + alias + '] spawned!');
        state.processes[alias] = {
            pid: proc.pid,
            proc,
            settings
        };
        notifyLaravel('events', {
            event: 'Native\\Laravel\\Events\\ChildProcess\\ProcessSpawned',
            payload: [alias, proc.pid]
        });
    });
    proc.on('exit', (code) => {
        console.log(`Process [${alias}] exited with code [${code}].`);
        notifyLaravel('events', {
            event: 'Native\\Laravel\\Events\\ChildProcess\\ProcessExited',
            payload: {
                alias,
                code,
            }
        });
        const settings = Object.assign({}, getSettings(alias));
        delete state.processes[alias];
        if (settings.persistent) {
            console.log('Process [' + alias + '] wathchdog restarting...');
            startProcess(settings);
        }
    });

So clearly, there is a manual process involved in making the parent PHP process aware of the child events. Btw, these work with Livewire! Is there a way you can accomodate for firing custom events on the nativephp channel from the child to the parent?

@SRWieZ
Copy link
Contributor

SRWieZ commented Nov 17, 2024

Hey @XbNz!

You're correct, the only two ways to have inter-process communication are:

@gwleuverink just finished the fix, so it should be merged soon enough 😉

@XbNz
Copy link
Contributor

XbNz commented Nov 17, 2024

  • Outputting text from the child process and receiving it by Native\Laravel\Events\ChildProcess\MessageReceived

I completely neglected that as a possible solution. It's even described in the docs lol.

In that case, it'll be possible to create a long-running worker using something like ReactPHP's WritableStreamInterface to implement a loop that handles a JSON-encoded workload and sends the response to STDOUT. This might be overkill though, since custom event support is coming.

Thanks for the quick help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants