hobots 1.3.5 → 1.5.0
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 +35 -17
- package/dist/index.cjs +79 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +123 -110
- package/dist/index.d.ts +123 -110
- package/dist/index.js +69 -11
- package/dist/index.js.map +1 -1
- package/dist/protocol.cjs.map +1 -1
- package/dist/protocol.d.cts +6 -2
- package/dist/protocol.d.ts +6 -2
- package/docs/README.md +4 -1
- package/docs/api-reference.md +87 -11
- package/docs/concepts.md +441 -0
- package/docs/getting-started.md +17 -2
- package/docs/manager.md +37 -7
- package/docs/monitor.md +38 -3
- package/docs/protocol.md +3 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -49,7 +49,7 @@ Hobots.init({
|
|
|
49
49
|
|
|
50
50
|
Hobots.register('processar-nfe', async (params, ctx) => {
|
|
51
51
|
ctx.log.info('começando…');
|
|
52
|
-
|
|
52
|
+
ctx.log.info('12 notas processadas'); // o retorno do handler é ignorado — reporte por log
|
|
53
53
|
});
|
|
54
54
|
|
|
55
55
|
Hobots.start(); // inicia o polling do Manager (segura o processo vivo)
|
|
@@ -135,6 +135,8 @@ Trilha do que aconteceu antes do erro; enviada junto do próximo evento (buffer
|
|
|
135
135
|
Hobots.addBreadcrumb({ category: 'nfe', message: 'Baixou XML da nota 123', level: 'info' });
|
|
136
136
|
```
|
|
137
137
|
|
|
138
|
+
A lista **não** é limpa ao enviar um evento e é global. Conceito: [Breadcrumb](./docs/concepts.md#breadcrumb).
|
|
139
|
+
|
|
138
140
|
### Escopo: tags, usuário, contexto, extras
|
|
139
141
|
|
|
140
142
|
Dados anexados a **todos** os eventos seguintes:
|
|
@@ -175,7 +177,9 @@ tx.finish(); // só aqui a transaction é enviada (respeitando tracesSam
|
|
|
175
177
|
|
|
176
178
|
- `startChild(op?, description?)` existe em `Transaction` **e** `Span` (aninhamento arbitrário).
|
|
177
179
|
- Métodos encadeáveis: `setStatus`, `setData` (span), `setTag`/`setName` (transaction).
|
|
178
|
-
- `finish()` na transaction fecha os spans abertos e envia o payload; nada é enviado se ela não foi amostrada.
|
|
180
|
+
- `finish()` na transaction fecha os spans abertos e envia o payload; nada é enviado se ela não foi amostrada. A amostragem é decidida no `startTransaction()`.
|
|
181
|
+
|
|
182
|
+
Dentro de um handler do Manager não abra transaction — já existe uma em `ctx.tx`. Conceitos: [Transaction](./docs/concepts.md#transaction) · [Span](./docs/concepts.md#span).
|
|
179
183
|
|
|
180
184
|
### Crons (check-ins)
|
|
181
185
|
|
|
@@ -208,7 +212,7 @@ Hobots.init({
|
|
|
208
212
|
});
|
|
209
213
|
```
|
|
210
214
|
|
|
211
|
-
`heartbeat: true` usa os defaults. A identidade é o `instanceId` do `init()
|
|
215
|
+
`heartbeat: true` usa os defaults. A identidade é o `instanceId` do `init()`; os campos são `intervalMs`, `name` (default: o `instanceId`) e `metadata` — valores em [Tempos e intervalos](./docs/api-reference.md#tempos-e-intervalos). O primeiro batimento sai **na hora** em que o `init()` roda, não depois do primeiro intervalo. Conceito: [Heartbeat](./docs/concepts.md#heartbeat).
|
|
212
216
|
|
|
213
217
|
### Flush e close
|
|
214
218
|
|
|
@@ -236,7 +240,7 @@ Hobots.init({
|
|
|
236
240
|
|
|
237
241
|
Hobots.register('processar-nfe', async (params, ctx) => {
|
|
238
242
|
ctx.log.info(`processando lote ${params.lote}…`);
|
|
239
|
-
|
|
243
|
+
ctx.throwIfCanceled(); // cancelamento cooperativo
|
|
240
244
|
ctx.log.info('12 notas processadas');
|
|
241
245
|
});
|
|
242
246
|
|
|
@@ -259,6 +263,8 @@ process.on('SIGINT', () => {
|
|
|
259
263
|
| `concurrency` | `number` | `1` | runs simultâneas (clamp 1..5) |
|
|
260
264
|
| `taskTimeoutMs` | `number` | — | timeout client-side por run (não mata o handler; servidor é o backstop) |
|
|
261
265
|
| `logFlushIntervalMs` | `number` | `2000` | intervalo do envio incremental de logs |
|
|
266
|
+
| `cancelCheckIntervalMs` | `number` | `5000` | heartbeat de cancelamento por run (clamp 1000..15000) — também é o sinal de vida da run |
|
|
267
|
+
| `installExitHandlers` | `boolean` | `true` | handlers de SIGINT/SIGTERM/uncaughtException que reportam as runs ativas como `AgentTerminated` antes do processo morrer; nunca interferem quando o programa tem handler próprio |
|
|
262
268
|
|
|
263
269
|
O Client Secret, o `debug` e a identidade do agente (`instanceId`) vêm do `init()` — o heartbeat do Monitor e o agente do Manager convergem em **um agente** no painel automaticamente.
|
|
264
270
|
|
|
@@ -272,13 +278,19 @@ interface RunContext {
|
|
|
272
278
|
runId: string;
|
|
273
279
|
task: string;
|
|
274
280
|
log(level: 'debug' | 'info' | 'warning' | 'error', message: string): void;
|
|
281
|
+
tx: Transaction; // transaction desta run — correlacionada e finalizada pelo SDK
|
|
275
282
|
signal: AbortSignal;
|
|
283
|
+
throwIfCanceled(): void; // lança RunCanceled se o signal já disparou
|
|
284
|
+
sleep(ms: number): Promise<void>; // espera cancelável — rejeita com RunCanceled no abort
|
|
276
285
|
}
|
|
277
286
|
```
|
|
278
287
|
|
|
279
288
|
- **`params`** — os dados do formulário configurado no app (JSON validado). Tipável: `Hobots.register<{ lote: number }>(...)`.
|
|
280
|
-
- **`ctx.log.<level>(message)`** — logs enviados **incrementalmente** ao app (PATCHes com throttle), visíveis na run quase em tempo real.
|
|
289
|
+
- **`ctx.log.<level>(message)`** — logs enviados **incrementalmente** ao app (PATCHes com throttle), visíveis na run quase em tempo real; também impressos no terminal local, coloridos por nível.
|
|
290
|
+
- **`ctx.tx`** — a transaction de performance desta run, já correlacionada e finalizada pelo SDK. Use `ctx.tx.startChild(op, description)` para medir as etapas — elas viram o waterfall da execução no app. Conceito: [ctx.tx](./docs/concepts.md#transaction-de-run-ctxtx).
|
|
281
291
|
- **`ctx.signal`** — `AbortSignal` que dispara quando a run é **cancelada no app**, em **timeout** ou no **shutdown**.
|
|
292
|
+
- **`ctx.throwIfCanceled()`** — o ponto de parada de uma linha; lança `RunCanceled` se o `signal` já disparou.
|
|
293
|
+
- **`ctx.sleep(ms)`** — espera que respeita o `signal` (rejeita com `RunCanceled` em vez de dormir até o fim).
|
|
282
294
|
- **Retorno** — **ignorado**: o SDK não captura nem envia o valor retornado pelo handler (resultados podem conter dados sensíveis e não são coletados).
|
|
283
295
|
- **Erro lançado** — a run é reportada como `failed` (mensagem cap 10k, stack 20k).
|
|
284
296
|
|
|
@@ -286,20 +298,21 @@ interface RunContext {
|
|
|
286
298
|
|
|
287
299
|
### Cancelamento cooperativo
|
|
288
300
|
|
|
289
|
-
Uma run cancelada no app **não mata** o handler — o SDK apenas dispara `ctx.signal`.
|
|
301
|
+
Uma run cancelada no app **não mata** o handler — o SDK apenas dispara `ctx.signal`. Chame **`ctx.throwIfCanceled()`** em loops longos e pontos de parada (e troque esperas longas por `ctx.sleep()`):
|
|
290
302
|
|
|
291
303
|
```js
|
|
292
304
|
Hobots.register('processar-nfe', async (params, ctx) => {
|
|
293
305
|
for (const nota of params.notas) {
|
|
294
|
-
|
|
295
|
-
ctx.log.warn('cancelamento detectado — parando');
|
|
296
|
-
return;
|
|
297
|
-
}
|
|
306
|
+
ctx.throwIfCanceled(); // lança RunCanceled se cancelada — o handler para aqui
|
|
298
307
|
await processar(nota);
|
|
299
308
|
}
|
|
300
309
|
});
|
|
301
310
|
```
|
|
302
311
|
|
|
312
|
+
Quando o cancelamento veio do app, o `RunCanceled` lançado é **suprimido** — a run já está `cancelada` no servidor e nada é reportado por cima. Para limpeza antes de parar (fechar navegador, desfazer estado), use `try/finally`.
|
|
313
|
+
|
|
314
|
+
> **Atenção:** não use `if (ctx.signal.aborted) return;`. Retornar normalmente faz o SDK reportar a run como **`succeeded`** — uma run cancelada apareceria como sucesso no app. É preciso **lançar**, e é o que o `throwIfCanceled()` faz.
|
|
315
|
+
|
|
303
316
|
### Concorrência
|
|
304
317
|
|
|
305
318
|
`concurrency` (default 1, máx 5) controla quantas runs o agente executa em paralelo. Com 1, as runs são sequenciais. O agente só reivindica o que consegue rodar (`max = concurrency - runs ativas`) e entra em **drain mode**: re-pesquisa imediatamente enquanto vem trabalho; quando não vem, espera `pollIntervalMs`.
|
|
@@ -308,9 +321,11 @@ Hobots.register('processar-nfe', async (params, ctx) => {
|
|
|
308
321
|
|
|
309
322
|
`taskTimeoutMs` é **client-side**. No estouro o SDK **não mata** o handler — dispara `ctx.signal`, libera o slot e reporta a run como falha (`TaskTimeout`). Respeite o `signal` para parar de verdade. Sem ele, o backstop é o servidor.
|
|
310
323
|
|
|
311
|
-
### Idempotência (at-least-once)
|
|
324
|
+
### Idempotência (at-least-once até `running`)
|
|
325
|
+
|
|
326
|
+
Se o agente morrer logo **após capturar** uma run (antes de reportar `running`), ela é re-entregue quando um agente voltar (até 3 tentativas; depois `AgentLost`). A partir do momento em que a run está `running`, a morte do agente **não re-entrega** — a run vira falha `AgentTerminated`, porque o trabalho pode ter efeitos colaterais parciais e re-executar automaticamente não é seguro (reexecute manualmente pelo app).
|
|
312
327
|
|
|
313
|
-
|
|
328
|
+
Ainda assim, escreva handlers **idempotentes**: a janela de re-entrega pós-claim existe, e processar a mesma run duas vezes não pode causar efeito duplicado (use uma chave de deduplicação sua, como o número da nota).
|
|
314
329
|
|
|
315
330
|
---
|
|
316
331
|
|
|
@@ -343,9 +358,9 @@ Empacotado em **ESM e CommonJS** com **definições de tipos** (`.d.ts`) para to
|
|
|
343
358
|
|
|
344
359
|
---
|
|
345
360
|
|
|
346
|
-
## Migração
|
|
361
|
+
## Migração da API antiga (`hobots/manager`)
|
|
347
362
|
|
|
348
|
-
|
|
363
|
+
O Manager foi unificado no import raiz — `hobots/manager` **foi removido**:
|
|
349
364
|
|
|
350
365
|
```diff
|
|
351
366
|
-import * as Monitor from 'hobots';
|
|
@@ -368,16 +383,19 @@ A 2.0 unifica o Manager no import raiz — `hobots/manager` **foi removido**:
|
|
|
368
383
|
|
|
369
384
|
- A `dsn` (mecanismo antigo, `https://<secretKey>@host/<slug>`) não existe mais — passe `clientSecret` (em desenvolvimento, aponte para outro host com a env `HOBOTS_API_URL`). Copie o Client Secret em **Configurações → Projetos**.
|
|
370
385
|
- `agentName` e `serverName` não existem mais — a identidade do agente é o `instanceId` (obrigatório, sem fallback).
|
|
371
|
-
- As opções do Manager (`pollIntervalMs`, `concurrency`, `taskTimeoutMs`, `logFlushIntervalMs`) vão no campo `manager` do `init()`; `clientSecret` e `debug` não se repetem.
|
|
386
|
+
- As opções do Manager (`pollIntervalMs`, `concurrency`, `taskTimeoutMs`, `logFlushIntervalMs`, `cancelCheckIntervalMs`, `installExitHandlers`) vão no campo `manager` do `init()`; `clientSecret` e `debug` não se repetem.
|
|
372
387
|
- Tipos (`ManagerTaskHandler`, `RunContext`, `ManagerOptions`) e classes (`ManagerAgent`, `ManagerApi`) agora vêm de `hobots`; o wire format vem de `hobots/protocol`.
|
|
373
388
|
|
|
374
389
|
---
|
|
375
390
|
|
|
376
391
|
## Documentação completa
|
|
377
392
|
|
|
378
|
-
Guias detalhados acompanham o pacote em [`docs/`](./docs/README.md)
|
|
393
|
+
Guias detalhados acompanham o pacote em [`docs/`](./docs/README.md).
|
|
394
|
+
|
|
395
|
+
Novo no vocabulário de observabilidade (transaction, span, breadcrumb, tag, context, extra, flush, close)? Comece por [Conceitos](./docs/concepts.md) — as outras páginas assumem esses termos.
|
|
379
396
|
|
|
380
|
-
- [
|
|
397
|
+
- [Conceitos](./docs/concepts.md) — o que cada coisa é, por que existe e quando escolher uma em vez da outra.
|
|
398
|
+
- [Getting started](./docs/getting-started.md) — instalação, Client Secret, primeiro `init`, Monitor e Manager.
|
|
381
399
|
- [Monitor](./docs/monitor.md) — erros, breadcrumbs, escopo, transactions/spans, crons, heartbeat.
|
|
382
400
|
- [Manager](./docs/manager.md) — handlers, `RunContext`, cancelamento, concorrência, idempotência.
|
|
383
401
|
- [Referência de API](./docs/api-reference.md) — todas as funções e tabelas de opções com defaults.
|
package/dist/index.cjs
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
8
|
var __export = (target, all) => {
|
|
7
9
|
for (var name in all)
|
|
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
17
|
}
|
|
16
18
|
return to;
|
|
17
19
|
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
18
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
29
|
|
|
20
30
|
// src/index.ts
|
|
@@ -111,7 +121,7 @@ function parseStacktrace(stack) {
|
|
|
111
121
|
|
|
112
122
|
// src/utils.ts
|
|
113
123
|
var SDK_NAME = "hobots";
|
|
114
|
-
var SDK_VERSION = true ? "1.
|
|
124
|
+
var SDK_VERSION = true ? "1.5.0" : "0.0.0-dev";
|
|
115
125
|
function isNode() {
|
|
116
126
|
return typeof process !== "undefined" && typeof process.versions?.node === "string";
|
|
117
127
|
}
|
|
@@ -141,11 +151,26 @@ function sleep(ms) {
|
|
|
141
151
|
var PREFIX = "[hobots-monitor]";
|
|
142
152
|
function makeLogger(enabled, prefix = PREFIX) {
|
|
143
153
|
return {
|
|
144
|
-
debug: (...args) => enabled && console.debug(prefix, ...args),
|
|
145
|
-
warn: (...args) => enabled && console.warn(prefix, ...args),
|
|
146
|
-
error: (...args) => console.error(prefix, ...args)
|
|
154
|
+
debug: (...args) => enabled && console.debug(colorize(prefix, "gray"), ...args),
|
|
155
|
+
warn: (...args) => enabled && console.warn(colorize(prefix, "yellow"), ...args),
|
|
156
|
+
error: (...args) => console.error(colorize(prefix, "red"), ...args)
|
|
147
157
|
};
|
|
148
158
|
}
|
|
159
|
+
var ANSI = {
|
|
160
|
+
reset: "\x1B[0m",
|
|
161
|
+
gray: "\x1B[90m",
|
|
162
|
+
cyan: "\x1B[36m",
|
|
163
|
+
yellow: "\x1B[33m",
|
|
164
|
+
red: "\x1B[31m"
|
|
165
|
+
};
|
|
166
|
+
function colorEnabled() {
|
|
167
|
+
if (!isNode()) return false;
|
|
168
|
+
return Boolean(process.stdout?.isTTY) && !process.env.NO_COLOR;
|
|
169
|
+
}
|
|
170
|
+
function colorize(text, color) {
|
|
171
|
+
if (!colorEnabled()) return text;
|
|
172
|
+
return `${ANSI[color]}${text}${ANSI.reset}`;
|
|
173
|
+
}
|
|
149
174
|
|
|
150
175
|
// src/eventbuilder.ts
|
|
151
176
|
function safeString(value) {
|
|
@@ -617,11 +642,12 @@ var Span = class {
|
|
|
617
642
|
}
|
|
618
643
|
};
|
|
619
644
|
var Transaction = class {
|
|
620
|
-
constructor(client2, name, op, sampled = true) {
|
|
645
|
+
constructor(client2, name, op, sampled = true, runId) {
|
|
621
646
|
this.client = client2;
|
|
622
647
|
this.name = name;
|
|
623
648
|
this.op = op;
|
|
624
649
|
this.sampled = sampled;
|
|
650
|
+
this.runId = runId;
|
|
625
651
|
}
|
|
626
652
|
eventId = uuid4();
|
|
627
653
|
spanId = spanId();
|
|
@@ -664,7 +690,8 @@ var Transaction = class {
|
|
|
664
690
|
start_timestamp: this.startTimestamp,
|
|
665
691
|
timestamp: nowISO(),
|
|
666
692
|
spans: this.spans.map((span) => span.toJSON()),
|
|
667
|
-
tags: Object.keys(this.tags).length > 0 ? this.tags : void 0
|
|
693
|
+
tags: Object.keys(this.tags).length > 0 ? this.tags : void 0,
|
|
694
|
+
run_id: this.runId
|
|
668
695
|
};
|
|
669
696
|
this.client.sendTransaction(payload);
|
|
670
697
|
}
|
|
@@ -799,6 +826,17 @@ var ManagerApi = class {
|
|
|
799
826
|
};
|
|
800
827
|
|
|
801
828
|
// src/manager/context.ts
|
|
829
|
+
var LOG_LEVEL_COLOR = {
|
|
830
|
+
debug: "gray",
|
|
831
|
+
info: "cyan",
|
|
832
|
+
warning: "yellow",
|
|
833
|
+
error: "red"
|
|
834
|
+
};
|
|
835
|
+
function printRunLog(task, level, message) {
|
|
836
|
+
const line = colorize(`[hobots:${task}] ${level.toUpperCase()}`, LOG_LEVEL_COLOR[level]);
|
|
837
|
+
const method = level === "warning" ? "warn" : level;
|
|
838
|
+
console[method](line, message);
|
|
839
|
+
}
|
|
802
840
|
function runCanceledError() {
|
|
803
841
|
return Object.assign(new Error("execu\xE7\xE3o cancelada"), { name: "RunCanceled" });
|
|
804
842
|
}
|
|
@@ -828,7 +866,7 @@ var MAX_LOGS_PER_RUN = 500;
|
|
|
828
866
|
var MAX_LOGS_PER_PATCH = 100;
|
|
829
867
|
var FLUSH_AT_BUFFERED = 20;
|
|
830
868
|
var RunReporter = class {
|
|
831
|
-
constructor(api, runId, task, logger, flushIntervalMs, cancelCheckIntervalMs) {
|
|
869
|
+
constructor(api, runId, task, logger, tx, flushIntervalMs, cancelCheckIntervalMs) {
|
|
832
870
|
this.api = api;
|
|
833
871
|
this.runId = runId;
|
|
834
872
|
this.logger = logger;
|
|
@@ -848,6 +886,7 @@ var RunReporter = class {
|
|
|
848
886
|
runId,
|
|
849
887
|
task,
|
|
850
888
|
log,
|
|
889
|
+
tx,
|
|
851
890
|
signal,
|
|
852
891
|
throwIfCanceled: () => {
|
|
853
892
|
if (signal.aborted) throw runCanceledError();
|
|
@@ -888,6 +927,7 @@ var RunReporter = class {
|
|
|
888
927
|
}
|
|
889
928
|
log(level, message) {
|
|
890
929
|
if (this.dead) return;
|
|
930
|
+
printRunLog(this.context.task, level, message);
|
|
891
931
|
if (this.loggedCount >= MAX_LOGS_PER_RUN) {
|
|
892
932
|
this.droppedCount++;
|
|
893
933
|
return;
|
|
@@ -1001,6 +1041,24 @@ var RunReporter = class {
|
|
|
1001
1041
|
}
|
|
1002
1042
|
};
|
|
1003
1043
|
|
|
1044
|
+
// src/manager/run-context-store.ts
|
|
1045
|
+
var storage;
|
|
1046
|
+
var initPromise;
|
|
1047
|
+
async function ensureStorage() {
|
|
1048
|
+
if (storage || !isNode()) return;
|
|
1049
|
+
initPromise ??= import("async_hooks").then(({ AsyncLocalStorage: ALS }) => {
|
|
1050
|
+
storage = new ALS();
|
|
1051
|
+
});
|
|
1052
|
+
await initPromise;
|
|
1053
|
+
}
|
|
1054
|
+
async function runWithRunId(runId, fn) {
|
|
1055
|
+
await ensureStorage();
|
|
1056
|
+
return storage ? storage.run({ runId }, fn) : fn();
|
|
1057
|
+
}
|
|
1058
|
+
function currentRunId() {
|
|
1059
|
+
return storage?.getStore()?.runId;
|
|
1060
|
+
}
|
|
1061
|
+
|
|
1004
1062
|
// src/manager/shutdown.ts
|
|
1005
1063
|
var WATCHED_SIGNALS = ["SIGINT", "SIGTERM"];
|
|
1006
1064
|
function installShutdownHandlers(agent2) {
|
|
@@ -1062,6 +1120,7 @@ var ManagerAgent = class {
|
|
|
1062
1120
|
this.logger = makeLogger(options.debug ?? false, "[hobots-manager]");
|
|
1063
1121
|
const config = resolveConfig(options, "[hobots-manager]");
|
|
1064
1122
|
this.api = new ManagerApi({ baseUrl: config.managerBaseUrl, key: config.key, logger: this.logger });
|
|
1123
|
+
this.client = options.client;
|
|
1065
1124
|
this.pollIntervalMs = Math.max(MIN_POLL_INTERVAL_MS, options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS);
|
|
1066
1125
|
this.concurrency = Math.min(MAX_CONCURRENCY, Math.max(1, options.concurrency ?? 1));
|
|
1067
1126
|
this.instanceId = options.instanceId;
|
|
@@ -1072,6 +1131,7 @@ var ManagerAgent = class {
|
|
|
1072
1131
|
}
|
|
1073
1132
|
logger;
|
|
1074
1133
|
api;
|
|
1134
|
+
client;
|
|
1075
1135
|
pollIntervalMs;
|
|
1076
1136
|
concurrency;
|
|
1077
1137
|
instanceId;
|
|
@@ -1209,7 +1269,8 @@ var ManagerAgent = class {
|
|
|
1209
1269
|
this.activeRuns.add(promise);
|
|
1210
1270
|
}
|
|
1211
1271
|
async executeRun(run) {
|
|
1212
|
-
const
|
|
1272
|
+
const tx = new Transaction(this.client, `run:${run.task}`, "manager.run", true, run.id);
|
|
1273
|
+
const reporter = new RunReporter(this.api, run.id, run.task, this.logger, tx, this.logFlushIntervalMs, this.cancelCheckIntervalMs);
|
|
1213
1274
|
this.reporters.add(reporter);
|
|
1214
1275
|
try {
|
|
1215
1276
|
const handler = this.registry.get(run.task);
|
|
@@ -1219,22 +1280,29 @@ var ManagerAgent = class {
|
|
|
1219
1280
|
message: `tarefa n\xE3o registrada no agente: ${run.task}`
|
|
1220
1281
|
});
|
|
1221
1282
|
await reporter.finalize();
|
|
1283
|
+
tx.setStatus("error");
|
|
1284
|
+
tx.finish();
|
|
1222
1285
|
return;
|
|
1223
1286
|
}
|
|
1224
1287
|
const ok = await reporter.reportRunning();
|
|
1225
1288
|
if (!ok) {
|
|
1226
1289
|
this.logger.debug(`run ${run.id} cancelada antes de iniciar \u2014 handler n\xE3o executado`);
|
|
1290
|
+
tx.setStatus("cancelled");
|
|
1291
|
+
tx.finish();
|
|
1227
1292
|
return;
|
|
1228
1293
|
}
|
|
1229
1294
|
this.logger.debug(`executando run ${run.id} (${run.task})`);
|
|
1230
1295
|
try {
|
|
1231
|
-
await this.invokeWithTimeout(handler, run, reporter);
|
|
1296
|
+
await runWithRunId(run.id, () => this.invokeWithTimeout(handler, run, reporter));
|
|
1232
1297
|
reporter.reportSuccess();
|
|
1298
|
+
tx.setStatus("ok");
|
|
1233
1299
|
this.logger.debug(`run ${run.id} conclu\xEDda`);
|
|
1234
1300
|
} catch (error) {
|
|
1235
1301
|
reporter.reportFailure(toRunError(error));
|
|
1302
|
+
tx.setStatus("error");
|
|
1236
1303
|
this.logger.debug(`run ${run.id} falhou: ${String(error)}`);
|
|
1237
1304
|
}
|
|
1305
|
+
tx.finish();
|
|
1238
1306
|
await reporter.finalize();
|
|
1239
1307
|
} finally {
|
|
1240
1308
|
this.reporters.delete(reporter);
|
|
@@ -1305,7 +1373,7 @@ function init(options) {
|
|
|
1305
1373
|
if (options.manager) {
|
|
1306
1374
|
const managerOptions = options.manager === true ? {} : options.manager;
|
|
1307
1375
|
agent = new ManagerAgent(
|
|
1308
|
-
{ ...managerOptions, clientSecret: options.clientSecret, instanceId: options.instanceId, debug: options.debug },
|
|
1376
|
+
{ ...managerOptions, clientSecret: options.clientSecret, instanceId: options.instanceId, debug: options.debug, client },
|
|
1309
1377
|
registry
|
|
1310
1378
|
);
|
|
1311
1379
|
}
|
|
@@ -1350,7 +1418,7 @@ function withScope(callback) {
|
|
|
1350
1418
|
function startTransaction(name, op) {
|
|
1351
1419
|
const rate = client?.options.tracesSampleRate ?? 1;
|
|
1352
1420
|
const sampled = rate >= 1 || Math.random() < rate;
|
|
1353
|
-
return new Transaction(client, name, op, sampled);
|
|
1421
|
+
return new Transaction(client, name, op, sampled, currentRunId());
|
|
1354
1422
|
}
|
|
1355
1423
|
function checkIn(options) {
|
|
1356
1424
|
return client ? sendCheckIn(client, options) : void 0;
|