Logo Aurabase
aurabazadokumenty
dokumenty›Edge Functions›Jobs, cron and the DLQ

Jobs, cron i kolejka niedostarczonych wiadomości

Jak uruchomić pracę poza żądaniem: czym jest zadanie, w jaki sposób jest ponawiane, jak cron tworzy zadania i co zrobić z zadaniami, które kończą się martwymi.

9 min przeczytane·Poziom mediator·Zmieniono 12 paź 2026
Ten tekst w języku angielskim został wygenerowany automatycznie na podstawie francuskiego oryginału i nie był jeszcze recenzowany.
Ta strona została przetłumaczona automatycznie. Wersja angielska jest miarodajna.
#
Kolejkuj

1. Umieść zadanie w kolejce

Zadanie to jedno wywołanie funkcji w tle. Kolejkuj go z serwera za pomocą klucza service_role.

server/enqueue.tstypescript
import { createClient } from '@aurabase/aurabase-js'

const admin = createClient(process.env.AURA_URL!, process.env.AURA_SERVICE_ROLE_KEY!)

const { data: job, error } = await admin.functions.enqueueJob('send-report', {
  payload: { month: '2026-10' },
  delaySecs: 60,   // odczekaj 60 sekund przed pierwszą próbą
  maxAttempts: 3,  // domyślny
})
OpcjaDomyślnyOznaczający
payloadnullJSON podany do funkcji jako treść żądania
delaySecs0Sekundy oczekiwania przed pierwszą próbą. Do tego czasu stanowisko pozostaje pending.
maxAttempts3Łączna liczba prób, łącznie z pierwszą

Odczytujesz zadanie za pomocą getJob(id) lub listJobs({ status, limit }) (limit mieści się w przedziale od 1 do 500, domyślnie 50). Zadanie ma status, attempts, max_attempts, error i daty scheduled_at, started_at, completed_at.

Zadania są narzędziem po stronie serwera

enqueueJob, getJob i listJobs potrzebują klucza service_role. Klucz publiczny otrzymuje 403.

#
Treser

2. Co otrzymuje Twoja funkcja

Zadanie wywołuje Twoją funkcję jak każde inne żądanie, z trzema różnicami, z którymi musisz się uporać:

CzęśćWartość
MetodaJOB (nie POST)
Ścieżka/jobs/<job id>
CiałoZadanie ma postać payload w formacie JSON
Nagłówki tożsamościBrak: x-aura-role i x-aura-user-id są nieobecne
aurabase/functions/send-report/index.tstypescript
Deno.serve(async (req) => {
  const jobId = new URL(req.url).pathname.split('/').pop()
  const { month } = await req.json()
  // … zbuduj i wyślij raport, używając JobId jako klucza idempotencji
  return new Response('ok')
})

Prawdziwe połączenie zostało zarejestrowane {"method":"JOB","path":"/jobs/d443d541-…","role":null,"userId":null,"body":"{\"items\":[\"a\",\"b\"],\"order\":42}"}.

Zadanie działa bez użytkownika: nie polegaj na x-aura-user-id. Jeśli utwór należy do użytkownika, umieść identyfikator użytkownika w ładunku.

#
Ponowne próby

3. Cykl życia i ponowne próby

statusestext
pending ──claimed──▶ running ──▶ completed
   ▲                    │
   └── after 5 s ◀── failed (attempts left)
                        └──▶ dead (no attempts left)
  • Zadanie jest uruchamiane przynajmniej raz. Może zostać uruchomiona dwukrotnie, jeśli proces roboczy zatrzyma się podczas jej działania, dlatego należy uczynić tę funkcję idempotentną.
  • Nieudana próba jest ponawiana po ustalonym opóźnieniu wynoszącym 5 sekund, aż do osiągnięcia maxAttempts. Zadaniem jest zatem dead. Opóźnienie i domyślna liczba prób to ustawienia usługi (JOB_RETRY_DELAY_SECS, JOB_MAX_RETRIES).
  • Zadanie, które po dzierżawie (domyślnie 450 sekund) nadal ma status running, jest odzyskiwane przez usługę.
  • Gotowe zadania są domyślnie przechowywane przez 14 dni.
Błąd HTTP z Twojej funkcji nie jest awarią

Zadanie jest completed, gdy tylko funkcja odpowie, niezależnie od kodu stanu. W prawdziwym działaniu funkcja, która zwróciła 500, po jednej próbie utworzyła zadanie completed i nigdy nie została ponowiona.

Zadanie kończy się niepowodzeniem i jest ponawiane tylko wtedy, gdy samo wywołanie nie powiedzie się: funkcja nie istnieje lub jest nieaktywna, środowisko wykonawcze jest nieosiągalne lub upłynął limit czasu wywołania. Jeśli chcesz ponowić próbę, gdy Twój własny kod wykryje błąd, umieść w kolejce nowe zadanie od procedury obsługi (z delaySecs w celu wycofania) zamiast polegać na kodzie stanu.

W tym samym rzeczywistym przebiegu zadanie dla funkcji, która nie istnieje, przeszło następującą sekwencję: próba 1 nie powiodła się po 3 s z Fonction 'ghost' introuvable, próba 2 nie powiodła się po około 9 s, a zadanie stało się dead z attempts równym max_attempts.

#
Powrót do zdrowia

4. Kolejka utraconych wiadomości

Martwe zadania pozostają w kolejce i można je wyświetlić i ponowić. Te trasy nie mają jeszcze metody SDK: użyj protokołu HTTP z kluczem service_role.

terminalbash
# lista martwych stanowisk pracy
curl "$AURA_URL/v1/functions/jobs/dlq" -H "apikey: $AURA_SERVICE_ROLE_KEY"

# spróbuj ponownie wykonać jedno zadanie
curl -X POST "$AURA_URL/v1/functions/jobs/$JOB_ID/retry" -H "apikey: $AURA_SERVICE_ROLE_KEY"

# spróbuj ponownie przy każdym martwym zadaniu (do 1000)
curl -X POST "$AURA_URL/v1/functions/jobs/dlq/requeue" -H "apikey: $AURA_SERVICE_ROLE_KEY"
# → {"dane":{"requeued":1},"meta":null}

Ponowna próba przywraca zadanie do pending bez resetowania licznika prób, więc wykonuje dokładnie jeszcze jedną próbę i powraca do dead, jeśli ponownie się nie powiedzie. Napraw przyczynę (na przykład wdróż brakującą funkcję) przed ponowną próbą.

#
Harmonogram

5. Zaplanuj za pomocą crona

Wpis cron nie wywołuje samej funkcji: za każdym razem, gdy zostaje uruchomiony, umieszcza zadanie w kolejce.

server/cron.tstypescript
await admin.functions.createCronJob('nightly-cleanup', '0 3 * * *', 'cleanup', {
  payload: { dryRun: false },
})

const { data: crons } = await admin.functions.listCronJobs()
await admin.functions.deleteCronJob('nightly-cleanup') // według NAZWY, a nie identyfikatora
  • Harmonogram zawiera 5 pól (min hour day month weekday) lub 6 pól (sec min hour day month weekday). Harmonogram 5-polowy ma 0 sekundy do przodu: */1 * * * * jest przechowywany jako 0 */1 * * * *.
  • Aliasy takie jak @daily są odrzucane za pomocą 400 określającego oczekiwany format.
  • Godziny są w formacie UTC.
  • last_run i next_run są null aż do pierwszego odpalenia. W rzeczywistości harmonogram utworzony o 15:40 uruchomił się o 15:41:00, a następnie pokazywał next_run 15:42:00.
  • Ładunek zostaje zablokowany podczas tworzenia wpisu.
  • Usunięcie nieznanej nazwy zwraca 404. Usunięcie wpisu cron również zatrzymuje jego uruchomienie.
  • SDK nie ma getCronJob ani updateCronJob: usuń wpis i utwórz go ponownie.

W przypadku pracy wyłącznie z bazą danych rozszerzenie Postgres pg_cron pozwala uniknąć podróży w obie strony do funkcji: zobacz stronę Cron.

Ostatnia aktualizacja · 12 paź 2026