Packages
FerricFlow durable workflows and queues with native-protocol storage, Raft durability, and Bitcask persistence.
Current section
Files
Jump to
Current section
Files
lib/ferricstore.ex
defmodule FerricStore do
@moduledoc """
Module-based cache instances for FerricStore.
Each module that calls `use FerricStore` gets a local direct cache instance
with its own shards, ETS tables, data directory, and config. The default
application instance owns the Raft system.
## Usage
defmodule MyApp.Cache do
use FerricStore,
data_dir: "/data/cache",
shard_count: 4,
max_memory: "1GB"
end
# In your supervision tree:
children = [MyApp.Cache]
# Then use it:
MyApp.Cache.set("key", "value")
{:ok, "value"} = MyApp.Cache.get("key")
## Multiple instances
defmodule MyApp.Sessions do
use FerricStore,
data_dir: "/data/sessions",
shard_count: 2
end
MyApp.Cache.set("page:home", html)
MyApp.Sessions.set("sess:abc", session_data)
## Options
* `:data_dir` — base directory for Bitcask data files (required)
* `:shard_count` — number of shards (default: 4)
* `:max_memory_bytes` — maximum memory budget (default: 1GB)
* `:keydir_max_ram` — maximum ETS keydir memory (default: 256MB)
* `:eviction_policy` — `:volatile_lfu` | `:allkeys_lfu` | `:noeviction` (default: `:volatile_lfu`)
* `:hot_cache_max_value_size` — max value size for ETS caching (default: 65536)
* `:read_sample_rate` — LFU sampling rate (default: 100)
* `:flow_retention_sweeper` — per-instance Flow timeout/retention sweeper
options such as `:initial_delay_ms`, `:interval_ms`, and `:limit`
"""
defmacro __using__(opts) do
quote do
use FerricStore.Macro, unquote(opts)
end
end
# ---------------------------------------------------------------------------
# Readiness
# ---------------------------------------------------------------------------
@doc """
Blocks until FerricStore is fully ready to serve requests.
Polls `Health.check/0` until all shards are alive and all Raft leaders
are elected. Returns `:ok` when ready, raises on timeout.
Call this in your application's `start/2` after FerricStore is in your
supervision tree, or in test setup, to ensure writes won't fail.
## Options
* `:timeout` - max milliseconds to wait (default: 30_000)
* `:interval` - polling interval in ms (default: 100)
## Examples
# In your Application.start/2:
def start(_type, _args) do
children = [
{FerricStore, []},
MyApp.Repo,
MyAppWeb.Endpoint
]
opts = [strategy: :one_for_one, name: MyApp.Supervisor]
{:ok, pid} = Supervisor.start_link(children, opts)
FerricStore.await_ready()
{:ok, pid}
end
# With custom timeout:
FerricStore.await_ready(timeout: 60_000)
"""
@spec await_ready(keyword()) :: :ok
def await_ready(opts \\ []) do
{timeout, interval} = validate_await_ready_options!(opts)
deadline = System.monotonic_time(:millisecond) + timeout
do_await_ready(deadline, interval)
end
defp validate_await_ready_options!(opts) when is_list(opts) do
case Keyword.validate(opts, timeout: 30_000, interval: 100) do
{:ok, validated} ->
timeout = Keyword.fetch!(validated, :timeout)
interval = Keyword.fetch!(validated, :interval)
if is_integer(timeout) and timeout >= 0 and is_integer(interval) and interval > 0 do
{timeout, interval}
else
raise ArgumentError,
"await_ready options require a non-negative integer timeout and positive integer interval"
end
{:error, invalid} ->
raise ArgumentError, "invalid await_ready options: #{inspect(invalid)}"
end
end
defp validate_await_ready_options!(_opts) do
raise ArgumentError, "await_ready options must be a keyword list"
end
defp do_await_ready(deadline, interval) do
case Ferricstore.Health.check() do
%{status: :ok} ->
:ok
_ ->
remaining = deadline - System.monotonic_time(:millisecond)
if remaining <= 0 do
raise "FerricStore not ready within timeout. Check shard health with FerricStore.health()"
end
Process.sleep(min(interval, remaining))
do_await_ready(deadline, interval)
end
end
@doc """
Returns the current health status without blocking.
## Examples
iex> FerricStore.health()
%{status: :ok, shard_count: 4, shards: [...], uptime_seconds: 120}
"""
@spec health() :: Ferricstore.Health.health_result()
def health do
Ferricstore.Health.check()
end
@doc """
Returns `true` if FerricStore is ready to serve requests.
## Examples
iex> FerricStore.ready?()
true
"""
@spec ready?() :: boolean()
def ready? do
Ferricstore.Health.ready?()
end
@doc """
Gracefully shuts down FerricStore, flushing all pending data to disk.
Flushes Raft batchers, BitcaskWriters, shard pending writes, and
triggers a WAL rollover. Call before stopping the application to
ensure zero data loss.
## Examples
FerricStore.shutdown()
Application.stop(:ferricstore)
"""
@spec shutdown() :: :ok
def shutdown do
Ferricstore.Application.prep_stop(nil)
:ok
end
# ---------------------------------------------------------------------------
# Types
# ---------------------------------------------------------------------------
@type key :: binary()
@type value :: binary()
@type write_error :: {:error, binary() | {:timeout, :unknown_outcome}}
@type set_opts :: [
ttl: non_neg_integer(),
exat: pos_integer(),
pxat: pos_integer(),
nx: boolean(),
xx: boolean(),
get: boolean(),
keepttl: boolean(),
cache: atom()
]
@type get_opts :: [cache: atom()]
@type cas_opts :: [ttl: non_neg_integer()]
@type fetch_or_compute_opts :: [ttl: pos_integer(), hint: binary()]
@type zrange_opts :: [withscores: boolean()]
# ---------------------------------------------------------------------------
# Strings
# ---------------------------------------------------------------------------
# ---------------------------------------------------------------------------
# Embedded FerricStore API
# ---------------------------------------------------------------------------
alias FerricStore.API.Bitmap, as: BitmapAPI
alias FerricStore.API.Generic, as: GenericAPI
alias FerricStore.API.Geo, as: GeoAPI
alias FerricStore.API.Hashes, as: HashesAPI
alias FerricStore.API.HyperLogLog, as: HyperLogLogAPI
alias FerricStore.API.Lists, as: ListsAPI
alias FerricStore.API.Locks, as: LocksAPI
alias FerricStore.API.Probabilistic, as: ProbabilisticAPI
alias FerricStore.API.Sets, as: SetsAPI
alias FerricStore.API.SortedSets, as: SortedSetsAPI
alias FerricStore.API.Streams, as: StreamsAPI
alias FerricStore.API.Strings, as: StringsAPI
alias FerricStore.API.System, as: SystemAPI
import FerricStore.API.PublicAccess, only: [defguardeddelegate: 2]
@spec set(key(), value(), set_opts()) :: :ok | {:ok, value() | nil} | nil | write_error()
defguardeddelegate(set(key, value, opts \\ []), to: StringsAPI, keys: [key])
defguardeddelegate(get(key, opts \\ []), to: StringsAPI, keys: [key])
defguardeddelegate(del(key), to: StringsAPI, keys: FerricStore.API.PublicAccess.keys(key))
defguardeddelegate(incr(key), to: StringsAPI, keys: [key])
defguardeddelegate(decr(key), to: StringsAPI, keys: [key])
defguardeddelegate(decr_by(key, amount), to: StringsAPI, keys: [key])
defguardeddelegate(incr_by(key, amount), to: StringsAPI, keys: [key])
defguardeddelegate(incr_by_float(key, amount), to: StringsAPI, keys: [key])
defguardeddelegate(mget(keys), to: StringsAPI, keys: keys)
defguardeddelegate(mset(pairs),
to: StringsAPI,
keys: FerricStore.API.PublicAccess.pair_keys(pairs)
)
defguardeddelegate(append(key, suffix), to: StringsAPI, keys: [key])
defguardeddelegate(strlen(key), to: StringsAPI, keys: [key])
defguardeddelegate(getset(key, value), to: StringsAPI, keys: [key])
defguardeddelegate(getdel(key), to: StringsAPI, keys: [key])
defguardeddelegate(getex(key, opts \\ []), to: StringsAPI, keys: [key])
defguardeddelegate(setnx(key, value), to: StringsAPI, keys: [key])
defguardeddelegate(setex(key, seconds, value), to: StringsAPI, keys: [key])
defguardeddelegate(psetex(key, milliseconds, value), to: StringsAPI, keys: [key])
defguardeddelegate(getrange(key, start, stop), to: StringsAPI, keys: [key])
defguardeddelegate(setrange(key, offset, value), to: StringsAPI, keys: [key])
defguardeddelegate(msetnx(pairs),
to: StringsAPI,
keys: FerricStore.API.PublicAccess.pair_keys(pairs)
)
defguardeddelegate(hset(key, fields), to: HashesAPI, keys: [key])
defguardeddelegate(hget(key, field), to: HashesAPI, keys: [key])
defguardeddelegate(hgetall(key), to: HashesAPI, keys: [key])
defguardeddelegate(hdel(key, fields), to: HashesAPI, keys: [key])
defguardeddelegate(hexists(key, field), to: HashesAPI, keys: [key])
defguardeddelegate(hlen(key), to: HashesAPI, keys: [key])
defguardeddelegate(hkeys(key), to: HashesAPI, keys: [key])
defguardeddelegate(hvals(key), to: HashesAPI, keys: [key])
defguardeddelegate(hmget(key, fields), to: HashesAPI, keys: [key])
defguardeddelegate(hincrby(key, field, amount), to: HashesAPI, keys: [key])
defguardeddelegate(hincrbyfloat(key, field, amount), to: HashesAPI, keys: [key])
defguardeddelegate(hsetnx(key, field, value), to: HashesAPI, keys: [key])
defguardeddelegate(hrandfield(key, count \\ nil), to: HashesAPI, keys: [key])
defguardeddelegate(hstrlen(key, field), to: HashesAPI, keys: [key])
defguardeddelegate(lpush(key, elements), to: ListsAPI, keys: [key])
defguardeddelegate(rpush(key, elements), to: ListsAPI, keys: [key])
defguardeddelegate(lpop(key, count \\ 1), to: ListsAPI, keys: [key])
defguardeddelegate(rpop(key, count \\ 1), to: ListsAPI, keys: [key])
defguardeddelegate(lrange(key, start, stop), to: ListsAPI, keys: [key])
defguardeddelegate(llen(key), to: ListsAPI, keys: [key])
defguardeddelegate(lindex(key, index), to: ListsAPI, keys: [key])
defguardeddelegate(lset(key, index, element), to: ListsAPI, keys: [key])
defguardeddelegate(lrem(key, count, element), to: ListsAPI, keys: [key])
defguardeddelegate(linsert(key, direction, pivot, element), to: ListsAPI, keys: [key])
defguardeddelegate(lmove(source, destination, from_dir, to_dir),
to: ListsAPI,
keys: [source, destination]
)
defguardeddelegate(lpos(key, element, opts \\ []), to: ListsAPI, keys: [key])
defguardeddelegate(sadd(key, members), to: SetsAPI, keys: [key])
defguardeddelegate(srem(key, members), to: SetsAPI, keys: [key])
defguardeddelegate(smembers(key), to: SetsAPI, keys: [key])
defguardeddelegate(sismember(key, member), to: SetsAPI, keys: [key])
defguardeddelegate(scard(key), to: SetsAPI, keys: [key])
defguardeddelegate(smismember(key, members), to: SetsAPI, keys: [key])
defguardeddelegate(srandmember(key, count \\ nil), to: SetsAPI, keys: [key])
defguardeddelegate(spop(key, count \\ nil), to: SetsAPI, keys: [key])
defguardeddelegate(sdiff(keys), to: SetsAPI, keys: keys)
defguardeddelegate(sinter(keys), to: SetsAPI, keys: keys)
defguardeddelegate(sunion(keys), to: SetsAPI, keys: keys)
defguardeddelegate(sdiffstore(destination, keys),
to: SetsAPI,
keys: FerricStore.API.PublicAccess.destination_keys(destination, keys)
)
defguardeddelegate(sinterstore(destination, keys),
to: SetsAPI,
keys: FerricStore.API.PublicAccess.destination_keys(destination, keys)
)
defguardeddelegate(sunionstore(destination, keys),
to: SetsAPI,
keys: FerricStore.API.PublicAccess.destination_keys(destination, keys)
)
defguardeddelegate(sintercard(keys, opts \\ []), to: SetsAPI, keys: keys)
defguardeddelegate(zadd(key, score_member_pairs), to: SortedSetsAPI, keys: [key])
defguardeddelegate(zrange(key, start, stop, opts \\ []), to: SortedSetsAPI, keys: [key])
defguardeddelegate(zscore(key, member), to: SortedSetsAPI, keys: [key])
defguardeddelegate(zcard(key), to: SortedSetsAPI, keys: [key])
defguardeddelegate(zrem(key, members), to: SortedSetsAPI, keys: [key])
defguardeddelegate(zrank(key, member), to: SortedSetsAPI, keys: [key])
defguardeddelegate(zrevrank(key, member), to: SortedSetsAPI, keys: [key])
defguardeddelegate(zrangebyscore(key, min, max, opts \\ []),
to: SortedSetsAPI,
keys: [key]
)
defguardeddelegate(zcount(key, min, max), to: SortedSetsAPI, keys: [key])
defguardeddelegate(zincrby(key, increment, member), to: SortedSetsAPI, keys: [key])
defguardeddelegate(zrandmember(key, count \\ nil), to: SortedSetsAPI, keys: [key])
defguardeddelegate(zpopmin(key, count \\ 1), to: SortedSetsAPI, keys: [key])
defguardeddelegate(zpopmax(key, count \\ 1), to: SortedSetsAPI, keys: [key])
defguardeddelegate(zmscore(key, members), to: SortedSetsAPI, keys: [key])
defguardeddelegate(cas(key, expected, new_value, opts \\ []), to: GenericAPI, keys: [key])
defguardeddelegate(fetch_or_compute(key, opts), to: GenericAPI, keys: [key])
defguardeddelegate(fetch_or_compute_result(key, value, opts),
to: GenericAPI,
keys: [key]
)
defguardeddelegate(fetch_or_compute_error(key, message, opts),
to: GenericAPI,
keys: [key]
)
defguardeddelegate(exists(key), to: GenericAPI, keys: [key])
defdelegate keys(pattern \\ "*"), to: GenericAPI
defdelegate dbsize(), to: GenericAPI
defdelegate flushdb(), to: GenericAPI
defguardeddelegate(expire(key, ttl_ms), to: GenericAPI, keys: [key])
defguardeddelegate(ttl(key), to: GenericAPI, keys: [key])
defguardeddelegate(copy(source, destination, opts \\ []),
to: GenericAPI,
keys: [source, destination]
)
defguardeddelegate(rename(source, destination),
to: GenericAPI,
keys: [source, destination]
)
defguardeddelegate(renamenx(source, destination),
to: GenericAPI,
keys: [source, destination]
)
defguardeddelegate(type(key), to: GenericAPI, keys: [key])
defdelegate randomkey(), to: GenericAPI
defguardeddelegate(persist(key), to: GenericAPI, keys: [key])
defguardeddelegate(pexpire(key, ttl_ms), to: GenericAPI, keys: [key])
defguardeddelegate(expireat(key, unix_ts_seconds), to: GenericAPI, keys: [key])
defguardeddelegate(pexpireat(key, unix_ts_ms), to: GenericAPI, keys: [key])
defguardeddelegate(expiretime(key), to: GenericAPI, keys: [key])
defguardeddelegate(pexpiretime(key), to: GenericAPI, keys: [key])
defguardeddelegate(pttl(key), to: GenericAPI, keys: [key])
defguardeddelegate(setbit(key, offset, bit_value), to: BitmapAPI, keys: [key])
defguardeddelegate(getbit(key, offset), to: BitmapAPI, keys: [key])
defguardeddelegate(bitcount(key, opts \\ []), to: BitmapAPI, keys: [key])
defguardeddelegate(bitop(op, dest_key, source_keys),
to: BitmapAPI,
keys: FerricStore.API.PublicAccess.destination_keys(dest_key, source_keys)
)
defguardeddelegate(bitpos(key, bit_value, opts \\ []), to: BitmapAPI, keys: [key])
defguardeddelegate(xadd(key, fields), to: StreamsAPI, keys: [key])
defguardeddelegate(xlen(key), to: StreamsAPI, keys: [key])
defguardeddelegate(xrange(key, start, stop, opts \\ []), to: StreamsAPI, keys: [key])
defguardeddelegate(xrevrange(key, stop, start, opts \\ []), to: StreamsAPI, keys: [key])
defguardeddelegate(xtrim(key, opts), to: StreamsAPI, keys: [key])
defguardeddelegate(bf_reserve(key, error_rate, capacity), to: ProbabilisticAPI, keys: [key])
defguardeddelegate(bf_add(key, element), to: ProbabilisticAPI, keys: [key])
defguardeddelegate(bf_madd(key, elements), to: ProbabilisticAPI, keys: [key])
defguardeddelegate(bf_exists(key, element), to: ProbabilisticAPI, keys: [key])
defguardeddelegate(bf_mexists(key, elements), to: ProbabilisticAPI, keys: [key])
defguardeddelegate(bf_card(key), to: ProbabilisticAPI, keys: [key])
defguardeddelegate(bf_info(key), to: ProbabilisticAPI, keys: [key])
defguardeddelegate(cf_reserve(key, capacity), to: ProbabilisticAPI, keys: [key])
defguardeddelegate(cf_add(key, element), to: ProbabilisticAPI, keys: [key])
defguardeddelegate(cf_addnx(key, element), to: ProbabilisticAPI, keys: [key])
defguardeddelegate(cf_del(key, element), to: ProbabilisticAPI, keys: [key])
defguardeddelegate(cf_exists(key, element), to: ProbabilisticAPI, keys: [key])
defguardeddelegate(cf_mexists(key, elements), to: ProbabilisticAPI, keys: [key])
defguardeddelegate(cf_count(key, element), to: ProbabilisticAPI, keys: [key])
defguardeddelegate(cf_info(key), to: ProbabilisticAPI, keys: [key])
defguardeddelegate(cms_initbydim(key, width, depth), to: ProbabilisticAPI, keys: [key])
defguardeddelegate(cms_initbyprob(key, error, probability),
to: ProbabilisticAPI,
keys: [key]
)
defguardeddelegate(cms_incrby(key, pairs), to: ProbabilisticAPI, keys: [key])
defguardeddelegate(cms_query(key, elements), to: ProbabilisticAPI, keys: [key])
defguardeddelegate(cms_info(key), to: ProbabilisticAPI, keys: [key])
defguardeddelegate(topk_reserve(key, k), to: ProbabilisticAPI, keys: [key])
defguardeddelegate(topk_add(key, elements), to: ProbabilisticAPI, keys: [key])
defguardeddelegate(topk_query(key, elements), to: ProbabilisticAPI, keys: [key])
defguardeddelegate(topk_list(key), to: ProbabilisticAPI, keys: [key])
defguardeddelegate(topk_info(key), to: ProbabilisticAPI, keys: [key])
defguardeddelegate(tdigest_create(key), to: ProbabilisticAPI, keys: [key])
defguardeddelegate(tdigest_add(key, values), to: ProbabilisticAPI, keys: [key])
defguardeddelegate(tdigest_quantile(key, quantiles), to: ProbabilisticAPI, keys: [key])
defguardeddelegate(tdigest_cdf(key, values), to: ProbabilisticAPI, keys: [key])
defguardeddelegate(tdigest_min(key), to: ProbabilisticAPI, keys: [key])
defguardeddelegate(tdigest_max(key), to: ProbabilisticAPI, keys: [key])
defguardeddelegate(tdigest_info(key), to: ProbabilisticAPI, keys: [key])
defguardeddelegate(tdigest_reset(key), to: ProbabilisticAPI, keys: [key])
defguardeddelegate(tdigest_trimmed_mean(key, lo, hi),
to: ProbabilisticAPI,
keys: [key]
)
defguardeddelegate(tdigest_rank(key, values), to: ProbabilisticAPI, keys: [key])
defguardeddelegate(tdigest_revrank(key, values), to: ProbabilisticAPI, keys: [key])
defguardeddelegate(tdigest_byrank(key, ranks), to: ProbabilisticAPI, keys: [key])
defguardeddelegate(tdigest_byrevrank(key, ranks), to: ProbabilisticAPI, keys: [key])
defguardeddelegate(geoadd(key, members), to: GeoAPI, keys: [key])
defguardeddelegate(geodist(key, member1, member2, unit \\ "m"), to: GeoAPI, keys: [key])
defguardeddelegate(geohash(key, members), to: GeoAPI, keys: [key])
defguardeddelegate(geopos(key, members), to: GeoAPI, keys: [key])
defguardeddelegate(lock(key, owner, ttl_ms), to: LocksAPI, keys: [key])
defguardeddelegate(unlock(key, owner), to: LocksAPI, keys: [key])
defguardeddelegate(extend(key, owner, ttl_ms), to: LocksAPI, keys: [key])
defguardeddelegate(ratelimit_add(key, window_ms, max, count \\ 1), to: LocksAPI, keys: [key])
defguardeddelegate(pfadd(key, elements), to: HyperLogLogAPI, keys: [key])
defguardeddelegate(pfcount(keys), to: HyperLogLogAPI, keys: keys)
defguardeddelegate(pfmerge(dest_key, source_keys),
to: HyperLogLogAPI,
keys: FerricStore.API.PublicAccess.destination_keys(dest_key, source_keys)
)
defdelegate multi(fun), to: SystemAPI
defdelegate ping(), to: SystemAPI
defdelegate echo(message), to: SystemAPI
@spec flushall() :: :ok | {:error, term()}
defdelegate flushall(), to: SystemAPI
defdelegate pipeline(fun), to: SystemAPI
defguardeddelegate(batch_get(keys), to: SystemAPI, keys: keys)
defdelegate packed_batch_get(packed_keys), to: SystemAPI
@spec batch_set([{binary(), binary()}]) :: [:ok | write_error()] | write_error()
defguardeddelegate(batch_set(kv_pairs),
to: SystemAPI,
keys: FerricStore.API.PublicAccess.pair_keys(kv_pairs)
)
# ---------------------------------------------------------------------------
# Flow API
# ---------------------------------------------------------------------------
alias FerricStore.API.Flow, as: FlowAPI
defdelegate flow_create(id, opts), to: FlowAPI
defdelegate flow_value_put(value, opts \\ []), to: FlowAPI
defdelegate flow_value_mget(refs, opts \\ []), to: FlowAPI
defdelegate flow_signal(id, opts), to: FlowAPI
defdelegate flow_create_many(partition_key, items, opts \\ []), to: FlowAPI
defdelegate flow_spawn_children(parent_id, children, opts \\ []), to: FlowAPI
defdelegate flow_get(id, opts \\ []), to: FlowAPI
defdelegate flow_query(query, params \\ %{}), to: FlowAPI
defdelegate flow_policy_set(type, opts), to: FlowAPI
defdelegate flow_policy_get(type, opts \\ []), to: FlowAPI
defdelegate flow_claim_due(type, opts), to: FlowAPI
defdelegate flow_reclaim(type, opts), to: FlowAPI
defdelegate flow_extend_lease(id, lease_token, opts \\ []), to: FlowAPI
defdelegate flow_complete(id, lease_token, opts \\ []), to: FlowAPI
defdelegate flow_complete_many(partition_key, items, opts \\ []), to: FlowAPI
defdelegate flow_run_steps_many(items, opts \\ []), to: FlowAPI
defdelegate flow_transition(id, from_state, to_state, opts \\ []), to: FlowAPI
defdelegate flow_schedule_create(id, opts), to: FlowAPI
defdelegate flow_schedule_get(id, opts \\ []), to: FlowAPI
defdelegate flow_schedule_fire(id, opts \\ []), to: FlowAPI
defdelegate flow_schedule_pause(id, opts \\ []), to: FlowAPI
defdelegate flow_schedule_resume(id, opts \\ []), to: FlowAPI
defdelegate flow_schedule_list(opts \\ []), to: FlowAPI
defdelegate flow_schedule_delete(id, opts \\ []), to: FlowAPI
defdelegate flow_schedule_fire_due(opts \\ []), to: FlowAPI
defdelegate flow_start_and_claim(id, type, initial_state, opts \\ []), to: FlowAPI
defdelegate flow_step_continue(id, lease_token, from_state, to_state, opts \\ []), to: FlowAPI
defdelegate flow_transition_many(partition_key, from_state, to_state, items, opts \\ []),
to: FlowAPI
defdelegate flow_retry(id, lease_token, opts), to: FlowAPI
defdelegate flow_retry_many(partition_key, items, opts \\ []), to: FlowAPI
defdelegate flow_fail(id, lease_token, opts \\ []), to: FlowAPI
defdelegate flow_fail_many(partition_key, items, opts \\ []), to: FlowAPI
defdelegate flow_cancel(id, opts \\ []), to: FlowAPI
defdelegate flow_cancel_many(partition_key, items, opts \\ []), to: FlowAPI
defdelegate flow_retention_cleanup(opts \\ []), to: FlowAPI
defdelegate flow_rewind(id, opts), to: FlowAPI
defdelegate flow_list(type, opts \\ []), to: FlowAPI
defdelegate flow_search(opts \\ []), to: FlowAPI
defdelegate flow_attributes(type, opts \\ []), to: FlowAPI
defdelegate flow_attribute_values(type, attr_name, opts \\ []), to: FlowAPI
defdelegate flow_effect_reserve(id, effect_key, effect_type, opts \\ []), to: FlowAPI
defdelegate flow_effect_confirm(id, effect_key, opts \\ []), to: FlowAPI
defdelegate flow_effect_fail(id, effect_key, opts \\ []), to: FlowAPI
defdelegate flow_effect_compensate(id, effect_key, opts \\ []), to: FlowAPI
defdelegate flow_effect_get(id, effect_key, opts \\ []), to: FlowAPI
defdelegate flow_governance_ledger(id, opts \\ []), to: FlowAPI
defdelegate flow_approval_request(id, opts \\ []), to: FlowAPI
defdelegate flow_approval_approve(id, opts \\ []), to: FlowAPI
defdelegate flow_approval_reject(id, opts \\ []), to: FlowAPI
defdelegate flow_approval_get(id, opts \\ []), to: FlowAPI
defdelegate flow_approval_list(opts \\ []), to: FlowAPI
defdelegate flow_governance_overview(opts \\ []), to: FlowAPI
defdelegate flow_circuit_open(scope, opts \\ []), to: FlowAPI
defdelegate flow_circuit_close(scope, opts \\ []), to: FlowAPI
defdelegate flow_circuit_get(scope, opts \\ []), to: FlowAPI
defdelegate flow_circuit_list(opts \\ []), to: FlowAPI
defdelegate flow_budget_reserve(scope, amount, opts \\ []), to: FlowAPI
defdelegate flow_budget_commit(scope, reservation_id, actual_amount, opts \\ []), to: FlowAPI
defdelegate flow_budget_release(scope, reservation_id, opts \\ []), to: FlowAPI
defdelegate flow_budget_get(scope, opts \\ []), to: FlowAPI
defdelegate flow_budget_list(opts \\ []), to: FlowAPI
defdelegate flow_limit_lease(scope, opts \\ []), to: FlowAPI
defdelegate flow_limit_spend(scope, opts \\ []), to: FlowAPI
defdelegate flow_limit_release(scope, opts \\ []), to: FlowAPI
defdelegate flow_limit_get(scope, opts \\ []), to: FlowAPI
defdelegate flow_limit_list(opts \\ []), to: FlowAPI
defdelegate flow_stats(type, opts \\ []), to: FlowAPI
defdelegate flow_terminals(type, opts \\ []), to: FlowAPI
defdelegate flow_failures(type, opts \\ []), to: FlowAPI
defdelegate flow_by_parent(parent_flow_id, opts \\ []), to: FlowAPI
defdelegate flow_by_root(root_flow_id, opts \\ []), to: FlowAPI
defdelegate flow_by_correlation(correlation_id, opts \\ []), to: FlowAPI
defdelegate flow_info(type, opts \\ []), to: FlowAPI
defdelegate flow_stuck(type, opts \\ []), to: FlowAPI
defdelegate flow_history(id, opts \\ []), to: FlowAPI
end