Packages
fnord
0.9.39
0.9.40
0.9.39
0.9.38
0.9.37
0.9.36
0.9.35
0.9.34
0.9.33
0.9.32
0.9.31
0.9.30
0.9.29
0.9.28
0.9.27
0.9.26
0.9.25
0.9.24
0.9.23
0.9.22
0.9.21
0.9.20
0.9.19
0.9.18
0.9.17
0.9.16
0.9.15
0.9.14
0.9.13
0.9.12
0.9.11
0.9.10
0.9.9
0.9.8
0.9.7
0.9.6
0.9.5
0.9.4
0.9.3
0.9.2
0.9.1
0.9.0
0.8.99
0.8.98
0.8.97
0.8.96
0.8.95
0.8.94
0.8.93
0.8.92
0.8.91
0.8.90
0.8.89
0.8.88
0.8.87
0.8.86
0.8.85
0.8.84
0.8.83
0.8.82
0.8.81
0.8.80
0.8.79
0.8.78
0.8.77
0.8.76
0.8.75
0.8.74
0.8.73
0.8.72
0.8.71
0.8.70
0.8.69
0.8.68
0.8.67
0.8.66
0.8.65
0.8.64
0.8.63
0.8.62
0.8.61
0.8.60
0.8.59
0.8.58
0.8.57
0.8.56
0.8.55
0.8.54
0.8.53
0.8.52
0.8.51
0.8.50
0.8.49
0.8.48
0.8.47
0.8.46
0.8.45
0.8.44
0.8.43
0.8.42
0.8.41
0.8.40
0.8.39
0.8.38
0.8.37
0.8.36
0.8.35
0.8.34
0.8.33
0.8.32
0.8.31
0.8.30
0.8.29
0.8.27
0.8.26
0.8.25
0.8.24
0.8.23
0.8.22
0.8.21
0.8.20
0.8.19
0.8.18
0.8.17
0.8.16
0.8.15
0.8.14
0.8.13
0.8.12
0.8.11
0.8.1
0.8.0
0.7.24
0.7.23
0.7.22
0.7.21
0.7.20
0.7.19
0.7.18
0.7.17
0.7.16
0.7.15
0.7.14
0.7.13
0.7.12
0.7.11
0.7.10
0.7.9
0.7.8
0.7.7
0.7.6
0.7.5
0.7.3
0.7.2
0.7.1
0.7.0
0.6.9
0.6.8
0.6.7
0.6.6
0.6.5
0.6.4
0.6.3
0.6.1
0.6.0
0.5.9
0.5.8
0.5.7
0.5.6
0.5.5
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.44
0.4.43
0.4.42
0.4.41
0.4.40
0.4.39
0.4.38
0.4.37
0.4.36
0.4.35
0.4.34
0.4.33
0.4.32
0.4.30
0.4.29
0.4.28
0.4.27
0.4.26
0.4.25
0.4.24
0.4.23
0.4.22
0.4.21
0.4.20
0.4.19
0.4.18
0.4.17
0.4.16
0.4.15
0.4.14
0.4.13
0.4.12
0.4.11
0.4.10
0.4.9
0.4.8
0.4.7
0.4.6
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.0
0.2.0
0.1.0
AI code archaeology
Current section
Files
Jump to
Current section
Files
lib/services/bg_indexing_control.ex
defmodule Services.BgIndexingControl do
@moduledoc """
Session-local (per BEAM node) control plane for pausing background indexing
on a per-model basis.
## Why this exists
Background indexing is a convenience feature. When OpenAI starts returning
throttling responses (HTTP 429 with a recognized throttling code), we can
disable background indexing for the affected model(s) to reduce load.
This module is intentionally:
- **model-agnostic**: any model string encountered can be tracked
- **boolean-only**: models are either paused or not paused (no timers)
- **session-local**: state is stored in `Services.Globals` and seeded idempotently
## State
Stored in `Services.Globals` under the `:fnord` app:
- `:bg_indexer_paused_models` => `%{model => true}`
- `:bg_indexer_throttle_counts` => `%{model => consecutive_throttles}`
- `:bg_indexer_throttle_threshold` => integer (default: 3)
"""
@paused_key :bg_indexer_paused_models
@counts_key :bg_indexer_throttle_counts
@threshold_key :bg_indexer_throttle_threshold
@default_threshold 3
@spec ensure_init() :: :ok
def ensure_init do
ensure_default(@paused_key, %{})
ensure_default(@counts_key, %{})
ensure_default(@threshold_key, @default_threshold)
:ok
end
defp ensure_default(key, default) do
sentinel = :__bg_indexing_control_missing__
case Services.Globals.get_env(:fnord, key, sentinel) do
^sentinel -> Services.Globals.put_env(:fnord, key, default)
_ -> :ok
end
end
@spec paused?(binary | nil) :: boolean
def paused?(nil), do: false
def paused?(model) when is_binary(model) do
ensure_init()
paused = Services.Globals.get_env(:fnord, @paused_key, %{})
Map.get(paused, model, false) == true
end
@spec pause(binary | nil) :: :ok
def pause(nil), do: :ok
def pause(model) when is_binary(model) do
ensure_init()
paused = Services.Globals.get_env(:fnord, @paused_key, %{})
Services.Globals.put_env(:fnord, @paused_key, Map.put(paused, model, true))
:ok
end
@spec clear_pause(binary | nil) :: :ok
def clear_pause(nil), do: :ok
def clear_pause(model) when is_binary(model) do
ensure_init()
paused = Services.Globals.get_env(:fnord, @paused_key, %{})
Services.Globals.put_env(:fnord, @paused_key, Map.delete(paused, model))
:ok
end
@spec threshold() :: non_neg_integer
def threshold do
ensure_init()
case Services.Globals.get_env(:fnord, @threshold_key, @default_threshold) do
n when is_integer(n) and n >= 0 -> n
_ -> @default_threshold
end
end
@spec set_threshold(non_neg_integer) :: :ok
def set_threshold(n) when is_integer(n) and n >= 0 do
ensure_init()
Services.Globals.put_env(:fnord, @threshold_key, n)
:ok
end
@doc """
Increment the consecutive throttling count for the model.
If the count reaches the configured threshold, the model is paused.
Returns `:ok` and ignores `nil` models.
"""
@spec note_throttle(binary | nil) :: :ok
def note_throttle(nil), do: :ok
def note_throttle(model) when is_binary(model) do
ensure_init()
counts = Services.Globals.get_env(:fnord, @counts_key, %{})
new_count = Map.get(counts, model, 0) + 1
Services.Globals.put_env(:fnord, @counts_key, Map.put(counts, model, new_count))
if new_count >= threshold() do
pause(model)
end
:ok
end
@doc """
Reset the consecutive throttling count for the model back to 0.
Returns `:ok` and ignores `nil` models.
"""
@spec note_success(binary | nil) :: :ok
def note_success(nil), do: :ok
def note_success(model) when is_binary(model) do
ensure_init()
counts = Services.Globals.get_env(:fnord, @counts_key, %{})
Services.Globals.put_env(:fnord, @counts_key, Map.put(counts, model, 0))
:ok
end
end