-
Notifications
You must be signed in to change notification settings - Fork 11.5k
[10.x] Process DX Layer #45314
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
[10.x] Process DX Layer #45314
Conversation
Outstanding work! What do you think about |
@geowrgetudor not sure I want to go down that road - would require supporting all sorts of SSH options, etc. |
Leaving thought to myself... if I have the same process but want to turn it into a pool without repeating myself, it could be nice to do something like: $pool = Process::timeout(60)->pool(10)->run('some-command');
$pool->start(); |
What's the reason for removing the functions like |
This PR continues and expands upon @nunomaduro's work on providing a convenient process layer in Laravel. Some features have been rebuilt and others have been added.
Notably, the ability to describe fake process lifecycles for async process handling / testing as well as process result sequences. In addition, the ability to interleave incoming output from a pool of processes and key them by name. Functionality for preventing stray processes during testing has also been added.
In addition, the object model has been rebuilt.
Usage
Basic API
The most basic usage of this feature looks like the following:
Building Processes
A variety of options can be set on the process before actually invoking it, including setting the timeout, idle timeout, TTY support, and environment variables:
Process Output
A callback may be passed to the
run
function to gather the process output as it is received. The signature on this callback is the same as the underlying Symfony Process callbacks you may be used to:Asynchronous Processes
The
start
method may be used to start an asynchronous process. Calling this method returns an implementation ofInvokedProcess
, allowing you to perform other tasks while the external process is running. Thewait
method may be used to resolve the invoked process into a process result, waiting on the process to finish executing if necessary:Process Pools
Process pools allow you to manage and interact with a pool of processes at once, then access their results by key. A callback may be passed to the
start
method of the pool to capture output from all processes by key (the third argument given to the closure). Thestart
method returns an instance ofInvokedProcessPool
, allowing you to interact with the pool via various methods. Calling thewait
method on the invoked pool will wait until all processes in the pool have finished running and run an instance ofProcessPoolResults
, which may be accessed like an array:For convenience, process pool processes may also be assigned string keys, just like HTTP request pools:
In addition, for convenience, a
concurrently
method is provided which is the equivalent to callingstart
andwait
on the process pool to resolve the results synchronously. In this example, we are using array destructuring to assign the pool process results to individual variables:Testing
Testing is similar to @nunomaduro's API, with the following basic API:
Fake process results can be defined in a variety of ways, from calling
Process::result
to just passing simple strings and arrays:Process Sequences
Like the HTTP fake's functionality, you may also define sequences of results for commands that are invoked multiple times in a request:
Async Process Lifecycles
Finally, you may also describe async process lifecycles in order to test code that starts processes asynchronously and then interacts with them while running. In this example,
running
will returntrue
three times as we specified by callingiterations(3)
when describing our process. In addition, we define several lines of standard output as well as some error output:Preventing Stray Processes
By default, if
Process::fake
has been called and Laravel isn't able to find a matching fake definition for a given process, the process will actually execute. This behavior is consistent with the HTTP facade's fake functionality. You can prevent this behavior by invoking thepreventStrayProcesses
method. This will cause Laravel to throw an exception when attempting to invoke a process that does not have a corresponding fake definition: