@blokjs/runner 0.2.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/dist/Blok.d.ts +19 -0
- package/dist/Blok.js +184 -0
- package/dist/Blok.js.map +1 -0
- package/dist/BlokResponse.d.ts +16 -0
- package/dist/BlokResponse.js +28 -0
- package/dist/BlokResponse.js.map +1 -0
- package/dist/Configuration.d.ts +37 -0
- package/dist/Configuration.js +248 -0
- package/dist/Configuration.js.map +1 -0
- package/dist/ConfigurationResolver.d.ts +7 -0
- package/dist/ConfigurationResolver.js +15 -0
- package/dist/ConfigurationResolver.js.map +1 -0
- package/dist/DefaultLogger.d.ts +65 -0
- package/dist/DefaultLogger.js +101 -0
- package/dist/DefaultLogger.js.map +1 -0
- package/dist/LocalStorage.d.ts +7 -0
- package/dist/LocalStorage.js +56 -0
- package/dist/LocalStorage.js.map +1 -0
- package/dist/MemoryUsage.d.ts +22 -0
- package/dist/MemoryUsage.js +83 -0
- package/dist/MemoryUsage.js.map +1 -0
- package/dist/NodeMap.d.ts +7 -0
- package/dist/NodeMap.js +13 -0
- package/dist/NodeMap.js.map +1 -0
- package/dist/ResolverBase.d.ts +8 -0
- package/dist/ResolverBase.js +18 -0
- package/dist/ResolverBase.js.map +1 -0
- package/dist/Runner.d.ts +25 -0
- package/dist/Runner.js +32 -0
- package/dist/Runner.js.map +1 -0
- package/dist/RunnerNode.d.ts +9 -0
- package/dist/RunnerNode.js +8 -0
- package/dist/RunnerNode.js.map +1 -0
- package/dist/RunnerNodeBase.d.ts +4 -0
- package/dist/RunnerNodeBase.js +3 -0
- package/dist/RunnerNodeBase.js.map +1 -0
- package/dist/RunnerSteps.d.ts +14 -0
- package/dist/RunnerSteps.js +110 -0
- package/dist/RunnerSteps.js.map +1 -0
- package/dist/RuntimeAdapterNode.d.ts +19 -0
- package/dist/RuntimeAdapterNode.js +87 -0
- package/dist/RuntimeAdapterNode.js.map +1 -0
- package/dist/RuntimeRegistry.d.ts +61 -0
- package/dist/RuntimeRegistry.js +87 -0
- package/dist/RuntimeRegistry.js.map +1 -0
- package/dist/TriggerBase.d.ts +119 -0
- package/dist/TriggerBase.js +413 -0
- package/dist/TriggerBase.js.map +1 -0
- package/dist/adapters/BunRuntimeAdapter.d.ts +38 -0
- package/dist/adapters/BunRuntimeAdapter.js +169 -0
- package/dist/adapters/BunRuntimeAdapter.js.map +1 -0
- package/dist/adapters/DockerRuntimeAdapter.d.ts +85 -0
- package/dist/adapters/DockerRuntimeAdapter.js +298 -0
- package/dist/adapters/DockerRuntimeAdapter.js.map +1 -0
- package/dist/adapters/HttpRuntimeAdapter.d.ts +58 -0
- package/dist/adapters/HttpRuntimeAdapter.js +152 -0
- package/dist/adapters/HttpRuntimeAdapter.js.map +1 -0
- package/dist/adapters/NodeJsRuntimeAdapter.d.ts +23 -0
- package/dist/adapters/NodeJsRuntimeAdapter.js +67 -0
- package/dist/adapters/NodeJsRuntimeAdapter.js.map +1 -0
- package/dist/adapters/RuntimeAdapter.d.ts +42 -0
- package/dist/adapters/RuntimeAdapter.js +2 -0
- package/dist/adapters/RuntimeAdapter.js.map +1 -0
- package/dist/adapters/WasmRuntimeAdapter.d.ts +69 -0
- package/dist/adapters/WasmRuntimeAdapter.js +279 -0
- package/dist/adapters/WasmRuntimeAdapter.js.map +1 -0
- package/dist/cache/NodeResultCache.d.ts +286 -0
- package/dist/cache/NodeResultCache.js +499 -0
- package/dist/cache/NodeResultCache.js.map +1 -0
- package/dist/cache/index.d.ts +1 -0
- package/dist/cache/index.js +2 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/cost/CostEstimator.d.ts +57 -0
- package/dist/cost/CostEstimator.js +171 -0
- package/dist/cost/CostEstimator.js.map +1 -0
- package/dist/cost/index.d.ts +4 -0
- package/dist/cost/index.js +3 -0
- package/dist/cost/index.js.map +1 -0
- package/dist/cost/pricing.d.ts +24 -0
- package/dist/cost/pricing.js +169 -0
- package/dist/cost/pricing.js.map +1 -0
- package/dist/defineNode.d.ts +155 -0
- package/dist/defineNode.js +191 -0
- package/dist/defineNode.js.map +1 -0
- package/dist/graphql/GraphQLSchemaGenerator.d.ts +129 -0
- package/dist/graphql/GraphQLSchemaGenerator.js +425 -0
- package/dist/graphql/GraphQLSchemaGenerator.js.map +1 -0
- package/dist/hmr/FileWatcher.d.ts +62 -0
- package/dist/hmr/FileWatcher.js +185 -0
- package/dist/hmr/FileWatcher.js.map +1 -0
- package/dist/hmr/HmrDevConsole.d.ts +13 -0
- package/dist/hmr/HmrDevConsole.js +46 -0
- package/dist/hmr/HmrDevConsole.js.map +1 -0
- package/dist/hmr/HotReloadManager.d.ts +84 -0
- package/dist/hmr/HotReloadManager.js +195 -0
- package/dist/hmr/HotReloadManager.js.map +1 -0
- package/dist/hmr/index.d.ts +39 -0
- package/dist/hmr/index.js +38 -0
- package/dist/hmr/index.js.map +1 -0
- package/dist/index.d.ts +107 -0
- package/dist/index.js +107 -0
- package/dist/index.js.map +1 -0
- package/dist/integrations/APMIntegration.d.ts +141 -0
- package/dist/integrations/APMIntegration.js +212 -0
- package/dist/integrations/APMIntegration.js.map +1 -0
- package/dist/integrations/AzureMonitorIntegration.d.ts +118 -0
- package/dist/integrations/AzureMonitorIntegration.js +254 -0
- package/dist/integrations/AzureMonitorIntegration.js.map +1 -0
- package/dist/integrations/CloudWatchIntegration.d.ts +135 -0
- package/dist/integrations/CloudWatchIntegration.js +293 -0
- package/dist/integrations/CloudWatchIntegration.js.map +1 -0
- package/dist/integrations/SentryIntegration.d.ts +153 -0
- package/dist/integrations/SentryIntegration.js +200 -0
- package/dist/integrations/SentryIntegration.js.map +1 -0
- package/dist/integrations/index.d.ts +19 -0
- package/dist/integrations/index.js +16 -0
- package/dist/integrations/index.js.map +1 -0
- package/dist/marketplace/RuntimeAutoScaler.d.ts +148 -0
- package/dist/marketplace/RuntimeAutoScaler.js +366 -0
- package/dist/marketplace/RuntimeAutoScaler.js.map +1 -0
- package/dist/marketplace/RuntimeCatalog.d.ts +174 -0
- package/dist/marketplace/RuntimeCatalog.js +339 -0
- package/dist/marketplace/RuntimeCatalog.js.map +1 -0
- package/dist/marketplace/RuntimeDiscovery.d.ts +86 -0
- package/dist/marketplace/RuntimeDiscovery.js +219 -0
- package/dist/marketplace/RuntimeDiscovery.js.map +1 -0
- package/dist/marketplace/RuntimeHealthMonitor.d.ts +100 -0
- package/dist/marketplace/RuntimeHealthMonitor.js +241 -0
- package/dist/marketplace/RuntimeHealthMonitor.js.map +1 -0
- package/dist/marketplace/RuntimeMetricsDashboard.d.ts +113 -0
- package/dist/marketplace/RuntimeMetricsDashboard.js +293 -0
- package/dist/marketplace/RuntimeMetricsDashboard.js.map +1 -0
- package/dist/monitoring/CircuitBreaker.d.ts +107 -0
- package/dist/monitoring/CircuitBreaker.js +238 -0
- package/dist/monitoring/CircuitBreaker.js.map +1 -0
- package/dist/monitoring/DistributedTracer.d.ts +125 -0
- package/dist/monitoring/DistributedTracer.js +230 -0
- package/dist/monitoring/DistributedTracer.js.map +1 -0
- package/dist/monitoring/HealthCheck.d.ts +54 -0
- package/dist/monitoring/HealthCheck.js +102 -0
- package/dist/monitoring/HealthCheck.js.map +1 -0
- package/dist/monitoring/PerformanceProfiler.d.ts +63 -0
- package/dist/monitoring/PerformanceProfiler.js +229 -0
- package/dist/monitoring/PerformanceProfiler.js.map +1 -0
- package/dist/monitoring/PrometheusBootstrap.d.ts +30 -0
- package/dist/monitoring/PrometheusBootstrap.js +71 -0
- package/dist/monitoring/PrometheusBootstrap.js.map +1 -0
- package/dist/monitoring/PrometheusMetricsBridge.d.ts +60 -0
- package/dist/monitoring/PrometheusMetricsBridge.js +216 -0
- package/dist/monitoring/PrometheusMetricsBridge.js.map +1 -0
- package/dist/monitoring/RateLimiter.d.ts +58 -0
- package/dist/monitoring/RateLimiter.js +128 -0
- package/dist/monitoring/RateLimiter.js.map +1 -0
- package/dist/monitoring/StructuredLogger.d.ts +131 -0
- package/dist/monitoring/StructuredLogger.js +207 -0
- package/dist/monitoring/StructuredLogger.js.map +1 -0
- package/dist/monitoring/TracingBootstrap.d.ts +69 -0
- package/dist/monitoring/TracingBootstrap.js +129 -0
- package/dist/monitoring/TracingBootstrap.js.map +1 -0
- package/dist/monitoring/TriggerMetricsCollector.d.ts +94 -0
- package/dist/monitoring/TriggerMetricsCollector.js +174 -0
- package/dist/monitoring/TriggerMetricsCollector.js.map +1 -0
- package/dist/monitoring/index.d.ts +9 -0
- package/dist/monitoring/index.js +10 -0
- package/dist/monitoring/index.js.map +1 -0
- package/dist/openapi/OpenAPIGenerator.d.ts +192 -0
- package/dist/openapi/OpenAPIGenerator.js +373 -0
- package/dist/openapi/OpenAPIGenerator.js.map +1 -0
- package/dist/openapi/index.d.ts +20 -0
- package/dist/openapi/index.js +20 -0
- package/dist/openapi/index.js.map +1 -0
- package/dist/security/ABAC.d.ts +224 -0
- package/dist/security/ABAC.js +380 -0
- package/dist/security/ABAC.js.map +1 -0
- package/dist/security/AuditLogger.d.ts +242 -0
- package/dist/security/AuditLogger.js +317 -0
- package/dist/security/AuditLogger.js.map +1 -0
- package/dist/security/AuthMiddleware.d.ts +163 -0
- package/dist/security/AuthMiddleware.js +274 -0
- package/dist/security/AuthMiddleware.js.map +1 -0
- package/dist/security/EncryptionAtRest.d.ts +206 -0
- package/dist/security/EncryptionAtRest.js +236 -0
- package/dist/security/EncryptionAtRest.js.map +1 -0
- package/dist/security/OAuthProvider.d.ts +334 -0
- package/dist/security/OAuthProvider.js +719 -0
- package/dist/security/OAuthProvider.js.map +1 -0
- package/dist/security/PIIDetector.d.ts +233 -0
- package/dist/security/PIIDetector.js +354 -0
- package/dist/security/PIIDetector.js.map +1 -0
- package/dist/security/RBAC.d.ts +143 -0
- package/dist/security/RBAC.js +285 -0
- package/dist/security/RBAC.js.map +1 -0
- package/dist/security/SecretManager.d.ts +652 -0
- package/dist/security/SecretManager.js +1146 -0
- package/dist/security/SecretManager.js.map +1 -0
- package/dist/security/TLSConfig.d.ts +305 -0
- package/dist/security/TLSConfig.js +550 -0
- package/dist/security/TLSConfig.js.map +1 -0
- package/dist/security/index.d.ts +79 -0
- package/dist/security/index.js +80 -0
- package/dist/security/index.js.map +1 -0
- package/dist/testing/TestHarness.d.ts +189 -0
- package/dist/testing/TestHarness.js +272 -0
- package/dist/testing/TestHarness.js.map +1 -0
- package/dist/testing/TestLogger.d.ts +103 -0
- package/dist/testing/TestLogger.js +153 -0
- package/dist/testing/TestLogger.js.map +1 -0
- package/dist/testing/WorkflowTestRunner.d.ts +172 -0
- package/dist/testing/WorkflowTestRunner.js +355 -0
- package/dist/testing/WorkflowTestRunner.js.map +1 -0
- package/dist/testing/index.d.ts +21 -0
- package/dist/testing/index.js +22 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/tracing/InMemoryRunStore.d.ts +44 -0
- package/dist/tracing/InMemoryRunStore.js +341 -0
- package/dist/tracing/InMemoryRunStore.js.map +1 -0
- package/dist/tracing/PostgresRunStore.d.ts +82 -0
- package/dist/tracing/PostgresRunStore.js +640 -0
- package/dist/tracing/PostgresRunStore.js.map +1 -0
- package/dist/tracing/RunStore.d.ts +38 -0
- package/dist/tracing/RunStore.js +2 -0
- package/dist/tracing/RunStore.js.map +1 -0
- package/dist/tracing/RunTracker.d.ts +75 -0
- package/dist/tracing/RunTracker.js +374 -0
- package/dist/tracing/RunTracker.js.map +1 -0
- package/dist/tracing/SqliteRunStore.d.ts +53 -0
- package/dist/tracing/SqliteRunStore.js +703 -0
- package/dist/tracing/SqliteRunStore.js.map +1 -0
- package/dist/tracing/TraceRouter.d.ts +47 -0
- package/dist/tracing/TraceRouter.js +904 -0
- package/dist/tracing/TraceRouter.js.map +1 -0
- package/dist/tracing/TracingLogger.d.ts +21 -0
- package/dist/tracing/TracingLogger.js +62 -0
- package/dist/tracing/TracingLogger.js.map +1 -0
- package/dist/tracing/createStore.d.ts +30 -0
- package/dist/tracing/createStore.js +75 -0
- package/dist/tracing/createStore.js.map +1 -0
- package/dist/tracing/index.d.ts +13 -0
- package/dist/tracing/index.js +9 -0
- package/dist/tracing/index.js.map +1 -0
- package/dist/tracing/sanitize.d.ts +7 -0
- package/dist/tracing/sanitize.js +95 -0
- package/dist/tracing/sanitize.js.map +1 -0
- package/dist/tracing/types.d.ts +178 -0
- package/dist/tracing/types.js +3 -0
- package/dist/tracing/types.js.map +1 -0
- package/dist/types/Average.d.ts +11 -0
- package/dist/types/Average.js +2 -0
- package/dist/types/Average.js.map +1 -0
- package/dist/types/Condition.d.ts +8 -0
- package/dist/types/Condition.js +2 -0
- package/dist/types/Condition.js.map +1 -0
- package/dist/types/Conditions.d.ts +5 -0
- package/dist/types/Conditions.js +2 -0
- package/dist/types/Conditions.js.map +1 -0
- package/dist/types/Config.d.ts +12 -0
- package/dist/types/Config.js +2 -0
- package/dist/types/Config.js.map +1 -0
- package/dist/types/Flow.d.ts +5 -0
- package/dist/types/Flow.js +2 -0
- package/dist/types/Flow.js.map +1 -0
- package/dist/types/GlobalOptions.d.ts +11 -0
- package/dist/types/GlobalOptions.js +2 -0
- package/dist/types/GlobalOptions.js.map +1 -0
- package/dist/types/Inputs.d.ts +5 -0
- package/dist/types/Inputs.js +2 -0
- package/dist/types/Inputs.js.map +1 -0
- package/dist/types/JsonLikeObject.d.ts +3 -0
- package/dist/types/JsonLikeObject.js +2 -0
- package/dist/types/JsonLikeObject.js.map +1 -0
- package/dist/types/Mapper.d.ts +5 -0
- package/dist/types/Mapper.js +2 -0
- package/dist/types/Mapper.js.map +1 -0
- package/dist/types/Node.d.ts +10 -0
- package/dist/types/Node.js +2 -0
- package/dist/types/Node.js.map +1 -0
- package/dist/types/ParamsDictionary.d.ts +3 -0
- package/dist/types/ParamsDictionary.js +2 -0
- package/dist/types/ParamsDictionary.js.map +1 -0
- package/dist/types/Properties.d.ts +5 -0
- package/dist/types/Properties.js +2 -0
- package/dist/types/Properties.js.map +1 -0
- package/dist/types/Targets.d.ts +5 -0
- package/dist/types/Targets.js +2 -0
- package/dist/types/Targets.js.map +1 -0
- package/dist/types/Trigger.d.ts +5 -0
- package/dist/types/Trigger.js +2 -0
- package/dist/types/Trigger.js.map +1 -0
- package/dist/types/TriggerHttp.d.ts +7 -0
- package/dist/types/TriggerHttp.js +2 -0
- package/dist/types/TriggerHttp.js.map +1 -0
- package/dist/types/TriggerResponse.d.ts +6 -0
- package/dist/types/TriggerResponse.js +2 -0
- package/dist/types/TriggerResponse.js.map +1 -0
- package/dist/types/Triggers.d.ts +5 -0
- package/dist/types/Triggers.js +2 -0
- package/dist/types/Triggers.js.map +1 -0
- package/dist/types/TryCatch.d.ts +6 -0
- package/dist/types/TryCatch.js +2 -0
- package/dist/types/TryCatch.js.map +1 -0
- package/dist/visualization/NodeDependencyGraph.d.ts +76 -0
- package/dist/visualization/NodeDependencyGraph.js +418 -0
- package/dist/visualization/NodeDependencyGraph.js.map +1 -0
- package/dist/visualization/WorkflowVisualizer.d.ts +144 -0
- package/dist/visualization/WorkflowVisualizer.js +446 -0
- package/dist/visualization/WorkflowVisualizer.js.map +1 -0
- package/package.json +95 -0
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Circuit Breaker Pattern for Blok Triggers
|
|
3
|
+
*
|
|
4
|
+
* Prevents cascading failures by detecting repeated errors
|
|
5
|
+
* and temporarily disabling failing operations.
|
|
6
|
+
*
|
|
7
|
+
* States:
|
|
8
|
+
* - CLOSED: Normal operation, requests flow through
|
|
9
|
+
* - OPEN: Failures exceeded threshold, requests are rejected
|
|
10
|
+
* - HALF_OPEN: Testing recovery, limited requests allowed
|
|
11
|
+
*/
|
|
12
|
+
export class CircuitBreaker {
|
|
13
|
+
state = "CLOSED";
|
|
14
|
+
failures = 0;
|
|
15
|
+
successes = 0;
|
|
16
|
+
consecutiveFailures = 0;
|
|
17
|
+
halfOpenAttempts = 0;
|
|
18
|
+
lastFailure = null;
|
|
19
|
+
lastSuccess = null;
|
|
20
|
+
lastStateChange = Date.now();
|
|
21
|
+
totalRequests = 0;
|
|
22
|
+
totalRejected = 0;
|
|
23
|
+
failureTimestamps = [];
|
|
24
|
+
config;
|
|
25
|
+
listeners = [];
|
|
26
|
+
resetTimer = null;
|
|
27
|
+
constructor(config) {
|
|
28
|
+
this.config = config;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Execute a function through the circuit breaker.
|
|
32
|
+
* Throws CircuitOpenError if the circuit is open.
|
|
33
|
+
*/
|
|
34
|
+
async execute(fn) {
|
|
35
|
+
if (!this.canExecute()) {
|
|
36
|
+
this.totalRejected++;
|
|
37
|
+
this.emit({
|
|
38
|
+
type: "request_rejected",
|
|
39
|
+
state: this.state,
|
|
40
|
+
timestamp: Date.now(),
|
|
41
|
+
});
|
|
42
|
+
throw new CircuitOpenError(`Circuit breaker is ${this.state}. Retry after ${this.getRetryAfterMs()}ms`, this.getRetryAfterMs());
|
|
43
|
+
}
|
|
44
|
+
this.totalRequests++;
|
|
45
|
+
try {
|
|
46
|
+
const result = await fn();
|
|
47
|
+
this.onSuccess();
|
|
48
|
+
return result;
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
this.onFailure(error instanceof Error ? error : new Error(String(error)));
|
|
52
|
+
throw error;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Check if the circuit allows execution without actually executing.
|
|
57
|
+
*/
|
|
58
|
+
canExecute() {
|
|
59
|
+
switch (this.state) {
|
|
60
|
+
case "CLOSED":
|
|
61
|
+
return true;
|
|
62
|
+
case "OPEN":
|
|
63
|
+
if (Date.now() - this.lastStateChange >= this.config.resetTimeoutMs) {
|
|
64
|
+
this.transitionTo("HALF_OPEN");
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
return false;
|
|
68
|
+
case "HALF_OPEN":
|
|
69
|
+
return this.halfOpenAttempts < this.config.halfOpenMaxAttempts;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Get current circuit breaker statistics.
|
|
74
|
+
*/
|
|
75
|
+
getStats() {
|
|
76
|
+
return {
|
|
77
|
+
state: this.state,
|
|
78
|
+
failures: this.failures,
|
|
79
|
+
successes: this.successes,
|
|
80
|
+
consecutiveFailures: this.consecutiveFailures,
|
|
81
|
+
lastFailure: this.lastFailure,
|
|
82
|
+
lastSuccess: this.lastSuccess,
|
|
83
|
+
lastStateChange: this.lastStateChange,
|
|
84
|
+
totalRequests: this.totalRequests,
|
|
85
|
+
totalRejected: this.totalRejected,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Get the current circuit state.
|
|
90
|
+
*/
|
|
91
|
+
getState() {
|
|
92
|
+
// Check if OPEN should transition to HALF_OPEN
|
|
93
|
+
if (this.state === "OPEN" && Date.now() - this.lastStateChange >= this.config.resetTimeoutMs) {
|
|
94
|
+
this.transitionTo("HALF_OPEN");
|
|
95
|
+
}
|
|
96
|
+
return this.state;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Get estimated time before the circuit will attempt recovery.
|
|
100
|
+
*/
|
|
101
|
+
getRetryAfterMs() {
|
|
102
|
+
if (this.state !== "OPEN")
|
|
103
|
+
return 0;
|
|
104
|
+
const elapsed = Date.now() - this.lastStateChange;
|
|
105
|
+
return Math.max(0, this.config.resetTimeoutMs - elapsed);
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Manually reset the circuit to CLOSED state.
|
|
109
|
+
*/
|
|
110
|
+
reset() {
|
|
111
|
+
this.transitionTo("CLOSED");
|
|
112
|
+
this.failures = 0;
|
|
113
|
+
this.successes = 0;
|
|
114
|
+
this.consecutiveFailures = 0;
|
|
115
|
+
this.halfOpenAttempts = 0;
|
|
116
|
+
this.failureTimestamps = [];
|
|
117
|
+
this.clearResetTimer();
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Register an event listener.
|
|
121
|
+
*/
|
|
122
|
+
on(listener) {
|
|
123
|
+
this.listeners.push(listener);
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Remove an event listener.
|
|
127
|
+
*/
|
|
128
|
+
off(listener) {
|
|
129
|
+
this.listeners = this.listeners.filter((l) => l !== listener);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Clean up resources. Call when shutting down.
|
|
133
|
+
*/
|
|
134
|
+
destroy() {
|
|
135
|
+
this.clearResetTimer();
|
|
136
|
+
this.listeners = [];
|
|
137
|
+
}
|
|
138
|
+
onSuccess() {
|
|
139
|
+
this.successes++;
|
|
140
|
+
this.consecutiveFailures = 0;
|
|
141
|
+
this.lastSuccess = Date.now();
|
|
142
|
+
this.emit({
|
|
143
|
+
type: "success",
|
|
144
|
+
state: this.state,
|
|
145
|
+
timestamp: Date.now(),
|
|
146
|
+
});
|
|
147
|
+
if (this.state === "HALF_OPEN") {
|
|
148
|
+
this.halfOpenAttempts++;
|
|
149
|
+
if (this.halfOpenAttempts >= this.config.halfOpenMaxAttempts) {
|
|
150
|
+
this.transitionTo("CLOSED");
|
|
151
|
+
this.failures = 0;
|
|
152
|
+
this.halfOpenAttempts = 0;
|
|
153
|
+
this.failureTimestamps = [];
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
onFailure(error) {
|
|
158
|
+
this.failures++;
|
|
159
|
+
this.consecutiveFailures++;
|
|
160
|
+
this.lastFailure = Date.now();
|
|
161
|
+
if (this.config.failureWindowMs) {
|
|
162
|
+
this.failureTimestamps.push(Date.now());
|
|
163
|
+
this.pruneOldFailures();
|
|
164
|
+
}
|
|
165
|
+
this.emit({
|
|
166
|
+
type: "failure",
|
|
167
|
+
state: this.state,
|
|
168
|
+
timestamp: Date.now(),
|
|
169
|
+
error,
|
|
170
|
+
});
|
|
171
|
+
if (this.state === "HALF_OPEN") {
|
|
172
|
+
this.transitionTo("OPEN");
|
|
173
|
+
this.halfOpenAttempts = 0;
|
|
174
|
+
this.scheduleResetTimer();
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
const failureCount = this.config.failureWindowMs ? this.failureTimestamps.length : this.consecutiveFailures;
|
|
178
|
+
if (this.state === "CLOSED" && failureCount >= this.config.failureThreshold) {
|
|
179
|
+
this.transitionTo("OPEN");
|
|
180
|
+
this.scheduleResetTimer();
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
transitionTo(newState) {
|
|
184
|
+
const previousState = this.state;
|
|
185
|
+
if (previousState === newState)
|
|
186
|
+
return;
|
|
187
|
+
this.state = newState;
|
|
188
|
+
this.lastStateChange = Date.now();
|
|
189
|
+
this.emit({
|
|
190
|
+
type: "state_change",
|
|
191
|
+
state: newState,
|
|
192
|
+
previousState,
|
|
193
|
+
timestamp: Date.now(),
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
pruneOldFailures() {
|
|
197
|
+
if (!this.config.failureWindowMs)
|
|
198
|
+
return;
|
|
199
|
+
const cutoff = Date.now() - this.config.failureWindowMs;
|
|
200
|
+
this.failureTimestamps = this.failureTimestamps.filter((t) => t > cutoff);
|
|
201
|
+
}
|
|
202
|
+
scheduleResetTimer() {
|
|
203
|
+
this.clearResetTimer();
|
|
204
|
+
this.resetTimer = setTimeout(() => {
|
|
205
|
+
if (this.state === "OPEN") {
|
|
206
|
+
this.transitionTo("HALF_OPEN");
|
|
207
|
+
}
|
|
208
|
+
}, this.config.resetTimeoutMs);
|
|
209
|
+
if (this.resetTimer.unref) {
|
|
210
|
+
this.resetTimer.unref();
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
clearResetTimer() {
|
|
214
|
+
if (this.resetTimer) {
|
|
215
|
+
clearTimeout(this.resetTimer);
|
|
216
|
+
this.resetTimer = null;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
emit(event) {
|
|
220
|
+
for (const listener of this.listeners) {
|
|
221
|
+
try {
|
|
222
|
+
listener(event);
|
|
223
|
+
}
|
|
224
|
+
catch {
|
|
225
|
+
// Listeners should not throw
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
export class CircuitOpenError extends Error {
|
|
231
|
+
retryAfterMs;
|
|
232
|
+
constructor(message, retryAfterMs) {
|
|
233
|
+
super(message);
|
|
234
|
+
this.name = "CircuitOpenError";
|
|
235
|
+
this.retryAfterMs = retryAfterMs;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
//# sourceMappingURL=CircuitBreaker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CircuitBreaker.js","sourceRoot":"","sources":["../../src/monitoring/CircuitBreaker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DistributedTracer - OpenTelemetry distributed tracing for Blok workflows
|
|
3
|
+
*
|
|
4
|
+
* Creates spans for workflow and node execution, propagates trace context
|
|
5
|
+
* across runtime boundaries, and correlates logs with traces via trace_id/span_id.
|
|
6
|
+
*
|
|
7
|
+
* Uses the OpenTelemetry API so any configured TracerProvider (OTLP, Jaeger,
|
|
8
|
+
* Zipkin, Datadog, etc.) receives the spans automatically.
|
|
9
|
+
*
|
|
10
|
+
* Works as a no-op when no TracerProvider is registered (graceful degradation).
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* import { DistributedTracer } from "@blokjs/runner";
|
|
15
|
+
*
|
|
16
|
+
* const tracer = new DistributedTracer({ serviceName: "blok-http" });
|
|
17
|
+
*
|
|
18
|
+
* // Start a workflow span
|
|
19
|
+
* const span = tracer.startWorkflowSpan("user-api", "/users/:id", { requestId: "abc" });
|
|
20
|
+
*
|
|
21
|
+
* // Start a child node span
|
|
22
|
+
* const nodeSpan = tracer.startNodeSpan("db-query", "postgres", span);
|
|
23
|
+
* // ... node execution ...
|
|
24
|
+
* tracer.endNodeSpan(nodeSpan, true);
|
|
25
|
+
*
|
|
26
|
+
* // End workflow span
|
|
27
|
+
* tracer.endWorkflowSpan(span, true);
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
import { type Span } from "@opentelemetry/api";
|
|
31
|
+
export interface DistributedTracerConfig {
|
|
32
|
+
/** Service name for the tracer */
|
|
33
|
+
serviceName: string;
|
|
34
|
+
/** Service version (default: "0.0.1") */
|
|
35
|
+
serviceVersion?: string;
|
|
36
|
+
/** Whether to record node-level spans (default: true) */
|
|
37
|
+
traceNodes?: boolean;
|
|
38
|
+
/** Whether to add request/response data as span attributes (default: false — may contain PII) */
|
|
39
|
+
recordPayloads?: boolean;
|
|
40
|
+
/** Max attribute value length (default: 256) */
|
|
41
|
+
maxAttributeLength?: number;
|
|
42
|
+
}
|
|
43
|
+
export interface WorkflowSpanAttributes {
|
|
44
|
+
requestId?: string;
|
|
45
|
+
triggerType?: string;
|
|
46
|
+
triggerName?: string;
|
|
47
|
+
env?: string;
|
|
48
|
+
}
|
|
49
|
+
export interface NodeSpanAttributes {
|
|
50
|
+
nodeType?: string;
|
|
51
|
+
runtimeKind?: string;
|
|
52
|
+
inputSize?: number;
|
|
53
|
+
outputSize?: number;
|
|
54
|
+
}
|
|
55
|
+
export interface TraceContext {
|
|
56
|
+
traceId: string;
|
|
57
|
+
spanId: string;
|
|
58
|
+
traceFlags: number;
|
|
59
|
+
}
|
|
60
|
+
export declare class DistributedTracer {
|
|
61
|
+
private config;
|
|
62
|
+
private tracer;
|
|
63
|
+
private workflowSpanCount;
|
|
64
|
+
private nodeSpanCount;
|
|
65
|
+
private errorSpanCount;
|
|
66
|
+
constructor(config: DistributedTracerConfig);
|
|
67
|
+
/**
|
|
68
|
+
* Start a span for a workflow execution.
|
|
69
|
+
* This is the root span for a request flowing through a workflow.
|
|
70
|
+
*/
|
|
71
|
+
startWorkflowSpan(workflowName: string, workflowPath: string, attrs?: WorkflowSpanAttributes): Span;
|
|
72
|
+
/**
|
|
73
|
+
* End a workflow span with success/failure status.
|
|
74
|
+
*/
|
|
75
|
+
endWorkflowSpan(span: Span, success: boolean, error?: Error): void;
|
|
76
|
+
/**
|
|
77
|
+
* Start a child span for node execution within a workflow.
|
|
78
|
+
* The parent context is taken from the provided workflow span.
|
|
79
|
+
*/
|
|
80
|
+
startNodeSpan(nodeName: string, nodeType: string, parentSpan: Span, attrs?: NodeSpanAttributes): Span;
|
|
81
|
+
/**
|
|
82
|
+
* End a node span with success/failure status.
|
|
83
|
+
*/
|
|
84
|
+
endNodeSpan(span: Span, success: boolean, error?: Error, attrs?: NodeSpanAttributes): void;
|
|
85
|
+
/**
|
|
86
|
+
* Start a span for a runtime adapter call (e.g., gRPC to Python, Docker exec).
|
|
87
|
+
* Used when a node delegates to a non-in-process runtime.
|
|
88
|
+
*/
|
|
89
|
+
startRuntimeSpan(runtimeKind: string, nodeName: string, parentSpan: Span): Span;
|
|
90
|
+
/**
|
|
91
|
+
* End a runtime span.
|
|
92
|
+
*/
|
|
93
|
+
endRuntimeSpan(span: Span, success: boolean, error?: Error): void;
|
|
94
|
+
/**
|
|
95
|
+
* Add an event to a span (e.g., "input validated", "cache hit").
|
|
96
|
+
*/
|
|
97
|
+
addSpanEvent(span: Span, name: string, attrs?: Record<string, string | number | boolean>): void;
|
|
98
|
+
/**
|
|
99
|
+
* Set an attribute on a span.
|
|
100
|
+
*/
|
|
101
|
+
setSpanAttribute(span: Span, key: string, value: string | number | boolean): void;
|
|
102
|
+
/**
|
|
103
|
+
* Extract trace context (trace_id, span_id) from a span for log correlation.
|
|
104
|
+
* Returns { traceId, spanId, traceFlags } or null if the span is not recording.
|
|
105
|
+
*/
|
|
106
|
+
extractTraceContext(span: Span): TraceContext | null;
|
|
107
|
+
/**
|
|
108
|
+
* Get W3C Trace Context headers for propagation across service boundaries.
|
|
109
|
+
* Pass these headers when calling remote runtimes (gRPC, HTTP, Docker).
|
|
110
|
+
*/
|
|
111
|
+
getTraceHeaders(span: Span): Record<string, string>;
|
|
112
|
+
/**
|
|
113
|
+
* Get stats about tracer usage.
|
|
114
|
+
*/
|
|
115
|
+
getStats(): {
|
|
116
|
+
workflowSpanCount: number;
|
|
117
|
+
nodeSpanCount: number;
|
|
118
|
+
errorSpanCount: number;
|
|
119
|
+
totalSpans: number;
|
|
120
|
+
};
|
|
121
|
+
/**
|
|
122
|
+
* Reset stats. Useful for testing.
|
|
123
|
+
*/
|
|
124
|
+
resetStats(): void;
|
|
125
|
+
}
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DistributedTracer - OpenTelemetry distributed tracing for Blok workflows
|
|
3
|
+
*
|
|
4
|
+
* Creates spans for workflow and node execution, propagates trace context
|
|
5
|
+
* across runtime boundaries, and correlates logs with traces via trace_id/span_id.
|
|
6
|
+
*
|
|
7
|
+
* Uses the OpenTelemetry API so any configured TracerProvider (OTLP, Jaeger,
|
|
8
|
+
* Zipkin, Datadog, etc.) receives the spans automatically.
|
|
9
|
+
*
|
|
10
|
+
* Works as a no-op when no TracerProvider is registered (graceful degradation).
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* import { DistributedTracer } from "@blokjs/runner";
|
|
15
|
+
*
|
|
16
|
+
* const tracer = new DistributedTracer({ serviceName: "blok-http" });
|
|
17
|
+
*
|
|
18
|
+
* // Start a workflow span
|
|
19
|
+
* const span = tracer.startWorkflowSpan("user-api", "/users/:id", { requestId: "abc" });
|
|
20
|
+
*
|
|
21
|
+
* // Start a child node span
|
|
22
|
+
* const nodeSpan = tracer.startNodeSpan("db-query", "postgres", span);
|
|
23
|
+
* // ... node execution ...
|
|
24
|
+
* tracer.endNodeSpan(nodeSpan, true);
|
|
25
|
+
*
|
|
26
|
+
* // End workflow span
|
|
27
|
+
* tracer.endWorkflowSpan(span, true);
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
import { SpanKind, SpanStatusCode, context, trace } from "@opentelemetry/api";
|
|
31
|
+
export class DistributedTracer {
|
|
32
|
+
config;
|
|
33
|
+
tracer;
|
|
34
|
+
// Stats
|
|
35
|
+
workflowSpanCount = 0;
|
|
36
|
+
nodeSpanCount = 0;
|
|
37
|
+
errorSpanCount = 0;
|
|
38
|
+
constructor(config) {
|
|
39
|
+
this.config = {
|
|
40
|
+
serviceVersion: "0.0.1",
|
|
41
|
+
traceNodes: true,
|
|
42
|
+
recordPayloads: false,
|
|
43
|
+
maxAttributeLength: 256,
|
|
44
|
+
...config,
|
|
45
|
+
};
|
|
46
|
+
this.tracer = trace.getTracer(this.config.serviceName, this.config.serviceVersion);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Start a span for a workflow execution.
|
|
50
|
+
* This is the root span for a request flowing through a workflow.
|
|
51
|
+
*/
|
|
52
|
+
startWorkflowSpan(workflowName, workflowPath, attrs) {
|
|
53
|
+
this.workflowSpanCount++;
|
|
54
|
+
const span = this.tracer.startSpan(`workflow ${workflowName}`, {
|
|
55
|
+
kind: SpanKind.SERVER,
|
|
56
|
+
attributes: {
|
|
57
|
+
"blok.workflow.name": workflowName,
|
|
58
|
+
"blok.workflow.path": workflowPath,
|
|
59
|
+
"blok.component": "runner",
|
|
60
|
+
...(attrs?.requestId && { "blok.request.id": attrs.requestId }),
|
|
61
|
+
...(attrs?.triggerType && { "blok.trigger.type": attrs.triggerType }),
|
|
62
|
+
...(attrs?.triggerName && { "blok.trigger.name": attrs.triggerName }),
|
|
63
|
+
...(attrs?.env && { "deployment.environment": attrs.env }),
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
return span;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* End a workflow span with success/failure status.
|
|
70
|
+
*/
|
|
71
|
+
endWorkflowSpan(span, success, error) {
|
|
72
|
+
if (success) {
|
|
73
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
span.setStatus({
|
|
77
|
+
code: SpanStatusCode.ERROR,
|
|
78
|
+
message: error?.message || "Workflow execution failed",
|
|
79
|
+
});
|
|
80
|
+
if (error) {
|
|
81
|
+
span.recordException(error);
|
|
82
|
+
}
|
|
83
|
+
this.errorSpanCount++;
|
|
84
|
+
}
|
|
85
|
+
span.end();
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Start a child span for node execution within a workflow.
|
|
89
|
+
* The parent context is taken from the provided workflow span.
|
|
90
|
+
*/
|
|
91
|
+
startNodeSpan(nodeName, nodeType, parentSpan, attrs) {
|
|
92
|
+
if (!this.config.traceNodes) {
|
|
93
|
+
return parentSpan;
|
|
94
|
+
}
|
|
95
|
+
this.nodeSpanCount++;
|
|
96
|
+
const parentContext = trace.setSpan(context.active(), parentSpan);
|
|
97
|
+
const span = this.tracer.startSpan(`node ${nodeName}`, {
|
|
98
|
+
kind: SpanKind.INTERNAL,
|
|
99
|
+
attributes: {
|
|
100
|
+
"blok.node.name": nodeName,
|
|
101
|
+
"blok.node.type": nodeType,
|
|
102
|
+
"blok.component": "node",
|
|
103
|
+
...(attrs?.runtimeKind && { "blok.runtime.kind": attrs.runtimeKind }),
|
|
104
|
+
...(attrs?.inputSize && { "blok.node.input_size": attrs.inputSize }),
|
|
105
|
+
},
|
|
106
|
+
}, parentContext);
|
|
107
|
+
return span;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* End a node span with success/failure status.
|
|
111
|
+
*/
|
|
112
|
+
endNodeSpan(span, success, error, attrs) {
|
|
113
|
+
if (attrs?.outputSize) {
|
|
114
|
+
span.setAttribute("blok.node.output_size", attrs.outputSize);
|
|
115
|
+
}
|
|
116
|
+
if (success) {
|
|
117
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
span.setStatus({
|
|
121
|
+
code: SpanStatusCode.ERROR,
|
|
122
|
+
message: error?.message || "Node execution failed",
|
|
123
|
+
});
|
|
124
|
+
if (error) {
|
|
125
|
+
span.recordException(error);
|
|
126
|
+
}
|
|
127
|
+
this.errorSpanCount++;
|
|
128
|
+
}
|
|
129
|
+
span.end();
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Start a span for a runtime adapter call (e.g., gRPC to Python, Docker exec).
|
|
133
|
+
* Used when a node delegates to a non-in-process runtime.
|
|
134
|
+
*/
|
|
135
|
+
startRuntimeSpan(runtimeKind, nodeName, parentSpan) {
|
|
136
|
+
const parentContext = trace.setSpan(context.active(), parentSpan);
|
|
137
|
+
return this.tracer.startSpan(`runtime ${runtimeKind}`, {
|
|
138
|
+
kind: SpanKind.CLIENT,
|
|
139
|
+
attributes: {
|
|
140
|
+
"blok.runtime.kind": runtimeKind,
|
|
141
|
+
"blok.node.name": nodeName,
|
|
142
|
+
"blok.component": "runtime-adapter",
|
|
143
|
+
},
|
|
144
|
+
}, parentContext);
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* End a runtime span.
|
|
148
|
+
*/
|
|
149
|
+
endRuntimeSpan(span, success, error) {
|
|
150
|
+
if (success) {
|
|
151
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
span.setStatus({
|
|
155
|
+
code: SpanStatusCode.ERROR,
|
|
156
|
+
message: error?.message || "Runtime execution failed",
|
|
157
|
+
});
|
|
158
|
+
if (error) {
|
|
159
|
+
span.recordException(error);
|
|
160
|
+
}
|
|
161
|
+
this.errorSpanCount++;
|
|
162
|
+
}
|
|
163
|
+
span.end();
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Add an event to a span (e.g., "input validated", "cache hit").
|
|
167
|
+
*/
|
|
168
|
+
addSpanEvent(span, name, attrs) {
|
|
169
|
+
span.addEvent(name, attrs);
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Set an attribute on a span.
|
|
173
|
+
*/
|
|
174
|
+
setSpanAttribute(span, key, value) {
|
|
175
|
+
if (typeof value === "string" && value.length > this.config.maxAttributeLength) {
|
|
176
|
+
span.setAttribute(key, `${value.substring(0, this.config.maxAttributeLength)}...`);
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
span.setAttribute(key, value);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Extract trace context (trace_id, span_id) from a span for log correlation.
|
|
184
|
+
* Returns { traceId, spanId, traceFlags } or null if the span is not recording.
|
|
185
|
+
*/
|
|
186
|
+
extractTraceContext(span) {
|
|
187
|
+
const spanContext = span.spanContext();
|
|
188
|
+
if (!spanContext || spanContext.traceId === "00000000000000000000000000000000") {
|
|
189
|
+
return null;
|
|
190
|
+
}
|
|
191
|
+
return {
|
|
192
|
+
traceId: spanContext.traceId,
|
|
193
|
+
spanId: spanContext.spanId,
|
|
194
|
+
traceFlags: spanContext.traceFlags,
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Get W3C Trace Context headers for propagation across service boundaries.
|
|
199
|
+
* Pass these headers when calling remote runtimes (gRPC, HTTP, Docker).
|
|
200
|
+
*/
|
|
201
|
+
getTraceHeaders(span) {
|
|
202
|
+
const ctx = span.spanContext();
|
|
203
|
+
if (!ctx || ctx.traceId === "00000000000000000000000000000000") {
|
|
204
|
+
return {};
|
|
205
|
+
}
|
|
206
|
+
// W3C traceparent format: version-traceId-spanId-flags
|
|
207
|
+
const traceparent = `00-${ctx.traceId}-${ctx.spanId}-${String(ctx.traceFlags).padStart(2, "0")}`;
|
|
208
|
+
return { traceparent };
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Get stats about tracer usage.
|
|
212
|
+
*/
|
|
213
|
+
getStats() {
|
|
214
|
+
return {
|
|
215
|
+
workflowSpanCount: this.workflowSpanCount,
|
|
216
|
+
nodeSpanCount: this.nodeSpanCount,
|
|
217
|
+
errorSpanCount: this.errorSpanCount,
|
|
218
|
+
totalSpans: this.workflowSpanCount + this.nodeSpanCount,
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Reset stats. Useful for testing.
|
|
223
|
+
*/
|
|
224
|
+
resetStats() {
|
|
225
|
+
this.workflowSpanCount = 0;
|
|
226
|
+
this.nodeSpanCount = 0;
|
|
227
|
+
this.errorSpanCount = 0;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
//# sourceMappingURL=DistributedTracer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DistributedTracer.js","sourceRoot":"","sources":["../../src/monitoring/DistributedTracer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Health Check Infrastructure for Blok Triggers
|
|
3
|
+
*
|
|
4
|
+
* Provides standardized health check capabilities across all trigger types.
|
|
5
|
+
* Supports Kubernetes readiness/liveness probes and custom dependency checks.
|
|
6
|
+
*/
|
|
7
|
+
export type HealthStatus = "healthy" | "degraded" | "unhealthy";
|
|
8
|
+
export interface HealthCheckResult {
|
|
9
|
+
status: HealthStatus;
|
|
10
|
+
timestamp: number;
|
|
11
|
+
uptime: number;
|
|
12
|
+
checks: Record<string, DependencyHealth>;
|
|
13
|
+
}
|
|
14
|
+
export interface DependencyHealth {
|
|
15
|
+
status: HealthStatus;
|
|
16
|
+
latency_ms?: number;
|
|
17
|
+
message?: string;
|
|
18
|
+
lastChecked: number;
|
|
19
|
+
}
|
|
20
|
+
export type DependencyCheckFn = () => Promise<DependencyHealth>;
|
|
21
|
+
export declare class HealthCheck {
|
|
22
|
+
private startTime;
|
|
23
|
+
private dependencies;
|
|
24
|
+
private cachedResults;
|
|
25
|
+
private cacheMaxAge;
|
|
26
|
+
constructor(cacheMaxAgeMs?: number);
|
|
27
|
+
/**
|
|
28
|
+
* Register a named dependency health check.
|
|
29
|
+
*/
|
|
30
|
+
registerDependency(name: string, checkFn: DependencyCheckFn): void;
|
|
31
|
+
/**
|
|
32
|
+
* Remove a registered dependency check.
|
|
33
|
+
*/
|
|
34
|
+
removeDependency(name: string): void;
|
|
35
|
+
/**
|
|
36
|
+
* Run all dependency checks and return aggregated health.
|
|
37
|
+
*/
|
|
38
|
+
check(): Promise<HealthCheckResult>;
|
|
39
|
+
/**
|
|
40
|
+
* Quick liveness check - is the process alive and responsive?
|
|
41
|
+
*/
|
|
42
|
+
liveness(): {
|
|
43
|
+
status: "ok";
|
|
44
|
+
uptime: number;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Readiness check - are all dependencies healthy?
|
|
48
|
+
*/
|
|
49
|
+
readiness(): Promise<{
|
|
50
|
+
ready: boolean;
|
|
51
|
+
status: HealthStatus;
|
|
52
|
+
}>;
|
|
53
|
+
private aggregateStatus;
|
|
54
|
+
}
|