Run risky tasks asynchronously or synchronously without endangering the calling process.
Jobbit is a thin, mildly opinionated wrapper for Elixir's Task and
Task.Supervisor modules and functionality.
Task and Task.Supervisor provide an easy-to-use, extensible, and
dependable interface for running one or many supervised or unsupervised
asynchronous tasks. If you want to "harness the power of OTP" you should
investigate those two modules and what can be achieved with their use.
Add jobbit to your list of dependencies in mix.exs:
def deps do
[
{:jobbit, "~> 0.5.0"},
]
endTasks in Jobbit can be run with a closure:
Jobbit.async(fn -> :ok end)
=> %Jobbit{}Or with a module, func, and args (similar to apply/3):
Jobbit.async_apply(Kernel, :div, [1, 0])
=> %Jobbit{}A task can be synchronized:
task = Jobbit.async(fn -> MyClient.send_request(payload) end)
=> %Jobbit{}
task
|> Jobbit.yield(2000) # yield with a custom timeout
|> case do
{:ok, %SomeResponse{}} -> :request_succeeded
{:error, :not_authorized} -> :request_returned_an_error
{:error, %TaskError{}} -> :request_crashed
{:error, %TimeoutError{}} -> :request_timeout
end-
Both are used to perform asynchronous tasks.
-
Both have
yield/2which waits for results for a certain amount of time (timeout), but does not raise upon timeout.
-
Both are used to perform asynchronous tasks.
-
Both can start caller-unlink, supervised tasks.
-
Both require a
Task.Supervisorto be running-
Note:
Jobbititself can be used as a child_spec callback module instead ofTask.Supervisor. -
Note:
Jobbitstarts its own task supervisor by default at application startup.
-
-
Jobbitnever links to the calling process. All the risk is move to the task process. -
Jobbitonly provides one function to (idiomatically) synchronize on a tasks result (viayield/2).Taskhas also hasyield/2which is similar, but also providesawait/2which will raise if the task times out;yeild/2will not raise. -
Jobbithomogenizes results of tasks. WithTaskyielding can return{:ok, :ok}.Jobbithomogenizes{:ok, :ok}into:ok. This way is much less boilerplate.
-
Jobbitprovides a default supervisor via its application tree. -
Jobbitis less generalized, but easier to out-of-the-box. -
Jobbithas fewer functions, and a more focused scope.JobbitONLY runs asynchronous, unlinked tasks.
With Jobbit, tasks are run on a Jobbit task supervisor and the
Jobbit.Application starts a default task supervisor (default:
Jobbit.DefaultTaskSupervisor) at application startup.
Jobbit implements child_spec/1 and can, therefore, be used as
a child's callback module for a supervisor
A supervisor can be added to a supervision tree using like so:
# in `MyApp.SomeSupervisor` or in `MyApp.Application`...
# Note: it's a good idea to `:name` your task supervisor
# (because you need to be able to address it)...
children = [
{Jobbit, name: MyApp.MyBusinessDomainTaskSupervisor}
]A custom Jobbit task supervisor can also be started directly via
Jobbit.start_link/1.
Jobbit.start_link(name: :some_task_sup)
=> {:ok, #PID<0.109.0>}
Or Jobbit.start_link/0:
Jobbit.start_link()
=> {:ok, #PID<0.110.0>}
Jobbit can be configured via config/*.exs files.
By default, the :jobbit OTP app will start a default
task supervisor called Jobbit.DefaultTaskSupervisor.
The default task supervisor can be configured via the :default_supervisor
config value.
Additionally, the entire :jobbit application can instructed not
to start by flagging :start_jobbit? with a falsey (nil or false)
value.
Note: Jobbit.async/1 and Jobbit.async_apply/3 rely on the default supervisor
to be running when they are called. If start_jobbit?: false is set in the config
and the :default_supervisor is not set to a running task supervisor these
functions will not work.
An example of configuring :jobbit:
config :jobbit,
start_jobbit?: true,
default_supervisor: Jobbit.DefaultTaskSupervisor,
default_supervisor_opts: []