Skip to content

Commit

Permalink
document callback and payload functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
perazz committed Feb 4, 2025
1 parent 80a2d0a commit 20c045d
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 7 deletions.
17 changes: 13 additions & 4 deletions doc/specs/stdlib_system.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,12 @@ Experimental

The `run` interface allows execution of external processes using a single command string or a list of arguments.
Processes run synchronously, meaning execution is blocked until the process finishes.
Optional arguments enable the collection of standard output and error streams, as well as sending input via standard input.
Optional arguments enable the collection of standard output and error streams, as well as sending input via standard input.
Additionally, a callback function can be specified to execute upon process completion, optionally receiving a user-defined payload.

### Syntax

`process = ` [[stdlib_subprocess(module):run(interface)]] `(args [, stdin] [, want_stdout] [, want_stderr])`
`process = ` [[stdlib_subprocess(module):run(interface)]] `(args [, stdin] [, want_stdout] [, want_stderr] [, callback] [, payload])`

### Arguments

Expand All @@ -35,6 +36,10 @@ Optional arguments enable the collection of standard output and error streams, a

`want_stderr` (optional): Shall be a logical flag. If `.true.`, the standard error output of the process will be captured. Default: `.false.`. This is an `intent(in)` argument.

`callback` (optional): Shall be a procedure conforming to the `process_callback` interface. If present, this function will be called upon process completion with the process ID, exit state, and optionally collected standard input, output, and error streams. This is an `intent(in)` argument.

`payload` (optional): Shall be a generic (`class(*)`) scalar that will be passed to the callback function upon process completion. It allows users to associate custom data with the process execution. This is an `intent(inout), target` argument.

### Return Value

Returns an object of type `process_type` that contains information about the state of the created process.
Expand All @@ -49,7 +54,6 @@ type(process_type) :: p
p = run("echo 'Hello, world!'", want_stdout=.true.)
```


## `runasync` - Execute an external process asynchronously

### Status
Expand All @@ -61,10 +65,11 @@ Experimental
The `runasync` interface allows execution of external processes using a single command string or a list of arguments.
Processes are run asynchronously (non-blocking), meaning execution does not wait for the process to finish.
Optional arguments enable the collection of standard output and error streams, as well as sending input via standard input.
Additionally, a callback function can be specified to execute upon process completion, optionally receiving a user-defined payload.

### Syntax

`process = ` [[stdlib_subprocess(module):runasync(interface)]] `(args [, stdin] [, want_stdout] [, want_stderr])`
`process = ` [[stdlib_subprocess(module):runasync(interface)]] `(args [, stdin] [, want_stdout] [, want_stderr] [, callback] [, payload])`

### Arguments

Expand All @@ -76,6 +81,10 @@ Optional arguments enable the collection of standard output and error streams, a

`want_stderr` (optional): Shall be a logical flag. If `.true.`, the standard error output of the process will be captured. Default: `.false.`. This is an `intent(in)` argument.

`callback` (optional): Shall be a procedure conforming to the `process_callback` interface. If present, this function will be called upon process completion with the process ID, exit state, and optionally collected standard input, output, and error streams. This is an `intent(in)` argument.

`payload` (optional): Shall be a generic (`class(*)`) scalar that will be passed to the callback function upon process completion. It allows users to associate custom data with the process execution. This is an `intent(inout), target` argument.

### Return Value

Returns an object of type `process_type` that contains information about the state of the created process.
Expand Down
23 changes: 20 additions & 3 deletions src/stdlib_system.F90
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ module stdlib_system
!! version: experimental
!!
!! Executes an external process asynchronously.
!! ([Specification](../page/specs/stdlib_system.html#run-execute-an-external-process-asynchronously))
!! ([Specification](../page/specs/stdlib_system.html#runasync-execute-an-external-process-asynchronously))
!!
!! ### Summary
!! Provides methods for executing external processes asynchronously, using either a single command string
Expand All @@ -96,8 +96,10 @@ module stdlib_system
!! This interface allows the user to spawn external processes asynchronously (non-blocking).
!! Processes can be executed via a single command string or a list of arguments, with options to collect
!! standard output and error streams, or to provide a standard input stream via a `character` string.
!! Additionally, a callback function can be provided, which will be called upon process completion.
!! A user-defined payload can be attached and passed to the callback for handling process-specific data.
!!
!! @note The implementation depends on system-level process management capabilitiesa
!! @note The implementation depends on system-level process management capabilities.
!!
module function run_async_cmd(cmd, stdin, want_stdout, want_stderr, callback, payload) result(process)
!> The command line string to execute.
Expand Down Expand Up @@ -139,7 +141,7 @@ end function run_async_args
!! version: experimental
!!
!! Executes an external process synchronously.
!! ([Specification](../page/specs/stdlib_system.html#runasync-execute-an-external-process-synchronously))
!! ([Specification](../page/specs/stdlib_system.html#run-execute-an-external-process-synchronously))
!!
!! ### Summary
!! Provides methods for executing external processes synchronously, using either a single command string
Expand All @@ -150,6 +152,9 @@ end function run_async_args
!! This interface allows the user to spawn external processes synchronously (blocking),
!! via either a single command string or a list of arguments. It also includes options to collect
!! standard output and error streams, or to provide a standard input stream via a `character` string.
!! Additionally, it supports an optional callback function that is invoked upon process completion,
!! allowing users to process results dynamically. A user-defined payload can also be provided,
!! which is passed to the callback function to facilitate contextual processing.
!!
!! @note The implementation depends on system-level process management capabilities.
!!
Expand Down Expand Up @@ -367,6 +372,18 @@ end subroutine sleep
end interface sleep

abstract interface

!! version: experimental
!!
!! Process callback interface
!!
!! ### Summary
!!
!! The `process_callback` interface defines a user-provided subroutine that will be called
!! upon process completion. It provides access to process metadata, including the process ID,
!! exit state, and optional input/output streams. If passed on creation, a generic payload can be
!! accessed by the callback function. This variable must be a valid `target` in the calling scope.
!!
subroutine process_callback(pid,exit_state,stdin,stdout,stderr,payload)
import process_ID
implicit none
Expand Down

0 comments on commit 20c045d

Please sign in to comment.