pub struct Job { /* private fields */ }Expand description
A handle to a job task spawned in the supervisor.
A job is a task which manages a Command. It is responsible for spawning the command’s
program, for handling messages which control it, for managing the program’s lifetime, and for
collecting its exit status and some timing information.
Most of the methods here queue Controls to the job task and return Tickets. Controls
execute in order, except where noted. Tickets are futures which resolve when the corresponding
control has been run. Unlike most futures, tickets don’t need to be polled for controls to make
progress; the future is only used to signal completion. Dropping a ticket will not drop the
control, so it’s safe to do so if you don’t care about when the control completes.
Note that controls are not guaranteed to run, like if the job task stops or panics before a control is processed. If a job task stops gracefully, all pending tickets will resolve immediately. If a job task panics (outside of hooks, panics are bugs!), pending tickets will never resolve.
This struct is cloneable (internally it is made of Arcs). Dropping the last instance of a Job
will close the job’s control queue, which will cause the job task to stop gracefully. Note that
a task graceful stop is not the same as a graceful stop of the contained command; when the job
drops, the command will be dropped in turn, and forcefully terminated via kill_on_drop.
Implementations§
Source§impl Job
impl Job
Sourcepub fn control(&self, control: Control) -> Ticket ⓘ
pub fn control(&self, control: Control) -> Ticket ⓘ
Send a control message to the command.
All control messages are queued in the order they’re sent and processed in order.
In general prefer using the other methods on this struct rather than sending Controls
directly.
Sourcepub fn stop(&self) -> Ticket ⓘ
pub fn stop(&self) -> Ticket ⓘ
Stop the command if it’s running and wait for completion.
If you don’t want to wait for completion, use signal(Signal::ForceStop) instead.
Sourcepub fn stop_with_signal(&self, signal: Signal, grace: Duration) -> Ticket ⓘ
pub fn stop_with_signal(&self, signal: Signal, grace: Duration) -> Ticket ⓘ
Gracefully stop the command if it’s running.
The command will be sent signal and then given grace time before being forcefully
terminated. If grace is zero, that still happens, but the command is terminated forcefully
on the next “tick” of the supervisor loop, which doesn’t leave the process a lot of time to
do anything.
Sourcepub fn restart(&self) -> Ticket ⓘ
pub fn restart(&self) -> Ticket ⓘ
Restart the command if it’s running, or start it if it’s not.
Sourcepub fn restart_with_signal(&self, signal: Signal, grace: Duration) -> Ticket ⓘ
pub fn restart_with_signal(&self, signal: Signal, grace: Duration) -> Ticket ⓘ
Gracefully restart the command if it’s running, or start it if it’s not.
The command will be sent signal and then given grace time before being forcefully
terminated. If grace is zero, that still happens, but the command is terminated forcefully
on the next “tick” of the supervisor loop, which doesn’t leave the process a lot of time to
do anything.
Sourcepub fn try_restart(&self) -> Ticket ⓘ
pub fn try_restart(&self) -> Ticket ⓘ
Restart the command if it’s running, but don’t start it if it’s not.
Sourcepub fn try_restart_with_signal(&self, signal: Signal, grace: Duration) -> Ticket ⓘ
pub fn try_restart_with_signal(&self, signal: Signal, grace: Duration) -> Ticket ⓘ
Restart the command if it’s running, but don’t start it if it’s not.
The command will be sent signal and then given grace time before being forcefully
terminated. If grace is zero, that still happens, but the command is terminated forcefully
on the next “tick” of the supervisor loop, which doesn’t leave the process a lot of time to
do anything.
Sourcepub fn signal(&self, sig: Signal) -> Ticket ⓘ
pub fn signal(&self, sig: Signal) -> Ticket ⓘ
Send a signal to the command.
Sends a signal to the current program, if there is one. If there isn’t, this is a no-op.
On Windows, this is a no-op for all signals but Signal::ForceStop, which tries to stop
the command like a stop() would, but doesn’t wait for completion. This is because Windows
doesn’t have signals; in future Hangup, Interrupt,
and Terminate may be implemented using GenerateConsoleCtrlEvent,
see tracking issue #219.
Sourcepub fn delete(&self) -> Ticket ⓘ
pub fn delete(&self) -> Ticket ⓘ
Stop the command, then mark it for garbage collection.
The underlying control messages are sent like normal, so they wait for all pending controls
to process. If you want to delete the command immediately, use delete_now().
Sourcepub fn delete_now(&self) -> Ticket ⓘ
pub fn delete_now(&self) -> Ticket ⓘ
Stop the command immediately, then mark it for garbage collection.
The underlying control messages are sent with higher priority than normal, so they bypass
all others. If you want to delete after all current controls are processed, use delete().
Sourcepub fn to_wait(&self) -> Ticket ⓘ
pub fn to_wait(&self) -> Ticket ⓘ
Get a future which resolves when the command ends.
If the command is not running, the future resolves immediately.
The underlying control message is sent with higher priority than normal, so it targets the actively running command, not the one that will be running after the rest of the controls get done; note that may still be racy if the command ends between the time the message is sent and the time it’s processed.
Sourcepub fn run(
&self,
fun: impl FnOnce(&JobTaskContext<'_>) + Send + Sync + 'static,
) -> Ticket ⓘ
pub fn run( &self, fun: impl FnOnce(&JobTaskContext<'_>) + Send + Sync + 'static, ) -> Ticket ⓘ
Run an arbitrary function.
The function is given &JobTaskContext, which contains the state of the
currently executing, next-to-start, or just-finished command, as well as the final state of
the previous run of the command.
Technically, some operations can be done through a &self shared borrow on the running
command’s [TokioChildWrapper], but this library recommends against taking advantage of this,
and prefer using the methods on here instead, so that the supervisor can keep track of
what’s going on.
Sourcepub fn run_async(
&self,
fun: impl FnOnce(&JobTaskContext<'_>) -> Box<dyn Future<Output = ()> + Send + Sync> + Send + Sync + 'static,
) -> Ticket ⓘ
pub fn run_async( &self, fun: impl FnOnce(&JobTaskContext<'_>) -> Box<dyn Future<Output = ()> + Send + Sync> + Send + Sync + 'static, ) -> Ticket ⓘ
Run an arbitrary function and await the returned future.
The function is given &JobTaskContext, which contains the state of the
currently executing, next-to-start, or just-finished command, as well as the final state of
the previous run of the command.
Technically, some operations can be done through a &self shared borrow on the running
command’s [TokioChildWrapper], but this library recommends against taking advantage of this,
and prefer using the methods on here instead, so that the supervisor can keep track of
what’s going on.
A gotcha when using this method is that the future returned by the function can live longer
than the &JobTaskContext it was given, so you can’t bring the context into the async block
and instead must clone or copy the parts you need beforehand, in the sync portion.
For example, this won’t compile:
let (channel, receiver) = mpsc::channel(10);
job.run_async(|context| Box::new(async move {
if let CommandState::Finished { status, .. } = context.current {
channel.send(status).await.ok();
}
}));But this does:
let (channel, receiver) = mpsc::channel(10);
job.run_async(|context| {
let status = if let CommandState::Finished { status, .. } = context.current {
Some(*status)
} else {
None
};
Box::new(async move {
if let Some(status) = status {
channel.send(status).await.ok();
}
})
});Sourcepub fn set_spawn_hook(
&self,
fun: impl Fn(&mut TokioCommandWrap, &JobTaskContext<'_>) + Send + Sync + 'static,
) -> Ticket ⓘ
pub fn set_spawn_hook( &self, fun: impl Fn(&mut TokioCommandWrap, &JobTaskContext<'_>) + Send + Sync + 'static, ) -> Ticket ⓘ
Set the spawn hook.
The hook will be called once per process spawned, before the process is spawned. It’s given
a mutable reference to the process_wrap::tokio::TokioCommandWrap and some context; it
can modify or further wrap the command as it sees fit.
Sourcepub fn set_spawn_async_hook(
&self,
fun: impl Fn(&mut TokioCommandWrap, &JobTaskContext<'_>) -> Box<dyn Future<Output = ()> + Send + Sync> + Send + Sync + 'static,
) -> Ticket ⓘ
pub fn set_spawn_async_hook( &self, fun: impl Fn(&mut TokioCommandWrap, &JobTaskContext<'_>) -> Box<dyn Future<Output = ()> + Send + Sync> + Send + Sync + 'static, ) -> Ticket ⓘ
Set the spawn hook (async version).
The hook will be called once per process spawned, before the process is spawned. It’s given
a mutable reference to the process_wrap::tokio::TokioCommandWrap and some context; it
can modify or further wrap the command as it sees fit.
A gotcha when using this method is that the future returned by the function can live longer
than the references it was given, so you can’t bring the command or context into the async
block and instead must clone or copy the parts you need beforehand, in the sync portion. See
the documentation for run_async for an example.
Fortunately, async spawn hooks should be exceedingly rare: there’s very few things to do in spawn hooks that can’t be done in the simpler sync version.
Sourcepub fn unset_spawn_hook(&self) -> Ticket ⓘ
pub fn unset_spawn_hook(&self) -> Ticket ⓘ
Unset any spawn hook.
Sourcepub fn set_error_handler(
&self,
fun: impl Fn(SyncIoError) + Send + Sync + 'static,
) -> Ticket ⓘ
pub fn set_error_handler( &self, fun: impl Fn(SyncIoError) + Send + Sync + 'static, ) -> Ticket ⓘ
Set the error handler.
Sourcepub fn set_async_error_handler(
&self,
fun: impl Fn(SyncIoError) -> Box<dyn Future<Output = ()> + Send + Sync> + Send + Sync + 'static,
) -> Ticket ⓘ
pub fn set_async_error_handler( &self, fun: impl Fn(SyncIoError) -> Box<dyn Future<Output = ()> + Send + Sync> + Send + Sync + 'static, ) -> Ticket ⓘ
Set the error handler (async version).
Sourcepub fn unset_error_handler(&self) -> Ticket ⓘ
pub fn unset_error_handler(&self) -> Ticket ⓘ
Unset the error handler.
Errors will be silently ignored.