@usherlabs/cex-broker 0.2.25 → 0.2.26
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/commands/cli.js +92 -4
- package/dist/handlers/subscribe/broker-lifecycle.d.ts +13 -0
- package/dist/handlers/subscribe/handler.d.ts +2 -0
- package/dist/handlers/subscribe/index.d.ts +1 -0
- package/dist/index.js +93 -5
- package/dist/index.js.map +6 -5
- package/dist/server.d.ts +2 -1
- package/package.json +2 -1
package/dist/commands/cli.js
CHANGED
|
@@ -332420,6 +332420,59 @@ function createExecuteActionHandler(deps) {
|
|
|
332420
332420
|
}
|
|
332421
332421
|
};
|
|
332422
332422
|
}
|
|
332423
|
+
// src/handlers/subscribe/broker-lifecycle.ts
|
|
332424
|
+
class SubscribeBrokerLifecycle {
|
|
332425
|
+
#brokers = new Map;
|
|
332426
|
+
#closing = new Map;
|
|
332427
|
+
#shuttingDown = false;
|
|
332428
|
+
register(broker, context2) {
|
|
332429
|
+
this.#brokers.set(broker, context2);
|
|
332430
|
+
if (this.#shuttingDown) {
|
|
332431
|
+
this.close(broker);
|
|
332432
|
+
}
|
|
332433
|
+
}
|
|
332434
|
+
close(broker) {
|
|
332435
|
+
const existing = this.#closing.get(broker);
|
|
332436
|
+
if (existing) {
|
|
332437
|
+
return existing;
|
|
332438
|
+
}
|
|
332439
|
+
const context2 = this.#brokers.get(broker) ?? {
|
|
332440
|
+
cex: "unknown",
|
|
332441
|
+
symbol: "unknown"
|
|
332442
|
+
};
|
|
332443
|
+
this.#brokers.delete(broker);
|
|
332444
|
+
const closing = (async () => {
|
|
332445
|
+
try {
|
|
332446
|
+
await broker.close();
|
|
332447
|
+
log.debug("Request-scoped Subscribe broker closed", context2);
|
|
332448
|
+
return "closed";
|
|
332449
|
+
} catch (error48) {
|
|
332450
|
+
log.warn("Failed to close request-scoped Subscribe broker", {
|
|
332451
|
+
...context2,
|
|
332452
|
+
error: error48
|
|
332453
|
+
});
|
|
332454
|
+
return "failed";
|
|
332455
|
+
} finally {
|
|
332456
|
+
this.#closing.delete(broker);
|
|
332457
|
+
}
|
|
332458
|
+
})();
|
|
332459
|
+
this.#closing.set(broker, closing);
|
|
332460
|
+
return closing;
|
|
332461
|
+
}
|
|
332462
|
+
async closeAll() {
|
|
332463
|
+
this.#shuttingDown = true;
|
|
332464
|
+
let failed = 0;
|
|
332465
|
+
while (this.#brokers.size > 0 || this.#closing.size > 0) {
|
|
332466
|
+
const inFlight = [...this.#closing.values()];
|
|
332467
|
+
const fresh = [...this.#brokers.keys()].map((broker) => this.close(broker));
|
|
332468
|
+
const outcomes = await Promise.all([...fresh, ...inFlight]);
|
|
332469
|
+
failed += outcomes.filter((outcome) => outcome === "failed").length;
|
|
332470
|
+
}
|
|
332471
|
+
if (failed > 0) {
|
|
332472
|
+
throw new Error(`${failed} request-scoped Subscribe broker(s) failed to close`);
|
|
332473
|
+
}
|
|
332474
|
+
}
|
|
332475
|
+
}
|
|
332423
332476
|
// src/handlers/subscribe/handler.ts
|
|
332424
332477
|
var grpc13 = __toESM(require_src3(), 1);
|
|
332425
332478
|
|
|
@@ -333496,15 +333549,34 @@ async function runCcxtSubscribeLoop(call, isClosed, symbol2, subscriptionType, w
|
|
|
333496
333549
|
}
|
|
333497
333550
|
function createSubscribeHandler(deps) {
|
|
333498
333551
|
const { brokers, whitelistIps, otelMetrics, brokerArchiver } = deps;
|
|
333552
|
+
const brokerLifecycle = deps.brokerLifecycle ?? new SubscribeBrokerLifecycle;
|
|
333499
333553
|
return async (call) => {
|
|
333500
333554
|
const subscribeStartTime = Date.now();
|
|
333501
333555
|
let streamClosed = false;
|
|
333556
|
+
let ownedBroker = null;
|
|
333557
|
+
let ownedBrokerClosePromise;
|
|
333502
333558
|
const markStreamClosed = () => {
|
|
333503
333559
|
streamClosed = true;
|
|
333504
333560
|
};
|
|
333505
|
-
const isStreamClosed = () => streamClosed || call.
|
|
333506
|
-
|
|
333561
|
+
const isStreamClosed = () => streamClosed || call.cancelled || call.writableEnded;
|
|
333562
|
+
const closeOwnedBroker = () => {
|
|
333563
|
+
if (ownedBrokerClosePromise) {
|
|
333564
|
+
return ownedBrokerClosePromise;
|
|
333565
|
+
}
|
|
333566
|
+
if (!ownedBroker) {
|
|
333567
|
+
return Promise.resolve();
|
|
333568
|
+
}
|
|
333569
|
+
const broker = ownedBroker;
|
|
333570
|
+
ownedBroker = null;
|
|
333571
|
+
ownedBrokerClosePromise = brokerLifecycle.close(broker);
|
|
333572
|
+
return ownedBrokerClosePromise;
|
|
333573
|
+
};
|
|
333574
|
+
const closeOwnedBrokerOnCallEnd = () => {
|
|
333575
|
+
closeOwnedBroker();
|
|
333576
|
+
};
|
|
333507
333577
|
call.once("cancelled", markStreamClosed);
|
|
333578
|
+
call.once("cancelled", closeOwnedBrokerOnCallEnd);
|
|
333579
|
+
call.once("error", closeOwnedBrokerOnCallEnd);
|
|
333508
333580
|
call.once("end", () => {
|
|
333509
333581
|
markStreamClosed();
|
|
333510
333582
|
log.info("Subscribe stream ended");
|
|
@@ -333576,6 +333648,17 @@ function createSubscribeHandler(deps) {
|
|
|
333576
333648
|
});
|
|
333577
333649
|
return;
|
|
333578
333650
|
}
|
|
333651
|
+
if (!selectedBrokerAccount) {
|
|
333652
|
+
ownedBroker = broker;
|
|
333653
|
+
brokerLifecycle.register(broker, {
|
|
333654
|
+
cex: normalizedCex,
|
|
333655
|
+
symbol: symbol2
|
|
333656
|
+
});
|
|
333657
|
+
if (isStreamClosed()) {
|
|
333658
|
+
await closeOwnedBroker();
|
|
333659
|
+
return;
|
|
333660
|
+
}
|
|
333661
|
+
}
|
|
333579
333662
|
const resolvedSymbol = await resolveSubscriptionSymbol(broker, symbol2, options?.marketType);
|
|
333580
333663
|
const assetType = parseMarketType(options?.marketType);
|
|
333581
333664
|
const deploymentId = brokerArchiver?.getDeploymentId() ?? "unknown";
|
|
@@ -333840,6 +333923,10 @@ function createSubscribeHandler(deps) {
|
|
|
333840
333923
|
symbol: "",
|
|
333841
333924
|
type: subscriptionType
|
|
333842
333925
|
});
|
|
333926
|
+
} finally {
|
|
333927
|
+
call.off("cancelled", closeOwnedBrokerOnCallEnd);
|
|
333928
|
+
call.off("error", closeOwnedBrokerOnCallEnd);
|
|
333929
|
+
await closeOwnedBroker();
|
|
333843
333930
|
}
|
|
333844
333931
|
};
|
|
333845
333932
|
}
|
|
@@ -333990,7 +334077,7 @@ var CEX_BROKER_PACKAGE_DEFINITION = protoLoader.fromJSON(node_descriptor_default
|
|
|
333990
334077
|
// src/server.ts
|
|
333991
334078
|
var grpcObj = grpc14.loadPackageDefinition(CEX_BROKER_PACKAGE_DEFINITION);
|
|
333992
334079
|
var cexNode = grpcObj.cex_broker;
|
|
333993
|
-
function getServer(policy, brokers, whitelistIps, useVerity, verityProverUrl, otelMetrics, brokerArchiver, orderActivityTracker, withdrawalObservationTracker) {
|
|
334080
|
+
function getServer(policy, brokers, whitelistIps, useVerity, verityProverUrl, otelMetrics, brokerArchiver, orderActivityTracker, withdrawalObservationTracker, subscribeBrokerLifecycle) {
|
|
333994
334081
|
const server = new grpc14.Server;
|
|
333995
334082
|
server.addService(cexNode.cex_service.service, {
|
|
333996
334083
|
ExecuteAction: createExecuteActionHandler({
|
|
@@ -334008,7 +334095,8 @@ function getServer(policy, brokers, whitelistIps, useVerity, verityProverUrl, ot
|
|
|
334008
334095
|
brokers,
|
|
334009
334096
|
whitelistIps,
|
|
334010
334097
|
otelMetrics,
|
|
334011
|
-
brokerArchiver
|
|
334098
|
+
brokerArchiver,
|
|
334099
|
+
brokerLifecycle: subscribeBrokerLifecycle
|
|
334012
334100
|
})
|
|
334013
334101
|
});
|
|
334014
334102
|
return server;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Exchange } from "@usherlabs/ccxt";
|
|
2
|
+
type BrokerContext = {
|
|
3
|
+
cex: string;
|
|
4
|
+
symbol: string;
|
|
5
|
+
};
|
|
6
|
+
export type BrokerCloseOutcome = "closed" | "failed";
|
|
7
|
+
export declare class SubscribeBrokerLifecycle {
|
|
8
|
+
#private;
|
|
9
|
+
register(broker: Exchange, context: BrokerContext): void;
|
|
10
|
+
close(broker: Exchange): Promise<BrokerCloseOutcome>;
|
|
11
|
+
closeAll(): Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
export {};
|
|
@@ -3,11 +3,13 @@ import { type BrokerPoolEntry } from "../../helpers/broker";
|
|
|
3
3
|
import type { BrokerExecutionArchiver } from "../../helpers/broker-execution-archive";
|
|
4
4
|
import type { OtelMetrics } from "../../helpers/otel";
|
|
5
5
|
import type { SubscribeRequest, SubscribeResponse } from "../types";
|
|
6
|
+
import { SubscribeBrokerLifecycle } from "./broker-lifecycle";
|
|
6
7
|
export type SubscribeDeps = {
|
|
7
8
|
brokers: Record<string, BrokerPoolEntry>;
|
|
8
9
|
whitelistIps: string[];
|
|
9
10
|
otelMetrics?: OtelMetrics;
|
|
10
11
|
brokerArchiver?: BrokerExecutionArchiver;
|
|
12
|
+
brokerLifecycle?: SubscribeBrokerLifecycle;
|
|
11
13
|
};
|
|
12
14
|
type SubscribeCall = grpc.ServerWritableStream<SubscribeRequest, SubscribeResponse>;
|
|
13
15
|
export declare function createSubscribeHandler(deps: SubscribeDeps): (call: SubscribeCall) => Promise<void>;
|
package/dist/index.js
CHANGED
|
@@ -295372,6 +295372,59 @@ function createExecuteActionHandler(deps) {
|
|
|
295372
295372
|
}
|
|
295373
295373
|
};
|
|
295374
295374
|
}
|
|
295375
|
+
// src/handlers/subscribe/broker-lifecycle.ts
|
|
295376
|
+
class SubscribeBrokerLifecycle {
|
|
295377
|
+
#brokers = new Map;
|
|
295378
|
+
#closing = new Map;
|
|
295379
|
+
#shuttingDown = false;
|
|
295380
|
+
register(broker, context3) {
|
|
295381
|
+
this.#brokers.set(broker, context3);
|
|
295382
|
+
if (this.#shuttingDown) {
|
|
295383
|
+
this.close(broker);
|
|
295384
|
+
}
|
|
295385
|
+
}
|
|
295386
|
+
close(broker) {
|
|
295387
|
+
const existing = this.#closing.get(broker);
|
|
295388
|
+
if (existing) {
|
|
295389
|
+
return existing;
|
|
295390
|
+
}
|
|
295391
|
+
const context3 = this.#brokers.get(broker) ?? {
|
|
295392
|
+
cex: "unknown",
|
|
295393
|
+
symbol: "unknown"
|
|
295394
|
+
};
|
|
295395
|
+
this.#brokers.delete(broker);
|
|
295396
|
+
const closing = (async () => {
|
|
295397
|
+
try {
|
|
295398
|
+
await broker.close();
|
|
295399
|
+
log.debug("Request-scoped Subscribe broker closed", context3);
|
|
295400
|
+
return "closed";
|
|
295401
|
+
} catch (error48) {
|
|
295402
|
+
log.warn("Failed to close request-scoped Subscribe broker", {
|
|
295403
|
+
...context3,
|
|
295404
|
+
error: error48
|
|
295405
|
+
});
|
|
295406
|
+
return "failed";
|
|
295407
|
+
} finally {
|
|
295408
|
+
this.#closing.delete(broker);
|
|
295409
|
+
}
|
|
295410
|
+
})();
|
|
295411
|
+
this.#closing.set(broker, closing);
|
|
295412
|
+
return closing;
|
|
295413
|
+
}
|
|
295414
|
+
async closeAll() {
|
|
295415
|
+
this.#shuttingDown = true;
|
|
295416
|
+
let failed = 0;
|
|
295417
|
+
while (this.#brokers.size > 0 || this.#closing.size > 0) {
|
|
295418
|
+
const inFlight = [...this.#closing.values()];
|
|
295419
|
+
const fresh = [...this.#brokers.keys()].map((broker) => this.close(broker));
|
|
295420
|
+
const outcomes = await Promise.all([...fresh, ...inFlight]);
|
|
295421
|
+
failed += outcomes.filter((outcome) => outcome === "failed").length;
|
|
295422
|
+
}
|
|
295423
|
+
if (failed > 0) {
|
|
295424
|
+
throw new Error(`${failed} request-scoped Subscribe broker(s) failed to close`);
|
|
295425
|
+
}
|
|
295426
|
+
}
|
|
295427
|
+
}
|
|
295375
295428
|
// src/handlers/subscribe/handler.ts
|
|
295376
295429
|
import * as grpc13 from "@grpc/grpc-js";
|
|
295377
295430
|
|
|
@@ -296449,15 +296502,34 @@ async function runCcxtSubscribeLoop(call, isClosed, symbol2, subscriptionType, w
|
|
|
296449
296502
|
}
|
|
296450
296503
|
function createSubscribeHandler(deps) {
|
|
296451
296504
|
const { brokers, whitelistIps, otelMetrics, brokerArchiver } = deps;
|
|
296505
|
+
const brokerLifecycle = deps.brokerLifecycle ?? new SubscribeBrokerLifecycle;
|
|
296452
296506
|
return async (call) => {
|
|
296453
296507
|
const subscribeStartTime = Date.now();
|
|
296454
296508
|
let streamClosed = false;
|
|
296509
|
+
let ownedBroker = null;
|
|
296510
|
+
let ownedBrokerClosePromise;
|
|
296455
296511
|
const markStreamClosed = () => {
|
|
296456
296512
|
streamClosed = true;
|
|
296457
296513
|
};
|
|
296458
|
-
const isStreamClosed = () => streamClosed || call.
|
|
296459
|
-
|
|
296514
|
+
const isStreamClosed = () => streamClosed || call.cancelled || call.writableEnded;
|
|
296515
|
+
const closeOwnedBroker = () => {
|
|
296516
|
+
if (ownedBrokerClosePromise) {
|
|
296517
|
+
return ownedBrokerClosePromise;
|
|
296518
|
+
}
|
|
296519
|
+
if (!ownedBroker) {
|
|
296520
|
+
return Promise.resolve();
|
|
296521
|
+
}
|
|
296522
|
+
const broker = ownedBroker;
|
|
296523
|
+
ownedBroker = null;
|
|
296524
|
+
ownedBrokerClosePromise = brokerLifecycle.close(broker);
|
|
296525
|
+
return ownedBrokerClosePromise;
|
|
296526
|
+
};
|
|
296527
|
+
const closeOwnedBrokerOnCallEnd = () => {
|
|
296528
|
+
closeOwnedBroker();
|
|
296529
|
+
};
|
|
296460
296530
|
call.once("cancelled", markStreamClosed);
|
|
296531
|
+
call.once("cancelled", closeOwnedBrokerOnCallEnd);
|
|
296532
|
+
call.once("error", closeOwnedBrokerOnCallEnd);
|
|
296461
296533
|
call.once("end", () => {
|
|
296462
296534
|
markStreamClosed();
|
|
296463
296535
|
log.info("Subscribe stream ended");
|
|
@@ -296529,6 +296601,17 @@ function createSubscribeHandler(deps) {
|
|
|
296529
296601
|
});
|
|
296530
296602
|
return;
|
|
296531
296603
|
}
|
|
296604
|
+
if (!selectedBrokerAccount) {
|
|
296605
|
+
ownedBroker = broker;
|
|
296606
|
+
brokerLifecycle.register(broker, {
|
|
296607
|
+
cex: normalizedCex,
|
|
296608
|
+
symbol: symbol2
|
|
296609
|
+
});
|
|
296610
|
+
if (isStreamClosed()) {
|
|
296611
|
+
await closeOwnedBroker();
|
|
296612
|
+
return;
|
|
296613
|
+
}
|
|
296614
|
+
}
|
|
296532
296615
|
const resolvedSymbol = await resolveSubscriptionSymbol(broker, symbol2, options?.marketType);
|
|
296533
296616
|
const assetType = parseMarketType(options?.marketType);
|
|
296534
296617
|
const deploymentId = brokerArchiver?.getDeploymentId() ?? "unknown";
|
|
@@ -296793,6 +296876,10 @@ function createSubscribeHandler(deps) {
|
|
|
296793
296876
|
symbol: "",
|
|
296794
296877
|
type: subscriptionType
|
|
296795
296878
|
});
|
|
296879
|
+
} finally {
|
|
296880
|
+
call.off("cancelled", closeOwnedBrokerOnCallEnd);
|
|
296881
|
+
call.off("error", closeOwnedBrokerOnCallEnd);
|
|
296882
|
+
await closeOwnedBroker();
|
|
296796
296883
|
}
|
|
296797
296884
|
};
|
|
296798
296885
|
}
|
|
@@ -296943,7 +297030,7 @@ var CEX_BROKER_PACKAGE_DEFINITION = protoLoader.fromJSON(node_descriptor_default
|
|
|
296943
297030
|
// src/server.ts
|
|
296944
297031
|
var grpcObj = grpc14.loadPackageDefinition(CEX_BROKER_PACKAGE_DEFINITION);
|
|
296945
297032
|
var cexNode = grpcObj.cex_broker;
|
|
296946
|
-
function getServer(policy, brokers, whitelistIps, useVerity, verityProverUrl, otelMetrics, brokerArchiver, orderActivityTracker, withdrawalObservationTracker) {
|
|
297033
|
+
function getServer(policy, brokers, whitelistIps, useVerity, verityProverUrl, otelMetrics, brokerArchiver, orderActivityTracker, withdrawalObservationTracker, subscribeBrokerLifecycle) {
|
|
296947
297034
|
const server = new grpc14.Server;
|
|
296948
297035
|
server.addService(cexNode.cex_service.service, {
|
|
296949
297036
|
ExecuteAction: createExecuteActionHandler({
|
|
@@ -296961,7 +297048,8 @@ function getServer(policy, brokers, whitelistIps, useVerity, verityProverUrl, ot
|
|
|
296961
297048
|
brokers,
|
|
296962
297049
|
whitelistIps,
|
|
296963
297050
|
otelMetrics,
|
|
296964
|
-
brokerArchiver
|
|
297051
|
+
brokerArchiver,
|
|
297052
|
+
brokerLifecycle: subscribeBrokerLifecycle
|
|
296965
297053
|
})
|
|
296966
297054
|
});
|
|
296967
297055
|
return server;
|
|
@@ -297324,4 +297412,4 @@ export {
|
|
|
297324
297412
|
CEXBroker as default
|
|
297325
297413
|
};
|
|
297326
297414
|
|
|
297327
|
-
//# debugId=
|
|
297415
|
+
//# debugId=1D08CFF8FA968C4064756E2164756E21
|