Files
elixirAI/lib/elixir_ai/audio/audio_processing.ex
Alex Mickelson 6fc4a686f8
Some checks failed
CI/CD Pipeline / build (push) Failing after 4s
can transcribe in the ui
2026-03-20 14:49:59 -06:00

48 lines
1.7 KiB
Elixir

defmodule ElixirAi.AudioProcessing do
@moduledoc """
Public API for the demand-driven audio transcription pool.
Dispatch strategy:
1. Pick a random idle worker from the :available pg group.
2. If none are idle and the pool is below @max_workers, spawn a fresh worker
under AudioWorkerSupervisor and route the job directly to it.
3. If already at @max_workers, queue the job to a random existing worker via
its Erlang mailbox — it will process it when its current job finishes.
Scale-up is fully automatic (on demand). Scale-down is handled by each worker's
idle-timeout logic; workers exit after idling and the pool can reach 0.
"""
@max_workers 10
@all_group :all
@available_group :available
@doc """
Submit audio for transcription. The result is delivered asynchronously to
`caller_pid` as:
{:transcription_result, {:ok, text} | {:error, reason}}
"""
def submit(audio_binary, mime_type, caller_pid) do
case :pg.get_members(ElixirAi.AudioProcessingPG, @available_group) do
[] ->
all = :pg.get_members(ElixirAi.AudioProcessingPG, @all_group)
if length(all) < @max_workers do
{:ok, pid} =
DynamicSupervisor.start_child(ElixirAi.AudioWorkerSupervisor, ElixirAi.AudioWorker)
GenServer.cast(pid, {:transcribe, caller_pid, audio_binary, mime_type})
else
# At max capacity — overflow to a random worker's mailbox
GenServer.cast(Enum.random(all), {:transcribe, caller_pid, audio_binary, mime_type})
end
available ->
GenServer.cast(Enum.random(available), {:transcribe, caller_pid, audio_binary, mime_type})
end
:ok
end
end