szdl-utils-kit 0.3.23 → 0.3.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Readme.md +111 -6
- package/dist/index.js +844 -812
- package/dist/index.umd.cjs +2 -2
- package/dist/types/background-worker.d.ts +11 -0
- package/dist/types/batch.d.ts +3 -1
- package/package.json +1 -1
package/Readme.md
CHANGED
|
@@ -97,11 +97,9 @@ const deals = await bx.batch({
|
|
|
97
97
|
- `appOption(key, value?)` – чтение/запись пользовательских настроек
|
|
98
98
|
- `call({ method, params, updateList })` – одиночный REST-вызов
|
|
99
99
|
- `batch(commandList, progressCall?, options?)` – пакетные вызовы с обновлениями/логом
|
|
100
|
-
- `errorCall(errors)` – вызывается после выполнения всего батча, получает объект с ключами запросов и списком ошибок Bitrix24
|
|
101
|
-
- `updateList` – массив описаний изменений для логера (`method`, `name`, `list[{ id, fields }]`), отображается в истории операций
|
|
100
|
+
- `errorCall(errors)` – вызывается после выполнения всего батча, получает объект с ключами запросов и списком ошибок Bitrix24
|
|
101
|
+
- `updateList` – массив описаний изменений для логера (`method`, `name`, `list[{ id, fields }]`), отображается в истории операций
|
|
102
102
|
- `batchTotalCount(commandList, progressCall?, options?)` – подсчет элементов в пакетном режиме
|
|
103
|
-
- `errorCall(errors)` – вызывается после выполнения всего батча, получает объект с ключами запросов и списком ошибок Bitrix24
|
|
104
|
-
- `updateList` – массив описаний изменений для логера (`method`, `name`, `list[{ id, fields }]`), отображается в истории операций
|
|
105
103
|
- `timeLimit` – глобальный статус лимита выполнения (`{ limit, date }`), можно напрямую читать в компонентах (например, в лоадере)
|
|
106
104
|
- `placementBind(place, userId?)`, `placementUnBind(...)`, `placementCheck()` – работа с встройками (кроме `PAGE_BACKGROUND_WORKER`, их ведёт `BackgroundWorker`)
|
|
107
105
|
- `getBotList()`, `regBot()`, `unRegBot()` – управление чат-ботом
|
|
@@ -187,7 +185,9 @@ await worker.init();
|
|
|
187
185
|
- `bx` – инициализированный экземпляр `BxBoot`, используемый для работы с REST;
|
|
188
186
|
- `appFunc` – функция, которая должна выполниться в «активном» табе;
|
|
189
187
|
- `users` – подготовленные данные (если не переданы, будут запрошены через REST);
|
|
190
|
-
- `continueBackground` – опциональная
|
|
188
|
+
- `continueBackground` – опциональная функция-условие, которая определяет, можно ли запускать воркер. Должна вернуть `true`, чтобы продолжить цикл. По умолчанию всегда возвращает `true`; см. пример ниже.
|
|
189
|
+
- `timing` – объект с таймингами poll-цикла, подтверждения лидерства и разнесённого старта приложений (см. [Тайминги](#тайминги-timing)). Можно передать только нужные поля — остальные возьмутся из `DEFAULT_BACKGROUND_WORKER_TIMING`;
|
|
190
|
+
- `coordinationScope` – область координации лидера и пула вкладок (см. [Область координации](#область-координации-coordinationscope)). По умолчанию `'user'`.
|
|
191
191
|
|
|
192
192
|
```ts
|
|
193
193
|
const worker = new BackgroundWorker({
|
|
@@ -206,6 +206,111 @@ const worker = new BackgroundWorker({
|
|
|
206
206
|
});
|
|
207
207
|
```
|
|
208
208
|
|
|
209
|
+
#### Область координации (`coordinationScope`)
|
|
210
|
+
|
|
211
|
+
Передаётся строкой: `'user'` или `'portal'`. Другие значения игнорируются с предупреждением в консоль, используется `'user'`.
|
|
212
|
+
|
|
213
|
+
| Значение | Поведение |
|
|
214
|
+
|----------|-----------|
|
|
215
|
+
| `'user'` (по умолчанию) | Один запуск `appFunc` одновременно **на пользователя**. Вкладки разных пользователей не конкурируют. |
|
|
216
|
+
| `'portal'` | Один запуск `appFunc` одновременно **на портал**. Все пользователи в общем пуле вкладок; лидер один на всё приложение. |
|
|
217
|
+
|
|
218
|
+
**Как это работает:**
|
|
219
|
+
|
|
220
|
+
- В режиме `'user'` записи в entity хранятся с `NAME = userId`, Web Lock тоже per-user.
|
|
221
|
+
- В режиме `'portal'` все вкладки пишутся с общим ключом `NAME = {appCodeName}:portal`, Web Lock — per-portal (per-app).
|
|
222
|
+
- В данных вкладки всегда сохраняется `userId` — в portal-режиме видно, у кого открыта вкладка, хотя `appFunc` выполняется только у лидера.
|
|
223
|
+
- `setBackgroundWorkerAll` в portal-режиме привязывает только общую встройку `PAGE_BACKGROUND_WORKER` и отвязывает персональные (`USER_ID=…`).
|
|
224
|
+
|
|
225
|
+
```ts
|
|
226
|
+
const worker = new BackgroundWorker({
|
|
227
|
+
bx,
|
|
228
|
+
appFunc: async () => {
|
|
229
|
+
console.log("background job started (once per portal)");
|
|
230
|
+
},
|
|
231
|
+
coordinationScope: "portal",
|
|
232
|
+
});
|
|
233
|
+
await worker.init();
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
#### Тайминги (`timing`)
|
|
237
|
+
|
|
238
|
+
Экспортируются `DEFAULT_BACKGROUND_WORKER_TIMING` и `resolveBackgroundWorkerTiming` — удобно собирать конфиг заранее или переопределять отдельные поля.
|
|
239
|
+
|
|
240
|
+
```ts
|
|
241
|
+
import {
|
|
242
|
+
BackgroundWorker,
|
|
243
|
+
DEFAULT_BACKGROUND_WORKER_TIMING,
|
|
244
|
+
resolveBackgroundWorkerTiming,
|
|
245
|
+
} from "szdl-utils-kit";
|
|
246
|
+
|
|
247
|
+
const timing = resolveBackgroundWorkerTiming({
|
|
248
|
+
startDelayMs: 10_000,
|
|
249
|
+
leaderConfirmDelayMs: 10_000,
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
const worker = new BackgroundWorker({ bx, appFunc, timing });
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
**Поля объекта `timing`:**
|
|
256
|
+
|
|
257
|
+
| Поле | По умолчанию | Назначение |
|
|
258
|
+
|------|--------------|------------|
|
|
259
|
+
| `startDelayMs` | `0` | Пауза перед первым poll-тиком. Разносит старт разных приложений (один апп — через 20 с, другой — через 4–5 мин). |
|
|
260
|
+
| `pollIntervalMs` | `60_000` | Базовый интервал фонового poll-цикла (обновление `lastActive`, выбор лидера, очистка мёртвых вкладок). |
|
|
261
|
+
| `pollIntervalJitterMs` | `30_000` | Случайная добавка к `pollIntervalMs`. Итоговый интервал: от `pollIntervalMs` до `pollIntervalMs + pollIntervalJitterMs` (по умолчанию 1–1,5 мин). |
|
|
262
|
+
| `leaderConfirmDelayMs` | `60_000` | Пауза после захвата Web Lock перед повторной проверкой лидерства и вызовом `appFunc`. Защита от гонки между вкладками. |
|
|
263
|
+
| `activeMaxPauseMs` | `180_000` | Порог «мёртвой» вкладки: если `lastActive` не обновлялся дольше — запись удаляется из entity. Должен быть **больше** `startDelayMs + leaderConfirmDelayMs`, иначе вкладка может удалиться во время пауз перед стартом. |
|
|
264
|
+
| `quickCleanupThresholdMs` | `300_000` | Отдельный порог для агрессивной очистки, когда достигнут лимит вкладок (`maxTabs`). |
|
|
265
|
+
| `leaderHeartbeatMs` | `null` | Интервал обновления `lastActive` лидером во время `appFunc`. Если не задан — вычисляется автоматически из `pollInterval` и `activeMaxPauseMs`. |
|
|
266
|
+
|
|
267
|
+
**Как устроен старт (без лишних раундов):**
|
|
268
|
+
|
|
269
|
+
1. Регистрация вкладки в entity.
|
|
270
|
+
2. Пауза `startDelayMs` (если задана).
|
|
271
|
+
3. Poll-тик: выбор лидера по entity (самая старая вкладка).
|
|
272
|
+
4. Если текущая вкладка — лидер: захват Web Lock → пауза `leaderConfirmDelayMs` → повторная проверка лидера → `appFunc`.
|
|
273
|
+
5. Далее poll-цикл продолжается с интервалом `pollIntervalMs` … `+ pollIntervalJitterMs`.
|
|
274
|
+
|
|
275
|
+
**Пример: старт через ~20 секунд**
|
|
276
|
+
|
|
277
|
+
```ts
|
|
278
|
+
const START_DELAY_MS = 10_000;
|
|
279
|
+
const LEADER_CONFIRM_MS = 10_000;
|
|
280
|
+
|
|
281
|
+
const worker = new BackgroundWorker({
|
|
282
|
+
bx,
|
|
283
|
+
appFunc: async () => {
|
|
284
|
+
console.log("background job started");
|
|
285
|
+
},
|
|
286
|
+
timing: {
|
|
287
|
+
...DEFAULT_BACKGROUND_WORKER_TIMING,
|
|
288
|
+
startDelayMs: START_DELAY_MS,
|
|
289
|
+
leaderConfirmDelayMs: LEADER_CONFIRM_MS,
|
|
290
|
+
activeMaxPauseMs: Math.max(
|
|
291
|
+
60_000,
|
|
292
|
+
(START_DELAY_MS + LEADER_CONFIRM_MS) * 3,
|
|
293
|
+
),
|
|
294
|
+
},
|
|
295
|
+
});
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
**Пример: отложенный старт (~4–5 минут)**
|
|
299
|
+
|
|
300
|
+
```ts
|
|
301
|
+
const worker = new BackgroundWorker({
|
|
302
|
+
bx,
|
|
303
|
+
appFunc: async () => {
|
|
304
|
+
/* ... */
|
|
305
|
+
},
|
|
306
|
+
timing: {
|
|
307
|
+
...DEFAULT_BACKGROUND_WORKER_TIMING,
|
|
308
|
+
startDelayMs: 4 * 60_000,
|
|
309
|
+
leaderConfirmDelayMs: 60_000,
|
|
310
|
+
},
|
|
311
|
+
});
|
|
312
|
+
```
|
|
313
|
+
|
|
209
314
|
Методы:
|
|
210
315
|
|
|
211
316
|
- **`init`** – регистрирует бек-встройку для текущего пользователя, создаёт запись текущего таба и запускает цикл наблюдения.
|
|
@@ -227,7 +332,7 @@ const formatted = tempus().format("%Y-%m-%d");
|
|
|
227
332
|
|
|
228
333
|
- `types/batch.d.ts` – детальное описание Batch;
|
|
229
334
|
- `types/bx-boot.d.ts`, `types/bx-helper.d.ts`, `types/bx-logger.d.ts`;
|
|
230
|
-
- `types/background-worker.d.ts`.
|
|
335
|
+
- `types/background-worker.d.ts` – в том числе `BackgroundWorkerTiming`, `DEFAULT_BACKGROUND_WORKER_TIMING`.
|
|
231
336
|
|
|
232
337
|
## Разработка и публикация
|
|
233
338
|
|