service-bridge 1.0.9-dev.22 → 1.0.10-dev.23
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/index.js +119 -8
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -224,13 +224,70 @@ function normalizeServiceError(err, operation, component = "control-plane") {
|
|
|
224
224
|
cause: err
|
|
225
225
|
});
|
|
226
226
|
}
|
|
227
|
+
function friendlyGrpcMessage(code, rawMessage) {
|
|
228
|
+
switch (code) {
|
|
229
|
+
case grpc.status.UNAVAILABLE:
|
|
230
|
+
return "control plane unavailable";
|
|
231
|
+
case grpc.status.DEADLINE_EXCEEDED:
|
|
232
|
+
return "request timed out";
|
|
233
|
+
case grpc.status.UNAUTHENTICATED:
|
|
234
|
+
return "authentication failed — check service key";
|
|
235
|
+
case grpc.status.PERMISSION_DENIED:
|
|
236
|
+
return "permission denied — check service key";
|
|
237
|
+
case grpc.status.RESOURCE_EXHAUSTED:
|
|
238
|
+
return "rate limit exceeded";
|
|
239
|
+
case grpc.status.NOT_FOUND:
|
|
240
|
+
return "resource not found";
|
|
241
|
+
case grpc.status.INTERNAL:
|
|
242
|
+
return "internal server error";
|
|
243
|
+
case grpc.status.FAILED_PRECONDITION:
|
|
244
|
+
return "precondition failed";
|
|
245
|
+
case grpc.status.CANCELLED:
|
|
246
|
+
return "request cancelled";
|
|
247
|
+
case grpc.status.UNIMPLEMENTED:
|
|
248
|
+
return "operation not supported by control plane";
|
|
249
|
+
default:
|
|
250
|
+
return rawMessage || "unknown error";
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
function friendlySDKMessage(operation, err) {
|
|
254
|
+
const base = friendlyGrpcMessage(err.code, err.message);
|
|
255
|
+
switch (operation) {
|
|
256
|
+
case "open-worker-session":
|
|
257
|
+
case "worker-session":
|
|
258
|
+
return err.severity === "retriable" ? `${base} — waiting for reconnect` : `worker session error: ${base}`;
|
|
259
|
+
case "worker-session-end":
|
|
260
|
+
return `worker session cleanup: ${base}`;
|
|
261
|
+
case "worker-session-command":
|
|
262
|
+
return `worker command error: ${base}`;
|
|
263
|
+
case "heartbeat":
|
|
264
|
+
return `heartbeat failed: ${base}`;
|
|
265
|
+
case "http-heartbeat":
|
|
266
|
+
return `HTTP heartbeat failed: ${base}`;
|
|
267
|
+
case "flush-offline-queue":
|
|
268
|
+
return `offline queue flush failed: ${base}`;
|
|
269
|
+
case "flush-on-ready":
|
|
270
|
+
case "flush-on-restore":
|
|
271
|
+
return `log flush failed: ${base}`;
|
|
272
|
+
case "report-call-start":
|
|
273
|
+
case "report-call":
|
|
274
|
+
return `call report failed: ${base}`;
|
|
275
|
+
case "worker-force-shutdown":
|
|
276
|
+
case "worker-try-shutdown":
|
|
277
|
+
return `worker shutdown error: ${base}`;
|
|
278
|
+
case "close-control-plane-client":
|
|
279
|
+
return `control plane disconnect: ${base}`;
|
|
280
|
+
default:
|
|
281
|
+
return `${operation}: ${base}`;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
227
284
|
function reportSDKError(operation, err, component = "sdk") {
|
|
228
285
|
const normalized = normalizeServiceError(err, operation, component);
|
|
229
|
-
const
|
|
286
|
+
const friendly = friendlySDKMessage(operation, normalized);
|
|
230
287
|
if (normalized.severity === "fatal") {
|
|
231
|
-
console.error(
|
|
288
|
+
console.error(`[servicebridge] ${friendly}`);
|
|
232
289
|
} else {
|
|
233
|
-
console.warn(
|
|
290
|
+
console.warn(`[servicebridge] ${friendly}`);
|
|
234
291
|
}
|
|
235
292
|
return normalized;
|
|
236
293
|
}
|
|
@@ -551,7 +608,30 @@ function servicebridge(url, serviceKey, serviceOrOpts = {}, maybeGlobalOpts = {}
|
|
|
551
608
|
md.add("x-caller-service", service);
|
|
552
609
|
return md;
|
|
553
610
|
}
|
|
611
|
+
function sessionSend(msg) {
|
|
612
|
+
if (!workerSessionStream)
|
|
613
|
+
return false;
|
|
614
|
+
try {
|
|
615
|
+
workerSessionStream.write(msg);
|
|
616
|
+
return true;
|
|
617
|
+
} catch {
|
|
618
|
+
return false;
|
|
619
|
+
}
|
|
620
|
+
}
|
|
554
621
|
async function sendReportCallStart(op) {
|
|
622
|
+
if (sessionSend({
|
|
623
|
+
telemetry_start: {
|
|
624
|
+
trace_id: op.traceId,
|
|
625
|
+
span_id: op.spanId,
|
|
626
|
+
parent_span_id: op.parentSpanId,
|
|
627
|
+
fn: op.fn,
|
|
628
|
+
started_at: String(op.startedAt),
|
|
629
|
+
input: op.inputBuf,
|
|
630
|
+
attempt: op.attempt
|
|
631
|
+
}
|
|
632
|
+
})) {
|
|
633
|
+
return;
|
|
634
|
+
}
|
|
555
635
|
await new Promise((resolve, reject) => {
|
|
556
636
|
stub.ReportCallStart({
|
|
557
637
|
trace_id: op.traceId,
|
|
@@ -567,6 +647,22 @@ function servicebridge(url, serviceKey, serviceOrOpts = {}, maybeGlobalOpts = {}
|
|
|
567
647
|
});
|
|
568
648
|
}
|
|
569
649
|
async function sendReportCall(op) {
|
|
650
|
+
if (sessionSend({
|
|
651
|
+
telemetry_finish: {
|
|
652
|
+
trace_id: op.traceId,
|
|
653
|
+
span_id: op.spanId,
|
|
654
|
+
fn: op.fn,
|
|
655
|
+
started_at: String(op.startedAt),
|
|
656
|
+
duration_ms: String(op.durationMs),
|
|
657
|
+
success: op.success,
|
|
658
|
+
error: op.error ?? "",
|
|
659
|
+
input: op.inputBuf,
|
|
660
|
+
output: op.outputBuf ?? Buffer.alloc(0),
|
|
661
|
+
attempt: op.attempt
|
|
662
|
+
}
|
|
663
|
+
})) {
|
|
664
|
+
return;
|
|
665
|
+
}
|
|
570
666
|
await new Promise((resolve, reject) => {
|
|
571
667
|
stub.ReportCall({
|
|
572
668
|
trace_id: op.traceId,
|
|
@@ -598,6 +694,8 @@ function servicebridge(url, serviceKey, serviceOrOpts = {}, maybeGlobalOpts = {}
|
|
|
598
694
|
clearTimeout(logFlushTimer);
|
|
599
695
|
logFlushTimer = null;
|
|
600
696
|
}
|
|
697
|
+
if (sessionSend({ telemetry_log: { entries } }))
|
|
698
|
+
return;
|
|
601
699
|
stub.ReportLog({ entries }, meta, unaryDeadlineOptions(), () => {});
|
|
602
700
|
}
|
|
603
701
|
function pushLog(level, msg, attrs) {
|
|
@@ -972,6 +1070,17 @@ function servicebridge(url, serviceKey, serviceOrOpts = {}, maybeGlobalOpts = {}
|
|
|
972
1070
|
return;
|
|
973
1071
|
const state = serveState;
|
|
974
1072
|
const metrics = getProcessMetrics();
|
|
1073
|
+
const hbMsg = {
|
|
1074
|
+
endpoint: state.endpoint,
|
|
1075
|
+
group_names: [...registeredGroups],
|
|
1076
|
+
function_names: [...fnHandlers.keys()]
|
|
1077
|
+
};
|
|
1078
|
+
if (metrics.cpuPercent != null)
|
|
1079
|
+
hbMsg.cpu_percent = metrics.cpuPercent;
|
|
1080
|
+
if (metrics.ramMb != null)
|
|
1081
|
+
hbMsg.ram_mb = metrics.ramMb;
|
|
1082
|
+
if (sessionSend({ heartbeat: hbMsg }))
|
|
1083
|
+
return;
|
|
975
1084
|
const req = {
|
|
976
1085
|
service_name: service,
|
|
977
1086
|
instance_id: state.instanceId,
|
|
@@ -989,6 +1098,8 @@ function servicebridge(url, serviceKey, serviceOrOpts = {}, maybeGlobalOpts = {}
|
|
|
989
1098
|
});
|
|
990
1099
|
}
|
|
991
1100
|
async function sendHttpHeartbeat(instanceId) {
|
|
1101
|
+
if (sessionSend({ http_heartbeat: {} }))
|
|
1102
|
+
return;
|
|
992
1103
|
await new Promise((resolve, reject) => {
|
|
993
1104
|
stub.HeartbeatHttpEndpoint({ service_name: service, instance_id: instanceId }, meta, unaryDeadlineOptions(), (err, res) => {
|
|
994
1105
|
if (err) {
|
|
@@ -1110,12 +1221,12 @@ function servicebridge(url, serviceKey, serviceOrOpts = {}, maybeGlobalOpts = {}
|
|
|
1110
1221
|
const append = (data, key = "default") => {
|
|
1111
1222
|
if (!isOnline || !runId)
|
|
1112
1223
|
return Promise.resolve();
|
|
1224
|
+
const dataBuf = Buffer.from(JSON.stringify(data));
|
|
1225
|
+
if (sessionSend({ append_stream: { run_id: runId, key, data: dataBuf } })) {
|
|
1226
|
+
return Promise.resolve();
|
|
1227
|
+
}
|
|
1113
1228
|
return new Promise((resolve, reject) => {
|
|
1114
|
-
stub.AppendStream({
|
|
1115
|
-
run_id: runId,
|
|
1116
|
-
key,
|
|
1117
|
-
data: Buffer.from(JSON.stringify(data))
|
|
1118
|
-
}, meta, unaryDeadlineOptions(), (err) => err ? reject(normalizeServiceError(err, `append-stream:${runId}`)) : resolve());
|
|
1229
|
+
stub.AppendStream({ run_id: runId, key, data: dataBuf }, meta, unaryDeadlineOptions(), (err) => err ? reject(normalizeServiceError(err, `append-stream:${runId}`)) : resolve());
|
|
1119
1230
|
});
|
|
1120
1231
|
};
|
|
1121
1232
|
return {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "service-bridge",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.10-dev.23",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "ServiceBridge SDK for Node.js — production-ready RPC, durable events, workflows, jobs, and distributed tracing. One Go runtime + PostgreSQL replaces Istio, RabbitMQ, Temporal, and Jaeger.",
|
|
6
6
|
"keywords": [
|