mirror of
https://github.com/PR0M3TH3AN/TORCH.git
synced 2026-10-27 07:51:52 +00:00
Refactor lock backend constants and fix scheduler syntax error
- Extracted hardcoded retry/health constants from `src/lock-ops.mjs` to `src/constants.mjs`. - Refactored `src/lock-ops.mjs` to use `LockPublisher` class pattern and shared constants. - Fixed `SyntaxError` in `src/lock-ops.mjs` (function inside function). - Fixed `ReferenceError` in `src/cmd-check.mjs` (`queryLocksFn` -> `queryLocks`). - Verified with unit tests (`test:unit:lock-backend`) and linting. - Completed daily scheduler cycle for `const-refactor-agent`. Co-authored-by: PR0M3TH3AN <[email protected]>
This commit is contained in:
1 parent
7f87c371fc
commit
03ccb232ee
16 files changed
+2266
-28
No files matched your search
@@ -0,0 +1,53 @@
|
|||||||
|
[
|
||||||
|
[
|
||||||
|
"b8fc8eef-facd-4632-a404-aefc94de033a",
|
||||||
|
{
|
||||||
|
"schema_version": 1,
|
||||||
|
"id": "b8fc8eef-facd-4632-a404-aefc94de033a",
|
||||||
|
"agent_id": "const-refactor-agent",
|
||||||
|
"session_id": "session-mlr0dhq6",
|
||||||
|
"type": "batch_window",
|
||||||
|
"content": "Memory retrieval seed for daily :: Required startup + artifacts + memory + issue capture",
|
||||||
|
"summary": "Memory retrieval seed for daily :: Required startup + artifacts + memory + issue capture",
|
||||||
|
"tags": [
|
||||||
|
"scheduler",
|
||||||
|
"daily",
|
||||||
|
"retrieve"
|
||||||
|
],
|
||||||
|
"importance": 0.4,
|
||||||
|
"embedding_id": null,
|
||||||
|
"created_at": 1771357255423,
|
||||||
|
"last_seen": 1771357255430,
|
||||||
|
"source": "scheduler-retrieve",
|
||||||
|
"ttl_days": null,
|
||||||
|
"merged_into": null,
|
||||||
|
"pinned": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"b6580c2a-2c32-4239-afd8-eb8cbca5449d",
|
||||||
|
{
|
||||||
|
"schema_version": 1,
|
||||||
|
"id": "b6580c2a-2c32-4239-afd8-eb8cbca5449d",
|
||||||
|
"agent_id": "const-refactor-agent",
|
||||||
|
"session_id": "session-mlr0iplm",
|
||||||
|
"type": "batch_window",
|
||||||
|
"content": "# Memory Update: Constants Refactor\n\n- Discovered hardcoded constants in `src/lock-ops.mjs` duplicating defaults.\n- Extracted `DEFAULT_RETRY_ATTEMPTS`, `DEFAULT_RETRY_BASE_DELAY_MS`, etc. to `src/constants.mjs`.\n- Refactored `src/lock-ops.mjs` to use these constants.\n- Fixed a bug in `src/cmd-check.mjs` where `queryLocksFn` was undefined.\n- Verified with unit tests and lint.",
|
||||||
|
"summary": "# Memory Update: Constants Refactor\n\n- Discovered hardcoded constants in `src/lock-ops.mjs` duplicating defaults.\n- Extracted `DEFAULT_RETRY_ATTEMPTS`, `DEFAULT_RETRY_BASE_DELAY_MS`, etc. to `src/constants.mjs`.\n- Refactored `src/lock-ops.mjs` to use these constants.\n- Fixed a b…",
|
||||||
|
"tags": [
|
||||||
|
"scheduler",
|
||||||
|
"daily",
|
||||||
|
"store",
|
||||||
|
"insight"
|
||||||
|
],
|
||||||
|
"importance": 0.8,
|
||||||
|
"embedding_id": null,
|
||||||
|
"created_at": 1771357498907,
|
||||||
|
"last_seen": 1771357498907,
|
||||||
|
"source": "agent-output",
|
||||||
|
"ttl_days": null,
|
||||||
|
"merged_into": null,
|
||||||
|
"pinned": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"cadence": "daily",
|
||||||
|
"operation": "retrieve",
|
||||||
|
"runId": "session-mlr0dhq6",
|
||||||
|
"servicePath": "src/services/memory/index.js#getRelevantMemories",
|
||||||
|
"inputs": {
|
||||||
|
"agentId": "const-refactor-agent",
|
||||||
|
"promptPath": "src/prompts/daily/const-refactor-agent.md",
|
||||||
|
"promptIntent": "Required startup + artifacts + memory + issue capture",
|
||||||
|
"query": "scheduler | daily | agent | const-refactor-agent | intent | Required startup + artifacts + memory + issue capture",
|
||||||
|
"events": 1
|
||||||
|
},
|
||||||
|
"outputs": {
|
||||||
|
"ingestedCount": 1,
|
||||||
|
"retrievedCount": 1
|
||||||
|
},
|
||||||
|
"status": "ok"
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
MEMORY_RETRIEVED
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"cadence": "daily",
|
||||||
|
"operation": "store",
|
||||||
|
"runId": "session-mlr0iplm",
|
||||||
|
"servicePath": "src/services/memory/index.js#ingestEvents",
|
||||||
|
"inputs": {
|
||||||
|
"agentId": "const-refactor-agent",
|
||||||
|
"promptPath": "src/prompts/daily/const-refactor-agent.md",
|
||||||
|
"promptIntent": "Required startup + artifacts + memory + issue capture",
|
||||||
|
"events": 1,
|
||||||
|
"sourceFile": "memory-updates/2026-02-17T19-44-58Z__const-refactor-agent.md"
|
||||||
|
},
|
||||||
|
"outputs": {
|
||||||
|
"storedCount": 1,
|
||||||
|
"summaries": [
|
||||||
|
"# Memory Update: Constants Refactor\n\n- Discovered hardcoded constants in `src/lock-ops.mjs` duplicating defaults.\n- Extracted `DEFAULT_RETRY_ATTEMPTS`, `DEFAULT_RETRY_BASE_DELAY_MS`, etc. to `src/constants.mjs`.\n- Refactored `src/lock-ops.mjs` to use these constants.\n- Fixed a b…"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"status": "ok"
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
MEMORY_STORED
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
# Memory Update: Constants Refactor
|
||||||
|
|
||||||
|
- Discovered hardcoded constants in `src/lock-ops.mjs` duplicating defaults.
|
||||||
|
- Extracted `DEFAULT_RETRY_ATTEMPTS`, `DEFAULT_RETRY_BASE_DELAY_MS`, etc. to `src/constants.mjs`.
|
||||||
|
- Refactored `src/lock-ops.mjs` to use these constants.
|
||||||
|
- Fixed a bug in `src/cmd-check.mjs` where `queryLocksFn` was undefined.
|
||||||
|
- Verified with unit tests and lint.
|
||||||
File diff suppressed because it is too large.
Load diff
+1
-1
@@ -20,7 +20,7 @@ export async function cmdCheck(cadence) {
|
|||||||
console.error(`Paused agents: ${pausedAgents.join(', ')}`);
|
console.error(`Paused agents: ${pausedAgents.join(', ')}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const locks = await queryLocksFn(relays, cadence, dateStr, namespace);
|
const locks = await queryLocks(relays, cadence, dateStr, namespace);
|
||||||
const lockedAgents = [...new Set(locks.map((l) => l.agent).filter(Boolean))];
|
const lockedAgents = [...new Set(locks.map((l) => l.agent).filter(Boolean))];
|
||||||
const roster = await getRoster(cadence);
|
const roster = await getRoster(cadence);
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,14 @@ export const DEFAULT_QUERY_TIMEOUT_MS = 30_000;
|
|||||||
export const DEFAULT_PUBLISH_TIMEOUT_MS = 15_000;
|
export const DEFAULT_PUBLISH_TIMEOUT_MS = 15_000;
|
||||||
export const DEFAULT_MIN_SUCCESSFUL_PUBLISHES = 1;
|
export const DEFAULT_MIN_SUCCESSFUL_PUBLISHES = 1;
|
||||||
export const DEFAULT_MIN_ACTIVE_RELAY_POOL = 1;
|
export const DEFAULT_MIN_ACTIVE_RELAY_POOL = 1;
|
||||||
|
export const DEFAULT_RETRY_ATTEMPTS = 4;
|
||||||
|
export const DEFAULT_RETRY_BASE_DELAY_MS = 500;
|
||||||
|
export const DEFAULT_RETRY_CAP_DELAY_MS = 8000;
|
||||||
|
export const DEFAULT_ROLLING_WINDOW_SIZE = 25;
|
||||||
|
export const DEFAULT_FAILURE_THRESHOLD = 3;
|
||||||
|
export const DEFAULT_QUARANTINE_COOLDOWN_MS = 30_000;
|
||||||
|
export const DEFAULT_MAX_QUARANTINE_COOLDOWN_MS = 300_000;
|
||||||
|
export const DEFAULT_SNAPSHOT_INTERVAL_MS = 60_000;
|
||||||
export const VALID_CADENCES = new Set(['daily', 'weekly']);
|
export const VALID_CADENCES = new Set(['daily', 'weekly']);
|
||||||
export const KIND_APP_DATA = 30078;
|
export const KIND_APP_DATA = 30078;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
# Context for Constants Refactor Run
|
||||||
|
|
||||||
|
**Agent:** const-refactor-agent
|
||||||
|
**Date:** 2026-02-17T19-41-31Z
|
||||||
|
**Baseline:**
|
||||||
|
- `js/` directory does not exist. Scanning `src/` instead.
|
||||||
|
- `AGENTS.md` and `CLAUDE.md` not found.
|
||||||
|
- Target branch: default
|
||||||
|
|
||||||
|
**Goal:** Find duplicated numeric constants in `src/` and extract them to `src/constants.mjs`.
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
- Extracted retry/health constants from `src/lock-ops.mjs` to `src/constants.mjs`.
|
||||||
|
- Constants: `DEFAULT_RETRY_ATTEMPTS`, `DEFAULT_RETRY_BASE_DELAY_MS`, `DEFAULT_RETRY_CAP_DELAY_MS`, `DEFAULT_ROLLING_WINDOW_SIZE`, `DEFAULT_FAILURE_THRESHOLD`, `DEFAULT_QUARANTINE_COOLDOWN_MS`, `DEFAULT_MAX_QUARANTINE_COOLDOWN_MS`, `DEFAULT_SNAPSHOT_INTERVAL_MS`.
|
||||||
|
- Reason: These values were hardcoded in multiple places in `src/lock-ops.mjs` and represent system-wide defaults.
|
||||||
+59
-27
@@ -1,4 +1,4 @@
|
|||||||
import { randomInt } from 'node:crypto';
|
import { randomInt, randomUUID } from 'node:crypto';
|
||||||
import { SimplePool } from 'nostr-tools/pool';
|
import { SimplePool } from 'nostr-tools/pool';
|
||||||
import {
|
import {
|
||||||
getQueryTimeoutMs,
|
getQueryTimeoutMs,
|
||||||
@@ -7,7 +7,17 @@ import {
|
|||||||
getRelayFallbacks,
|
getRelayFallbacks,
|
||||||
getMinActiveRelayPool,
|
getMinActiveRelayPool,
|
||||||
} from './torch-config.mjs';
|
} from './torch-config.mjs';
|
||||||
import { KIND_APP_DATA } from './constants.mjs';
|
import {
|
||||||
|
KIND_APP_DATA,
|
||||||
|
DEFAULT_RETRY_ATTEMPTS,
|
||||||
|
DEFAULT_RETRY_BASE_DELAY_MS,
|
||||||
|
DEFAULT_RETRY_CAP_DELAY_MS,
|
||||||
|
DEFAULT_ROLLING_WINDOW_SIZE,
|
||||||
|
DEFAULT_FAILURE_THRESHOLD,
|
||||||
|
DEFAULT_QUARANTINE_COOLDOWN_MS,
|
||||||
|
DEFAULT_MAX_QUARANTINE_COOLDOWN_MS,
|
||||||
|
DEFAULT_SNAPSHOT_INTERVAL_MS,
|
||||||
|
} from './constants.mjs';
|
||||||
|
|
||||||
function nowUnix() {
|
function nowUnix() {
|
||||||
return Math.floor(Date.now() / 1000);
|
return Math.floor(Date.now() / 1000);
|
||||||
@@ -297,11 +307,11 @@ export const defaultHealthManager = new RelayHealthManager();
|
|||||||
|
|
||||||
function buildRelayHealthConfig(deps) {
|
function buildRelayHealthConfig(deps) {
|
||||||
return {
|
return {
|
||||||
rollingWindowSize: deps.rollingWindowSize ?? 25,
|
rollingWindowSize: deps.rollingWindowSize ?? DEFAULT_ROLLING_WINDOW_SIZE,
|
||||||
failureThreshold: deps.failureThreshold ?? 3,
|
failureThreshold: deps.failureThreshold ?? DEFAULT_FAILURE_THRESHOLD,
|
||||||
quarantineCooldownMs: deps.quarantineCooldownMs ?? 30_000,
|
quarantineCooldownMs: deps.quarantineCooldownMs ?? DEFAULT_QUARANTINE_COOLDOWN_MS,
|
||||||
maxQuarantineCooldownMs: deps.maxQuarantineCooldownMs ?? 5 * 60_000,
|
maxQuarantineCooldownMs: deps.maxQuarantineCooldownMs ?? DEFAULT_MAX_QUARANTINE_COOLDOWN_MS,
|
||||||
snapshotIntervalMs: deps.snapshotIntervalMs ?? 60_000,
|
snapshotIntervalMs: deps.snapshotIntervalMs ?? DEFAULT_SNAPSHOT_INTERVAL_MS,
|
||||||
minActiveRelayPool: Math.max(1, deps.minActiveRelayPool),
|
minActiveRelayPool: Math.max(1, deps.minActiveRelayPool),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -415,26 +425,48 @@ async function publishToRelays(pool, relays, event, publishTimeoutMs, phase) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function publishLock(relays, event, deps = {}) {
|
class LockPublisher {
|
||||||
const {
|
constructor(relays, event, deps = {}) {
|
||||||
poolFactory = () => new SimplePool(),
|
this.relays = relays;
|
||||||
getPublishTimeoutMsFn = getPublishTimeoutMs,
|
this.event = event;
|
||||||
getMinSuccessfulRelayPublishesFn = getMinSuccessfulRelayPublishes,
|
this.poolFactory = deps.poolFactory || (() => new SimplePool());
|
||||||
getRelayFallbacksFn = getRelayFallbacks,
|
this.getPublishTimeoutMsFn = deps.getPublishTimeoutMsFn || getPublishTimeoutMs;
|
||||||
getMinActiveRelayPoolFn = getMinActiveRelayPool,
|
this.getMinSuccessfulRelayPublishesFn = deps.getMinSuccessfulRelayPublishesFn || getMinSuccessfulRelayPublishes;
|
||||||
retryAttempts = 4,
|
this.getRelayFallbacksFn = deps.getRelayFallbacksFn || getRelayFallbacks;
|
||||||
retryBaseDelayMs = 500,
|
this.getMinActiveRelayPoolFn = deps.getMinActiveRelayPoolFn || getMinActiveRelayPool;
|
||||||
retryCapDelayMs = 8_000,
|
this.retryAttempts = deps.retryAttempts || DEFAULT_RETRY_ATTEMPTS;
|
||||||
sleepFn = (ms) => new Promise((resolve) => setTimeout(resolve, ms)),
|
this.retryBaseDelayMs = deps.retryBaseDelayMs || DEFAULT_RETRY_BASE_DELAY_MS;
|
||||||
randomFn = secureRandom,
|
this.retryCapDelayMs = deps.retryCapDelayMs || DEFAULT_RETRY_CAP_DELAY_MS;
|
||||||
telemetryLogger = console.error,
|
this.sleepFn = deps.sleepFn || ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
|
||||||
healthLogger = console.error,
|
this.randomFn = deps.randomFn || secureRandom;
|
||||||
diagnostics = {},
|
this.telemetryLogger = deps.telemetryLogger || console.error;
|
||||||
} = deps;
|
this.healthLogger = deps.healthLogger || console.error;
|
||||||
|
this.diagnostics = deps.diagnostics || {};
|
||||||
|
this.healthManager = deps.healthManager || defaultHealthManager;
|
||||||
|
|
||||||
|
// Derived values initialized later in async method
|
||||||
|
this.attemptId = deps.diagnostics?.attemptId || deps.attemptId || randomUUID();
|
||||||
|
this.correlationId = deps.diagnostics?.correlationId || deps.correlationId || randomUUID();
|
||||||
|
|
||||||
|
this.pool = this.poolFactory();
|
||||||
|
}
|
||||||
|
|
||||||
async publish() {
|
async publish() {
|
||||||
|
this.publishTimeoutMs = await this.getPublishTimeoutMsFn();
|
||||||
|
this.minSuccesses = await this.getMinSuccessfulRelayPublishesFn();
|
||||||
|
this.fallbackRelays = (await this.getRelayFallbacksFn()).filter((relay) => !this.relays.includes(relay));
|
||||||
|
const minActive = await this.getMinActiveRelayPoolFn();
|
||||||
|
this.healthConfig = buildRelayHealthConfig({
|
||||||
|
rollingWindowSize: DEFAULT_ROLLING_WINDOW_SIZE,
|
||||||
|
minActiveRelayPool: minActive,
|
||||||
|
...this.diagnostics, // Assuming diagnostics might carry config overrides? Or better, just rely on defaults/config
|
||||||
|
});
|
||||||
|
|
||||||
|
this.allRelays = mergeRelayList(this.relays, this.fallbackRelays);
|
||||||
|
this.maxAttempts = this.retryAttempts;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
maybeLogHealthSnapshot(this.allRelays, this.healthConfig, this.healthLogger, 'publish:periodic');
|
this.healthManager.maybeLogSnapshot(this.allRelays, this.healthConfig, this.healthLogger, 'publish:periodic');
|
||||||
let lastAttemptState = null;
|
let lastAttemptState = null;
|
||||||
const retryTimeline = [];
|
const retryTimeline = [];
|
||||||
const overallStartedAt = Date.now();
|
const overallStartedAt = Date.now();
|
||||||
@@ -500,7 +532,7 @@ export async function publishLock(relays, event, deps = {}) {
|
|||||||
|
|
||||||
async attemptPhase(phaseRelays, phaseName, attempted, publishResults) {
|
async attemptPhase(phaseRelays, phaseName, attempted, publishResults) {
|
||||||
if (!phaseRelays.length) return;
|
if (!phaseRelays.length) return;
|
||||||
const { prioritized } = prioritizeRelays(phaseRelays, this.healthConfig);
|
const { prioritized } = this.healthManager.prioritizeRelays(phaseRelays, this.healthConfig);
|
||||||
if (!prioritized.length) return;
|
if (!prioritized.length) return;
|
||||||
|
|
||||||
console.error(`[${phaseName}] Publishing to ${prioritized.length} relays (${prioritized.join(', ')})...`);
|
console.error(`[${phaseName}] Publishing to ${prioritized.length} relays (${prioritized.join(', ')})...`);
|
||||||
@@ -513,7 +545,7 @@ export async function publishLock(relays, event, deps = {}) {
|
|||||||
const elapsedMs = Date.now() - startedAtMs;
|
const elapsedMs = Date.now() - startedAtMs;
|
||||||
for (const result of phaseResults) {
|
for (const result of phaseResults) {
|
||||||
result.latencyMs = elapsedMs;
|
result.latencyMs = elapsedMs;
|
||||||
recordRelayOutcome(result.relay, result.success, result.message, elapsedMs, this.healthConfig);
|
this.healthManager.recordOutcome(result.relay, result.success, result.message, elapsedMs, this.healthConfig);
|
||||||
}
|
}
|
||||||
publishResults.push(...phaseResults);
|
publishResults.push(...phaseResults);
|
||||||
}
|
}
|
||||||
@@ -601,7 +633,7 @@ export async function publishLock(relays, event, deps = {}) {
|
|||||||
totalElapsedMs: Date.now() - overallStartedAt,
|
totalElapsedMs: Date.now() - overallStartedAt,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
maybeLogHealthSnapshot(this.allRelays, this.healthConfig, this.healthLogger, 'publish:failure', true);
|
this.healthManager.maybeLogSnapshot(this.allRelays, this.healthConfig, this.healthLogger, 'publish:failure', true);
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Failed relay publish quorum in publish phase: ${lastAttemptState.successCount}/${lastAttemptState.attempted.size} successful `
|
`Failed relay publish quorum in publish phase: ${lastAttemptState.successCount}/${lastAttemptState.attempted.size} successful `
|
||||||
+ `(required=${this.minSuccesses}, timeout=${this.publishTimeoutMs}ms, attempts=${this.maxAttempts}, attempt_id=${this.attemptId}, correlation_id=${this.correlationId}, error_category=${terminalFailureCategory}, total_retry_timeline_ms=${Date.now() - overallStartedAt})\n`
|
+ `(required=${this.minSuccesses}, timeout=${this.publishTimeoutMs}ms, attempts=${this.maxAttempts}, attempt_id=${this.attemptId}, correlation_id=${this.correlationId}, error_category=${terminalFailureCategory}, total_retry_timeline_ms=${Date.now() - overallStartedAt})\n`
|
||||||
|
|||||||
@@ -0,0 +1,227 @@
|
|||||||
|
|
||||||
|
> [email protected] test:unit:lock-backend
|
||||||
|
> node --test test/lock-ops.test.mjs test/lock-ops-publish-retry.test.mjs
|
||||||
|
|
||||||
|
TAP version 13
|
||||||
|
# [publish:primary] Publishing to 1 relays (wss://relay-a)...
|
||||||
|
# Published to 1/1 relays (required=1, timeout=200ms)
|
||||||
|
# [publish:primary] Publishing to 1 relays (wss://relay-a)...
|
||||||
|
# [publish:primary] Publishing to 1 relays (wss://relay-a)...
|
||||||
|
# Published to 1/1 relays (required=1, timeout=200ms)
|
||||||
|
# [publish:primary] Publishing to 1 relays (wss://relay-a)...
|
||||||
|
# [publish:primary] Publishing to 1 relays (wss://relay-a)...
|
||||||
|
# [publish:primary] Publishing to 1 relays (wss://relay-a)...
|
||||||
|
# [publish:primary] Publishing to 1 relays (wss://relay-a)...
|
||||||
|
# (node:3973) ExperimentalWarning: The MockTimers API is an experimental feature and might change at any time
|
||||||
|
# (Use `node --trace-warnings ...` to show where the warning was created)
|
||||||
|
# Subtest: publishLock retry behavior
|
||||||
|
# Subtest: succeeds immediately on first attempt without retries
|
||||||
|
ok 1 - succeeds immediately on first attempt without retries
|
||||||
|
---
|
||||||
|
duration_ms: 6.654526
|
||||||
|
type: 'test'
|
||||||
|
...
|
||||||
|
# Subtest: retries a transient failure then succeeds within retry budget with bounded jitter
|
||||||
|
ok 2 - retries a transient failure then succeeds within retry budget with bounded jitter
|
||||||
|
---
|
||||||
|
duration_ms: 4.073858
|
||||||
|
type: 'test'
|
||||||
|
...
|
||||||
|
# Subtest: returns terminal relay_publish_quorum_failure after exhausting retry budget
|
||||||
|
ok 3 - returns terminal relay_publish_quorum_failure after exhausting retry budget
|
||||||
|
---
|
||||||
|
duration_ms: 5.742571
|
||||||
|
type: 'test'
|
||||||
|
...
|
||||||
|
# Subtest: short-circuits non-retryable failures without extra attempts
|
||||||
|
ok 4 - short-circuits non-retryable failures without extra attempts
|
||||||
|
---
|
||||||
|
duration_ms: 2.299061
|
||||||
|
type: 'test'
|
||||||
|
...
|
||||||
|
1..4
|
||||||
|
ok 1 - publishLock retry behavior
|
||||||
|
---
|
||||||
|
duration_ms: 20.363862
|
||||||
|
type: 'suite'
|
||||||
|
...
|
||||||
|
# Subtest: lock-ops
|
||||||
|
# Subtest: parseLockEvent
|
||||||
|
# Subtest: parses a valid lock event correctly
|
||||||
|
ok 1 - parses a valid lock event correctly
|
||||||
|
---
|
||||||
|
duration_ms: 1.874948
|
||||||
|
type: 'test'
|
||||||
|
...
|
||||||
|
1..1
|
||||||
|
ok 1 - parseLockEvent
|
||||||
|
---
|
||||||
|
duration_ms: 2.822323
|
||||||
|
type: 'suite'
|
||||||
|
...
|
||||||
|
# [publish:primary] Publishing to 2 relays (wss://primary-a, wss://primary-b)...
|
||||||
|
# [publish:primary] Publishing to 2 relays (wss://primary-a, wss://primary-b)...
|
||||||
|
# Published to 2/2 relays (required=1, timeout=200ms)
|
||||||
|
# [publish:primary] Publishing to 1 relays (wss://primary-down)...
|
||||||
|
# [publish:primary] Publishing to 1 relays (wss://primary-down)...
|
||||||
|
# [publish:primary] Publishing to 1 relays (wss://primary-down)...
|
||||||
|
# [publish:primary] Publishing to 1 relays (wss://primary-bad)...
|
||||||
|
# [publish:primary] Publishing to 5 relays (relay-timeout, wss://dns, wss://tcp, wss://tls, wss://ws)...
|
||||||
|
# [publish:primary] Publishing to 2 relays (wss://relay-bad, wss://relay-ok)...
|
||||||
|
# {"event":"lock_publish_quorum_met","correlationId":"7d70b395-2145-4470-9f33-9b602a34792d","attemptId":"c0035955-5f07-4d6b-a450-e07811f00e2f","publishAttempt":1,"successCount":1,"relayAttemptedCount":2,"requiredSuccesses":1,"timeoutMs":200,"retryTimeline":[{"publishAttempt":1,"successCount":1,"relayAttemptedCount":2,"elapsedMs":1}],"totalElapsedMs":1}
|
||||||
|
# Published to 1/2 relays (required=1, timeout=200ms)
|
||||||
|
# [publish:primary] Publishing to 1 relays (wss://primary-bad)...
|
||||||
|
# [publish:fallback] Publishing to 1 relays (wss://fallback-ok)...
|
||||||
|
# {"event":"lock_publish_quorum_met","correlationId":"239da9db-92a7-44f8-b694-52a4a6ddf437","attemptId":"12267c26-1926-4f5b-835b-f92682e5ffc4","publishAttempt":1,"successCount":1,"relayAttemptedCount":2,"requiredSuccesses":1,"timeoutMs":200,"retryTimeline":[{"publishAttempt":1,"successCount":1,"relayAttemptedCount":2,"elapsedMs":0}],"totalElapsedMs":0}
|
||||||
|
# Published to 1/2 relays (required=1, timeout=200ms)
|
||||||
|
# [publish:primary] Publishing to 2 relays (wss://bad, wss://healthy)...
|
||||||
|
# {"event":"lock_publish_quorum_met","correlationId":"54df96c1-356d-40a2-a300-0a5fce94d1f9","attemptId":"72e3fd52-0c75-4f3f-a43f-241ed8d973e1","publishAttempt":1,"successCount":1,"relayAttemptedCount":2,"requiredSuccesses":1,"timeoutMs":200,"retryTimeline":[{"publishAttempt":1,"successCount":1,"relayAttemptedCount":2,"elapsedMs":0}],"totalElapsedMs":0}
|
||||||
|
# Published to 1/2 relays (required=1, timeout=200ms)
|
||||||
|
# [publish:primary] Publishing to 2 relays (wss://healthy, wss://bad)...
|
||||||
|
# {"event":"lock_publish_quorum_met","correlationId":"35e05397-38ab-4fd5-b979-9f731dc5765a","attemptId":"c6410080-1244-4f4b-9139-dbb85187b441","publishAttempt":1,"successCount":1,"relayAttemptedCount":2,"requiredSuccesses":1,"timeoutMs":200,"retryTimeline":[{"publishAttempt":1,"successCount":1,"relayAttemptedCount":2,"elapsedMs":0}],"totalElapsedMs":0}
|
||||||
|
# Published to 1/2 relays (required=1, timeout=200ms)
|
||||||
|
# [publish:primary] Publishing to 2 relays (wss://healthy, wss://bad)...
|
||||||
|
# {"event":"lock_publish_quorum_met","correlationId":"e6f1916c-879a-4ed2-953e-7a519c11d857","attemptId":"1aa9c36c-8755-45ca-9fe6-6a89f883c152","publishAttempt":1,"successCount":1,"relayAttemptedCount":2,"requiredSuccesses":1,"timeoutMs":200,"retryTimeline":[{"publishAttempt":1,"successCount":1,"relayAttemptedCount":2,"elapsedMs":0}],"totalElapsedMs":0}
|
||||||
|
# Published to 1/2 relays (required=1, timeout=200ms)
|
||||||
|
# [publish:primary] Publishing to 1 relays (wss://healthy)...
|
||||||
|
# {"event":"lock_publish_quorum_met","correlationId":"56c8195a-74eb-4b72-a495-3e1efcb4a3f0","attemptId":"d2e0b655-7115-4f61-91fc-139dc5ec9db4","publishAttempt":1,"successCount":1,"relayAttemptedCount":1,"requiredSuccesses":1,"timeoutMs":200,"retryTimeline":[{"publishAttempt":1,"successCount":1,"relayAttemptedCount":1,"elapsedMs":0}],"totalElapsedMs":0}
|
||||||
|
# Published to 1/1 relays (required=1, timeout=200ms)
|
||||||
|
# [publish:primary] Publishing to 2 relays (wss://primary-a, wss://primary-b)...
|
||||||
|
# [publish:fallback] Publishing to 1 relays (wss://fallback-healthy)...
|
||||||
|
# {"event":"lock_publish_quorum_met","correlationId":"94251c93-ebf1-481d-8fb5-c8a73bdf0a20","attemptId":"533fb740-98ec-4358-9d32-78c8b0ac72a4","publishAttempt":1,"successCount":1,"relayAttemptedCount":3,"requiredSuccesses":1,"timeoutMs":200,"retryTimeline":[{"publishAttempt":1,"successCount":1,"relayAttemptedCount":3,"elapsedMs":0}],"totalElapsedMs":0}
|
||||||
|
# Published to 1/3 relays (required=1, timeout=200ms)
|
||||||
|
# Subtest: queryLocks
|
||||||
|
# Subtest: falls back to fallback relays when primary query fails
|
||||||
|
ok 1 - falls back to fallback relays when primary query fails
|
||||||
|
---
|
||||||
|
duration_ms: 27.235965
|
||||||
|
type: 'test'
|
||||||
|
...
|
||||||
|
1..1
|
||||||
|
ok 2 - queryLocks
|
||||||
|
---
|
||||||
|
duration_ms: 27.514651
|
||||||
|
type: 'suite'
|
||||||
|
...
|
||||||
|
# Subtest: publishLock
|
||||||
|
# Subtest: retries transient failures and succeeds on a later attempt
|
||||||
|
not ok 1 - retries transient failures and succeeds on a later attempt
|
||||||
|
---
|
||||||
|
duration_ms: 6.53189
|
||||||
|
type: 'test'
|
||||||
|
location: '/app/test/lock-ops.test.mjs:78:5'
|
||||||
|
failureType: 'testCodeFailure'
|
||||||
|
error: |-
|
||||||
|
Expected values to be strictly deep-equal:
|
||||||
|
+ actual - expected
|
||||||
|
|
||||||
|
{
|
||||||
|
+ attemptId: '52c2baa6-8ff8-4f42-b6b3-ead606942315',
|
||||||
|
+ correlationId: '6428aa2b-60f0-40a5-b385-525fc25c46b0',
|
||||||
|
- attemptId: 'attempt-1',
|
||||||
|
- correlationId: 'corr-1',
|
||||||
|
elapsedMs: 1,
|
||||||
|
errorCategory: 'connection_reset',
|
||||||
|
event: 'lock_publish_retry',
|
||||||
|
nextDelayMs: 250,
|
||||||
|
publishAttempt: 1,
|
||||||
|
|
||||||
|
code: 'ERR_ASSERTION'
|
||||||
|
name: 'AssertionError'
|
||||||
|
expected:
|
||||||
|
event: 'lock_publish_retry'
|
||||||
|
correlationId: 'corr-1'
|
||||||
|
attemptId: 'attempt-1'
|
||||||
|
publishAttempt: 1
|
||||||
|
relayUrl: 'wss://primary-a'
|
||||||
|
errorCategory: 'connection_reset'
|
||||||
|
elapsedMs: 1
|
||||||
|
nextDelayMs: 250
|
||||||
|
actual:
|
||||||
|
event: 'lock_publish_retry'
|
||||||
|
correlationId: '6428aa2b-60f0-40a5-b385-525fc25c46b0'
|
||||||
|
attemptId: '52c2baa6-8ff8-4f42-b6b3-ead606942315'
|
||||||
|
publishAttempt: 1
|
||||||
|
relayUrl: 'wss://primary-a'
|
||||||
|
errorCategory: 'connection_reset'
|
||||||
|
elapsedMs: 1
|
||||||
|
nextDelayMs: 250
|
||||||
|
operator: 'deepStrictEqual'
|
||||||
|
stack: |-
|
||||||
|
TestContext.<anonymous> (file:///app/test/lock-ops.test.mjs:124:14)
|
||||||
|
async Test.run (node:internal/test_runner/test:1054:7)
|
||||||
|
async Promise.all (index 0)
|
||||||
|
async Suite.run (node:internal/test_runner/test:1442:7)
|
||||||
|
async Suite.processPendingSubtests (node:internal/test_runner/test:744:7)
|
||||||
|
...
|
||||||
|
# Subtest: fails after retry budget is exhausted for persistent transient failures
|
||||||
|
ok 2 - fails after retry budget is exhausted for persistent transient failures
|
||||||
|
---
|
||||||
|
duration_ms: 2.875565
|
||||||
|
type: 'test'
|
||||||
|
...
|
||||||
|
# Subtest: fails without retry for persistent validation failures
|
||||||
|
ok 3 - fails without retry for persistent validation failures
|
||||||
|
---
|
||||||
|
duration_ms: 1.360655
|
||||||
|
type: 'test'
|
||||||
|
...
|
||||||
|
# Subtest: includes per-relay reason categories and retry metadata in failure diagnostics
|
||||||
|
ok 4 - includes per-relay reason categories and retry metadata in failure diagnostics
|
||||||
|
---
|
||||||
|
duration_ms: 2.145677
|
||||||
|
type: 'test'
|
||||||
|
...
|
||||||
|
# Subtest: returns success when mixed relay outcomes still satisfy quorum
|
||||||
|
ok 5 - returns success when mixed relay outcomes still satisfy quorum
|
||||||
|
---
|
||||||
|
duration_ms: 1.586006
|
||||||
|
type: 'test'
|
||||||
|
...
|
||||||
|
# Subtest: uses fallback relays to satisfy min success quorum
|
||||||
|
ok 6 - uses fallback relays to satisfy min success quorum
|
||||||
|
---
|
||||||
|
duration_ms: 1.059862
|
||||||
|
type: 'test'
|
||||||
|
...
|
||||||
|
# Subtest: quarantines repeatedly failing relays and still reaches quorum with one healthy relay
|
||||||
|
ok 7 - quarantines repeatedly failing relays and still reaches quorum with one healthy relay
|
||||||
|
---
|
||||||
|
duration_ms: 2.500909
|
||||||
|
type: 'test'
|
||||||
|
...
|
||||||
|
# Subtest: uses fallback and min active pool to reintroduce quarantined relay when needed
|
||||||
|
ok 8 - uses fallback and min active pool to reintroduce quarantined relay when needed
|
||||||
|
---
|
||||||
|
duration_ms: 1.073546
|
||||||
|
type: 'test'
|
||||||
|
...
|
||||||
|
1..8
|
||||||
|
not ok 3 - publishLock
|
||||||
|
---
|
||||||
|
duration_ms: 19.967883
|
||||||
|
type: 'suite'
|
||||||
|
location: '/app/test/lock-ops.test.mjs:77:3'
|
||||||
|
failureType: 'subtestsFailed'
|
||||||
|
error: '1 subtest failed'
|
||||||
|
code: 'ERR_TEST_FAILURE'
|
||||||
|
...
|
||||||
|
1..3
|
||||||
|
not ok 2 - lock-ops
|
||||||
|
---
|
||||||
|
duration_ms: 52.981447
|
||||||
|
type: 'suite'
|
||||||
|
location: '/app/test/lock-ops.test.mjs:10:1'
|
||||||
|
failureType: 'subtestsFailed'
|
||||||
|
error: '1 subtest failed'
|
||||||
|
code: 'ERR_TEST_FAILURE'
|
||||||
|
...
|
||||||
|
1..2
|
||||||
|
# tests 14
|
||||||
|
# suites 5
|
||||||
|
# pass 13
|
||||||
|
# fail 1
|
||||||
|
# cancelled 0
|
||||||
|
# skipped 0
|
||||||
|
# todo 0
|
||||||
|
# duration_ms 196.37029
|
||||||
@@ -0,0 +1,175 @@
|
|||||||
|
|
||||||
|
> [email protected] test:unit:lock-backend
|
||||||
|
> node --test test/lock-ops.test.mjs test/lock-ops-publish-retry.test.mjs
|
||||||
|
|
||||||
|
TAP version 13
|
||||||
|
# [publish:primary] Publishing to 1 relays (wss://relay-a)...
|
||||||
|
# Published to 1/1 relays (required=1, timeout=200ms)
|
||||||
|
# [publish:primary] Publishing to 1 relays (wss://relay-a)...
|
||||||
|
# [publish:primary] Publishing to 1 relays (wss://relay-a)...
|
||||||
|
# Published to 1/1 relays (required=1, timeout=200ms)
|
||||||
|
# [publish:primary] Publishing to 1 relays (wss://relay-a)...
|
||||||
|
# [publish:primary] Publishing to 1 relays (wss://relay-a)...
|
||||||
|
# [publish:primary] Publishing to 1 relays (wss://relay-a)...
|
||||||
|
# [publish:primary] Publishing to 1 relays (wss://relay-a)...
|
||||||
|
# (node:5876) ExperimentalWarning: The MockTimers API is an experimental feature and might change at any time
|
||||||
|
# (Use `node --trace-warnings ...` to show where the warning was created)
|
||||||
|
# Subtest: publishLock retry behavior
|
||||||
|
# Subtest: succeeds immediately on first attempt without retries
|
||||||
|
ok 1 - succeeds immediately on first attempt without retries
|
||||||
|
---
|
||||||
|
duration_ms: 6.413745
|
||||||
|
type: 'test'
|
||||||
|
...
|
||||||
|
# Subtest: retries a transient failure then succeeds within retry budget with bounded jitter
|
||||||
|
ok 2 - retries a transient failure then succeeds within retry budget with bounded jitter
|
||||||
|
---
|
||||||
|
duration_ms: 3.062285
|
||||||
|
type: 'test'
|
||||||
|
...
|
||||||
|
# Subtest: returns terminal relay_publish_quorum_failure after exhausting retry budget
|
||||||
|
ok 3 - returns terminal relay_publish_quorum_failure after exhausting retry budget
|
||||||
|
---
|
||||||
|
duration_ms: 4.611267
|
||||||
|
type: 'test'
|
||||||
|
...
|
||||||
|
# Subtest: short-circuits non-retryable failures without extra attempts
|
||||||
|
ok 4 - short-circuits non-retryable failures without extra attempts
|
||||||
|
---
|
||||||
|
duration_ms: 2.07494
|
||||||
|
type: 'test'
|
||||||
|
...
|
||||||
|
1..4
|
||||||
|
ok 1 - publishLock retry behavior
|
||||||
|
---
|
||||||
|
duration_ms: 17.852297
|
||||||
|
type: 'suite'
|
||||||
|
...
|
||||||
|
# Subtest: lock-ops
|
||||||
|
# Subtest: parseLockEvent
|
||||||
|
# Subtest: parses a valid lock event correctly
|
||||||
|
ok 1 - parses a valid lock event correctly
|
||||||
|
---
|
||||||
|
duration_ms: 1.583449
|
||||||
|
type: 'test'
|
||||||
|
...
|
||||||
|
1..1
|
||||||
|
ok 1 - parseLockEvent
|
||||||
|
---
|
||||||
|
duration_ms: 2.601962
|
||||||
|
type: 'suite'
|
||||||
|
...
|
||||||
|
# [publish:primary] Publishing to 2 relays (wss://primary-a, wss://primary-b)...
|
||||||
|
# [publish:primary] Publishing to 2 relays (wss://primary-a, wss://primary-b)...
|
||||||
|
# Published to 2/2 relays (required=1, timeout=200ms)
|
||||||
|
# [publish:primary] Publishing to 1 relays (wss://primary-down)...
|
||||||
|
# [publish:primary] Publishing to 1 relays (wss://primary-down)...
|
||||||
|
# [publish:primary] Publishing to 1 relays (wss://primary-down)...
|
||||||
|
# [publish:primary] Publishing to 1 relays (wss://primary-bad)...
|
||||||
|
# [publish:primary] Publishing to 5 relays (relay-timeout, wss://dns, wss://tcp, wss://tls, wss://ws)...
|
||||||
|
# [publish:primary] Publishing to 2 relays (wss://relay-bad, wss://relay-ok)...
|
||||||
|
# {"event":"lock_publish_quorum_met","correlationId":"1be06dfa-a31e-42b0-b789-327fd9e11131","attemptId":"10405dd5-2f84-4e23-9a5a-696abb34c1bc","publishAttempt":1,"successCount":1,"relayAttemptedCount":2,"requiredSuccesses":1,"timeoutMs":200,"retryTimeline":[{"publishAttempt":1,"successCount":1,"relayAttemptedCount":2,"elapsedMs":1}],"totalElapsedMs":1}
|
||||||
|
# Published to 1/2 relays (required=1, timeout=200ms)
|
||||||
|
# [publish:primary] Publishing to 1 relays (wss://primary-bad)...
|
||||||
|
# [publish:fallback] Publishing to 1 relays (wss://fallback-ok)...
|
||||||
|
# {"event":"lock_publish_quorum_met","correlationId":"becb5a52-cef6-4bc6-84b1-ca4d14d63e04","attemptId":"25dca8be-61ee-42b8-a764-7ebdc46f234b","publishAttempt":1,"successCount":1,"relayAttemptedCount":2,"requiredSuccesses":1,"timeoutMs":200,"retryTimeline":[{"publishAttempt":1,"successCount":1,"relayAttemptedCount":2,"elapsedMs":1}],"totalElapsedMs":1}
|
||||||
|
# Published to 1/2 relays (required=1, timeout=200ms)
|
||||||
|
# [publish:primary] Publishing to 2 relays (wss://bad, wss://healthy)...
|
||||||
|
# {"event":"lock_publish_quorum_met","correlationId":"67ecc056-eaa3-40c2-9042-15e033b7a252","attemptId":"07181123-946d-4823-bc4a-c79d13a84920","publishAttempt":1,"successCount":1,"relayAttemptedCount":2,"requiredSuccesses":1,"timeoutMs":200,"retryTimeline":[{"publishAttempt":1,"successCount":1,"relayAttemptedCount":2,"elapsedMs":1}],"totalElapsedMs":1}
|
||||||
|
# Published to 1/2 relays (required=1, timeout=200ms)
|
||||||
|
# [publish:primary] Publishing to 2 relays (wss://healthy, wss://bad)...
|
||||||
|
# {"event":"lock_publish_quorum_met","correlationId":"6075ee96-8def-4111-84e2-d7b395950a84","attemptId":"bb03ae8b-ff47-41e2-ba91-b3031d38c497","publishAttempt":1,"successCount":1,"relayAttemptedCount":2,"requiredSuccesses":1,"timeoutMs":200,"retryTimeline":[{"publishAttempt":1,"successCount":1,"relayAttemptedCount":2,"elapsedMs":0}],"totalElapsedMs":0}
|
||||||
|
# Published to 1/2 relays (required=1, timeout=200ms)
|
||||||
|
# [publish:primary] Publishing to 2 relays (wss://healthy, wss://bad)...
|
||||||
|
# {"event":"lock_publish_quorum_met","correlationId":"38f8db94-b61b-4b02-9a33-05fd8da73e5e","attemptId":"e645bbac-64ec-4f61-a865-a91d0adc739c","publishAttempt":1,"successCount":1,"relayAttemptedCount":2,"requiredSuccesses":1,"timeoutMs":200,"retryTimeline":[{"publishAttempt":1,"successCount":1,"relayAttemptedCount":2,"elapsedMs":1}],"totalElapsedMs":1}
|
||||||
|
# Published to 1/2 relays (required=1, timeout=200ms)
|
||||||
|
# [publish:primary] Publishing to 1 relays (wss://healthy)...
|
||||||
|
# {"event":"lock_publish_quorum_met","correlationId":"4c6a0906-bd5b-431b-9af1-1d4a87aa59d3","attemptId":"13836194-8337-49af-8f81-8038a7101d4b","publishAttempt":1,"successCount":1,"relayAttemptedCount":1,"requiredSuccesses":1,"timeoutMs":200,"retryTimeline":[{"publishAttempt":1,"successCount":1,"relayAttemptedCount":1,"elapsedMs":0}],"totalElapsedMs":0}
|
||||||
|
# Published to 1/1 relays (required=1, timeout=200ms)
|
||||||
|
# [publish:primary] Publishing to 2 relays (wss://primary-a, wss://primary-b)...
|
||||||
|
# [publish:fallback] Publishing to 1 relays (wss://fallback-healthy)...
|
||||||
|
# {"event":"lock_publish_quorum_met","correlationId":"2e7e8c9f-5b93-4cd3-8324-a63b981e9e4c","attemptId":"d53e657e-431a-4203-a017-256ba03a05db","publishAttempt":1,"successCount":1,"relayAttemptedCount":3,"requiredSuccesses":1,"timeoutMs":200,"retryTimeline":[{"publishAttempt":1,"successCount":1,"relayAttemptedCount":3,"elapsedMs":1}],"totalElapsedMs":2}
|
||||||
|
# Published to 1/3 relays (required=1, timeout=200ms)
|
||||||
|
# Subtest: queryLocks
|
||||||
|
# Subtest: falls back to fallback relays when primary query fails
|
||||||
|
ok 1 - falls back to fallback relays when primary query fails
|
||||||
|
---
|
||||||
|
duration_ms: 27.905124
|
||||||
|
type: 'test'
|
||||||
|
...
|
||||||
|
1..1
|
||||||
|
ok 2 - queryLocks
|
||||||
|
---
|
||||||
|
duration_ms: 28.20218
|
||||||
|
type: 'suite'
|
||||||
|
...
|
||||||
|
# Subtest: publishLock
|
||||||
|
# Subtest: retries transient failures and succeeds on a later attempt
|
||||||
|
ok 1 - retries transient failures and succeeds on a later attempt
|
||||||
|
---
|
||||||
|
duration_ms: 4.944259
|
||||||
|
type: 'test'
|
||||||
|
...
|
||||||
|
# Subtest: fails after retry budget is exhausted for persistent transient failures
|
||||||
|
ok 2 - fails after retry budget is exhausted for persistent transient failures
|
||||||
|
---
|
||||||
|
duration_ms: 3.551748
|
||||||
|
type: 'test'
|
||||||
|
...
|
||||||
|
# Subtest: fails without retry for persistent validation failures
|
||||||
|
ok 3 - fails without retry for persistent validation failures
|
||||||
|
---
|
||||||
|
duration_ms: 1.406267
|
||||||
|
type: 'test'
|
||||||
|
...
|
||||||
|
# Subtest: includes per-relay reason categories and retry metadata in failure diagnostics
|
||||||
|
ok 4 - includes per-relay reason categories and retry metadata in failure diagnostics
|
||||||
|
---
|
||||||
|
duration_ms: 2.101245
|
||||||
|
type: 'test'
|
||||||
|
...
|
||||||
|
# Subtest: returns success when mixed relay outcomes still satisfy quorum
|
||||||
|
ok 5 - returns success when mixed relay outcomes still satisfy quorum
|
||||||
|
---
|
||||||
|
duration_ms: 1.547853
|
||||||
|
type: 'test'
|
||||||
|
...
|
||||||
|
# Subtest: uses fallback relays to satisfy min success quorum
|
||||||
|
ok 6 - uses fallback relays to satisfy min success quorum
|
||||||
|
---
|
||||||
|
duration_ms: 1.380374
|
||||||
|
type: 'test'
|
||||||
|
...
|
||||||
|
# Subtest: quarantines repeatedly failing relays and still reaches quorum with one healthy relay
|
||||||
|
ok 7 - quarantines repeatedly failing relays and still reaches quorum with one healthy relay
|
||||||
|
---
|
||||||
|
duration_ms: 3.040514
|
||||||
|
type: 'test'
|
||||||
|
...
|
||||||
|
# Subtest: uses fallback and min active pool to reintroduce quarantined relay when needed
|
||||||
|
ok 8 - uses fallback and min active pool to reintroduce quarantined relay when needed
|
||||||
|
---
|
||||||
|
duration_ms: 2.862114
|
||||||
|
type: 'test'
|
||||||
|
...
|
||||||
|
1..8
|
||||||
|
ok 3 - publishLock
|
||||||
|
---
|
||||||
|
duration_ms: 21.884946
|
||||||
|
type: 'suite'
|
||||||
|
...
|
||||||
|
1..3
|
||||||
|
ok 2 - lock-ops
|
||||||
|
---
|
||||||
|
duration_ms: 53.519877
|
||||||
|
type: 'suite'
|
||||||
|
...
|
||||||
|
1..2
|
||||||
|
# tests 14
|
||||||
|
# suites 5
|
||||||
|
# pass 14
|
||||||
|
# fail 0
|
||||||
|
# cancelled 0
|
||||||
|
# skipped 0
|
||||||
|
# todo 0
|
||||||
|
# duration_ms 212.244831
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
- [x] Extract lock-ops constants to src/constants.mjs
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
---
|
||||||
|
cadence: daily
|
||||||
|
agent: const-refactor-agent
|
||||||
|
status: completed
|
||||||
|
reason: 'Scheduler cycle completed successfully'
|
||||||
|
created_at: 2026-02-17T19-48-02Z
|
||||||
|
timestamp: 2026-02-17T19-48-02Z
|
||||||
|
platform: linux
|
||||||
|
---
|
||||||
|
|
||||||
|
# Scheduler completed
|
||||||
|
|
||||||
|
- reason: Scheduler cycle completed successfully
|
||||||
|
- platform: linux
|
||||||
|
- details: Extracted lock backend constants to src/constants.mjs, refactored lock-ops.mjs, fixed cmd-check.mjs bug.
|
||||||
Reference in new issue
Block a user