bath
Types
An error returned when failing to apply a function to a pooled resource.
pub type ApplyError {
NoResourcesAvailable
CheckOutResourceCreateError(error: String)
}
Constructors
-
NoResourcesAvailable
-
CheckOutResourceCreateError(error: String)
The strategy used to check out a resource from the pool.
pub type CheckoutStrategy {
FIFO
LIFO
}
Constructors
-
FIFO
-
LIFO
How to create resources in the pool. Lazy
will create resources when
required (i.e. the pool is empty but has extra capacity), while Eager
will
create the maximum number of resources upfront.
pub type CreationStrategy {
Lazy
Eager
}
Constructors
-
Lazy
-
Eager
The type used to indicate what to do with a resource after use.
pub opaque type Next(return)
An error returned when the resource pool fails to shut down.
pub type ShutdownError {
ResourcesInUse
}
Constructors
-
ResourcesInUse
There are still resources checked out. Ignore this failure case by calling
shutdown
function withforce
set toTrue
.
Values
pub fn apply(
pool pool: process.Subject(Msg(resource_type)),
timeout timeout: Int,
next next: fn(resource_type) -> Next(result_type),
) -> Result(result_type, ApplyError)
Check out a resource from the pool, apply the next
function, then check
the resource back in.
let assert Ok(pool) =
bath.new(fn() { Ok("Some pooled resource") })
|> bath.start(1000)
use resource <- bath.apply(pool, 1000)
// Do stuff with resource...
// Return the resource to the pool, returning "Hello!" to the caller.
bath.keep()
|> bath.returning("Hello!")
pub fn checkout_strategy(
builder builder: Builder(resource_type),
strategy checkout_strategy: CheckoutStrategy,
) -> Builder(resource_type)
Change the checkout strategy for the pool. Defaults to FIFO
.
pub fn creation_strategy(
builder builder: Builder(resource_type),
strategy creation_strategy: CreationStrategy,
) -> Builder(resource_type)
Change the resource creation strategy for the pool. Defaults to Lazy
.
pub fn discard() -> Next(Nil)
Instruct Bath to discard the checked out resource, running the shutdown function on it.
Discarded resources will be recreated lazily, regardless of the pool’s creation strategy.
pub fn keep() -> Next(Nil)
Instruct Bath to keep the checked out resource, returning it to the pool.
pub fn log_errors(
builder builder: Builder(resource_type),
log_errors log_errors: Bool,
) -> Builder(resource_type)
Set whether the pool logs errors when resources fail to create.
pub fn name(
builder builder: Builder(resource_type),
name name: process.Name(Msg(resource_type)),
) -> Builder(resource_type)
Set the name for the pool process. Defaults to None
.
You will need to provide a name if you plan on using the pool under a static supervisor.
pub fn new(
resource create_resource: fn() -> Result(resource_type, String),
) -> Builder(resource_type)
Create a new Builder
for creating a pool of resources.
import bath
import fake_db
pub fn main() {
// Create a pool of 10 connections to some fictional database.
let assert Ok(pool) =
bath.new(fn() { fake_db.connect() })
|> bath.with_size(10)
|> bath.start(1000)
}
Default values
Config | Default |
---|---|
name | option.None |
size | 10 |
shutdown_resource | fn(_resource) { Nil } |
checkout_strategy | FIFO |
creation_strategy | Lazy |
log_errors | False |
pub fn on_shutdown(
builder builder: Builder(resource_type),
shutdown shutdown_resource: fn(resource_type) -> Nil,
) -> Builder(resource_type)
Set a shutdown function to be run for each resource when the pool exits.
pub fn shutdown(
pool pool: process.Subject(Msg(resource_type)),
force force: Bool,
timeout timeout: Int,
) -> Result(Nil, ShutdownError)
Shut down the pool, calling the shutdown function on each
resource in the pool. Calling with force
set to True
will
force the shutdown, not calling the shutdown function on any
resources.
Will fail if there are still resources checked out, unless force
is
True
.
You only need to call this when using unsupervised pools. You should let your supervision tree handle the shutdown of supervised resource pools.
pub fn size(
builder builder: Builder(resource_type),
size size: Int,
) -> Builder(resource_type)
Set the pool size. Defaults to 10. Will be clamped to a minimum of 1.
pub fn start(
builder builder: Builder(resource_type),
timeout init_timeout: Int,
) -> Result(process.Subject(Msg(resource_type)), actor.StartError)
Start an unsupervised pool using the given Builder
and return a
Pool
. In most cases, you should use the supervised
function instead.
pub fn supervised(
builder builder: Builder(resource_type),
timeout init_timeout: Int,
) -> supervision.ChildSpecification(
process.Subject(Msg(resource_type)),
)
Return the ChildSpecification
for creating a supervised resource pool.
In order to use a supervised pool, your pool must be named, otherwise you will
not be able to send messages to your pool. See the name
function.
Example
import bath
import gleam/erlang/process
import gleam/otp/static_supervisor as supervisor
fn main() {
// Create a name to interact with the pool once it's started under the
// static supervisor.
let pool_name = process.new_name("bath_pool")
let assert Ok(_started) =
supervisor.new(supervisor.OneForOne)
|> supervisor.add(
bath.new(create_resource)
|> bath.name(pool_name)
|> bath.supervised(1000)
)
|> supervisor.start
let pool = process.named_subject(pool_name)
// Do more stuff...
}
pub fn supervised_map(
builder builder: Builder(resource_type),
using mapper: fn(process.Subject(Msg(resource_type))) -> a,
timeout init_timeout: Int,
) -> supervision.ChildSpecification(a)
Like supervised
, but allows you to pass a mapping function to
transform the pool return value to the receiver. This is mostly useful for library
authors who wish to use Bath to create a pool of resources.