← Harvester

Sync

harvester · workzone

Когда и как обновляются данные источника. Три режима — Full Sync, Incremental и Reconciliation — отвечают на один вопрос по-разному: взять всё, взять только дельту или свериться с источником целиком. Режим выбирает лишь окно выборки (since) и агрессивность entity resolution; сам конвейер у всех трёх один и тот же. Все режимы гоняет фоновый воркер — устойчивость прогона (SyncRun, checkpoint, DLQ) держит reliability.

1 Full Sync Полный импорт от начала времён.
Окно выборки открыто от нуля — конвейер проходит каждую сущность источника. Режим включается, когда подключают новый источник или просят пересобрать существующий с чистого листа. Прогон долгий, но безопасный: на выходе всё тот же идемпотентный upsert, так что повтор не плодит дубли, а обновляет уже собранное — Load.
2 Incremental Только дельты: что изменилось с прошлого раза.
Рабочий режим после первичной загрузки. Источник сам сообщает об изменениях через webhooks; чего он не присылает, добираем опросом (polling) по since от прошлого прогона. Конвейер видит только дельту — это дёшево и быстро. Механику событий и инкремента по since держит sources. Два случая ниже — partial re-sync и dlq retry — не отдельные режимы, а тот же incremental с другим триггером и scope; «тип» в истории прогонов выводится из этой пары, отдельной колонкой не хранится.
Потеря событий → partial re-sync auto история прогонов
Webhook может не дойти, источник — отлежаться в простое; на один поток событий полагаться нельзя. За источником следит watchdog: молчание дольше порога тишины (12 часов — глобальный дефолт платформы, см. Расписание) — повод для подозрения, не приговор. Сначала идёт дешёвая проверка опросом по since — дельты нет, значит была просто тишина, разошлись даром; дельта нашлась — вот и пропущенное. Тогда watchdog запускает обычный incremental c since = incremental_cursor — отдельного «окна пересборки» нет: курсор продвигается лишь при успехе, а Load идемпотентен, так что переспрос дельты безопасен. Всё без полного импорта и без участия человека. В истории прогонов такой re-sync помечен своим типом — череда их подряд читается как нездоровый webhook, а не как норма.
Сбойные items → dlq_retry разбор сбойных
Точечный повтор по списку, а не по окну. Когда items копятся в DLQ, «Повторить сбойные» поднимает прогон со scope не из since, а из конкретных identity очереди разбора. Родня partial_resync — оба латают точечно, — но запускается вручную, после починки причины (права, источник), а не watchdog'ом. Обработанные уходят из очереди; её механику держат reliability и модель данных.
3 Reconciliation Сверка по расписанию: аудит и наведение порядка.
Комплексный аудит источника auto расписание сверки
Идёт по расписанию — дефолт еженедельно (см. Расписание). Сверяет собранное с источником целиком: чего уже нет в источнике — чистит как устаревшее, расхождения — выправляет. Тот же конвейер, что у Full Sync и Incremental, но с агрессивным resolve. Разница — в размере окна видимости, не в логике: область resolve всегда ограничена тем, что попало в fetch-окно прогона. Incremental видит узкое окно по since → дедуп только локальный; reconciliation тянет источник целиком одним прогоном и схлопывает внутри- источниковые дубли, разнесённые по прежним инкрементам, — узкому окну они были не видны. Противоречия с конвейером тут нет: upsert-ключ (source_id + source_type + source_entity_id) покрывает один и тот же source_entity_id между прогонами, а агрессивный resolve работает с одной сущностью под разными id в пределах видимого полного источника (cross-source склейку держит Knowledge Store). Это режим гигиены, а не доставки свежих данных.

Независимость per-source

Режим — это всегда состояние одного источника, не платформы. Каждый источник синхронизируется сам по себе и держит собственный since, свой график и свой текущий режим. «Синхронизировать всё» — не особый общий прогон, а запуск всех per-source синхронизаций разом.

Параллельно с доставкой идёт платформенная доводка графа в Knowledge Store. Полосы по умолчанию не мешают друг другу; лишь на время разрушительных шагов доводки (мёрж, retention) прогон затронутого источника встаёт в queued — взаимное исключение держит Knowledge Store · Координация полос.

Расписание → Cache & Workers

Когда запускать Incremental и Reconciliation, задаёт расписание: глобальный дефолт платформы плюс override на уровне источника. Источник без своего графика наследует общий; со своим — идёт по нему.

Управление графиком — UI поверх backend-домена синхронизаций, не часть конвейера. Оба расписания держат экраны — Admin Panel · incremental и Admin Panel · reconciliation.