ingest: закрыты мелочи приёма — вырожденное имя, контракт Result, корреляция add
- имя раздачи нормализуется на границе разбора: вырожденное `-` (metainfo.NoName) даёт пустое имя, пробельное схлопывается — сентинел больше не доходит ни до контекста распознавания, ни до source_ref, ни до подсказки вывода имени - контракт «на любом пути ошибки приёма результат нулевой» объявлен в ingest и удерживается структурно; три транспорта перестали обещать идентификатор, которого нет, и коррелируют отказ по request_id - scoped-логгер загрузки ставится до вызова внешнего сервиса в семи командах воркера — записи об отказе qBittorrent и метабаз получили download_id и infohash; граница разбора bencode записана в docs/research
This commit is contained in:
@@ -404,6 +404,10 @@ func (w *Worker) Relink(ctx context.Context, id string) (err error) {
|
||||
if d.State != store.StateReverted && d.State != store.StateCancelled && d.State != store.StateTargetMissing {
|
||||
return fmt.Errorf("relink: download %s is in state %s (expected reverted/cancelled/target_missing): %w", id, d.State, ErrConflict)
|
||||
}
|
||||
// Scoped-логгер загрузки — ДО первого вызова внешнего сервиса (обязанность
|
||||
// вызывающего, capability identity): иначе запись клиента об отказе уходит
|
||||
// без download_id/infohash.
|
||||
ctx = w.scoped(ctx, capReview, id, d.PrimaryInfohash())
|
||||
// Источник нужен для распознавания и должен быть докачан — проверяем
|
||||
// синхронно (без дебаунса); отсутствие приводит состояние к реальности
|
||||
// (orphaned/deleted), недокачанный — ErrNotReady.
|
||||
@@ -414,7 +418,6 @@ func (w *Worker) Relink(ctx context.Context, id string) (err error) {
|
||||
if err := w.store.SetOverride(ctx, id, ovrForceReview, "1"); err != nil {
|
||||
return fmt.Errorf("relink: %w", err)
|
||||
}
|
||||
ctx = w.scoped(ctx, capReview, id, d.PrimaryInfohash())
|
||||
// Возврат в активную обработку — только через атомарный гард инварианта
|
||||
// «не более одной активной задачи на infohash» (см. design ulid-identity, D4).
|
||||
if err := w.store.ActivateIfNoOtherActive(ctx, id, store.StateRecognizing, "", ""); err != nil {
|
||||
@@ -439,10 +442,13 @@ func (w *Worker) Rerecognize(ctx context.Context, id string) (err error) {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Scoped-логгер загрузки — ДО первого вызова внешнего сервиса (обязанность
|
||||
// вызывающего, capability identity): иначе запись клиента об отказе уходит
|
||||
// без download_id/infohash.
|
||||
ctx = w.scoped(ctx, capReview, id, d.PrimaryInfohash())
|
||||
if err := w.ensureSourceReady(ctx, d, "rerecognize"); err != nil {
|
||||
return err
|
||||
}
|
||||
ctx = w.scoped(ctx, capReview, id, d.PrimaryInfohash())
|
||||
logctx.From(ctx).Info("review re-recognizing without hint")
|
||||
w.transition(ctx, *d, store.StateRecognizing, "", "")
|
||||
return nil
|
||||
@@ -462,10 +468,13 @@ func (w *Worker) Refine(ctx context.Context, id string, hint string) (err error)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Scoped-логгер загрузки — ДО первого вызова внешнего сервиса (обязанность
|
||||
// вызывающего, capability identity): иначе запись клиента об отказе уходит
|
||||
// без download_id/infohash.
|
||||
ctx = w.scoped(ctx, capReview, id, d.PrimaryInfohash())
|
||||
if err := w.ensureSourceReady(ctx, d, "refine"); err != nil {
|
||||
return err
|
||||
}
|
||||
ctx = w.scoped(ctx, capReview, id, d.PrimaryInfohash())
|
||||
if err := w.store.AddHint(ctx, id, hint); err != nil {
|
||||
return fmt.Errorf("refine: %w", err)
|
||||
}
|
||||
@@ -688,6 +697,10 @@ func (w *Worker) ChooseCandidate(ctx context.Context, id, candidateID string) (e
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Scoped-логгер загрузки — ДО первого вызова внешнего сервиса (обязанность
|
||||
// вызывающего, capability identity): иначе запись клиента об отказе уходит
|
||||
// без download_id/infohash.
|
||||
ctx = w.scoped(ctx, capReview, id, d.PrimaryInfohash())
|
||||
rec, err := w.store.GetCurrentRecognition(ctx, id)
|
||||
if err != nil {
|
||||
return fmt.Errorf("choose candidate: %w", err)
|
||||
@@ -724,6 +737,10 @@ func (w *Worker) AddManualSource(ctx context.Context, id, provider, providerID s
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Scoped-логгер загрузки — ДО первого вызова внешнего сервиса (обязанность
|
||||
// вызывающего, capability identity): иначе запись клиента об отказе уходит
|
||||
// без download_id/infohash.
|
||||
ctx = w.scoped(ctx, capReview, id, d.PrimaryInfohash())
|
||||
rec, err := w.store.GetCurrentRecognition(ctx, id)
|
||||
if err != nil {
|
||||
return fmt.Errorf("add source: %w", err)
|
||||
@@ -809,7 +826,7 @@ func (w *Worker) chooseCandidateLocked(ctx context.Context, id string, d *store.
|
||||
// раздачи (best-effort, косметика). Сбой обновления имени не должен ронять
|
||||
// выбор кандидата: логируем и продолжаем.
|
||||
if err := w.refreshDisplayNameLocked(ctx, id); err != nil {
|
||||
logctx.From(w.scoped(ctx, capReview, id, d.PrimaryInfohash())).
|
||||
logctx.From(ctx).
|
||||
Warn("display name refresh after candidate choice failed", "error", err)
|
||||
}
|
||||
return nil
|
||||
@@ -835,6 +852,10 @@ func (w *Worker) SetProviderID(ctx context.Context, id string, provider, provide
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Scoped-логгер загрузки — ДО первого вызова внешнего сервиса (обязанность
|
||||
// вызывающего, capability identity): иначе запись клиента об отказе уходит
|
||||
// без download_id/infohash.
|
||||
ctx = w.scoped(ctx, capReview, id, d.PrimaryInfohash())
|
||||
// Режиссёр вручную заданного источника из метабазы (credits) — best-effort
|
||||
// косметика: сбой чтения рекогниции не валит смену источника (тип по умолчанию
|
||||
// movie, как трактует candMediaType(nil)).
|
||||
@@ -842,7 +863,7 @@ func (w *Worker) SetProviderID(ctx context.Context, id string, provider, provide
|
||||
if w.recognizer != nil {
|
||||
rec, rerr := w.store.GetCurrentRecognition(ctx, id)
|
||||
if rerr != nil {
|
||||
logctx.From(w.scoped(ctx, capReview, id, d.PrimaryInfohash())).
|
||||
logctx.From(ctx).
|
||||
Warn("set provider: recognition lookup for director failed", "error", rerr)
|
||||
rec = nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user