@yuants/app-virtual-exchange 0.18.6 → 0.18.8
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/app-virtual-exchange.d.ts +1 -0
- package/dist/credential.js.map +1 -1
- package/dist/general.js +17 -0
- package/dist/general.js.map +1 -1
- package/dist/legacy-services.js.map +1 -1
- package/dist/position.js.map +1 -1
- package/dist/quote/__tests__/implementations.test.js +1 -1
- package/dist/quote/__tests__/implementations.test.js.map +1 -1
- package/dist/quote/benchmark/ForkedQuoteStateComparisonTest.js.map +1 -1
- package/dist/quote/benchmark/PerformanceTester.js.map +1 -1
- package/dist/quote/benchmark/QuoteStateComparisonTest.js.map +1 -1
- package/dist/quote/benchmark/QuoteStateTestRunner.js.map +1 -1
- package/dist/quote/benchmark/index.js.map +1 -1
- package/dist/quote/benchmark/test-helpers.js.map +1 -1
- package/dist/quote/benchmark/worker.js.map +1 -1
- package/dist/quote/implementations/v0.js.map +1 -1
- package/dist/quote/implementations/v1.js.map +1 -1
- package/dist/quote/implementations/v2.js.map +1 -1
- package/dist/quote/implementations/v3.js +1 -1
- package/dist/quote/implementations/v3.js.map +1 -1
- package/dist/quote/scheduler.js.map +1 -1
- package/dist/quote/service.js.map +1 -1
- package/dist/quote/state.benchmark.js.map +1 -1
- package/dist/series-collector/backwards-interest-rate.js.map +1 -1
- package/dist/series-collector/backwards-ohlc.js.map +1 -1
- package/dist/series-collector/discovery.js.map +1 -1
- package/dist/series-collector/forwards-interest-rate.js.map +1 -1
- package/dist/series-collector/forwards-ohlc.js.map +1 -1
- package/dist/series-collector/patch-interest-rate.js.map +1 -1
- package/dist/series-collector/patch-ohlc.js.map +1 -1
- package/dist/series-collector/setup.js.map +1 -1
- package/dist/series-data/fifo-queue.js.map +1 -1
- package/dist/series-data/scheduler.js.map +1 -1
- package/lib/credential.d.ts +1 -2
- package/lib/credential.d.ts.map +1 -1
- package/lib/credential.js.map +1 -1
- package/lib/general.js +17 -0
- package/lib/general.js.map +1 -1
- package/lib/legacy-services.js.map +1 -1
- package/lib/position.d.ts.map +1 -1
- package/lib/position.js.map +1 -1
- package/lib/quote/__tests__/implementations.test.js +1 -1
- package/lib/quote/__tests__/implementations.test.js.map +1 -1
- package/lib/quote/benchmark/ForkedQuoteStateComparisonTest.js.map +1 -1
- package/lib/quote/benchmark/PerformanceTester.d.ts +0 -1
- package/lib/quote/benchmark/PerformanceTester.d.ts.map +1 -1
- package/lib/quote/benchmark/PerformanceTester.js.map +1 -1
- package/lib/quote/benchmark/QuoteStateComparisonTest.js.map +1 -1
- package/lib/quote/benchmark/QuoteStateTestRunner.js.map +1 -1
- package/lib/quote/benchmark/index.js +2 -2
- package/lib/quote/benchmark/index.js.map +1 -1
- package/lib/quote/benchmark/test-helpers.js +4 -5
- package/lib/quote/benchmark/test-helpers.js.map +1 -1
- package/lib/quote/benchmark/worker.js.map +1 -1
- package/lib/quote/implementations/v0.js +1 -2
- package/lib/quote/implementations/v0.js.map +1 -1
- package/lib/quote/implementations/v1.js.map +1 -1
- package/lib/quote/implementations/v2.js.map +1 -1
- package/lib/quote/implementations/v3.js +1 -1
- package/lib/quote/implementations/v3.js.map +1 -1
- package/lib/quote/scheduler.d.ts.map +1 -1
- package/lib/quote/scheduler.js.map +1 -1
- package/lib/quote/service.js.map +1 -1
- package/lib/quote/state.benchmark.js.map +1 -1
- package/lib/quote/types.d.ts +2 -2
- package/lib/quote/types.d.ts.map +1 -1
- package/lib/series-collector/backwards-interest-rate.d.ts +1 -2
- package/lib/series-collector/backwards-interest-rate.d.ts.map +1 -1
- package/lib/series-collector/backwards-interest-rate.js.map +1 -1
- package/lib/series-collector/backwards-ohlc.d.ts +1 -2
- package/lib/series-collector/backwards-ohlc.d.ts.map +1 -1
- package/lib/series-collector/backwards-ohlc.js.map +1 -1
- package/lib/series-collector/discovery.js.map +1 -1
- package/lib/series-collector/forwards-interest-rate.d.ts +1 -2
- package/lib/series-collector/forwards-interest-rate.d.ts.map +1 -1
- package/lib/series-collector/forwards-interest-rate.js.map +1 -1
- package/lib/series-collector/forwards-ohlc.d.ts +1 -2
- package/lib/series-collector/forwards-ohlc.d.ts.map +1 -1
- package/lib/series-collector/forwards-ohlc.js.map +1 -1
- package/lib/series-collector/patch-interest-rate.d.ts +1 -2
- package/lib/series-collector/patch-interest-rate.d.ts.map +1 -1
- package/lib/series-collector/patch-interest-rate.js.map +1 -1
- package/lib/series-collector/patch-ohlc.d.ts +1 -2
- package/lib/series-collector/patch-ohlc.d.ts.map +1 -1
- package/lib/series-collector/patch-ohlc.js.map +1 -1
- package/lib/series-collector/setup.js.map +1 -1
- package/lib/series-collector/sql-helpers.d.ts.map +1 -1
- package/lib/series-data/fifo-queue.d.ts.map +1 -1
- package/lib/series-data/fifo-queue.js.map +1 -1
- package/lib/series-data/scheduler.js.map +1 -1
- package/lib/tsdoc-metadata.json +11 -0
- package/package.json +42 -42
- package/temp/app-virtual-exchange.api.json +193 -0
- package/temp/app-virtual-exchange.api.md +9 -0
- package/temp/build/typescript/ts_KjrfbUqK.json +1 -0
- package/temp/test/jest/haste-map-76b16e3ab892e2fd05068740b7223d57-a6c52f003baf5bf33cffc52364f3bd7a-4ce9ff2cd20d69bbaecd1543c7e32e02 +0 -0
- package/temp/test/jest/perf-cache-76b16e3ab892e2fd05068740b7223d57-da39a3ee5e6b4b0d3255bfef95601890 +1 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../../src/quote/scheduler.ts"],"names":[],"mappings":"AACA,OAAO,EAAsC,mCAAmC,EAAE,MAAM,kBAAkB,CAAC;AAC3G,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAuBrC,MAAM,eAAe,GAAG,GAAqB,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;AAEzE,MAAM,WAAW,GAAG,CAAI,KAAoB,EAAE,KAAQ,EAAE,EAAE;IACxD,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC1B,CAAC,CAAC;AAEF,MAAM,WAAW,GAAG,CAAI,KAAoB,EAAiB,EAAE;IAC7D,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM;QAAE,OAAO,SAAS,CAAC;IACvD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IACxC,IAAI,KAAK,CAAC,IAAI,GAAG,IAAI,IAAI,KAAK,CAAC,IAAI,GAAG,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE;QAC5D,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC5C,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC;KAChB;IACD,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAEF,MAAM,QAAQ,GAAG,CAAI,KAAoB,EAAU,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC;AAEtF,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,+BAA+B,KAAK,GAAG,CAAC;AAE3E,kDAAkD;AAElD,iBAAiB;AACjB,0BAA0B;AAC1B,kCAAkC;AAClC,yCAAyC;AACzC,0BAA0B;AAC1B,oBAAoB;AACpB,sDAAsD;AACtD,iCAAiC;AACjC,wBAAwB;AACxB,+BAA+B;AAC/B,0BAA0B;AAC1B,iDAAiD;AAEjD,gEAAgE;AAChE,MAAM,QAAQ,GAAyB,EAAE,CAAC;AAC1C,MAAM,oBAAoB,GAAG,IAAI,GAAG,EAA2B,CAAC;AAEhE,sEAAsE;AACtE,4EAA4E;AAC5E,mBAAmB;AACnB;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,KAAK,GAAsB,EAAE,CAAC;AAC3C,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAsB,CAAC;AASvD,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAuB,CAAC;AAEzD,MAAM,qBAAqB,GAAG,CAAC,QAAgB,EAAe,EAAE;IAC9D,MAAM,QAAQ,GAAG,iBAAiB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACjD,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC9B,MAAM,IAAI,GAAgB;QACxB,YAAY,EAAE,eAAe,EAAE;QAC/B,OAAO,EAAE,IAAI,GAAG,EAAU;QAC1B,gBAAgB,EAAE,IAAI,GAAG,EAAU;QACnC,oBAAoB,EAAE,IAAI,GAAG,EAA4B;KAC1D,CAAC;IACF,iBAAiB,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IACtC,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAEF,MAAM,KAAK,GAAG,CAAC,UAAkB,EAAE,KAAkB,EAAE,EAAE;IACvD,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE;QAC9B,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC;YAAE,SAAS;QACrE,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC;YAAE,SAAS;QAChD,OAAO,OAAO,CAAC,gBAAgB,CAAC;KACjC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC,CAAC;AAEF,MAAM,YAAY,GAAG,CAAC,MAA4E,EAAE,EAAE;;IACpG,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,gBAAgB,EAAE,GAAG,MAAM,CAAC;IACvD,IAAI,CAAC,gBAAgB;QAAE,OAAO;IAC9B,MAAM,UAAU,GAAG,qBAAqB,CAAC,gBAAgB,CAAC,CAAC;IAC3D,MAAM,WAAW,GACf,MAAA,UAAU,CAAC,oBAAoB,CAAC,GAAG,CAAC,UAAU,CAAC,mCAC/C,CAAC,GAAG,EAAE;QACJ,MAAM,IAAI,GAAG,IAAI,GAAG,EAAe,CAAC;QACpC,UAAU,CAAC,oBAAoB,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QACtD,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,EAAE,CAAC;IACP,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAEvB,IAAI,UAAU,CAAC,gBAAgB,CAAC,GAAG,CAAC,UAAU,CAAC;QAAE,OAAO;IACxD,IAAI,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;QAAE,OAAO;IAC/C,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACnC,WAAW,CAAC,UAAU,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;AACnD,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,UAAkB,EAAE,KAAkB,EAAE,EAAE;IAClE,MAAM,gBAAgB,GAAG,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;IAElD,MAAM,OAAO,GAAG,UAAU,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;IAC9C,MAAM,QAAQ,GAAG,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC/C,IAAI,CAAC,QAAQ,EAAE;QACb,MAAM,IAAI,GAAe;YACvB,UAAU;YACV,KAAK;YACL,gBAAgB;YAChB,QAAQ,EAAE,IAAI;YACd,WAAW,EAAE,KAAK;YAClB,KAAK,EAAE,CAAC;SACT,CAAC;QACF,gBAAgB,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACpC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;KAClB;SAAM;QACL,QAAQ,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;QAC7C,QAAQ,CAAC,QAAQ,GAAG,IAAI,CAAC;KAC1B;IAED,YAAY,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC,CAAC;IACtD,sBAAsB,CAAC,gBAAgB,CAAC,CAAC;AAC3C,CAAC,CAAC;AAEF,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAAU,CAAC;AAE7C,MAAM,sBAAsB,GAAG,CAAC,cAAsB,EAAQ,EAAE;IAC9D,IAAI,CAAC,cAAc;QAAE,OAAO;IAC5B,MAAM,WAAW,GAAG,oBAAoB,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAC7D,IAAI,CAAC,WAAW,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAErD,KAAK,MAAM,OAAO,IAAI,WAAW,EAAE;QACjC,IAAI,kBAAkB,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC;YAAE,SAAS;QACzD,kBAAkB,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAC3C,aAAa,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE;YAClC,kBAAkB,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;KACJ;AACH,CAAC,CAAC;AAEF,MAAM,aAAa,GAAG,KAAK,EAAE,OAAsB,EAAE,EAAE;;IACrD,MAAM,UAAU,GAAG,iBAAiB,CAAC,GAAG,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACnE,IAAI,CAAC,UAAU;QAAE,OAAO;IAExB,OAAO,IAAI,EAAE;QACX,MAAM,WAAW,GAAG,MAAA,OAAO,CAAC,IAAI,CAAC,wBAAwB,mCAAI,QAAQ,CAAC;QACtE,MAAM,sBAAsB,GAAG,IAAI,GAAG,EAA4B,CAAC;QACnE,MAAM,eAAe,GAAa,EAAE,CAAC;QACrC,MAAM,YAAY,GAAiB,EAAE,CAAC;QAEtC,OAAO,eAAe,CAAC,MAAM,GAAG,WAAW,IAAI,QAAQ,CAAC,UAAU,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE;YACpF,MAAM,UAAU,GAAG,WAAW,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;YACxD,IAAI,CAAC,UAAU;gBAAE,MAAM;YACvB,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YAEtC,IAAI,UAAU,CAAC,gBAAgB,CAAC,GAAG,CAAC,UAAU,CAAC;gBAAE,SAAS;YAC1D,MAAM,WAAW,GAAG,UAAU,CAAC,oBAAoB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YACpE,IAAI,CAAC,WAAW,IAAI,WAAW,CAAC,IAAI,KAAK,CAAC;gBAAE,SAAS;YAErD,MAAM,aAAa,GAAkB,EAAE,CAAC;YACxC,KAAK,MAAM,CAAC,IAAI,WAAW,EAAE;gBAC3B,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC;oBAAE,SAAS;gBAC5C,MAAM,IAAI,GAAG,gBAAgB,CAAC,GAAG,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;gBAC7D,IAAI,CAAC,IAAI;oBAAE,SAAS;gBACpB,IAAI,IAAI,CAAC,gBAAgB,KAAK,OAAO,CAAC,gBAAgB;oBAAE,SAAS;gBACjE,IAAI,CAAC,IAAI,CAAC,QAAQ;oBAAE,SAAS;gBAC7B,IAAI,IAAI,CAAC,WAAW;oBAAE,SAAS;gBAC/B,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBACtB,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;aACzB;YAED,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC;gBAAE,SAAS;YACzC,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACjC,UAAU,CAAC,gBAAgB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YAC5C,sBAAsB,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC;SAChE;QAED,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAEzC,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE;YAC/B,IAAI,CAAC,KAAK,EAAE,CAAC;YACb,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;SACzB;QAED,MAAM,GAAG,GAAG,MAAM,WAAW,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAyB,CAAA,CAAC,CAAC;QAChG,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAEvB,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE;YAC/B,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;YACzB,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;SACvB;QAED,KAAK,MAAM,UAAU,IAAI,eAAe,EAAE;YACxC,UAAU,CAAC,gBAAgB,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YAC/C,MAAM,WAAW,GAAG,UAAU,CAAC,oBAAoB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YACpE,MAAM,aAAa,GAAG,sBAAsB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YAC7D,IAAI,CAAC,WAAW,IAAI,CAAC,aAAa;gBAAE,SAAS;YAC7C,KAAK,MAAM,CAAC,IAAI,aAAa,EAAE;gBAC7B,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;aACvB;YACD,IAAI,WAAW,CAAC,IAAI,KAAK,CAAC,EAAE;gBAC1B,UAAU,CAAC,oBAAoB,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;gBACnD,SAAS;aACV;YACD,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE;gBACvC,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;gBACnC,WAAW,CAAC,UAAU,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;aAClD;SACF;KACF;AACH,CAAC,CAAC;AAEF,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;AAExC,MAAM,WAAW,GAAG,KAAK,EAAE,OAAsB,EAAE,WAAqB,EAA+B,EAAE;IACvG,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,sBAAsB,CAAyB,WAAW,EAAE;QAC5F,WAAW;QACX,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,MAAM;KAC5B,CAAC,CAAC;IACH,IAAI,cAAc,EAAE;QAClB,OAAO,CAAC,IAAI,CACV,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,+BAA+B,EAC/B,cAAc,OAAO,CAAC,UAAU,EAAE,EAClC,SAAS,OAAO,CAAC,gBAAgB,EAAE,EACnC,YAAY,WAAW,CAAC,MAAM,EAAE,CACjC,CAAC;KACH;IACD,OAAO,GAAG,CAAC;AACb,CAAC,CAAC;AAEF,QAAQ,CAAC,cAAc;KACpB,IAAI,CACH,QAAQ,CAAC,CAAC,aAAa,EAAE,EAAE,CACzB,IAAI,CAAC,aAAa,CAAC,CAAC,IAAI,CACtB,QAAQ,CAAC,CAAC,YAAY,EAAE,EAAE,CACxB,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CACtD,MAAM,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,WAAW,CAAC,MAAM,KAAK,WAAW,CAAC,EAC3D,GAAG,CAAC,CAAC,WAAW,EAA6B,EAAE;;IAC7C,IAAI;QACF,MAAM,IAAI,GAAG,mCAAmC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QACrE,MAAM,gBAAgB,GAAG,UAAU,CACjC,IAAI,CAAC,iBAAiB,EACrB,IAAI,CAAC,MAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,EAChC,MAAA,IAAI,CAAC,wBAAwB,mCAAI,EAAE,CACpC,CAAC;QACF,OAAO;YACL,UAAU,EAAE,WAAW,CAAC,UAAU;YAClC,gBAAgB;YAChB,IAAI;YACJ,aAAa,EAAE,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;SACpC,CAAC;KACH;IAAC,WAAM,GAAE;AACZ,CAAC,CAAC,EACF,MAAM,CAAC,CAAC,CAAC,EAAqC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CACtD,CACF,EACD,OAAO,EAAE,EACT,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;IACR,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;IACpB,oBAAoB,CAAC,KAAK,EAAE,CAAC;IAC7B,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;;QACpB,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACvB,MAAM,IAAI,GAAG,MAAA,oBAAoB,CAAC,GAAG,CAAC,OAAO,CAAC,gBAAgB,CAAC,mCAAI,EAAE,CAAC;QACtE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACnB,oBAAoB,CAAC,GAAG,CAAC,OAAO,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CACH,CACF,CACF;KACA,SAAS,EAAE,CAAC","sourcesContent":["import { IQuoteUpdateAction } from '@yuants/data-quote';\nimport { IQuoteField, IQuoteServiceMetadata, parseQuoteServiceMetadataFromSchema } from '@yuants/exchange';\nimport { Terminal } from '@yuants/protocol';\nimport { encodePath, formatTime } from '@yuants/utils';\nimport { filter, from, map, mergeMap, tap, toArray } from 'rxjs';\nimport { quoteState } from './state';\n\ninterface IQuoteService {\n service_id: string;\n service_group_id: string;\n meta: IQuoteServiceMetadata;\n metaFieldsSet: Set<IQuoteField>;\n}\n\ninterface ICellState {\n product_id: string;\n field: IQuoteField;\n service_group_id: string;\n is_dirty: boolean;\n is_fetching: boolean;\n round: number;\n}\n\ntype IFifoQueue<T> = {\n items: T[];\n head: number;\n};\n\nconst createFifoQueue = <T>(): IFifoQueue<T> => ({ items: [], head: 0 });\n\nconst fifoEnqueue = <T>(queue: IFifoQueue<T>, value: T) => {\n queue.items.push(value);\n};\n\nconst fifoDequeue = <T>(queue: IFifoQueue<T>): T | undefined => {\n if (queue.head >= queue.items.length) return undefined;\n const value = queue.items[queue.head++];\n if (queue.head > 1024 && queue.head * 2 > queue.items.length) {\n queue.items = queue.items.slice(queue.head);\n queue.head = 0;\n }\n return value;\n};\n\nconst fifoSize = <T>(queue: IFifoQueue<T>): number => queue.items.length - queue.head;\n\nconst isTraceEnabled = process.env.VEX_QUOTE_UPSTREAM_REFINE_TRACE === '1';\n\n// Query -> Make Cell Dirty -> Trigger Dirty Check\n\n// Dirty Check():\n// Acquire dirtyCheck lock\n// Foreach Dirty cell in parallel:\n//. Routing the dirty cell to ServiceID\n//. Acquire Service Lock\n//. if success:\n// request the service and wait for response\n//. release service lock\n// clean cells\n//. if failed: do nothing.\n// Release dirtyCheck lock\n// if any cell dirty remaining, call dirtyCheck()\n\n// (service_id, service_group_id) -> sync func state (hash func)\nconst services: Array<IQuoteService> = [];\nconst mapGroupIdToServices = new Map<string, IQuoteService[]>();\n\n// (product_id, field, service_group_id, is_dirty = true, is_fetching)\n// use-case 1: find unique product_ids (not is_fetching) by service_group_id\n// use-case 2: mark\n/**\n * Use cases:\n * - upsert items (when queryQuotes)\n * - find unique product_ids (is_dirty = true and is_fetching = false) by service_group_id\n * - when service fired, update is_fetching = true for some items (product_id, field)\n * - when service failed, update is_fetching = false for some items (product_id, field)\n * - when service success, update is_fetching = false and is_dirty = false for some items (product_id, field)\n */\nexport const cells: Array<ICellState> = [];\nconst mapCellKeyToCell = new Map<string, ICellState>();\n\ntype IGroupState = {\n productQueue: IFifoQueue<string>;\n inQueue: Set<string>;\n fetchingProducts: Set<string>;\n dirtyFieldsByProduct: Map<string, Set<IQuoteField>>;\n};\n\nconst mapGroupIdToState = new Map<string, IGroupState>();\n\nconst getOrCreateGroupState = (group_id: string): IGroupState => {\n const existing = mapGroupIdToState.get(group_id);\n if (existing) return existing;\n const next: IGroupState = {\n productQueue: createFifoQueue(),\n inQueue: new Set<string>(),\n fetchingProducts: new Set<string>(),\n dirtyFieldsByProduct: new Map<string, Set<IQuoteField>>(),\n };\n mapGroupIdToState.set(group_id, next);\n return next;\n};\n\nconst route = (product_id: string, field: IQuoteField) => {\n for (const service of services) {\n if (!product_id.startsWith(service.meta.product_id_prefix)) continue;\n if (!service.metaFieldsSet.has(field)) continue;\n return service.service_group_id;\n }\n return '';\n};\n\nconst enqueueDirty = (params: { product_id: string; field: IQuoteField; service_group_id: string }) => {\n const { product_id, field, service_group_id } = params;\n if (!service_group_id) return;\n const groupState = getOrCreateGroupState(service_group_id);\n const dirtyFields =\n groupState.dirtyFieldsByProduct.get(product_id) ??\n (() => {\n const next = new Set<IQuoteField>();\n groupState.dirtyFieldsByProduct.set(product_id, next);\n return next;\n })();\n dirtyFields.add(field);\n\n if (groupState.fetchingProducts.has(product_id)) return;\n if (groupState.inQueue.has(product_id)) return;\n groupState.inQueue.add(product_id);\n fifoEnqueue(groupState.productQueue, product_id);\n};\n\nexport const markDirty = (product_id: string, field: IQuoteField) => {\n const service_group_id = route(product_id, field);\n\n const cellKey = encodePath(product_id, field);\n const existing = mapCellKeyToCell.get(cellKey);\n if (!existing) {\n const cell: ICellState = {\n product_id,\n field,\n service_group_id,\n is_dirty: true,\n is_fetching: false,\n round: 0,\n };\n mapCellKeyToCell.set(cellKey, cell);\n cells.push(cell);\n } else {\n existing.service_group_id = service_group_id;\n existing.is_dirty = true;\n }\n\n enqueueDirty({ product_id, field, service_group_id });\n scheduleServiceGroupId(service_group_id);\n};\n\nconst isServiceIdRunning = new Set<string>();\n\nconst scheduleServiceGroupId = (serviceGroupId: string): void => {\n if (!serviceGroupId) return;\n const serviceList = mapGroupIdToServices.get(serviceGroupId);\n if (!serviceList || serviceList.length === 0) return;\n\n for (const service of serviceList) {\n if (isServiceIdRunning.has(service.service_id)) continue;\n isServiceIdRunning.add(service.service_id);\n handleService(service).finally(() => {\n isServiceIdRunning.delete(service.service_id);\n });\n }\n};\n\nconst handleService = async (service: IQuoteService) => {\n const groupState = mapGroupIdToState.get(service.service_group_id);\n if (!groupState) return;\n\n while (true) {\n const maxProducts = service.meta.max_products_per_request ?? Infinity;\n const fetchedFieldsByProduct = new Map<string, Set<IQuoteField>>();\n const productsToFetch: string[] = [];\n const cellsToFetch: ICellState[] = [];\n\n while (productsToFetch.length < maxProducts && fifoSize(groupState.productQueue) > 0) {\n const product_id = fifoDequeue(groupState.productQueue);\n if (!product_id) break;\n groupState.inQueue.delete(product_id);\n\n if (groupState.fetchingProducts.has(product_id)) continue;\n const dirtyFields = groupState.dirtyFieldsByProduct.get(product_id);\n if (!dirtyFields || dirtyFields.size === 0) continue;\n\n const matchedFields: IQuoteField[] = [];\n for (const f of dirtyFields) {\n if (!service.metaFieldsSet.has(f)) continue;\n const cell = mapCellKeyToCell.get(encodePath(product_id, f));\n if (!cell) continue;\n if (cell.service_group_id !== service.service_group_id) continue;\n if (!cell.is_dirty) continue;\n if (cell.is_fetching) continue;\n matchedFields.push(f);\n cellsToFetch.push(cell);\n }\n\n if (matchedFields.length === 0) continue;\n productsToFetch.push(product_id);\n groupState.fetchingProducts.add(product_id);\n fetchedFieldsByProduct.set(product_id, new Set(matchedFields));\n }\n\n if (productsToFetch.length === 0) return;\n\n for (const cell of cellsToFetch) {\n cell.round++;\n cell.is_fetching = true;\n }\n\n const res = await makeRequest(service, productsToFetch).catch(() => ({} as IQuoteUpdateAction));\n quoteState.update(res);\n\n for (const cell of cellsToFetch) {\n cell.is_fetching = false;\n cell.is_dirty = false;\n }\n\n for (const product_id of productsToFetch) {\n groupState.fetchingProducts.delete(product_id);\n const dirtyFields = groupState.dirtyFieldsByProduct.get(product_id);\n const fetchedFields = fetchedFieldsByProduct.get(product_id);\n if (!dirtyFields || !fetchedFields) continue;\n for (const f of fetchedFields) {\n dirtyFields.delete(f);\n }\n if (dirtyFields.size === 0) {\n groupState.dirtyFieldsByProduct.delete(product_id);\n continue;\n }\n if (!groupState.inQueue.has(product_id)) {\n groupState.inQueue.add(product_id);\n fifoEnqueue(groupState.productQueue, product_id);\n }\n }\n }\n};\n\nconst terminal = Terminal.fromNodeEnv();\n\nconst makeRequest = async (service: IQuoteService, product_ids: string[]): Promise<IQuoteUpdateAction> => {\n const res = await terminal.client.requestForResponseData<{}, IQuoteUpdateAction>('GetQuotes', {\n product_ids,\n fields: service.meta.fields,\n });\n if (isTraceEnabled) {\n console.info(\n formatTime(Date.now()),\n `[VEX][Quote][Refine]GetQuotes`,\n `service_id=${service.service_id}`,\n `group=${service.service_group_id}`,\n `products=${product_ids.length}`,\n );\n }\n return res;\n};\n\nterminal.terminalInfos$\n .pipe(\n mergeMap((terminalInfos) =>\n from(terminalInfos).pipe(\n mergeMap((terminalInfo) =>\n from(Object.values(terminalInfo.serviceInfo || {})).pipe(\n filter((serviceInfo) => serviceInfo.method === 'GetQuotes'),\n map((serviceInfo): IQuoteService | undefined => {\n try {\n const meta = parseQuoteServiceMetadataFromSchema(serviceInfo.schema);\n const service_group_id = encodePath(\n meta.product_id_prefix,\n (meta.fields as any[]).join(','),\n meta.max_products_per_request ?? '',\n );\n return {\n service_id: serviceInfo.service_id,\n service_group_id,\n meta,\n metaFieldsSet: new Set(meta.fields),\n };\n } catch {}\n }),\n filter((x): x is Exclude<typeof x, undefined> => !!x),\n ),\n ),\n toArray(),\n tap((x) => {\n services.length = 0;\n mapGroupIdToServices.clear();\n x.forEach((service) => {\n services.push(service);\n const list = mapGroupIdToServices.get(service.service_group_id) ?? [];\n list.push(service);\n mapGroupIdToServices.set(service.service_group_id, list);\n });\n }),\n ),\n ),\n )\n .subscribe();\n"]}
|
|
1
|
+
{"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../../src/quote/scheduler.ts"],"names":[],"mappings":"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","sourcesContent":["import { IQuoteUpdateAction } from '@yuants/data-quote';\nimport { IQuoteField, IQuoteServiceMetadata, parseQuoteServiceMetadataFromSchema } from '@yuants/exchange';\nimport { Terminal } from '@yuants/protocol';\nimport { encodePath, formatTime } from '@yuants/utils';\nimport { filter, from, map, mergeMap, tap, toArray } from 'rxjs';\nimport { quoteState } from './state';\n\ninterface IQuoteService {\n service_id: string;\n service_group_id: string;\n meta: IQuoteServiceMetadata;\n metaFieldsSet: Set<IQuoteField>;\n}\n\ninterface ICellState {\n product_id: string;\n field: IQuoteField;\n service_group_id: string;\n is_dirty: boolean;\n is_fetching: boolean;\n round: number;\n}\n\ntype IFifoQueue<T> = {\n items: T[];\n head: number;\n};\n\nconst createFifoQueue = <T>(): IFifoQueue<T> => ({ items: [], head: 0 });\n\nconst fifoEnqueue = <T>(queue: IFifoQueue<T>, value: T) => {\n queue.items.push(value);\n};\n\nconst fifoDequeue = <T>(queue: IFifoQueue<T>): T | undefined => {\n if (queue.head >= queue.items.length) return undefined;\n const value = queue.items[queue.head++];\n if (queue.head > 1024 && queue.head * 2 > queue.items.length) {\n queue.items = queue.items.slice(queue.head);\n queue.head = 0;\n }\n return value;\n};\n\nconst fifoSize = <T>(queue: IFifoQueue<T>): number => queue.items.length - queue.head;\n\nconst isTraceEnabled = process.env.VEX_QUOTE_UPSTREAM_REFINE_TRACE === '1';\n\n// Query -> Make Cell Dirty -> Trigger Dirty Check\n\n// Dirty Check():\n// Acquire dirtyCheck lock\n// Foreach Dirty cell in parallel:\n//. Routing the dirty cell to ServiceID\n//. Acquire Service Lock\n//. if success:\n// request the service and wait for response\n//. release service lock\n// clean cells\n//. if failed: do nothing.\n// Release dirtyCheck lock\n// if any cell dirty remaining, call dirtyCheck()\n\n// (service_id, service_group_id) -> sync func state (hash func)\nconst services: Array<IQuoteService> = [];\nconst mapGroupIdToServices = new Map<string, IQuoteService[]>();\n\n// (product_id, field, service_group_id, is_dirty = true, is_fetching)\n// use-case 1: find unique product_ids (not is_fetching) by service_group_id\n// use-case 2: mark\n/**\n * Use cases:\n * - upsert items (when queryQuotes)\n * - find unique product_ids (is_dirty = true and is_fetching = false) by service_group_id\n * - when service fired, update is_fetching = true for some items (product_id, field)\n * - when service failed, update is_fetching = false for some items (product_id, field)\n * - when service success, update is_fetching = false and is_dirty = false for some items (product_id, field)\n */\nexport const cells: Array<ICellState> = [];\nconst mapCellKeyToCell = new Map<string, ICellState>();\n\ntype IGroupState = {\n productQueue: IFifoQueue<string>;\n inQueue: Set<string>;\n fetchingProducts: Set<string>;\n dirtyFieldsByProduct: Map<string, Set<IQuoteField>>;\n};\n\nconst mapGroupIdToState = new Map<string, IGroupState>();\n\nconst getOrCreateGroupState = (group_id: string): IGroupState => {\n const existing = mapGroupIdToState.get(group_id);\n if (existing) return existing;\n const next: IGroupState = {\n productQueue: createFifoQueue(),\n inQueue: new Set<string>(),\n fetchingProducts: new Set<string>(),\n dirtyFieldsByProduct: new Map<string, Set<IQuoteField>>(),\n };\n mapGroupIdToState.set(group_id, next);\n return next;\n};\n\nconst route = (product_id: string, field: IQuoteField) => {\n for (const service of services) {\n if (!product_id.startsWith(service.meta.product_id_prefix)) continue;\n if (!service.metaFieldsSet.has(field)) continue;\n return service.service_group_id;\n }\n return '';\n};\n\nconst enqueueDirty = (params: { product_id: string; field: IQuoteField; service_group_id: string }) => {\n const { product_id, field, service_group_id } = params;\n if (!service_group_id) return;\n const groupState = getOrCreateGroupState(service_group_id);\n const dirtyFields =\n groupState.dirtyFieldsByProduct.get(product_id) ??\n (() => {\n const next = new Set<IQuoteField>();\n groupState.dirtyFieldsByProduct.set(product_id, next);\n return next;\n })();\n dirtyFields.add(field);\n\n if (groupState.fetchingProducts.has(product_id)) return;\n if (groupState.inQueue.has(product_id)) return;\n groupState.inQueue.add(product_id);\n fifoEnqueue(groupState.productQueue, product_id);\n};\n\nexport const markDirty = (product_id: string, field: IQuoteField) => {\n const service_group_id = route(product_id, field);\n\n const cellKey = encodePath(product_id, field);\n const existing = mapCellKeyToCell.get(cellKey);\n if (!existing) {\n const cell: ICellState = {\n product_id,\n field,\n service_group_id,\n is_dirty: true,\n is_fetching: false,\n round: 0,\n };\n mapCellKeyToCell.set(cellKey, cell);\n cells.push(cell);\n } else {\n existing.service_group_id = service_group_id;\n existing.is_dirty = true;\n }\n\n enqueueDirty({ product_id, field, service_group_id });\n scheduleServiceGroupId(service_group_id);\n};\n\nconst isServiceIdRunning = new Set<string>();\n\nconst scheduleServiceGroupId = (serviceGroupId: string): void => {\n if (!serviceGroupId) return;\n const serviceList = mapGroupIdToServices.get(serviceGroupId);\n if (!serviceList || serviceList.length === 0) return;\n\n for (const service of serviceList) {\n if (isServiceIdRunning.has(service.service_id)) continue;\n isServiceIdRunning.add(service.service_id);\n handleService(service).finally(() => {\n isServiceIdRunning.delete(service.service_id);\n });\n }\n};\n\nconst handleService = async (service: IQuoteService) => {\n const groupState = mapGroupIdToState.get(service.service_group_id);\n if (!groupState) return;\n\n while (true) {\n const maxProducts = service.meta.max_products_per_request ?? Infinity;\n const fetchedFieldsByProduct = new Map<string, Set<IQuoteField>>();\n const productsToFetch: string[] = [];\n const cellsToFetch: ICellState[] = [];\n\n while (productsToFetch.length < maxProducts && fifoSize(groupState.productQueue) > 0) {\n const product_id = fifoDequeue(groupState.productQueue);\n if (!product_id) break;\n groupState.inQueue.delete(product_id);\n\n if (groupState.fetchingProducts.has(product_id)) continue;\n const dirtyFields = groupState.dirtyFieldsByProduct.get(product_id);\n if (!dirtyFields || dirtyFields.size === 0) continue;\n\n const matchedFields: IQuoteField[] = [];\n for (const f of dirtyFields) {\n if (!service.metaFieldsSet.has(f)) continue;\n const cell = mapCellKeyToCell.get(encodePath(product_id, f));\n if (!cell) continue;\n if (cell.service_group_id !== service.service_group_id) continue;\n if (!cell.is_dirty) continue;\n if (cell.is_fetching) continue;\n matchedFields.push(f);\n cellsToFetch.push(cell);\n }\n\n if (matchedFields.length === 0) continue;\n productsToFetch.push(product_id);\n groupState.fetchingProducts.add(product_id);\n fetchedFieldsByProduct.set(product_id, new Set(matchedFields));\n }\n\n if (productsToFetch.length === 0) return;\n\n for (const cell of cellsToFetch) {\n cell.round++;\n cell.is_fetching = true;\n }\n\n const res = await makeRequest(service, productsToFetch).catch(() => ({} as IQuoteUpdateAction));\n quoteState.update(res);\n\n for (const cell of cellsToFetch) {\n cell.is_fetching = false;\n cell.is_dirty = false;\n }\n\n for (const product_id of productsToFetch) {\n groupState.fetchingProducts.delete(product_id);\n const dirtyFields = groupState.dirtyFieldsByProduct.get(product_id);\n const fetchedFields = fetchedFieldsByProduct.get(product_id);\n if (!dirtyFields || !fetchedFields) continue;\n for (const f of fetchedFields) {\n dirtyFields.delete(f);\n }\n if (dirtyFields.size === 0) {\n groupState.dirtyFieldsByProduct.delete(product_id);\n continue;\n }\n if (!groupState.inQueue.has(product_id)) {\n groupState.inQueue.add(product_id);\n fifoEnqueue(groupState.productQueue, product_id);\n }\n }\n }\n};\n\nconst terminal = Terminal.fromNodeEnv();\n\nconst makeRequest = async (service: IQuoteService, product_ids: string[]): Promise<IQuoteUpdateAction> => {\n const res = await terminal.client.requestForResponseData<{}, IQuoteUpdateAction>('GetQuotes', {\n product_ids,\n fields: service.meta.fields,\n });\n if (isTraceEnabled) {\n console.info(\n formatTime(Date.now()),\n `[VEX][Quote][Refine]GetQuotes`,\n `service_id=${service.service_id}`,\n `group=${service.service_group_id}`,\n `products=${product_ids.length}`,\n );\n }\n return res;\n};\n\nterminal.terminalInfos$\n .pipe(\n mergeMap((terminalInfos) =>\n from(terminalInfos).pipe(\n mergeMap((terminalInfo) =>\n from(Object.values(terminalInfo.serviceInfo || {})).pipe(\n filter((serviceInfo) => serviceInfo.method === 'GetQuotes'),\n map((serviceInfo): IQuoteService | undefined => {\n try {\n const meta = parseQuoteServiceMetadataFromSchema(serviceInfo.schema);\n const service_group_id = encodePath(\n meta.product_id_prefix,\n (meta.fields as any[]).join(','),\n meta.max_products_per_request ?? '',\n );\n return {\n service_id: serviceInfo.service_id,\n service_group_id,\n meta,\n metaFieldsSet: new Set(meta.fields),\n };\n } catch {}\n }),\n filter((x): x is Exclude<typeof x, undefined> => !!x),\n ),\n ),\n toArray(),\n tap((x) => {\n services.length = 0;\n mapGroupIdToServices.clear();\n x.forEach((service) => {\n services.push(service);\n const list = mapGroupIdToServices.get(service.service_group_id) ?? [];\n list.push(service);\n mapGroupIdToServices.set(service.service_group_id, list);\n });\n }),\n ),\n ),\n )\n .subscribe();\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/quote/service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;AAExC,MAAM,gBAAgB,GAAG,CAAC,MAAgB,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;AAC3E,MAAM,eAAe,GAAG,CAAC,MAAmB,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;AAE7E,MAAM,sBAAsB,GAAG,CAC7B,UAAuB,EACvB,WAAqB,EACrB,MAAmB,EACnB,UAAkB,EACe,EAAE;IACnC,MAAM,UAAU,GAAoB,EAAE,CAAC;IACvC,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE;
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/quote/service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Terminal } from '@yuants/protocol';\nimport { IQuoteField } from '@yuants/exchange';\nimport { quoteState } from './state';\nimport { IQuoteKey, IQuoteRequire, IQuoteState, IQuoteUpdateAction } from './types';\nimport { markDirty } from './scheduler';\n\nconst terminal = Terminal.fromNodeEnv();\n\nconst normalizeStrings = (values: string[]) => [...new Set(values)].sort();\nconst normalizeFields = (values: IQuoteKey[]) => [...new Set(values)].sort();\n\nconst analyzeRequestedQuotes = (\n quoteState: IQuoteState,\n product_ids: string[],\n fields: IQuoteKey[],\n updated_at: number,\n): { needUpdate: IQuoteRequire[] } => {\n const needUpdate: IQuoteRequire[] = [];\n for (const product_id of product_ids) {\n for (const field of fields) {\n const tuple = quoteState.getValueTuple(product_id, field);\n if (tuple === undefined) {\n needUpdate.push({ product_id, field });\n continue;\n }\n if (tuple[1] < updated_at) {\n needUpdate.push({ product_id, field });\n }\n }\n }\n return { needUpdate };\n};\n\nterminal.server.provideService<IQuoteUpdateAction>('VEX/UpdateQuotes', {}, async (msg) => {\n quoteState.update(msg.req);\n return { res: { code: 0, message: 'OK' } };\n});\n\nterminal.server.provideService<{}, IQuoteUpdateAction>('VEX/DumpQuoteState', {}, async () => {\n return { res: { code: 0, message: 'OK', data: quoteState.dumpAsObject() } };\n});\n\nterminal.server.provideService<\n { product_ids: string[]; fields: IQuoteKey[]; updated_at: number },\n Record<string, Partial<Record<IQuoteKey, string>>>\n>(\n 'VEX/QueryQuotes',\n {\n type: 'object',\n required: ['product_ids', 'fields', 'updated_at'],\n properties: {\n product_ids: {\n type: 'array',\n items: { type: 'string' },\n },\n fields: {\n type: 'array',\n items: { type: 'string' },\n },\n updated_at: { type: 'number' },\n },\n },\n async (msg) => {\n const product_ids = normalizeStrings(msg.req.product_ids);\n const fields = normalizeFields(msg.req.fields);\n const { updated_at } = msg.req;\n\n const { needUpdate } = analyzeRequestedQuotes(quoteState, product_ids, fields, updated_at);\n for (const { product_id, field } of needUpdate) {\n markDirty(product_id, field as any as IQuoteField);\n }\n\n const data = quoteState.filterValues(product_ids, fields);\n return { res: { code: 0, message: 'OK', data } };\n },\n);\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.benchmark.js","sourceRoot":"","sources":["../../src/quote/state.benchmark.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,8BAA8B,EAAE,MAAM,4CAA4C,CAAC;AAE5F;;;GAGG;AACH,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAEnC,cAAc;IACd,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE;
|
|
1
|
+
{"version":3,"file":"state.benchmark.js","sourceRoot":"","sources":["../../src/quote/state.benchmark.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,8BAA8B,EAAE,MAAM,4CAA4C,CAAC;AAE5F;;;GAGG;AACH,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAEnC,cAAc;IACd,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACrC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACrB,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC;QACzD,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC;QACzD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;QAC7C,OAAO;IACT,CAAC;IAED,gBAAgB;IAChB,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IAClC,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;IAE7C,MAAM,oBAAoB,GAAG,IAAI,8BAA8B,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;IAEvF,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QAC7B,MAAM,oBAAoB,CAAC,sBAAsB,EAAE,CAAC;IACtD,CAAC;SAAM,CAAC;QACN,MAAM,oBAAoB,CAAC,sBAAsB,EAAE,CAAC;IACtD,CAAC;AACH,CAAC;AAED,kBAAkB;AAClB,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;IAC5B,IAAI,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9B,CAAC","sourcesContent":["import { ForkedQuoteStateComparisonTest } from './benchmark/ForkedQuoteStateComparisonTest';\n\n/**\n * 主函数 - 命令行入口点\n * 仅支持 --fork-compare 和 --fork-compare --quick 模式\n */\nasync function main() {\n const args = process.argv.slice(2);\n\n // 检查是否使用正确的模式\n if (!args.includes('--fork-compare')) {\n console.log('使用方法:');\n console.log(' --fork-compare 运行完整的子进程隔离内存对比测试');\n console.log(' --fork-compare --quick 运行快速的子进程隔离内存对比测试');\n console.log('');\n console.log('注意:每个实现都在独立的子进程中运行,确保内存测试的公平性');\n return;\n }\n\n // 子进程隔离内存对比测试模式\n console.log('运行子进程隔离内存对比测试模式...');\n console.log('注意:每个实现都在独立的子进程中运行,确保内存测试的公平性');\n\n const forkedComparisonTest = new ForkedQuoteStateComparisonTest('Current', 'Baseline');\n\n if (args.includes('--quick')) {\n await forkedComparisonTest.runQuickComparisonTest();\n } else {\n await forkedComparisonTest.runComparisonTestSuite();\n }\n}\n\n// 如果直接运行此文件,则执行测试\nif (require.main === module) {\n main().catch(console.error);\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backwards-interest-rate.js","sourceRoot":"","sources":["../../src/series-collector/backwards-interest-rate.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,iCAAiC,EAAE,MAAM,eAAe,CAAC;AAElE,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;AACxC,MAAM,aAAa,GAAG,QAAQ,CAAC,OAAO;KACnC,OAAO,CAAC,+BAA+B,EAAE,EAAE,CAAC;KAC5C,MAAM,CAAC,EAAE,WAAW,EAAE,QAAQ,CAAC,WAAW,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;AAE1F,MAAM,CAAC,MAAM,gCAAgC,GAAG,KAAK,EACnD,UAAkB,EAClB,SAAiC,EACjC,MAAmB,EACnB,EAAE;;IACF,IAAI,GAA+B,CAAC;IACpC,IAAI,SAAS,KAAK,UAAU,EAAE;
|
|
1
|
+
{"version":3,"file":"backwards-interest-rate.js","sourceRoot":"","sources":["../../src/series-collector/backwards-interest-rate.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,iCAAiC,EAAE,MAAM,eAAe,CAAC;AAElE,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;AACxC,MAAM,aAAa,GAAG,QAAQ,CAAC,OAAO;KACnC,OAAO,CAAC,+BAA+B,EAAE,EAAE,CAAC;KAC5C,MAAM,CAAC,EAAE,WAAW,EAAE,QAAQ,CAAC,WAAW,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;AAE1F,MAAM,CAAC,MAAM,gCAAgC,GAAG,KAAK,EACnD,UAAkB,EAClB,SAAiC,EACjC,MAAmB,EACnB,EAAE;;IACF,IAAI,GAA+B,CAAC;IACpC,IAAI,SAAS,KAAK,UAAU,EAAE,CAAC;QAC7B,MAAM,SAAS,GAAG,MAAM,iCAAiC,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;QAChF,MAAM,UAAU,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;QAE1E,GAAG,GAAG;YACJ,UAAU,EAAE,UAAU;YACtB,SAAS,EAAE,UAAU;YACrB,IAAI,EAAE,UAAU;SACjB,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,GAAG,GAAG;YACJ,UAAU,EAAE,UAAU;YACtB,SAAS,EAAE,SAAS;YACpB,IAAI,EAAE,CAAC;SACR,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,IAAI,CACV,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,2CAA2C,EAC3C,SAAS,EACT,cAAc,GAAG,CAAC,UAAU,eAAe,GAAG,CAAC,SAAS,UAAU,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CACzF,CAAC;IAEF,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,sBAAsB,CACtD,oBAAoB,EACpB,GAAG,CACJ,CAAC;IAEF,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,CAAC,CAAC;IAExC,OAAO,CAAC,IAAI,CACV,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,2CAA2C,EAC3C,QAAQ,EACR,aAAa,UAAU,oBAAoB,GAAG,CAAC,WAAW,gBAAgB,UAAU,CAClF,MAAA,MAAA,GAAG,CAAC,KAAK,0CAAE,UAAU,mCAAI,GAAG,CAC7B,cAAc,UAAU,CAAC,MAAA,MAAA,GAAG,CAAC,KAAK,0CAAE,QAAQ,mCAAI,GAAG,CAAC,EAAE,CACxD,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import { IIngestInterestRateRequest, ISeriesIngestResult } from '@yuants/exchange';\nimport { Terminal } from '@yuants/protocol';\nimport { formatTime } from '@yuants/utils';\nimport { findInterestRateStartTimeBackward } from './sql-helpers';\n\nconst terminal = Terminal.fromNodeEnv();\nconst ingestCounter = terminal.metrics\n .counter('series_collector_ingest_count', '')\n .labels({ terminal_id: terminal.terminal_id, type: 'interest_rate', task: 'backward' });\n\nexport const handleIngestInterestRateBackward = async (\n product_id: string,\n direction: 'forward' | 'backward',\n signal: AbortSignal,\n) => {\n let req: IIngestInterestRateRequest;\n if (direction === 'backward') {\n const startTime = await findInterestRateStartTimeBackward(terminal, product_id);\n const start_time = startTime ? new Date(startTime).getTime() : Date.now();\n\n req = {\n product_id: product_id,\n direction: 'backward',\n time: start_time,\n };\n } else {\n req = {\n product_id: product_id,\n direction: 'forward',\n time: 0,\n };\n }\n\n console.info(\n formatTime(Date.now()),\n '[SeriesCollector][InterestRate][Backward]',\n 'Request',\n `product_id=${req.product_id}, direction=${req.direction}, time=${formatTime(req.time)}`,\n );\n\n const res = await terminal.client.requestForResponseData<IIngestInterestRateRequest, ISeriesIngestResult>(\n 'IngestInterestRate',\n req,\n );\n\n ingestCounter.inc(res.wrote_count || 0);\n\n console.info(\n formatTime(Date.now()),\n '[SeriesCollector][InterestRate][Backward]',\n 'Result',\n `series_id=${product_id}, ingested_count=${res.wrote_count}, start_time=${formatTime(\n res.range?.start_time ?? NaN,\n )}, end_time=${formatTime(res.range?.end_time ?? NaN)}`,\n );\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backwards-ohlc.js","sourceRoot":"","sources":["../../src/series-collector/backwards-ohlc.ts"],"names":[],"mappings":"AAAA,0BAA0B;AAC1B,6DAA6D;AAC7D,iDAAiD;AACjD,qCAAqC;AAErC,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEvD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;AAExC,MAAM,aAAa,GAAG,QAAQ,CAAC,OAAO;KACnC,OAAO,CAAC,+BAA+B,EAAE,EAAE,CAAC;KAC5C,MAAM,CAAC,EAAE,WAAW,EAAE,QAAQ,CAAC,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;AAEjF,MAAM,CAAC,MAAM,wBAAwB,GAAG,KAAK,EAC3C,SAAiB,EACjB,SAAiC,EACjC,MAAmB,EACnB,EAAE;;IACF,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;IAE/D,IAAI,GAAuB,CAAC;IAC5B,IAAI,SAAS,KAAK,UAAU,EAAE;
|
|
1
|
+
{"version":3,"file":"backwards-ohlc.js","sourceRoot":"","sources":["../../src/series-collector/backwards-ohlc.ts"],"names":[],"mappings":"AAAA,0BAA0B;AAC1B,6DAA6D;AAC7D,iDAAiD;AACjD,qCAAqC;AAErC,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEvD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;AAExC,MAAM,aAAa,GAAG,QAAQ,CAAC,OAAO;KACnC,OAAO,CAAC,+BAA+B,EAAE,EAAE,CAAC;KAC5C,MAAM,CAAC,EAAE,WAAW,EAAE,QAAQ,CAAC,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;AAEjF,MAAM,CAAC,MAAM,wBAAwB,GAAG,KAAK,EAC3C,SAAiB,EACjB,SAAiC,EACjC,MAAmB,EACnB,EAAE;;IACF,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;IAE/D,IAAI,GAAuB,CAAC;IAC5B,IAAI,SAAS,KAAK,UAAU,EAAE,CAAC;QAC7B,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,UAAU,CAK/B,QAAQ,EACR,8DAA8D,SAAS,CACrE,SAAS,CACV,yDAAyD,CAC3D,CAAC;QACF,MAAM,UAAU,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;QAE/E,GAAG,GAAG;YACJ,UAAU;YACV,QAAQ;YACR,SAAS,EAAE,UAAU;YACrB,IAAI,EAAE,UAAU;SACjB,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,UAAU;QACV,GAAG,GAAG;YACJ,UAAU;YACV,QAAQ;YACR,SAAS;YACT,IAAI,EAAE,CAAC;SACR,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,IAAI,CACV,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,mCAAmC,EACnC,SAAS,EACT,cAAc,GAAG,CAAC,UAAU,cAAc,GAAG,CAAC,QAAQ,eAAe,GAAG,CAAC,SAAS,UAAU,UAAU,CACpG,GAAG,CAAC,IAAI,CACT,EAAE,CACJ,CAAC;IAEF,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,sBAAsB,CACtD,YAAY,EACZ,GAAG,CACJ,CAAC;IAEF,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,CAAC,CAAC;IAExC,OAAO,CAAC,IAAI,CACV,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,mCAAmC,EACnC,UAAU,EACV,aAAa,SAAS,oBAAoB,GAAG,CAAC,WAAW,gBAAgB,UAAU,CACjF,MAAA,MAAA,GAAG,CAAC,KAAK,0CAAE,UAAU,mCAAI,GAAG,CAC7B,cAAc,UAAU,CAAC,MAAA,MAAA,GAAG,CAAC,KAAK,0CAAE,QAAQ,mCAAI,GAAG,CAAC,EAAE,CACxD,CAAC;AACJ,CAAC,CAAC","sourcesContent":["// 解决 Backwards 拉取历史数据的调度器\n// 该文件会定期扫描所有 Terminal 的 ServiceInfo,提取出所有支持 Backwards 拉取的序列。\n// 然后对每个序列,向对应的 IngestOHLC Service 发送拉取请求,补齐历史数据。\n// 使用 Token Bucket 控制每个数据源的请求速率,避免过载。\n\nimport { decodeOHLCSeriesId } from '@yuants/data-ohlc';\nimport { IIngestOHLCRequest, ISeriesIngestResult } from '@yuants/exchange';\nimport { Terminal } from '@yuants/protocol';\nimport { escapeSQL, requestSQL } from '@yuants/sql';\nimport { formatTime } from '@yuants/utils';\n\nconst terminal = Terminal.fromNodeEnv();\n\nconst ingestCounter = terminal.metrics\n .counter('series_collector_ingest_count', '')\n .labels({ terminal_id: terminal.terminal_id, type: 'ohlc', task: 'backward' });\n\nexport const handleIngestOHLCBackward = async (\n series_id: string,\n direction: 'forward' | 'backward',\n signal: AbortSignal,\n) => {\n const { product_id, duration } = decodeOHLCSeriesId(series_id);\n\n let req: IIngestOHLCRequest;\n if (direction === 'backward') {\n const [record] = await requestSQL<\n {\n start_time: string;\n }[]\n >(\n terminal,\n `select start_time from series_data_range where series_id = ${escapeSQL(\n series_id,\n )} and table_name = 'ohlc_v2' order by start_time limit 1`,\n );\n const start_time = record ? new Date(record.start_time).getTime() : Date.now();\n\n req = {\n product_id,\n duration,\n direction: 'backward',\n time: start_time,\n };\n } else {\n // forward\n req = {\n product_id,\n duration,\n direction,\n time: 0,\n };\n }\n\n console.info(\n formatTime(Date.now()),\n '[SeriesCollector][OHLC][Backward]',\n 'Request',\n `product_id=${req.product_id}, duration=${req.duration}, direction=${req.direction}, time=${formatTime(\n req.time,\n )}`,\n );\n\n const res = await terminal.client.requestForResponseData<IIngestOHLCRequest, ISeriesIngestResult>(\n 'IngestOHLC',\n req,\n );\n\n ingestCounter.inc(res.wrote_count || 0);\n\n console.info(\n formatTime(Date.now()),\n '[SeriesCollector][OHLC][Backward]',\n 'Response',\n `series_id=${series_id}, ingested_count=${res.wrote_count}, start_time=${formatTime(\n res.range?.start_time ?? NaN,\n )}, end_time=${formatTime(res.range?.end_time ?? NaN)}`,\n );\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"discovery.js","sourceRoot":"","sources":["../../src/series-collector/discovery.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAEL,0CAA0C,EAC1C,kCAAkC,GACnC,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;AAExC;;;GAGG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,KAAK,IAAI,EAAE;IAClD,MAAM,WAAW,GAAG,MAAM,UAAU,CAClC,QAAQ;IACR,aAAa;IACb,+DAA+D,CAChE,CAAC;IAEF,MAAM,UAAU,GAAG,IAAI,GAAG,EAAkC,CAAC;IAC7D,KAAK,MAAM,YAAY,IAAI,QAAQ,CAAC,aAAa,EAAE;
|
|
1
|
+
{"version":3,"file":"discovery.js","sourceRoot":"","sources":["../../src/series-collector/discovery.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAEL,0CAA0C,EAC1C,kCAAkC,GACnC,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;AAExC;;;GAGG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,KAAK,IAAI,EAAE;IAClD,MAAM,WAAW,GAAG,MAAM,UAAU,CAClC,QAAQ;IACR,aAAa;IACb,+DAA+D,CAChE,CAAC;IAEF,MAAM,UAAU,GAAG,IAAI,GAAG,EAAkC,CAAC;IAC7D,KAAK,MAAM,YAAY,IAAI,QAAQ,CAAC,aAAa,EAAE,CAAC;QAClD,KAAK,MAAM,WAAW,IAAI,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,WAAW,IAAI,EAAE,CAAC,EAAE,CAAC;YACxE,IAAI,WAAW,CAAC,MAAM,KAAK,oBAAoB;gBAAE,SAAS;YAC1D,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,0CAA0C,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;gBAE5E,KAAK,MAAM,EAAE,UAAU,EAAE,IAAI,WAAW,EAAE,CAAC;oBACzC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,iBAAiB,CAAC;wBAAE,SAAS;oBAC7D,UAAU,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;gBAC7C,CAAC;YACH,CAAC;oBAAS,CAAC;YACX,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,IAAI,EAAE;IAC1C,MAAM,WAAW,GAAG,MAAM,UAAU,CAA2B,QAAQ,EAAE,gCAAgC,CAAC,CAAC;IAE3G,MAAM,UAAU,GAAG,IAAI,GAAG,EAAkC,CAAC;IAC7D,KAAK,MAAM,YAAY,IAAI,QAAQ,CAAC,aAAa,EAAE,CAAC;QAClD,KAAK,MAAM,WAAW,IAAI,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,WAAW,IAAI,EAAE,CAAC,EAAE,CAAC;YACxE,IAAI,WAAW,CAAC,MAAM,KAAK,YAAY;gBAAE,SAAS;YAClD,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,kCAAkC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;gBAEpE,KAAK,MAAM,EAAE,UAAU,EAAE,IAAI,WAAW,EAAE,CAAC;oBACzC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,iBAAiB,CAAC;wBAAE,SAAS;oBAC7D,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;wBAC1C,MAAM,SAAS,GAAG,kBAAkB,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;wBAC3D,UAAU,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;oBAC5C,CAAC;gBACH,CAAC;YACH,CAAC;oBAAS,CAAC;YACX,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC,CAAC","sourcesContent":["import { encodeOHLCSeriesId } from '@yuants/data-ohlc';\nimport {\n IInterestRateServiceMetadata,\n parseInterestRateServiceMetadataFromSchema,\n parseOHLCServiceMetadataFromSchema,\n} from '@yuants/exchange';\nimport { Terminal } from '@yuants/protocol';\nimport { requestSQL } from '@yuants/sql';\n\nconst terminal = Terminal.fromNodeEnv();\n\n/**\n * 列出所有支持利率的品种系列ID以及对应的 Service Metadata\n * @returns\n */\nexport const listInterestRateSeriesIds = async () => {\n const product_ids = await requestSQL<{ product_id: string }[]>(\n terminal,\n // 必须是支持利率的品种\n `select product_id from product where no_interest_rate = false`,\n );\n\n const series_ids = new Map<string, 'forward' | 'backward'>();\n for (const terminalInfo of terminal.terminalInfos) {\n for (const serviceInfo of Object.values(terminalInfo.serviceInfo || {})) {\n if (serviceInfo.method !== 'IngestInterestRate') continue;\n try {\n const meta = parseInterestRateServiceMetadataFromSchema(serviceInfo.schema);\n\n for (const { product_id } of product_ids) {\n if (!product_id.startsWith(meta.product_id_prefix)) continue;\n series_ids.set(product_id, meta.direction);\n }\n } finally {\n }\n }\n }\n\n return series_ids;\n};\n\n/**\n *\n * @returns\n */\nexport const listOHLCSeriesIds = async () => {\n const product_ids = await requestSQL<{ product_id: string }[]>(terminal, `select product_id from product`);\n\n const series_ids = new Map<string, 'forward' | 'backward'>();\n for (const terminalInfo of terminal.terminalInfos) {\n for (const serviceInfo of Object.values(terminalInfo.serviceInfo || {})) {\n if (serviceInfo.method !== 'IngestOHLC') continue;\n try {\n const meta = parseOHLCServiceMetadataFromSchema(serviceInfo.schema);\n\n for (const { product_id } of product_ids) {\n if (!product_id.startsWith(meta.product_id_prefix)) continue;\n for (const duration of meta.duration_list) {\n const series_id = encodeOHLCSeriesId(product_id, duration);\n series_ids.set(series_id, meta.direction);\n }\n }\n } finally {\n }\n }\n }\n\n return series_ids;\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"forwards-interest-rate.js","sourceRoot":"","sources":["../../src/series-collector/forwards-interest-rate.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,8BAA8B,EAAE,MAAM,eAAe,CAAC;AAE/D,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;AAExC,MAAM,aAAa,GAAG,QAAQ,CAAC,OAAO;KACnC,OAAO,CAAC,+BAA+B,EAAE,EAAE,CAAC;KAC5C,MAAM,CAAC,EAAE,WAAW,EAAE,QAAQ,CAAC,WAAW,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;AAEzF,MAAM,CAAC,MAAM,+BAA+B,GAAG,KAAK,EAClD,UAAkB,EAClB,SAAiC,EACjC,MAAmB,EACnB,EAAE;;IACF,IAAI,GAA+B,CAAC;IACpC,IAAI,SAAS,KAAK,SAAS,EAAE;
|
|
1
|
+
{"version":3,"file":"forwards-interest-rate.js","sourceRoot":"","sources":["../../src/series-collector/forwards-interest-rate.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,8BAA8B,EAAE,MAAM,eAAe,CAAC;AAE/D,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;AAExC,MAAM,aAAa,GAAG,QAAQ,CAAC,OAAO;KACnC,OAAO,CAAC,+BAA+B,EAAE,EAAE,CAAC;KAC5C,MAAM,CAAC,EAAE,WAAW,EAAE,QAAQ,CAAC,WAAW,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;AAEzF,MAAM,CAAC,MAAM,+BAA+B,GAAG,KAAK,EAClD,UAAkB,EAClB,SAAiC,EACjC,MAAmB,EACnB,EAAE;;IACF,IAAI,GAA+B,CAAC;IACpC,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,MAAM,OAAO,GAAG,MAAM,8BAA8B,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;QAC3E,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAEvD,GAAG,GAAG;YACJ,UAAU,EAAE,UAAU;YACtB,SAAS,EAAE,SAAS;YACpB,IAAI;SACL,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,WAAW;QACX,GAAG,GAAG;YACJ,UAAU;YACV,SAAS,EAAE,UAAU;YACrB,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE;SACjB,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,IAAI,CACV,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,0CAA0C,EAC1C,SAAS,EACT,cAAc,GAAG,CAAC,UAAU,eAAe,GAAG,CAAC,SAAS,UAAU,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CACzF,CAAC;IAEF,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,sBAAsB,CACtD,oBAAoB,EACpB,GAAG,CACJ,CAAC;IAEF,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,CAAC,CAAC;IAExC,OAAO,CAAC,IAAI,CACV,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,0CAA0C,EAC1C,QAAQ,EACR,aAAa,UAAU,oBAAoB,GAAG,CAAC,WAAW,gBAAgB,UAAU,CAClF,MAAA,MAAA,GAAG,CAAC,KAAK,0CAAE,UAAU,mCAAI,GAAG,CAC7B,cAAc,UAAU,CAAC,MAAA,MAAA,GAAG,CAAC,KAAK,0CAAE,QAAQ,mCAAI,GAAG,CAAC,EAAE,CACxD,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import { IIngestInterestRateRequest, ISeriesIngestResult } from '@yuants/exchange';\nimport { Terminal } from '@yuants/protocol';\nimport { formatTime } from '@yuants/utils';\nimport { findInterestRateEndTimeForward } from './sql-helpers';\n\nconst terminal = Terminal.fromNodeEnv();\n\nconst ingestCounter = terminal.metrics\n .counter('series_collector_ingest_count', '')\n .labels({ terminal_id: terminal.terminal_id, type: 'interest_rate', task: 'forward' });\n\nexport const handleIngestInterestRateForward = async (\n product_id: string,\n direction: 'forward' | 'backward',\n signal: AbortSignal,\n) => {\n let req: IIngestInterestRateRequest;\n if (direction === 'forward') {\n const endTime = await findInterestRateEndTimeForward(terminal, product_id);\n const time = endTime ? new Date(endTime).getTime() : 0;\n\n req = {\n product_id: product_id,\n direction: 'forward',\n time,\n };\n } else {\n // backward\n req = {\n product_id,\n direction: 'backward',\n time: Date.now(),\n };\n }\n\n console.info(\n formatTime(Date.now()),\n '[SeriesCollector][InterestRate][Forward]',\n 'Request',\n `product_id=${req.product_id}, direction=${req.direction}, time=${formatTime(req.time)}`,\n );\n\n const res = await terminal.client.requestForResponseData<IIngestInterestRateRequest, ISeriesIngestResult>(\n 'IngestInterestRate',\n req,\n );\n\n ingestCounter.inc(res.wrote_count || 0);\n\n console.info(\n formatTime(Date.now()),\n '[SeriesCollector][InterestRate][Forward]',\n 'Result',\n `series_id=${product_id}, ingested_count=${res.wrote_count}, start_time=${formatTime(\n res.range?.start_time ?? NaN,\n )}, end_time=${formatTime(res.range?.end_time ?? NaN)}`,\n );\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"forwards-ohlc.js","sourceRoot":"","sources":["../../src/series-collector/forwards-ohlc.ts"],"names":[],"mappings":"AAAA,yBAAyB;AACzB,4DAA4D;AAC5D,iDAAiD;AACjD,qCAAqC;AAErC,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEvD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;AAExC,MAAM,aAAa,GAAG,QAAQ,CAAC,OAAO;KACnC,OAAO,CAAC,+BAA+B,EAAE,EAAE,CAAC;KAC5C,MAAM,CAAC,EAAE,WAAW,EAAE,QAAQ,CAAC,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;AAEhF,MAAM,CAAC,MAAM,uBAAuB,GAAG,KAAK,EAC1C,SAAiB,EACjB,SAAiC,EACjC,MAAmB,EACnB,EAAE;;IACF,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;IAC/D,IAAI,GAAuB,CAAC;IAC5B,IAAI,SAAS,KAAK,SAAS,EAAE;
|
|
1
|
+
{"version":3,"file":"forwards-ohlc.js","sourceRoot":"","sources":["../../src/series-collector/forwards-ohlc.ts"],"names":[],"mappings":"AAAA,yBAAyB;AACzB,4DAA4D;AAC5D,iDAAiD;AACjD,qCAAqC;AAErC,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEvD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;AAExC,MAAM,aAAa,GAAG,QAAQ,CAAC,OAAO;KACnC,OAAO,CAAC,+BAA+B,EAAE,EAAE,CAAC;KAC5C,MAAM,CAAC,EAAE,WAAW,EAAE,QAAQ,CAAC,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;AAEhF,MAAM,CAAC,MAAM,uBAAuB,GAAG,KAAK,EAC1C,SAAiB,EACjB,SAAiC,EACjC,MAAmB,EACnB,EAAE;;IACF,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;IAC/D,IAAI,GAAuB,CAAC;IAC5B,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,UAAU,CAK/B,QAAQ,EACR,4DAA4D,SAAS,CACnE,SAAS,CACV,4DAA4D,CAC9D,CAAC;QAEF,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAE9D,GAAG,GAAG;YACJ,UAAU;YACV,QAAQ;YACR,SAAS,EAAE,SAAS;YACpB,IAAI;SACL,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,WAAW;QACX,GAAG,GAAG;YACJ,UAAU;YACV,QAAQ;YACR,SAAS;YACT,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE;SACjB,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,IAAI,CACV,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,kCAAkC,EAClC,SAAS,EACT,cAAc,GAAG,CAAC,UAAU,cAAc,GAAG,CAAC,QAAQ,eAAe,GAAG,CAAC,SAAS,UAAU,UAAU,CACpG,GAAG,CAAC,IAAI,CACT,EAAE,CACJ,CAAC;IAEF,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,sBAAsB,CACtD,YAAY,EACZ,GAAG,CACJ,CAAC;IAEF,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,CAAC,CAAC;IAExC,OAAO,CAAC,IAAI,CACV,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,kCAAkC,EAClC,UAAU,EACV,aAAa,SAAS,oBAAoB,GAAG,CAAC,WAAW,gBAAgB,UAAU,CACjF,MAAA,MAAA,GAAG,CAAC,KAAK,0CAAE,UAAU,mCAAI,GAAG,CAC7B,cAAc,UAAU,CAAC,MAAA,MAAA,GAAG,CAAC,KAAK,0CAAE,QAAQ,mCAAI,GAAG,CAAC,EAAE,CACxD,CAAC;AACJ,CAAC,CAAC","sourcesContent":["// 解决 Forwards 拉取历史数据的调度器\n// 该文件会定期扫描所有 Terminal 的 ServiceInfo,提取出所有支持 Forwards 拉取的序列。\n// 然后对每个序列,向对应的 IngestOHLC Service 发送拉取请求,补齐历史数据。\n// 使用 Token Bucket 控制每个数据源的请求速率,避免过载。\n\nimport { decodeOHLCSeriesId } from '@yuants/data-ohlc';\nimport { IIngestOHLCRequest, ISeriesIngestResult } from '@yuants/exchange';\nimport { Terminal } from '@yuants/protocol';\nimport { escapeSQL, requestSQL } from '@yuants/sql';\nimport { formatTime } from '@yuants/utils';\n\nconst terminal = Terminal.fromNodeEnv();\n\nconst ingestCounter = terminal.metrics\n .counter('series_collector_ingest_count', '')\n .labels({ terminal_id: terminal.terminal_id, type: 'ohlc', task: 'forward' });\n\nexport const handleIngestOHLCForward = async (\n series_id: string,\n direction: 'forward' | 'backward',\n signal: AbortSignal,\n) => {\n const { product_id, duration } = decodeOHLCSeriesId(series_id);\n let req: IIngestOHLCRequest;\n if (direction === 'forward') {\n const [record] = await requestSQL<\n {\n end_time: string;\n }[]\n >(\n terminal,\n `select end_time from series_data_range where series_id = ${escapeSQL(\n series_id,\n )} and table_name = 'ohlc_v2' order by end_time desc limit 1`,\n );\n\n const time = record ? new Date(record.end_time).getTime() : 0;\n\n req = {\n product_id,\n duration,\n direction: 'forward',\n time,\n };\n } else {\n // backward\n req = {\n product_id,\n duration,\n direction,\n time: Date.now(),\n };\n }\n\n console.info(\n formatTime(Date.now()),\n '[SeriesCollector][OHLC][Forward]',\n 'Request',\n `product_id=${req.product_id}, duration=${req.duration}, direction=${req.direction}, time=${formatTime(\n req.time,\n )}`,\n );\n\n const res = await terminal.client.requestForResponseData<IIngestOHLCRequest, ISeriesIngestResult>(\n 'IngestOHLC',\n req,\n );\n\n ingestCounter.inc(res.wrote_count || 0);\n\n console.info(\n formatTime(Date.now()),\n '[SeriesCollector][OHLC][Forward]',\n 'Response',\n `series_id=${series_id}, ingested_count=${res.wrote_count}, start_time=${formatTime(\n res.range?.start_time ?? NaN,\n )}, end_time=${formatTime(res.range?.end_time ?? NaN)}`,\n );\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"patch-interest-rate.js","sourceRoot":"","sources":["../../src/series-collector/patch-interest-rate.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;AAExC,MAAM,aAAa,GAAG,QAAQ,CAAC,OAAO;KACnC,OAAO,CAAC,+BAA+B,EAAE,EAAE,CAAC;KAC5C,MAAM,CAAC,EAAE,WAAW,EAAE,QAAQ,CAAC,WAAW,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;AAEzF,uBAAuB;AACvB,MAAM,CAAC,MAAM,uBAAuB,GAAG,KAAK,EAC1C,UAAkB,EAClB,SAAiC,EACjC,MAAmB,EACnB,EAAE;;IACF,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,UAAU,CAC/B,QAAQ,EACR;;;;;;;;;;;wBAWoB,SAAS,CAAC,UAAU,CAAC;;;;;;;;;;KAUxC,CACF,CAAC;IAEF,SAAS;IACT,IAAI,CAAC,MAAM;QAAE,OAAO;IAEpB,MAAM,YAAY,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,OAAO,EAAE,CAAC;IAC/D,MAAM,UAAU,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,OAAO,EAAE,CAAC;IAE3D,OAAO,CAAC,IAAI,CACV,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,wCAAwC,EACxC,SAAS,EACT,UAAU,UAAU,UAAU,UAAU,CAAC,YAAY,CAAC,QAAQ,UAAU,CAAC,UAAU,CAAC,EAAE,CACvF,CAAC;IAEF,IAAI,GAA+B,CAAC;IAEpC,IAAI,SAAS,KAAK,SAAS,EAAE;
|
|
1
|
+
{"version":3,"file":"patch-interest-rate.js","sourceRoot":"","sources":["../../src/series-collector/patch-interest-rate.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;AAExC,MAAM,aAAa,GAAG,QAAQ,CAAC,OAAO;KACnC,OAAO,CAAC,+BAA+B,EAAE,EAAE,CAAC;KAC5C,MAAM,CAAC,EAAE,WAAW,EAAE,QAAQ,CAAC,WAAW,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;AAEzF,uBAAuB;AACvB,MAAM,CAAC,MAAM,uBAAuB,GAAG,KAAK,EAC1C,UAAkB,EAClB,SAAiC,EACjC,MAAmB,EACnB,EAAE;;IACF,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,UAAU,CAC/B,QAAQ,EACR;;;;;;;;;;;wBAWoB,SAAS,CAAC,UAAU,CAAC;;;;;;;;;;KAUxC,CACF,CAAC;IAEF,SAAS;IACT,IAAI,CAAC,MAAM;QAAE,OAAO;IAEpB,MAAM,YAAY,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,OAAO,EAAE,CAAC;IAC/D,MAAM,UAAU,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,OAAO,EAAE,CAAC;IAE3D,OAAO,CAAC,IAAI,CACV,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,wCAAwC,EACxC,SAAS,EACT,UAAU,UAAU,UAAU,UAAU,CAAC,YAAY,CAAC,QAAQ,UAAU,CAAC,UAAU,CAAC,EAAE,CACvF,CAAC;IAEF,IAAI,GAA+B,CAAC;IAEpC,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,gBAAgB;QAChB,GAAG,GAAG;YACJ,UAAU,EAAE,UAAU;YACtB,SAAS,EAAE,SAAkB;YAC7B,IAAI,EAAE,YAAY;SACnB,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,iBAAiB;QACjB,GAAG,GAAG;YACJ,UAAU,EAAE,UAAU;YACtB,SAAS,EAAE,UAAmB;YAC9B,IAAI,EAAE,UAAU;SACjB,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,IAAI,CACV,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,wCAAwC,EACxC,UAAU,EACV,cAAc,EACd,aAAa,GAAG,CAAC,SAAS,UAAU,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAC3D,CAAC;IAEF,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,sBAAsB,CACtD,oBAAoB,EACpB,GAAG,CACJ,CAAC;IAEF,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,CAAC,CAAC;IAExC,OAAO,CAAC,IAAI,CACV,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,wCAAwC,EACxC,UAAU,EACV,qBAAqB,EACrB,kBAAkB,GAAG,CAAC,WAAW,gBAAgB,UAAU,CACzD,MAAA,MAAA,GAAG,CAAC,KAAK,0CAAE,UAAU,mCAAI,GAAG,CAC7B,cAAc,UAAU,CAAC,MAAA,MAAA,GAAG,CAAC,KAAK,0CAAE,QAAQ,mCAAI,GAAG,CAAC,EAAE,CACxD,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import { IIngestInterestRateRequest, ISeriesIngestResult } from '@yuants/exchange';\nimport { Terminal } from '@yuants/protocol';\nimport { escapeSQL, requestSQL } from '@yuants/sql';\nimport { formatTime } from '@yuants/utils';\n\nconst terminal = Terminal.fromNodeEnv();\n\nconst ingestCounter = terminal.metrics\n .counter('series_collector_ingest_count', '')\n .labels({ terminal_id: terminal.terminal_id, type: 'interest_rate', task: 'forward' });\n\n// Patch 任务:查找数据缺口并进行补齐\nexport const handleInterestRatePatch = async (\n product_id: string,\n direction: 'forward' | 'backward',\n signal: AbortSignal,\n) => {\n const [record] = await requestSQL<{ gap_start_time: string; gap_end_time: string }[]>(\n terminal,\n `\nWITH reversed_ranges AS (\n SELECT \n start_time,\n end_time,\n LEAD(end_time) OVER (\n PARTITION BY table_name, series_id \n ORDER BY start_time DESC\n ) AS next_end_time -- 注意:倒序时 LEAD 是前一个区间\n FROM series_data_range\n WHERE table_name = 'interest_rate' \n AND series_id = ${escapeSQL(product_id)}\n)\nSELECT \n next_end_time AS gap_start_time, -- 前一个区间的结束时间\n start_time AS gap_end_time -- 当前区间的开始时间\nFROM reversed_ranges\nWHERE next_end_time IS NOT NULL \n AND start_time > next_end_time -- 有空缺\nORDER BY start_time DESC -- 从最新开始\nLIMIT 1;\n `,\n );\n\n // no gap\n if (!record) return;\n\n const gapStartTime = new Date(record.gap_start_time).getTime();\n const gapEndTime = new Date(record.gap_end_time).getTime();\n\n console.info(\n formatTime(Date.now()),\n '[SeriesCollector][InterestRate][Patch]',\n 'FindGap',\n `series=${product_id}, from=${formatTime(gapStartTime)}, to=${formatTime(gapEndTime)}`,\n );\n\n let req: IIngestInterestRateRequest;\n\n if (direction === 'forward') {\n // forward patch\n req = {\n product_id: product_id,\n direction: 'forward' as const,\n time: gapStartTime,\n };\n } else {\n // backward patch\n req = {\n product_id: product_id,\n direction: 'backward' as const,\n time: gapEndTime,\n };\n }\n\n console.info(\n formatTime(Date.now()),\n '[SeriesCollector][InterestRate][Patch]',\n product_id,\n 'PatchRequest',\n `direction=${req.direction}, time=${formatTime(req.time)}`,\n );\n\n const res = await terminal.client.requestForResponseData<IIngestInterestRateRequest, ISeriesIngestResult>(\n 'IngestInterestRate',\n req,\n );\n\n ingestCounter.inc(res.wrote_count || 0);\n\n console.info(\n formatTime(Date.now()),\n '[SeriesCollector][InterestRate][Patch]',\n product_id,\n 'PatchBackwardResult',\n `ingested_count=${res.wrote_count}, start_time=${formatTime(\n res.range?.start_time ?? NaN,\n )}, end_time=${formatTime(res.range?.end_time ?? NaN)}`,\n );\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"patch-ohlc.js","sourceRoot":"","sources":["../../src/series-collector/patch-ohlc.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEvD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;AAExC,MAAM,aAAa,GAAG,QAAQ,CAAC,OAAO;KACnC,OAAO,CAAC,+BAA+B,EAAE,EAAE,CAAC;KAC5C,MAAM,CAAC,EAAE,WAAW,EAAE,QAAQ,CAAC,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;AAEhF,uBAAuB;AACvB,MAAM,CAAC,MAAM,qBAAqB,GAAG,KAAK,EACxC,SAAiB,EACjB,SAAiC,EACjC,MAAmB,EACnB,EAAE;;IACF,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,UAAU,CAC/B,QAAQ,EACR;;;;;;;;;;;wBAWoB,SAAS,CAAC,SAAS,CAAC;;;;;;;;;;KAUvC,CACF,CAAC;IAEF,SAAS;IACT,IAAI,CAAC,MAAM;QAAE,OAAO;IAEpB,MAAM,YAAY,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,OAAO,EAAE,CAAC;IAC/D,MAAM,UAAU,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,OAAO,EAAE,CAAC;IAE3D,OAAO,CAAC,IAAI,CACV,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,gCAAgC,EAChC,SAAS,EACT,UAAU,SAAS,UAAU,UAAU,CAAC,YAAY,CAAC,QAAQ,UAAU,CAAC,UAAU,CAAC,EAAE,CACtF,CAAC;IAEF,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;IAE/D,IAAI,GAAuB,CAAC;IAE5B,IAAI,SAAS,KAAK,SAAS,EAAE;
|
|
1
|
+
{"version":3,"file":"patch-ohlc.js","sourceRoot":"","sources":["../../src/series-collector/patch-ohlc.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEvD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;AAExC,MAAM,aAAa,GAAG,QAAQ,CAAC,OAAO;KACnC,OAAO,CAAC,+BAA+B,EAAE,EAAE,CAAC;KAC5C,MAAM,CAAC,EAAE,WAAW,EAAE,QAAQ,CAAC,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;AAEhF,uBAAuB;AACvB,MAAM,CAAC,MAAM,qBAAqB,GAAG,KAAK,EACxC,SAAiB,EACjB,SAAiC,EACjC,MAAmB,EACnB,EAAE;;IACF,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,UAAU,CAC/B,QAAQ,EACR;;;;;;;;;;;wBAWoB,SAAS,CAAC,SAAS,CAAC;;;;;;;;;;KAUvC,CACF,CAAC;IAEF,SAAS;IACT,IAAI,CAAC,MAAM;QAAE,OAAO;IAEpB,MAAM,YAAY,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,OAAO,EAAE,CAAC;IAC/D,MAAM,UAAU,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,OAAO,EAAE,CAAC;IAE3D,OAAO,CAAC,IAAI,CACV,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,gCAAgC,EAChC,SAAS,EACT,UAAU,SAAS,UAAU,UAAU,CAAC,YAAY,CAAC,QAAQ,UAAU,CAAC,UAAU,CAAC,EAAE,CACtF,CAAC;IAEF,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;IAE/D,IAAI,GAAuB,CAAC;IAE5B,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,gBAAgB;QAChB,GAAG,GAAG;YACJ,UAAU,EAAE,UAAU;YACtB,QAAQ;YACR,SAAS,EAAE,SAAkB;YAC7B,IAAI,EAAE,YAAY;SACnB,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,iBAAiB;QACjB,GAAG,GAAG;YACJ,UAAU,EAAE,UAAU;YACtB,QAAQ;YACR,SAAS,EAAE,UAAmB;YAC9B,IAAI,EAAE,UAAU;SACjB,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,IAAI,CACV,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,gCAAgC,EAChC,SAAS,EACT,cAAc,EACd,aAAa,GAAG,CAAC,SAAS,UAAU,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAC3D,CAAC;IAEF,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,sBAAsB,CACtD,YAAY,EACZ,GAAG,CACJ,CAAC;IAEF,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,CAAC,CAAC;IAExC,OAAO,CAAC,IAAI,CACV,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,gCAAgC,EAChC,SAAS,EACT,qBAAqB,EACrB,kBAAkB,GAAG,CAAC,WAAW,gBAAgB,UAAU,CACzD,MAAA,MAAA,GAAG,CAAC,KAAK,0CAAE,UAAU,mCAAI,GAAG,CAC7B,cAAc,UAAU,CAAC,MAAA,MAAA,GAAG,CAAC,KAAK,0CAAE,QAAQ,mCAAI,GAAG,CAAC,EAAE,CACxD,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import { decodeOHLCSeriesId } from '@yuants/data-ohlc';\nimport { IIngestOHLCRequest, ISeriesIngestResult } from '@yuants/exchange';\nimport { Terminal } from '@yuants/protocol';\nimport { escapeSQL, requestSQL } from '@yuants/sql';\nimport { formatTime } from '@yuants/utils';\n\nconst terminal = Terminal.fromNodeEnv();\n\nconst ingestCounter = terminal.metrics\n .counter('series_collector_ingest_count', '')\n .labels({ terminal_id: terminal.terminal_id, type: 'ohlc', task: 'forward' });\n\n// Patch 任务:查找数据缺口并进行补齐\nexport const handleIngestOHLCPatch = async (\n series_id: string,\n direction: 'forward' | 'backward',\n signal: AbortSignal,\n) => {\n const [record] = await requestSQL<{ gap_start_time: string; gap_end_time: string }[]>(\n terminal,\n `\nWITH reversed_ranges AS (\n SELECT \n start_time,\n end_time,\n LEAD(end_time) OVER (\n PARTITION BY table_name, series_id \n ORDER BY start_time DESC\n ) AS next_end_time -- 注意:倒序时 LEAD 是前一个区间\n FROM series_data_range\n WHERE table_name = 'ohlc_v2' \n AND series_id = ${escapeSQL(series_id)}\n)\nSELECT \n next_end_time AS gap_start_time, -- 前一个区间的结束时间\n start_time AS gap_end_time -- 当前区间的开始时间\nFROM reversed_ranges\nWHERE next_end_time IS NOT NULL \n AND start_time > next_end_time -- 有空缺\nORDER BY start_time DESC -- 从最新开始\nLIMIT 1;\n `,\n );\n\n // no gap\n if (!record) return;\n\n const gapStartTime = new Date(record.gap_start_time).getTime();\n const gapEndTime = new Date(record.gap_end_time).getTime();\n\n console.info(\n formatTime(Date.now()),\n '[SeriesCollector][OHLC][Patch]',\n 'FindGap',\n `series=${series_id}, from=${formatTime(gapStartTime)}, to=${formatTime(gapEndTime)}`,\n );\n\n const { product_id, duration } = decodeOHLCSeriesId(series_id);\n\n let req: IIngestOHLCRequest;\n\n if (direction === 'forward') {\n // forward patch\n req = {\n product_id: product_id,\n duration,\n direction: 'forward' as const,\n time: gapStartTime,\n };\n } else {\n // backward patch\n req = {\n product_id: product_id,\n duration,\n direction: 'backward' as const,\n time: gapEndTime,\n };\n }\n\n console.info(\n formatTime(Date.now()),\n '[SeriesCollector][OHLC][Patch]',\n series_id,\n 'PatchRequest',\n `direction=${req.direction}, time=${formatTime(req.time)}`,\n );\n\n const res = await terminal.client.requestForResponseData<IIngestOHLCRequest, ISeriesIngestResult>(\n 'IngestOHLC',\n req,\n );\n\n ingestCounter.inc(res.wrote_count || 0);\n\n console.info(\n formatTime(Date.now()),\n '[SeriesCollector][OHLC][Patch]',\n series_id,\n 'PatchBackwardResult',\n `ingested_count=${res.wrote_count}, start_time=${formatTime(\n res.range?.start_time ?? NaN,\n )}, end_time=${formatTime(res.range?.end_time ?? NaN)}`,\n );\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/series-collector/setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACpE,OAAO,EAAE,gCAAgC,EAAE,MAAM,2BAA2B,CAAC;AAC7E,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,yBAAyB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAC3E,OAAO,EAAE,+BAA+B,EAAE,MAAM,0BAA0B,CAAC;AAC3E,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAErD,MAAM,GAAG,GAAG;IACV,IAAI,EAAE;QACJ,IAAI,EAAE,iBAAiB;QACvB,OAAO,EAAE,uBAAuB;QAChC,QAAQ,EAAE,wBAAwB;QAClC,KAAK,EAAE,qBAAqB;KAC7B;IACD,YAAY,EAAE;QACZ,IAAI,EAAE,yBAAyB;QAC/B,OAAO,EAAE,+BAA+B;QACxC,QAAQ,EAAE,gCAAgC;QAC1C,KAAK,EAAE,uBAAuB;KAC/B;CACF,CAAC;AAEF,CAAC,KAAK,IAAI,EAAE;IACV,MAAM,eAAe,GAAG,IAAI,eAAe,EAAE,CAAC;IAC9C,MAAM,MAAM,GAAG,eAAe,CAAC,MAAM,CAAC;IACtC,KAAK,MAAM,IAAI,IAAI,CAAC,MAAM,EAAE,cAAc,CAAU,EAAE;
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/series-collector/setup.ts"],"names":[],"mappings":"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","sourcesContent":["import { decodePath, formatTime, tokenBucket } from '@yuants/utils';\nimport { handleIngestInterestRateBackward } from './backwards-interest-rate';\nimport { handleIngestOHLCBackward } from './backwards-ohlc';\nimport { listInterestRateSeriesIds, listOHLCSeriesIds } from './discovery';\nimport { handleIngestInterestRateForward } from './forwards-interest-rate';\nimport { handleIngestOHLCForward } from './forwards-ohlc';\nimport { handleInterestRatePatch } from './patch-interest-rate';\nimport { handleIngestOHLCPatch } from './patch-ohlc';\n\nconst api = {\n OHLC: {\n list: listOHLCSeriesIds,\n forward: handleIngestOHLCForward,\n backward: handleIngestOHLCBackward,\n patch: handleIngestOHLCPatch,\n },\n InterestRate: {\n list: listInterestRateSeriesIds,\n forward: handleIngestInterestRateForward,\n backward: handleIngestInterestRateBackward,\n patch: handleInterestRatePatch,\n },\n};\n\n(async () => {\n const abortController = new AbortController();\n const signal = abortController.signal;\n for (const type of ['OHLC', 'InterestRate'] as const) {\n const list = api[type].list;\n for (const task of ['forward', 'backward', 'patch'] as const) {\n const handler = api[type][task];\n (async () => {\n while (true) {\n await tokenBucket(`${type}:${task}`).acquire(1, signal);\n try {\n const tasks = await list();\n\n // const groups = Map.groupBy(tasks, item => decodePath(item[0])[0]);\n const groups = new Map<string, [string, 'forward' | 'backward'][]>();\n for (const item of tasks) {\n const [datasource_id] = decodePath(item[0]);\n let items = groups.get(datasource_id);\n if (!items) {\n items = [];\n groups.set(datasource_id, items);\n }\n items.push(item);\n }\n\n await Promise.all(\n Array.from(groups.entries()).map(async ([datasource_id, tasks]) => {\n for (const [series_id, direction] of tasks) {\n await tokenBucket(`${type}:${task}:${datasource_id}`).acquire(1, signal);\n await handler(series_id, direction, signal).catch((err) => {\n console.info(\n formatTime(Date.now()),\n `[SeriesCollector][${type}][${task}]`,\n series_id,\n 'Error',\n err,\n );\n });\n }\n }),\n );\n } catch (e) {}\n }\n })();\n }\n }\n})();\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fifo-queue.js","sourceRoot":"","sources":["../../src/series-data/fifo-queue.ts"],"names":[],"mappings":"AAOA,MAAM,CAAC,MAAM,eAAe,GAAG,GAAiB,EAAE;IAChD,IAAI,KAAK,GAAQ,EAAE,CAAC;IACpB,IAAI,IAAI,GAAG,CAAC,CAAC;IAEb,OAAO;QACL,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YACjB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACpB,CAAC;QACD,OAAO,EAAE,GAAG,EAAE;YACZ,IAAI,IAAI,IAAI,KAAK,CAAC,MAAM;gBAAE,OAAO,SAAS,CAAC;YAC3C,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;YAC5B,IAAI,IAAI,GAAG,IAAI,IAAI,IAAI,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE;
|
|
1
|
+
{"version":3,"file":"fifo-queue.js","sourceRoot":"","sources":["../../src/series-data/fifo-queue.ts"],"names":[],"mappings":"AAOA,MAAM,CAAC,MAAM,eAAe,GAAG,GAAiB,EAAE;IAChD,IAAI,KAAK,GAAQ,EAAE,CAAC;IACpB,IAAI,IAAI,GAAG,CAAC,CAAC;IAEb,OAAO;QACL,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YACjB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACpB,CAAC;QACD,OAAO,EAAE,GAAG,EAAE;YACZ,IAAI,IAAI,IAAI,KAAK,CAAC,MAAM;gBAAE,OAAO,SAAS,CAAC;YAC3C,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;YAC5B,IAAI,IAAI,GAAG,IAAI,IAAI,IAAI,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;gBAC3C,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC1B,IAAI,GAAG,CAAC,CAAC;YACX,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;QACD,IAAI,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI;QAC/B,QAAQ,EAAE,CAAC,KAAK,GAAG,EAAE,EAAE,EAAE;YACvB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;YACjD,OAAO,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,CAAC,CAAC;QAC7C,CAAC;KACF,CAAC;AACJ,CAAC,CAAC","sourcesContent":["export interface IQueue<T> {\n enqueue: (value: T) => void;\n dequeue: () => T | undefined;\n size: () => number;\n snapshot: (limit?: number) => T[];\n}\n\nexport const createFifoQueue = <T>(): IQueue<T> => {\n let items: T[] = [];\n let head = 0;\n\n return {\n enqueue: (value) => {\n items.push(value);\n },\n dequeue: () => {\n if (head >= items.length) return undefined;\n const value = items[head++];\n if (head > 1024 && head * 2 > items.length) {\n items = items.slice(head);\n head = 0;\n }\n return value;\n },\n size: () => items.length - head,\n snapshot: (limit = 20) => {\n const safeLimit = Math.max(0, Math.floor(limit));\n return items.slice(head, head + safeLimit);\n },\n };\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../../src/series-data/scheduler.ts"],"names":[],"mappings":"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","sourcesContent":["import { encodeInterestRateSeriesId } from '@yuants/data-interest-rate';\nimport { encodeOHLCSeriesId } from '@yuants/data-ohlc';\nimport {\n IIngestInterestRateRequest,\n IIngestOHLCRequest,\n ISeriesIngestResult,\n parseInterestRateServiceMetadataFromSchema,\n parseOHLCServiceMetadataFromSchema,\n SeriesFetchDirection,\n} from '@yuants/exchange';\nimport { Terminal } from '@yuants/protocol';\nimport { escapeSQL, requestSQL } from '@yuants/sql';\nimport { convertDurationToOffset, encodePath, formatTime } from '@yuants/utils';\nimport { catchError, defer, EMPTY, filter, from, map, mergeMap, repeat, tap, timer, toArray } from 'rxjs';\nimport { createFifoQueue } from './fifo-queue';\n\nconst terminal = Terminal.fromNodeEnv();\n\nconst isEnabled = process.env.VEX_SERIES_DATA_ENABLED === '1';\nconst onlyProductIdPrefix = (process.env.VEX_SERIES_DATA_ONLY_PRODUCT_ID_PREFIX ?? '').trim();\n\nconst CONFIG = {\n tickIntervalMs: 1_000,\n scanFullLoopIntervalMs: 5 * 60_000,\n /**\n * Maximum number of inflight series data ingest requests.\n */\n maxInflight: 20,\n /**\n * Only run tail jobs when the global head backlog is below this threshold.\n */\n tailOnlyWhenGlobalHeadBelow: 20,\n defaultInterestRateHeadLagMs: 8 * 60 * 60_000,\n defaultForwardSeedWindowMs: 24 * 60 * 60_000,\n maxBackoffMs: 5 * 60_000,\n backoffStepMs: 5_000,\n} as const;\n\n// Per-capability bucket scheduler.\n//\n// Service Discovery -> Scan Products -> Schedule Series -> Tick -> Execute Job -> Merge Range -> Repeat\n//\n// 1) Service Discovery:\n// Subscribe `terminal.terminalInfos$`, find services with method `IngestOHLC` / `IngestInterestRate`,\n// parse schema -> capability metadata (product_id_prefix, direction, duration_list).\n//\n// 2) Capability buckets (capKey):\n// capKey = encodePath(method, product_id_prefix, direction)\n// - each cap has its own headQueue/tailQueue and runs serially (cap inflight=1)\n// - tick chooses a cap in round-robin; cap runs head first\n// - tail runs only when global head backlog is low (avoid hurting freshness)\n// - errors/backoff are isolated per-cap (a noisy cap won't block others)\n//\n// 3) Scan Products:\n// For each capability, scan `product` table by `product_id_prefix` (full scan) and expand product -> series:\n// - OHLC: product x duration_list\n// - InterestRate: product\n//\n// 4) Progress source of truth:\n// We do NOT depend on wrote_count/inserted_count to decide progress.\n// After each successful ingest, we merge `series_data_range` and recompute:\n// - segments[]: merged ranges (used for gap detection)\n// - union: { min(start), max(end) } (used for head/tail decisions; union does NOT mean continuous coverage)\n//\n// 5) Gap semantics:\n// - merge only on strict overlap: prev.end_time > next.start_time\n// - touch (prev.end_time == next.start_time): NOT merged, and NOT a gap\n// - gap only when prev.end_time < next.start_time\n// Tail will prioritize filling the nearest-now gap (by range boundaries).\n//\n// 6) Each request must overlap:\n// Because merge is strict-overlap only, a \"touching\" page would keep accumulating fragments.\n// Therefore we deliberately shift request `time` into the already-covered area by `overlapMs`:\n// - backward: time += overlapMs (clamp to <= now)\n// - forward: time -= overlapMs (clamp to >= 0)\n// Duplicate writes are OK (unique key / ON CONFLICT absorbs them).\n//\n// 7) Retry/backoff:\n// When request fails or returns no range, we apply backoff and reschedule,\n// otherwise the queue may be consumed to empty and appear \"stuck\".\n//\n// 8) Routing / load balancing:\n// Scheduler does not pin a request to a specific instance; it uses `terminal.client.requestForResponseData`\n// and relies on Terminal's schema-based service selection + load balancing.\n\ntype ISeriesType = 'ohlc' | 'interest_rate';\ntype IJobKind = 'head' | 'tail';\n\ntype IJob = {\n kind: IJobKind;\n seriesKey: string;\n};\n\ntype ISeriesState = {\n capKey: string;\n seriesKey: string;\n seriesType: ISeriesType;\n table_name: string;\n series_id: string;\n product_id: string;\n duration?: string;\n direction: SeriesFetchDirection;\n ranges: { startMs: number; endMs: number }[];\n union_start_ms?: number;\n union_end_ms?: number;\n last_window_ms?: number;\n};\n\ntype ICapability = {\n capKey: string;\n method: 'IngestOHLC' | 'IngestInterestRate';\n seriesType: ISeriesType;\n product_id_prefix: string;\n direction: SeriesFetchDirection;\n duration_list?: string[];\n nextScanAt: number;\n};\n\ntype ICapabilityState = {\n capKey: string;\n headQueue: ReturnType<typeof createFifoQueue<IJob>>;\n tailQueue: ReturnType<typeof createFifoQueue<IJob>>;\n pendingHead: Set<string>;\n pendingTail: Set<string>;\n inflight: boolean;\n nextEligibleAt: number;\n backoffMs: number;\n};\n\nconst capabilities: ICapability[] = [];\nconst mapCapKeyToCapability = new Map<string, ICapability>();\nconst mapCapKeyToState = new Map<string, ICapabilityState>();\n\nconst mapSeriesKeyToState = new Map<string, ISeriesState>();\n\nlet inflight = 0;\nlet scanIndex = 0;\nlet capRunIndex = 0;\nconst LOG_QUEUE_INTERVAL_MS = Number(process.env.VEX_SERIES_DATA_LOG_QUEUE_INTERVAL_MS ?? '10000');\n\nconst getOrCreateCapState = (capKey: string): ICapabilityState => {\n const existing = mapCapKeyToState.get(capKey);\n if (existing) return existing;\n const next: ICapabilityState = {\n capKey,\n headQueue: createFifoQueue<IJob>(),\n tailQueue: createFifoQueue<IJob>(),\n pendingHead: new Set<string>(),\n pendingTail: new Set<string>(),\n inflight: false,\n nextEligibleAt: 0,\n backoffMs: 0,\n };\n mapCapKeyToState.set(capKey, next);\n return next;\n};\n\nconst computeSeriesId = (seriesType: ISeriesType, product_id: string, duration?: string): string => {\n if (seriesType === 'ohlc') return encodeOHLCSeriesId(product_id, duration ?? '');\n return encodeInterestRateSeriesId(product_id);\n};\n\nconst getOrCreateSeriesState = (params: {\n capKey: string;\n seriesType: ISeriesType;\n product_id: string;\n duration?: string;\n direction: SeriesFetchDirection;\n}): ISeriesState => {\n const { capKey, seriesType, product_id, duration, direction } = params;\n const table_name = seriesType === 'ohlc' ? 'ohlc_v2' : 'interest_rate';\n const series_id = computeSeriesId(seriesType, product_id, duration);\n const seriesKey = encodePath(table_name, direction, product_id, duration ?? '');\n\n const existing = mapSeriesKeyToState.get(seriesKey);\n if (existing) {\n existing.capKey = capKey;\n return existing;\n }\n\n const next: ISeriesState = {\n capKey,\n seriesKey,\n seriesType,\n table_name,\n series_id,\n product_id,\n duration,\n direction,\n ranges: [],\n };\n mapSeriesKeyToState.set(seriesKey, next);\n return next;\n};\n\nconst computeHeadLagMs = (series: ISeriesState): number => {\n if (series.seriesType === 'interest_rate') return CONFIG.defaultInterestRateHeadLagMs;\n const offset = convertDurationToOffset(series.duration ?? '');\n if (!isFinite(offset) || offset <= 0) return 60_000;\n return Math.max(60_000, offset);\n};\n\nconst computeOverlapMs = (series: ISeriesState): number => {\n const maxOverlapMs = 60 * 60_000;\n let overlapMs = 60_000;\n if (series.seriesType === 'ohlc') {\n const offset = convertDurationToOffset(series.duration ?? '');\n if (isFinite(offset) && offset > 0) overlapMs = offset;\n } else {\n overlapMs = 60 * 60_000;\n }\n if (series.last_window_ms && isFinite(series.last_window_ms) && series.last_window_ms > 0) {\n overlapMs = Math.min(overlapMs, Math.max(1, series.last_window_ms - 1));\n }\n return Math.max(1, Math.min(maxOverlapMs, overlapMs));\n};\n\nconst applyOverlapToRequestTime = (series: ISeriesState, baseTime: number): number => {\n const hasAnyRange =\n series.union_start_ms !== undefined || series.union_end_ms !== undefined || series.ranges.length > 0;\n if (!hasAnyRange) return baseTime;\n const overlapMs = computeOverlapMs(series);\n if (series.direction === 'backward') return Math.min(baseTime + overlapMs, Date.now());\n return Math.max(0, baseTime - overlapMs);\n};\n\nconst computeBackoffMs = (current: number): number => {\n const next =\n current <= 0 ? CONFIG.backoffStepMs : Math.min(CONFIG.maxBackoffMs, current + CONFIG.backoffStepMs);\n return next;\n};\n\nconst enqueueCapJob = (capKey: string, kind: IJobKind, seriesKey: string) => {\n const capState = getOrCreateCapState(capKey);\n const pendingSet = kind === 'head' ? capState.pendingHead : capState.pendingTail;\n const queue = kind === 'head' ? capState.headQueue : capState.tailQueue;\n if (pendingSet.has(seriesKey)) return;\n pendingSet.add(seriesKey);\n queue.enqueue({ kind, seriesKey });\n};\n\nconst scheduleSeries = (series: ISeriesState) => {\n const now = Date.now();\n\n const headLagMs = computeHeadLagMs(series);\n const needHead = series.union_end_ms === undefined || now - series.union_end_ms > headLagMs;\n if (needHead) {\n enqueueCapJob(series.capKey, 'head', series.seriesKey);\n return;\n }\n\n if (series.union_start_ms === undefined) return;\n enqueueCapJob(series.capKey, 'tail', series.seriesKey);\n};\n\nconst mergeRangesAndGetUnion = async (\n series_id: string,\n table_name: string,\n): Promise<{\n segments: { startMs: number; endMs: number }[];\n union?: { startMs: number; endMs: number };\n}> => {\n const rows = await requestSQL<{ start_time: string; end_time: string }[]>(\n terminal,\n `\n WITH locked AS (\n SELECT series_id, table_name, start_time, end_time\n FROM series_data_range\n WHERE series_id = ${escapeSQL(series_id)} AND table_name = ${escapeSQL(table_name)}\n ORDER BY start_time ASC, end_time ASC\n FOR UPDATE\n ),\n ordered AS (\n SELECT\n start_time,\n end_time,\n max(end_time) OVER (\n ORDER BY start_time ASC, end_time ASC\n ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW\n ) AS running_end\n FROM locked\n ),\n marks AS (\n SELECT\n start_time,\n end_time,\n running_end,\n CASE\n WHEN start_time >= COALESCE(\n lag(running_end) OVER (ORDER BY start_time ASC, end_time ASC),\n '-infinity'::timestamptz\n ) THEN 1\n ELSE 0\n END AS is_new_group\n FROM ordered\n ),\n groups AS (\n SELECT\n start_time,\n end_time,\n sum(is_new_group) OVER (\n ORDER BY start_time ASC, end_time ASC\n ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW\n ) AS grp\n FROM marks\n ),\n merged AS (\n SELECT min(start_time) AS start_time, max(end_time) AS end_time\n FROM groups\n GROUP BY grp\n ),\n to_delete AS (\n SELECT l.series_id, l.table_name, l.start_time, l.end_time\n FROM locked l\n WHERE NOT EXISTS (\n SELECT 1\n FROM merged m\n WHERE m.start_time = l.start_time AND m.end_time = l.end_time\n )\n ),\n deleted AS (\n DELETE FROM series_data_range t\n USING to_delete d\n WHERE\n t.series_id = d.series_id\n AND t.table_name = d.table_name\n AND t.start_time = d.start_time\n AND t.end_time = d.end_time\n RETURNING 1\n ),\n to_insert AS (\n SELECT m.start_time, m.end_time\n FROM merged m\n WHERE NOT EXISTS (\n SELECT 1\n FROM locked l\n WHERE l.start_time = m.start_time AND l.end_time = m.end_time\n )\n ),\n inserted AS (\n INSERT INTO series_data_range (series_id, table_name, start_time, end_time)\n SELECT ${escapeSQL(series_id)}, ${escapeSQL(table_name)}, start_time, end_time\n FROM to_insert\n ON CONFLICT DO NOTHING\n RETURNING 1\n )\n SELECT start_time, end_time\n FROM series_data_range\n WHERE series_id = ${escapeSQL(series_id)} AND table_name = ${escapeSQL(table_name)}\n ORDER BY start_time ASC, end_time ASC;\n `,\n );\n\n if (rows.length === 0) return { segments: [] };\n const segments: { startMs: number; endMs: number }[] = [];\n let startMs = Number.POSITIVE_INFINITY;\n let endMs = Number.NEGATIVE_INFINITY;\n for (const r of rows) {\n const s = Date.parse(r.start_time);\n const e = Date.parse(r.end_time);\n if (!isNaN(s) && !isNaN(e) && e >= s) {\n segments.push({ startMs: s, endMs: e });\n startMs = Math.min(startMs, s);\n endMs = Math.max(endMs, e);\n }\n }\n if (!isFinite(startMs) || !isFinite(endMs)) return { segments };\n return { segments, union: { startMs, endMs } };\n};\n\nconst findNearestGap = (\n segments: { startMs: number; endMs: number }[],\n): { left: { startMs: number; endMs: number }; right: { startMs: number; endMs: number } } | undefined => {\n for (let i = segments.length - 2; i >= 0; i--) {\n const left = segments[i];\n const right = segments[i + 1];\n if (left.endMs < right.startMs) return { left, right };\n }\n};\n\nconst computeTailTime = (series: ISeriesState, now: number): number => {\n const gap = findNearestGap(series.ranges);\n if (gap) {\n return series.direction === 'backward' ? gap.right.startMs : gap.left.endMs;\n }\n\n const first = series.ranges[0];\n const mostRecent = series.ranges[series.ranges.length - 1];\n if (series.direction === 'backward') {\n return series.union_start_ms ?? first?.startMs ?? mostRecent?.startMs ?? now;\n }\n\n const windowMs = series.last_window_ms ?? CONFIG.defaultForwardSeedWindowMs;\n const start = series.union_start_ms ?? Math.max(0, now - windowMs);\n return Math.max(0, start - windowMs);\n};\n\nconst computeRequestTime = (series: ISeriesState, kind: IJobKind): number => {\n const now = Date.now();\n if (series.direction === 'backward') {\n if (kind === 'head') return applyOverlapToRequestTime(series, now);\n return applyOverlapToRequestTime(series, computeTailTime(series, now));\n }\n\n const windowMs = series.last_window_ms ?? CONFIG.defaultForwardSeedWindowMs;\n if (kind === 'head') {\n if (series.union_end_ms !== undefined) return applyOverlapToRequestTime(series, series.union_end_ms);\n return applyOverlapToRequestTime(series, Math.max(0, now - windowMs));\n }\n return applyOverlapToRequestTime(series, computeTailTime(series, now));\n};\n\nconst requestIngest = async (series: ISeriesState, time: number): Promise<ISeriesIngestResult> => {\n if (series.seriesType === 'ohlc') {\n const req: IIngestOHLCRequest = {\n product_id: series.product_id,\n duration: series.duration ?? '',\n direction: series.direction,\n time,\n };\n return terminal.client.requestForResponseData<IIngestOHLCRequest, ISeriesIngestResult>('IngestOHLC', req);\n }\n\n const req: IIngestInterestRateRequest = {\n product_id: series.product_id,\n direction: series.direction,\n time,\n };\n return terminal.client.requestForResponseData<IIngestInterestRateRequest, ISeriesIngestResult>(\n 'IngestInterestRate',\n req,\n );\n};\n\nconst executeJob = async (capState: ICapabilityState, job: IJob) => {\n const series = mapSeriesKeyToState.get(job.seriesKey);\n if (!series) return;\n\n if (job.kind === 'head') capState.pendingHead.delete(job.seriesKey);\n else capState.pendingTail.delete(job.seriesKey);\n\n try {\n // make sure each request overlaps existing ranges\n const time = computeRequestTime(series, job.kind);\n const result = await requestIngest(series, time);\n\n capState.backoffMs = 0;\n capState.nextEligibleAt = 0;\n\n if (!result.range) {\n capState.backoffMs = computeBackoffMs(capState.backoffMs);\n capState.nextEligibleAt = Date.now() + capState.backoffMs;\n scheduleSeries(series);\n return;\n }\n\n const startMs = Date.parse(result.range.start_time);\n const endMs = Date.parse(result.range.end_time);\n if (!isNaN(startMs) && !isNaN(endMs) && endMs > startMs) {\n series.last_window_ms = endMs - startMs;\n }\n\n const merged = await mergeRangesAndGetUnion(series.series_id, series.table_name);\n series.ranges = merged.segments;\n if (merged.union) {\n series.union_start_ms = merged.union.startMs;\n series.union_end_ms = merged.union.endMs;\n }\n\n scheduleSeries(series);\n } catch (e) {\n capState.backoffMs = computeBackoffMs(capState.backoffMs);\n capState.nextEligibleAt = Date.now() + capState.backoffMs;\n console.warn(\n formatTime(Date.now()),\n '[VEX][SeriesData]CapFailed',\n `cap=${capState.capKey}`,\n `backoff_ms=${capState.backoffMs}`,\n `${e}`,\n );\n scheduleSeries(series);\n }\n};\n\nconst computeGlobalHeadBacklog = (): number => {\n let total = 0;\n for (const s of mapCapKeyToState.values()) {\n total += s.headQueue.size();\n }\n return total;\n};\n\nconst pickNextRunnableCap = (now: number): ICapabilityState | undefined => {\n if (capabilities.length === 0) return;\n const n = capabilities.length;\n for (let i = 0; i < n; i++) {\n // Round-robin pick\n const cap = capabilities[capRunIndex++ % n];\n const capState = getOrCreateCapState(cap.capKey);\n if (capState.inflight) continue;\n if (capState.nextEligibleAt > now) continue;\n if (capState.headQueue.size() === 0 && capState.tailQueue.size() === 0) continue;\n return capState;\n }\n};\n\nconst dequeueFromCap = (\n capState: ICapabilityState,\n canRunTail: boolean,\n): { job: IJob; kind: IJobKind } | undefined => {\n const head = capState.headQueue.dequeue();\n if (head) return { job: head, kind: 'head' };\n if (!canRunTail) return;\n const tail = capState.tailQueue.dequeue();\n if (!tail) return;\n return { job: tail, kind: 'tail' };\n};\n\nconst scanProductsOnce = async () => {\n if (capabilities.length === 0) return;\n\n const now = Date.now();\n const cap = capabilities[scanIndex++ % capabilities.length];\n if (cap.nextScanAt > now) return;\n\n const where = [\n `product_id LIKE ${escapeSQL(`${cap.product_id_prefix}%`)}`,\n onlyProductIdPrefix ? `product_id LIKE ${escapeSQL(`${onlyProductIdPrefix}%`)}` : '',\n cap.seriesType === 'interest_rate' ? `COALESCE(no_interest_rate, false) = false` : '',\n ]\n .filter(Boolean)\n .join(' AND ');\n\n const rows = await requestSQL<{ product_id: string }[]>(\n terminal,\n `\n SELECT product_id\n FROM product\n WHERE ${where}\n ORDER BY product_id ASC\n `,\n );\n cap.nextScanAt = now + CONFIG.scanFullLoopIntervalMs;\n\n for (const row of rows) {\n if (cap.seriesType === 'ohlc') {\n for (const duration of cap.duration_list ?? []) {\n const series = getOrCreateSeriesState({\n capKey: cap.capKey,\n seriesType: 'ohlc',\n product_id: row.product_id,\n duration,\n direction: cap.direction,\n });\n scheduleSeries(series);\n }\n } else {\n const series = getOrCreateSeriesState({\n capKey: cap.capKey,\n seriesType: 'interest_rate',\n product_id: row.product_id,\n direction: cap.direction,\n });\n scheduleSeries(series);\n }\n }\n};\n\nconst tick = async () => {\n if (!isEnabled) return;\n\n try {\n await scanProductsOnce();\n } catch (e) {\n console.error(formatTime(Date.now()), '[VEX][SeriesData]ScanFailed', `${e}`);\n }\n\n const now = Date.now();\n while (inflight < CONFIG.maxInflight) {\n const capState = pickNextRunnableCap(now);\n if (!capState) return;\n\n const globalHeadBacklog = computeGlobalHeadBacklog();\n const canRunTail =\n globalHeadBacklog < CONFIG.tailOnlyWhenGlobalHeadBelow && capState.headQueue.size() === 0;\n const next = dequeueFromCap(capState, canRunTail);\n if (!next) return;\n\n capState.inflight = true;\n inflight++;\n executeJob(capState, next.job).finally(() => {\n capState.inflight = false;\n inflight--;\n });\n }\n};\n\nif (!isEnabled) {\n console.info(formatTime(Date.now()), '[VEX][SeriesData]Disabled', 'VEX_SERIES_DATA_ENABLED!=1');\n} else {\n terminal.server.provideService('VEX/SeriesData/Peek', {}, async () => {\n const now = Date.now();\n const caps = capabilities.map((cap) => {\n const s = getOrCreateCapState(cap.capKey);\n return {\n capKey: cap.capKey,\n method: cap.method,\n product_id_prefix: cap.product_id_prefix,\n direction: cap.direction,\n head_queue_size: s.headQueue.size(),\n tail_queue_size: s.tailQueue.size(),\n inflight: s.inflight,\n backoff_ms: s.backoffMs,\n nextEligibleAt: s.nextEligibleAt > now ? formatTime(s.nextEligibleAt) : undefined,\n };\n });\n return {\n res: {\n code: 0,\n message: 'OK',\n data: {\n enabled: true,\n only_product_id_prefix: onlyProductIdPrefix || undefined,\n inflight,\n cap_count: capabilities.length,\n global_head_backlog: computeGlobalHeadBacklog(),\n series_count: mapSeriesKeyToState.size,\n caps: caps.slice(0, 50),\n },\n },\n };\n });\n\n // Setup trace log\n timer(0, LOG_QUEUE_INTERVAL_MS).subscribe(() => {\n const now = Date.now();\n const caps = capabilities\n .map((cap) => {\n const s = getOrCreateCapState(cap.capKey);\n return {\n capKey: cap.capKey,\n head: s.headQueue.size(),\n tail: s.tailQueue.size(),\n inflight: s.inflight,\n backoffMs: s.backoffMs,\n nextEligibleAt: s.nextEligibleAt,\n };\n })\n .filter((x) => x.inflight || x.head > 0 || x.tail > 0 || x.nextEligibleAt > now)\n .slice(0, 20)\n .map(\n (x) =>\n `cap=${x.capKey} head=${x.head} tail=${x.tail} inflight=${x.inflight ? 1 : 0} backoff_ms=${\n x.backoffMs\n }${x.nextEligibleAt > now ? ` next=${formatTime(x.nextEligibleAt)}` : ''}`,\n );\n\n console.info(\n formatTime(now),\n '[VEX][SeriesData]Queues',\n `inflight=${inflight}`,\n `cap_count=${capabilities.length}`,\n `global_head_backlog=${computeGlobalHeadBacklog()}`,\n `series_count=${mapSeriesKeyToState.size}`,\n caps.length ? `caps=[${caps.join(' | ')}]` : 'caps=[]',\n );\n });\n\n terminal.terminalInfos$\n .pipe(\n mergeMap((terminalInfos) =>\n from(terminalInfos).pipe(\n mergeMap((terminalInfo) =>\n from(Object.values(terminalInfo.serviceInfo || {})).pipe(\n filter(\n (serviceInfo) =>\n serviceInfo.method === 'IngestOHLC' || serviceInfo.method === 'IngestInterestRate',\n ),\n map((serviceInfo): ICapability | undefined => {\n try {\n if (serviceInfo.method === 'IngestOHLC') {\n const meta = parseOHLCServiceMetadataFromSchema(serviceInfo.schema);\n const capKey = encodePath('IngestOHLC', meta.product_id_prefix, meta.direction);\n const existing = mapCapKeyToCapability.get(capKey);\n const duration_list = [...new Set(meta.duration_list)].sort();\n if (existing) {\n existing.duration_list = duration_list;\n return existing;\n }\n return {\n capKey,\n method: 'IngestOHLC',\n seriesType: 'ohlc',\n product_id_prefix: meta.product_id_prefix,\n direction: meta.direction,\n duration_list,\n nextScanAt: 0,\n };\n }\n\n const meta = parseInterestRateServiceMetadataFromSchema(serviceInfo.schema);\n const capKey = encodePath('IngestInterestRate', meta.product_id_prefix, meta.direction);\n const existing = mapCapKeyToCapability.get(capKey);\n if (existing) return existing;\n return {\n capKey,\n method: 'IngestInterestRate',\n seriesType: 'interest_rate',\n product_id_prefix: meta.product_id_prefix,\n direction: meta.direction,\n nextScanAt: 0,\n };\n } catch {\n console.info(\n formatTime(Date.now()),\n '[VEX][SeriesData]ParseServiceMetadataFailed',\n `method=${serviceInfo.method}`,\n `terminal_id=${terminalInfo.terminal_id}`,\n );\n return;\n }\n }),\n filter((x): x is Exclude<typeof x, undefined> => !!x),\n ),\n ),\n toArray(),\n tap((nextCaps) => {\n const nextMap = new Map<string, ICapability>();\n for (const cap of nextCaps) {\n nextMap.set(cap.capKey, cap);\n }\n mapCapKeyToCapability.clear();\n nextMap.forEach((v, k) => mapCapKeyToCapability.set(k, v));\n capabilities.length = 0;\n nextMap.forEach((v) => capabilities.push(v));\n }),\n ),\n ),\n )\n .subscribe();\n\n defer(() => from(tick()))\n .pipe(\n catchError((e) => {\n console.error(formatTime(Date.now()), '[VEX][SeriesData]TickError', `${e}`);\n return EMPTY;\n }),\n repeat({ delay: CONFIG.tickIntervalMs }),\n )\n .subscribe();\n}\n"]}
|
|
1
|
+
{"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../../src/series-data/scheduler.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAIL,0CAA0C,EAC1C,kCAAkC,GAEnC,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,uBAAuB,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChF,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC1G,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;AAExC,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,uBAAuB,KAAK,GAAG,CAAC;AAC9D,MAAM,mBAAmB,GAAG,CAAC,MAAA,OAAO,CAAC,GAAG,CAAC,sCAAsC,mCAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;AAE9F,MAAM,MAAM,GAAG;IACb,cAAc,EAAE,IAAK;IACrB,sBAAsB,EAAE,CAAC,GAAG,KAAM;IAClC;;OAEG;IACH,WAAW,EAAE,EAAE;IACf;;OAEG;IACH,2BAA2B,EAAE,EAAE;IAC/B,4BAA4B,EAAE,CAAC,GAAG,EAAE,GAAG,KAAM;IAC7C,0BAA0B,EAAE,EAAE,GAAG,EAAE,GAAG,KAAM;IAC5C,YAAY,EAAE,CAAC,GAAG,KAAM;IACxB,aAAa,EAAE,IAAK;CACZ,CAAC;AA6FX,MAAM,YAAY,GAAkB,EAAE,CAAC;AACvC,MAAM,qBAAqB,GAAG,IAAI,GAAG,EAAuB,CAAC;AAC7D,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAA4B,CAAC;AAE7D,MAAM,mBAAmB,GAAG,IAAI,GAAG,EAAwB,CAAC;AAE5D,IAAI,QAAQ,GAAG,CAAC,CAAC;AACjB,IAAI,SAAS,GAAG,CAAC,CAAC;AAClB,IAAI,WAAW,GAAG,CAAC,CAAC;AACpB,MAAM,qBAAqB,GAAG,MAAM,CAAC,MAAA,OAAO,CAAC,GAAG,CAAC,qCAAqC,mCAAI,OAAO,CAAC,CAAC;AAEnG,MAAM,mBAAmB,GAAG,CAAC,MAAc,EAAoB,EAAE;IAC/D,MAAM,QAAQ,GAAG,gBAAgB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC9C,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC9B,MAAM,IAAI,GAAqB;QAC7B,MAAM;QACN,SAAS,EAAE,eAAe,EAAQ;QAClC,SAAS,EAAE,eAAe,EAAQ;QAClC,WAAW,EAAE,IAAI,GAAG,EAAU;QAC9B,WAAW,EAAE,IAAI,GAAG,EAAU;QAC9B,QAAQ,EAAE,KAAK;QACf,cAAc,EAAE,CAAC;QACjB,SAAS,EAAE,CAAC;KACb,CAAC;IACF,gBAAgB,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACnC,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAEF,MAAM,eAAe,GAAG,CAAC,UAAuB,EAAE,UAAkB,EAAE,QAAiB,EAAU,EAAE;IACjG,IAAI,UAAU,KAAK,MAAM;QAAE,OAAO,kBAAkB,CAAC,UAAU,EAAE,QAAQ,aAAR,QAAQ,cAAR,QAAQ,GAAI,EAAE,CAAC,CAAC;IACjF,OAAO,0BAA0B,CAAC,UAAU,CAAC,CAAC;AAChD,CAAC,CAAC;AAEF,MAAM,sBAAsB,GAAG,CAAC,MAM/B,EAAgB,EAAE;IACjB,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC;IACvE,MAAM,UAAU,GAAG,UAAU,KAAK,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC;IACvE,MAAM,SAAS,GAAG,eAAe,CAAC,UAAU,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;IACpE,MAAM,SAAS,GAAG,UAAU,CAAC,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,aAAR,QAAQ,cAAR,QAAQ,GAAI,EAAE,CAAC,CAAC;IAEhF,MAAM,QAAQ,GAAG,mBAAmB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACpD,IAAI,QAAQ,EAAE,CAAC;QACb,QAAQ,CAAC,MAAM,GAAG,MAAM,CAAC;QACzB,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,MAAM,IAAI,GAAiB;QACzB,MAAM;QACN,SAAS;QACT,UAAU;QACV,UAAU;QACV,SAAS;QACT,UAAU;QACV,QAAQ;QACR,SAAS;QACT,MAAM,EAAE,EAAE;KACX,CAAC;IACF,mBAAmB,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IACzC,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAEF,MAAM,gBAAgB,GAAG,CAAC,MAAoB,EAAU,EAAE;;IACxD,IAAI,MAAM,CAAC,UAAU,KAAK,eAAe;QAAE,OAAO,MAAM,CAAC,4BAA4B,CAAC;IACtF,MAAM,MAAM,GAAG,uBAAuB,CAAC,MAAA,MAAM,CAAC,QAAQ,mCAAI,EAAE,CAAC,CAAC;IAC9D,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,IAAI,CAAC;QAAE,OAAO,KAAM,CAAC;IACpD,OAAO,IAAI,CAAC,GAAG,CAAC,KAAM,EAAE,MAAM,CAAC,CAAC;AAClC,CAAC,CAAC;AAEF,MAAM,gBAAgB,GAAG,CAAC,MAAoB,EAAU,EAAE;;IACxD,MAAM,YAAY,GAAG,EAAE,GAAG,KAAM,CAAC;IACjC,IAAI,SAAS,GAAG,KAAM,CAAC;IACvB,IAAI,MAAM,CAAC,UAAU,KAAK,MAAM,EAAE,CAAC;QACjC,MAAM,MAAM,GAAG,uBAAuB,CAAC,MAAA,MAAM,CAAC,QAAQ,mCAAI,EAAE,CAAC,CAAC;QAC9D,IAAI,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC;YAAE,SAAS,GAAG,MAAM,CAAC;IACzD,CAAC;SAAM,CAAC;QACN,SAAS,GAAG,EAAE,GAAG,KAAM,CAAC;IAC1B,CAAC;IACD,IAAI,MAAM,CAAC,cAAc,IAAI,QAAQ,CAAC,MAAM,CAAC,cAAc,CAAC,IAAI,MAAM,CAAC,cAAc,GAAG,CAAC,EAAE,CAAC;QAC1F,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,cAAc,GAAG,CAAC,CAAC,CAAC,CAAC;IAC1E,CAAC;IACD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC,CAAC;AACxD,CAAC,CAAC;AAEF,MAAM,yBAAyB,GAAG,CAAC,MAAoB,EAAE,QAAgB,EAAU,EAAE;IACnF,MAAM,WAAW,GACf,MAAM,CAAC,cAAc,KAAK,SAAS,IAAI,MAAM,CAAC,YAAY,KAAK,SAAS,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;IACvG,IAAI,CAAC,WAAW;QAAE,OAAO,QAAQ,CAAC;IAClC,MAAM,SAAS,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAC3C,IAAI,MAAM,CAAC,SAAS,KAAK,UAAU;QAAE,OAAO,IAAI,CAAC,GAAG,CAAC,QAAQ,GAAG,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IACvF,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC,CAAC;AAC3C,CAAC,CAAC;AAEF,MAAM,gBAAgB,GAAG,CAAC,OAAe,EAAU,EAAE;IACnD,MAAM,IAAI,GACR,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,YAAY,EAAE,OAAO,GAAG,MAAM,CAAC,aAAa,CAAC,CAAC;IACtG,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAEF,MAAM,aAAa,GAAG,CAAC,MAAc,EAAE,IAAc,EAAE,SAAiB,EAAE,EAAE;IAC1E,MAAM,QAAQ,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAC7C,MAAM,UAAU,GAAG,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC;IACjF,MAAM,KAAK,GAAG,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC;IACxE,IAAI,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC;QAAE,OAAO;IACtC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAC1B,KAAK,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;AACrC,CAAC,CAAC;AAEF,MAAM,cAAc,GAAG,CAAC,MAAoB,EAAE,EAAE;IAC9C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAEvB,MAAM,SAAS,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAC3C,MAAM,QAAQ,GAAG,MAAM,CAAC,YAAY,KAAK,SAAS,IAAI,GAAG,GAAG,MAAM,CAAC,YAAY,GAAG,SAAS,CAAC;IAC5F,IAAI,QAAQ,EAAE,CAAC;QACb,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;QACvD,OAAO;IACT,CAAC;IAED,IAAI,MAAM,CAAC,cAAc,KAAK,SAAS;QAAE,OAAO;IAChD,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;AACzD,CAAC,CAAC;AAEF,MAAM,sBAAsB,GAAG,KAAK,EAClC,SAAiB,EACjB,UAAkB,EAIjB,EAAE;IACH,MAAM,IAAI,GAAG,MAAM,UAAU,CAC3B,QAAQ,EACR;;;;0BAIsB,SAAS,CAAC,SAAS,CAAC,qBAAqB,SAAS,CAAC,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eAyEzE,SAAS,CAAC,SAAS,CAAC,KAAK,SAAS,CAAC,UAAU,CAAC;;;;;;;wBAOrC,SAAS,CAAC,SAAS,CAAC,qBAAqB,SAAS,CAAC,UAAU,CAAC;;KAEjF,CACF,CAAC;IAEF,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IAC/C,MAAM,QAAQ,GAAyC,EAAE,CAAC;IAC1D,IAAI,OAAO,GAAG,MAAM,CAAC,iBAAiB,CAAC;IACvC,IAAI,KAAK,GAAG,MAAM,CAAC,iBAAiB,CAAC;IACrC,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;QACnC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QACjC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACrC,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;YACxC,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YAC/B,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;IAChE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,CAAC;AACjD,CAAC,CAAC;AAEF,MAAM,cAAc,GAAG,CACrB,QAA8C,EACuD,EAAE;IACvG,KAAK,IAAI,CAAC,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9C,MAAM,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;QACzB,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAC9B,IAAI,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,OAAO;YAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IACzD,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,eAAe,GAAG,CAAC,MAAoB,EAAE,GAAW,EAAU,EAAE;;IACpE,MAAM,GAAG,GAAG,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC1C,IAAI,GAAG,EAAE,CAAC;QACR,OAAO,MAAM,CAAC,SAAS,KAAK,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC;IAC9E,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAC/B,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC3D,IAAI,MAAM,CAAC,SAAS,KAAK,UAAU,EAAE,CAAC;QACpC,OAAO,MAAA,MAAA,MAAA,MAAM,CAAC,cAAc,mCAAI,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,OAAO,mCAAI,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,OAAO,mCAAI,GAAG,CAAC;IAC/E,CAAC;IAED,MAAM,QAAQ,GAAG,MAAA,MAAM,CAAC,cAAc,mCAAI,MAAM,CAAC,0BAA0B,CAAC;IAC5E,MAAM,KAAK,GAAG,MAAA,MAAM,CAAC,cAAc,mCAAI,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,GAAG,QAAQ,CAAC,CAAC;IACnE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAC,CAAC;AACvC,CAAC,CAAC;AAEF,MAAM,kBAAkB,GAAG,CAAC,MAAoB,EAAE,IAAc,EAAU,EAAE;;IAC1E,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,IAAI,MAAM,CAAC,SAAS,KAAK,UAAU,EAAE,CAAC;QACpC,IAAI,IAAI,KAAK,MAAM;YAAE,OAAO,yBAAyB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACnE,OAAO,yBAAyB,CAAC,MAAM,EAAE,eAAe,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;IACzE,CAAC;IAED,MAAM,QAAQ,GAAG,MAAA,MAAM,CAAC,cAAc,mCAAI,MAAM,CAAC,0BAA0B,CAAC;IAC5E,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;QACpB,IAAI,MAAM,CAAC,YAAY,KAAK,SAAS;YAAE,OAAO,yBAAyB,CAAC,MAAM,EAAE,MAAM,CAAC,YAAY,CAAC,CAAC;QACrG,OAAO,yBAAyB,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC;IACxE,CAAC;IACD,OAAO,yBAAyB,CAAC,MAAM,EAAE,eAAe,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;AACzE,CAAC,CAAC;AAEF,MAAM,aAAa,GAAG,KAAK,EAAE,MAAoB,EAAE,IAAY,EAAgC,EAAE;;IAC/F,IAAI,MAAM,CAAC,UAAU,KAAK,MAAM,EAAE,CAAC;QACjC,MAAM,GAAG,GAAuB;YAC9B,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,QAAQ,EAAE,MAAA,MAAM,CAAC,QAAQ,mCAAI,EAAE;YAC/B,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,IAAI;SACL,CAAC;QACF,OAAO,QAAQ,CAAC,MAAM,CAAC,sBAAsB,CAA0C,YAAY,EAAE,GAAG,CAAC,CAAC;IAC5G,CAAC;IAED,MAAM,GAAG,GAA+B;QACtC,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,IAAI;KACL,CAAC;IACF,OAAO,QAAQ,CAAC,MAAM,CAAC,sBAAsB,CAC3C,oBAAoB,EACpB,GAAG,CACJ,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,UAAU,GAAG,KAAK,EAAE,QAA0B,EAAE,GAAS,EAAE,EAAE;IACjE,MAAM,MAAM,GAAG,mBAAmB,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACtD,IAAI,CAAC,MAAM;QAAE,OAAO;IAEpB,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM;QAAE,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;;QAC/D,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAEhD,IAAI,CAAC;QACH,kDAAkD;QAClD,MAAM,IAAI,GAAG,kBAAkB,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;QAClD,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAEjD,QAAQ,CAAC,SAAS,GAAG,CAAC,CAAC;QACvB,QAAQ,CAAC,cAAc,GAAG,CAAC,CAAC;QAE5B,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YAClB,QAAQ,CAAC,SAAS,GAAG,gBAAgB,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;YAC1D,QAAQ,CAAC,cAAc,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,CAAC,SAAS,CAAC;YAC1D,cAAc,CAAC,MAAM,CAAC,CAAC;YACvB,OAAO;QACT,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QACpD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAChD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,OAAO,EAAE,CAAC;YACxD,MAAM,CAAC,cAAc,GAAG,KAAK,GAAG,OAAO,CAAC;QAC1C,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,sBAAsB,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;QACjF,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC;QAChC,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YACjB,MAAM,CAAC,cAAc,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC;YAC7C,MAAM,CAAC,YAAY,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC;QAC3C,CAAC;QAED,cAAc,CAAC,MAAM,CAAC,CAAC;IACzB,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,QAAQ,CAAC,SAAS,GAAG,gBAAgB,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;QAC1D,QAAQ,CAAC,cAAc,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,CAAC,SAAS,CAAC;QAC1D,OAAO,CAAC,IAAI,CACV,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,4BAA4B,EAC5B,OAAO,QAAQ,CAAC,MAAM,EAAE,EACxB,cAAc,QAAQ,CAAC,SAAS,EAAE,EAClC,GAAG,CAAC,EAAE,CACP,CAAC;QACF,cAAc,CAAC,MAAM,CAAC,CAAC;IACzB,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,wBAAwB,GAAG,GAAW,EAAE;IAC5C,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,CAAC,IAAI,gBAAgB,CAAC,MAAM,EAAE,EAAE,CAAC;QAC1C,KAAK,IAAI,CAAC,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;IAC9B,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAEF,MAAM,mBAAmB,GAAG,CAAC,GAAW,EAAgC,EAAE;IACxE,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IACtC,MAAM,CAAC,GAAG,YAAY,CAAC,MAAM,CAAC;IAC9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,mBAAmB;QACnB,MAAM,GAAG,GAAG,YAAY,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,CAAC;QAC5C,MAAM,QAAQ,GAAG,mBAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACjD,IAAI,QAAQ,CAAC,QAAQ;YAAE,SAAS;QAChC,IAAI,QAAQ,CAAC,cAAc,GAAG,GAAG;YAAE,SAAS;QAC5C,IAAI,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC;YAAE,SAAS;QACjF,OAAO,QAAQ,CAAC;IAClB,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,cAAc,GAAG,CACrB,QAA0B,EAC1B,UAAmB,EACwB,EAAE;IAC7C,MAAM,IAAI,GAAG,QAAQ,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;IAC1C,IAAI,IAAI;QAAE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAC7C,IAAI,CAAC,UAAU;QAAE,OAAO;IACxB,MAAM,IAAI,GAAG,QAAQ,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;IAC1C,IAAI,CAAC,IAAI;QAAE,OAAO;IAClB,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AACrC,CAAC,CAAC;AAEF,MAAM,gBAAgB,GAAG,KAAK,IAAI,EAAE;;IAClC,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAEtC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,GAAG,GAAG,YAAY,CAAC,SAAS,EAAE,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IAC5D,IAAI,GAAG,CAAC,UAAU,GAAG,GAAG;QAAE,OAAO;IAEjC,MAAM,KAAK,GAAG;QACZ,mBAAmB,SAAS,CAAC,GAAG,GAAG,CAAC,iBAAiB,GAAG,CAAC,EAAE;QAC3D,mBAAmB,CAAC,CAAC,CAAC,mBAAmB,SAAS,CAAC,GAAG,mBAAmB,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE;QACpF,GAAG,CAAC,UAAU,KAAK,eAAe,CAAC,CAAC,CAAC,2CAA2C,CAAC,CAAC,CAAC,EAAE;KACtF;SACE,MAAM,CAAC,OAAO,CAAC;SACf,IAAI,CAAC,OAAO,CAAC,CAAC;IAEjB,MAAM,IAAI,GAAG,MAAM,UAAU,CAC3B,QAAQ,EACR;;;YAGQ,KAAK;;KAEZ,CACF,CAAC;IACF,GAAG,CAAC,UAAU,GAAG,GAAG,GAAG,MAAM,CAAC,sBAAsB,CAAC;IAErD,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,GAAG,CAAC,UAAU,KAAK,MAAM,EAAE,CAAC;YAC9B,KAAK,MAAM,QAAQ,IAAI,MAAA,GAAG,CAAC,aAAa,mCAAI,EAAE,EAAE,CAAC;gBAC/C,MAAM,MAAM,GAAG,sBAAsB,CAAC;oBACpC,MAAM,EAAE,GAAG,CAAC,MAAM;oBAClB,UAAU,EAAE,MAAM;oBAClB,UAAU,EAAE,GAAG,CAAC,UAAU;oBAC1B,QAAQ;oBACR,SAAS,EAAE,GAAG,CAAC,SAAS;iBACzB,CAAC,CAAC;gBACH,cAAc,CAAC,MAAM,CAAC,CAAC;YACzB,CAAC;QACH,CAAC;aAAM,CAAC;YACN,MAAM,MAAM,GAAG,sBAAsB,CAAC;gBACpC,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,UAAU,EAAE,eAAe;gBAC3B,UAAU,EAAE,GAAG,CAAC,UAAU;gBAC1B,SAAS,EAAE,GAAG,CAAC,SAAS;aACzB,CAAC,CAAC;YACH,cAAc,CAAC,MAAM,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,IAAI,GAAG,KAAK,IAAI,EAAE;IACtB,IAAI,CAAC,SAAS;QAAE,OAAO;IAEvB,IAAI,CAAC;QACH,MAAM,gBAAgB,EAAE,CAAC;IAC3B,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,6BAA6B,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;IAC/E,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,OAAO,QAAQ,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;QACrC,MAAM,QAAQ,GAAG,mBAAmB,CAAC,GAAG,CAAC,CAAC;QAC1C,IAAI,CAAC,QAAQ;YAAE,OAAO;QAEtB,MAAM,iBAAiB,GAAG,wBAAwB,EAAE,CAAC;QACrD,MAAM,UAAU,GACd,iBAAiB,GAAG,MAAM,CAAC,2BAA2B,IAAI,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC5F,MAAM,IAAI,GAAG,cAAc,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;QAClD,IAAI,CAAC,IAAI;YAAE,OAAO;QAElB,QAAQ,CAAC,QAAQ,GAAG,IAAI,CAAC;QACzB,QAAQ,EAAE,CAAC;QACX,UAAU,CAAC,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE;YAC1C,QAAQ,CAAC,QAAQ,GAAG,KAAK,CAAC;YAC1B,QAAQ,EAAE,CAAC;QACb,CAAC,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC;AAEF,IAAI,CAAC,SAAS,EAAE,CAAC;IACf,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,2BAA2B,EAAE,4BAA4B,CAAC,CAAC;AAClG,CAAC;KAAM,CAAC;IACN,QAAQ,CAAC,MAAM,CAAC,cAAc,CAAC,qBAAqB,EAAE,EAAE,EAAE,KAAK,IAAI,EAAE;QACnE,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,IAAI,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;YACpC,MAAM,CAAC,GAAG,mBAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAC1C,OAAO;gBACL,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,iBAAiB,EAAE,GAAG,CAAC,iBAAiB;gBACxC,SAAS,EAAE,GAAG,CAAC,SAAS;gBACxB,eAAe,EAAE,CAAC,CAAC,SAAS,CAAC,IAAI,EAAE;gBACnC,eAAe,EAAE,CAAC,CAAC,SAAS,CAAC,IAAI,EAAE;gBACnC,QAAQ,EAAE,CAAC,CAAC,QAAQ;gBACpB,UAAU,EAAE,CAAC,CAAC,SAAS;gBACvB,cAAc,EAAE,CAAC,CAAC,cAAc,GAAG,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,SAAS;aAClF,CAAC;QACJ,CAAC,CAAC,CAAC;QACH,OAAO;YACL,GAAG,EAAE;gBACH,IAAI,EAAE,CAAC;gBACP,OAAO,EAAE,IAAI;gBACb,IAAI,EAAE;oBACJ,OAAO,EAAE,IAAI;oBACb,sBAAsB,EAAE,mBAAmB,IAAI,SAAS;oBACxD,QAAQ;oBACR,SAAS,EAAE,YAAY,CAAC,MAAM;oBAC9B,mBAAmB,EAAE,wBAAwB,EAAE;oBAC/C,YAAY,EAAE,mBAAmB,CAAC,IAAI;oBACtC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;iBACxB;aACF;SACF,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,kBAAkB;IAClB,KAAK,CAAC,CAAC,EAAE,qBAAqB,CAAC,CAAC,SAAS,CAAC,GAAG,EAAE;QAC7C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,IAAI,GAAG,YAAY;aACtB,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;YACX,MAAM,CAAC,GAAG,mBAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAC1C,OAAO;gBACL,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,IAAI,EAAE,CAAC,CAAC,SAAS,CAAC,IAAI,EAAE;gBACxB,IAAI,EAAE,CAAC,CAAC,SAAS,CAAC,IAAI,EAAE;gBACxB,QAAQ,EAAE,CAAC,CAAC,QAAQ;gBACpB,SAAS,EAAE,CAAC,CAAC,SAAS;gBACtB,cAAc,EAAE,CAAC,CAAC,cAAc;aACjC,CAAC;QACJ,CAAC,CAAC;aACD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,cAAc,GAAG,GAAG,CAAC;aAC/E,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;aACZ,GAAG,CACF,CAAC,CAAC,EAAE,EAAE,CACJ,OAAO,CAAC,CAAC,MAAM,SAAS,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,IAAI,aAAa,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,eAC1E,CAAC,CAAC,SACJ,GAAG,CAAC,CAAC,cAAc,GAAG,GAAG,CAAC,CAAC,CAAC,SAAS,UAAU,CAAC,CAAC,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAC7E,CAAC;QAEJ,OAAO,CAAC,IAAI,CACV,UAAU,CAAC,GAAG,CAAC,EACf,yBAAyB,EACzB,YAAY,QAAQ,EAAE,EACtB,aAAa,YAAY,CAAC,MAAM,EAAE,EAClC,uBAAuB,wBAAwB,EAAE,EAAE,EACnD,gBAAgB,mBAAmB,CAAC,IAAI,EAAE,EAC1C,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CACvD,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,cAAc;SACpB,IAAI,CACH,QAAQ,CAAC,CAAC,aAAa,EAAE,EAAE,CACzB,IAAI,CAAC,aAAa,CAAC,CAAC,IAAI,CACtB,QAAQ,CAAC,CAAC,YAAY,EAAE,EAAE,CACxB,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CACtD,MAAM,CACJ,CAAC,WAAW,EAAE,EAAE,CACd,WAAW,CAAC,MAAM,KAAK,YAAY,IAAI,WAAW,CAAC,MAAM,KAAK,oBAAoB,CACrF,EACD,GAAG,CAAC,CAAC,WAAW,EAA2B,EAAE;QAC3C,IAAI,CAAC;YACH,IAAI,WAAW,CAAC,MAAM,KAAK,YAAY,EAAE,CAAC;gBACxC,MAAM,IAAI,GAAG,kCAAkC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;gBACpE,MAAM,MAAM,GAAG,UAAU,CAAC,YAAY,EAAE,IAAI,CAAC,iBAAiB,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;gBAChF,MAAM,QAAQ,GAAG,qBAAqB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;gBACnD,MAAM,aAAa,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;gBAC9D,IAAI,QAAQ,EAAE,CAAC;oBACb,QAAQ,CAAC,aAAa,GAAG,aAAa,CAAC;oBACvC,OAAO,QAAQ,CAAC;gBAClB,CAAC;gBACD,OAAO;oBACL,MAAM;oBACN,MAAM,EAAE,YAAY;oBACpB,UAAU,EAAE,MAAM;oBAClB,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;oBACzC,SAAS,EAAE,IAAI,CAAC,SAAS;oBACzB,aAAa;oBACb,UAAU,EAAE,CAAC;iBACd,CAAC;YACJ,CAAC;YAED,MAAM,IAAI,GAAG,0CAA0C,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;YAC5E,MAAM,MAAM,GAAG,UAAU,CAAC,oBAAoB,EAAE,IAAI,CAAC,iBAAiB,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;YACxF,MAAM,QAAQ,GAAG,qBAAqB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACnD,IAAI,QAAQ;gBAAE,OAAO,QAAQ,CAAC;YAC9B,OAAO;gBACL,MAAM;gBACN,MAAM,EAAE,oBAAoB;gBAC5B,UAAU,EAAE,eAAe;gBAC3B,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;gBACzC,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,UAAU,EAAE,CAAC;aACd,CAAC;QACJ,CAAC;QAAC,WAAM,CAAC;YACP,OAAO,CAAC,IAAI,CACV,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,6CAA6C,EAC7C,UAAU,WAAW,CAAC,MAAM,EAAE,EAC9B,eAAe,YAAY,CAAC,WAAW,EAAE,CAC1C,CAAC;YACF,OAAO;QACT,CAAC;IACH,CAAC,CAAC,EACF,MAAM,CAAC,CAAC,CAAC,EAAqC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CACtD,CACF,EACD,OAAO,EAAE,EACT,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE;QACf,MAAM,OAAO,GAAG,IAAI,GAAG,EAAuB,CAAC;QAC/C,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC3B,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC/B,CAAC;QACD,qBAAqB,CAAC,KAAK,EAAE,CAAC;QAC9B,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC3D,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC;QACxB,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/C,CAAC,CAAC,CACH,CACF,CACF;SACA,SAAS,EAAE,CAAC;IAEf,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;SACtB,IAAI,CACH,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE;QACf,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,4BAA4B,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;QAC5E,OAAO,KAAK,CAAC;IACf,CAAC,CAAC,EACF,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,cAAc,EAAE,CAAC,CACzC;SACA,SAAS,EAAE,CAAC;AACjB,CAAC","sourcesContent":["import { encodeInterestRateSeriesId } from '@yuants/data-interest-rate';\nimport { encodeOHLCSeriesId } from '@yuants/data-ohlc';\nimport {\n IIngestInterestRateRequest,\n IIngestOHLCRequest,\n ISeriesIngestResult,\n parseInterestRateServiceMetadataFromSchema,\n parseOHLCServiceMetadataFromSchema,\n SeriesFetchDirection,\n} from '@yuants/exchange';\nimport { Terminal } from '@yuants/protocol';\nimport { escapeSQL, requestSQL } from '@yuants/sql';\nimport { convertDurationToOffset, encodePath, formatTime } from '@yuants/utils';\nimport { catchError, defer, EMPTY, filter, from, map, mergeMap, repeat, tap, timer, toArray } from 'rxjs';\nimport { createFifoQueue } from './fifo-queue';\n\nconst terminal = Terminal.fromNodeEnv();\n\nconst isEnabled = process.env.VEX_SERIES_DATA_ENABLED === '1';\nconst onlyProductIdPrefix = (process.env.VEX_SERIES_DATA_ONLY_PRODUCT_ID_PREFIX ?? '').trim();\n\nconst CONFIG = {\n tickIntervalMs: 1_000,\n scanFullLoopIntervalMs: 5 * 60_000,\n /**\n * Maximum number of inflight series data ingest requests.\n */\n maxInflight: 20,\n /**\n * Only run tail jobs when the global head backlog is below this threshold.\n */\n tailOnlyWhenGlobalHeadBelow: 20,\n defaultInterestRateHeadLagMs: 8 * 60 * 60_000,\n defaultForwardSeedWindowMs: 24 * 60 * 60_000,\n maxBackoffMs: 5 * 60_000,\n backoffStepMs: 5_000,\n} as const;\n\n// Per-capability bucket scheduler.\n//\n// Service Discovery -> Scan Products -> Schedule Series -> Tick -> Execute Job -> Merge Range -> Repeat\n//\n// 1) Service Discovery:\n// Subscribe `terminal.terminalInfos$`, find services with method `IngestOHLC` / `IngestInterestRate`,\n// parse schema -> capability metadata (product_id_prefix, direction, duration_list).\n//\n// 2) Capability buckets (capKey):\n// capKey = encodePath(method, product_id_prefix, direction)\n// - each cap has its own headQueue/tailQueue and runs serially (cap inflight=1)\n// - tick chooses a cap in round-robin; cap runs head first\n// - tail runs only when global head backlog is low (avoid hurting freshness)\n// - errors/backoff are isolated per-cap (a noisy cap won't block others)\n//\n// 3) Scan Products:\n// For each capability, scan `product` table by `product_id_prefix` (full scan) and expand product -> series:\n// - OHLC: product x duration_list\n// - InterestRate: product\n//\n// 4) Progress source of truth:\n// We do NOT depend on wrote_count/inserted_count to decide progress.\n// After each successful ingest, we merge `series_data_range` and recompute:\n// - segments[]: merged ranges (used for gap detection)\n// - union: { min(start), max(end) } (used for head/tail decisions; union does NOT mean continuous coverage)\n//\n// 5) Gap semantics:\n// - merge only on strict overlap: prev.end_time > next.start_time\n// - touch (prev.end_time == next.start_time): NOT merged, and NOT a gap\n// - gap only when prev.end_time < next.start_time\n// Tail will prioritize filling the nearest-now gap (by range boundaries).\n//\n// 6) Each request must overlap:\n// Because merge is strict-overlap only, a \"touching\" page would keep accumulating fragments.\n// Therefore we deliberately shift request `time` into the already-covered area by `overlapMs`:\n// - backward: time += overlapMs (clamp to <= now)\n// - forward: time -= overlapMs (clamp to >= 0)\n// Duplicate writes are OK (unique key / ON CONFLICT absorbs them).\n//\n// 7) Retry/backoff:\n// When request fails or returns no range, we apply backoff and reschedule,\n// otherwise the queue may be consumed to empty and appear \"stuck\".\n//\n// 8) Routing / load balancing:\n// Scheduler does not pin a request to a specific instance; it uses `terminal.client.requestForResponseData`\n// and relies on Terminal's schema-based service selection + load balancing.\n\ntype ISeriesType = 'ohlc' | 'interest_rate';\ntype IJobKind = 'head' | 'tail';\n\ntype IJob = {\n kind: IJobKind;\n seriesKey: string;\n};\n\ntype ISeriesState = {\n capKey: string;\n seriesKey: string;\n seriesType: ISeriesType;\n table_name: string;\n series_id: string;\n product_id: string;\n duration?: string;\n direction: SeriesFetchDirection;\n ranges: { startMs: number; endMs: number }[];\n union_start_ms?: number;\n union_end_ms?: number;\n last_window_ms?: number;\n};\n\ntype ICapability = {\n capKey: string;\n method: 'IngestOHLC' | 'IngestInterestRate';\n seriesType: ISeriesType;\n product_id_prefix: string;\n direction: SeriesFetchDirection;\n duration_list?: string[];\n nextScanAt: number;\n};\n\ntype ICapabilityState = {\n capKey: string;\n headQueue: ReturnType<typeof createFifoQueue<IJob>>;\n tailQueue: ReturnType<typeof createFifoQueue<IJob>>;\n pendingHead: Set<string>;\n pendingTail: Set<string>;\n inflight: boolean;\n nextEligibleAt: number;\n backoffMs: number;\n};\n\nconst capabilities: ICapability[] = [];\nconst mapCapKeyToCapability = new Map<string, ICapability>();\nconst mapCapKeyToState = new Map<string, ICapabilityState>();\n\nconst mapSeriesKeyToState = new Map<string, ISeriesState>();\n\nlet inflight = 0;\nlet scanIndex = 0;\nlet capRunIndex = 0;\nconst LOG_QUEUE_INTERVAL_MS = Number(process.env.VEX_SERIES_DATA_LOG_QUEUE_INTERVAL_MS ?? '10000');\n\nconst getOrCreateCapState = (capKey: string): ICapabilityState => {\n const existing = mapCapKeyToState.get(capKey);\n if (existing) return existing;\n const next: ICapabilityState = {\n capKey,\n headQueue: createFifoQueue<IJob>(),\n tailQueue: createFifoQueue<IJob>(),\n pendingHead: new Set<string>(),\n pendingTail: new Set<string>(),\n inflight: false,\n nextEligibleAt: 0,\n backoffMs: 0,\n };\n mapCapKeyToState.set(capKey, next);\n return next;\n};\n\nconst computeSeriesId = (seriesType: ISeriesType, product_id: string, duration?: string): string => {\n if (seriesType === 'ohlc') return encodeOHLCSeriesId(product_id, duration ?? '');\n return encodeInterestRateSeriesId(product_id);\n};\n\nconst getOrCreateSeriesState = (params: {\n capKey: string;\n seriesType: ISeriesType;\n product_id: string;\n duration?: string;\n direction: SeriesFetchDirection;\n}): ISeriesState => {\n const { capKey, seriesType, product_id, duration, direction } = params;\n const table_name = seriesType === 'ohlc' ? 'ohlc_v2' : 'interest_rate';\n const series_id = computeSeriesId(seriesType, product_id, duration);\n const seriesKey = encodePath(table_name, direction, product_id, duration ?? '');\n\n const existing = mapSeriesKeyToState.get(seriesKey);\n if (existing) {\n existing.capKey = capKey;\n return existing;\n }\n\n const next: ISeriesState = {\n capKey,\n seriesKey,\n seriesType,\n table_name,\n series_id,\n product_id,\n duration,\n direction,\n ranges: [],\n };\n mapSeriesKeyToState.set(seriesKey, next);\n return next;\n};\n\nconst computeHeadLagMs = (series: ISeriesState): number => {\n if (series.seriesType === 'interest_rate') return CONFIG.defaultInterestRateHeadLagMs;\n const offset = convertDurationToOffset(series.duration ?? '');\n if (!isFinite(offset) || offset <= 0) return 60_000;\n return Math.max(60_000, offset);\n};\n\nconst computeOverlapMs = (series: ISeriesState): number => {\n const maxOverlapMs = 60 * 60_000;\n let overlapMs = 60_000;\n if (series.seriesType === 'ohlc') {\n const offset = convertDurationToOffset(series.duration ?? '');\n if (isFinite(offset) && offset > 0) overlapMs = offset;\n } else {\n overlapMs = 60 * 60_000;\n }\n if (series.last_window_ms && isFinite(series.last_window_ms) && series.last_window_ms > 0) {\n overlapMs = Math.min(overlapMs, Math.max(1, series.last_window_ms - 1));\n }\n return Math.max(1, Math.min(maxOverlapMs, overlapMs));\n};\n\nconst applyOverlapToRequestTime = (series: ISeriesState, baseTime: number): number => {\n const hasAnyRange =\n series.union_start_ms !== undefined || series.union_end_ms !== undefined || series.ranges.length > 0;\n if (!hasAnyRange) return baseTime;\n const overlapMs = computeOverlapMs(series);\n if (series.direction === 'backward') return Math.min(baseTime + overlapMs, Date.now());\n return Math.max(0, baseTime - overlapMs);\n};\n\nconst computeBackoffMs = (current: number): number => {\n const next =\n current <= 0 ? CONFIG.backoffStepMs : Math.min(CONFIG.maxBackoffMs, current + CONFIG.backoffStepMs);\n return next;\n};\n\nconst enqueueCapJob = (capKey: string, kind: IJobKind, seriesKey: string) => {\n const capState = getOrCreateCapState(capKey);\n const pendingSet = kind === 'head' ? capState.pendingHead : capState.pendingTail;\n const queue = kind === 'head' ? capState.headQueue : capState.tailQueue;\n if (pendingSet.has(seriesKey)) return;\n pendingSet.add(seriesKey);\n queue.enqueue({ kind, seriesKey });\n};\n\nconst scheduleSeries = (series: ISeriesState) => {\n const now = Date.now();\n\n const headLagMs = computeHeadLagMs(series);\n const needHead = series.union_end_ms === undefined || now - series.union_end_ms > headLagMs;\n if (needHead) {\n enqueueCapJob(series.capKey, 'head', series.seriesKey);\n return;\n }\n\n if (series.union_start_ms === undefined) return;\n enqueueCapJob(series.capKey, 'tail', series.seriesKey);\n};\n\nconst mergeRangesAndGetUnion = async (\n series_id: string,\n table_name: string,\n): Promise<{\n segments: { startMs: number; endMs: number }[];\n union?: { startMs: number; endMs: number };\n}> => {\n const rows = await requestSQL<{ start_time: string; end_time: string }[]>(\n terminal,\n `\n WITH locked AS (\n SELECT series_id, table_name, start_time, end_time\n FROM series_data_range\n WHERE series_id = ${escapeSQL(series_id)} AND table_name = ${escapeSQL(table_name)}\n ORDER BY start_time ASC, end_time ASC\n FOR UPDATE\n ),\n ordered AS (\n SELECT\n start_time,\n end_time,\n max(end_time) OVER (\n ORDER BY start_time ASC, end_time ASC\n ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW\n ) AS running_end\n FROM locked\n ),\n marks AS (\n SELECT\n start_time,\n end_time,\n running_end,\n CASE\n WHEN start_time >= COALESCE(\n lag(running_end) OVER (ORDER BY start_time ASC, end_time ASC),\n '-infinity'::timestamptz\n ) THEN 1\n ELSE 0\n END AS is_new_group\n FROM ordered\n ),\n groups AS (\n SELECT\n start_time,\n end_time,\n sum(is_new_group) OVER (\n ORDER BY start_time ASC, end_time ASC\n ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW\n ) AS grp\n FROM marks\n ),\n merged AS (\n SELECT min(start_time) AS start_time, max(end_time) AS end_time\n FROM groups\n GROUP BY grp\n ),\n to_delete AS (\n SELECT l.series_id, l.table_name, l.start_time, l.end_time\n FROM locked l\n WHERE NOT EXISTS (\n SELECT 1\n FROM merged m\n WHERE m.start_time = l.start_time AND m.end_time = l.end_time\n )\n ),\n deleted AS (\n DELETE FROM series_data_range t\n USING to_delete d\n WHERE\n t.series_id = d.series_id\n AND t.table_name = d.table_name\n AND t.start_time = d.start_time\n AND t.end_time = d.end_time\n RETURNING 1\n ),\n to_insert AS (\n SELECT m.start_time, m.end_time\n FROM merged m\n WHERE NOT EXISTS (\n SELECT 1\n FROM locked l\n WHERE l.start_time = m.start_time AND l.end_time = m.end_time\n )\n ),\n inserted AS (\n INSERT INTO series_data_range (series_id, table_name, start_time, end_time)\n SELECT ${escapeSQL(series_id)}, ${escapeSQL(table_name)}, start_time, end_time\n FROM to_insert\n ON CONFLICT DO NOTHING\n RETURNING 1\n )\n SELECT start_time, end_time\n FROM series_data_range\n WHERE series_id = ${escapeSQL(series_id)} AND table_name = ${escapeSQL(table_name)}\n ORDER BY start_time ASC, end_time ASC;\n `,\n );\n\n if (rows.length === 0) return { segments: [] };\n const segments: { startMs: number; endMs: number }[] = [];\n let startMs = Number.POSITIVE_INFINITY;\n let endMs = Number.NEGATIVE_INFINITY;\n for (const r of rows) {\n const s = Date.parse(r.start_time);\n const e = Date.parse(r.end_time);\n if (!isNaN(s) && !isNaN(e) && e >= s) {\n segments.push({ startMs: s, endMs: e });\n startMs = Math.min(startMs, s);\n endMs = Math.max(endMs, e);\n }\n }\n if (!isFinite(startMs) || !isFinite(endMs)) return { segments };\n return { segments, union: { startMs, endMs } };\n};\n\nconst findNearestGap = (\n segments: { startMs: number; endMs: number }[],\n): { left: { startMs: number; endMs: number }; right: { startMs: number; endMs: number } } | undefined => {\n for (let i = segments.length - 2; i >= 0; i--) {\n const left = segments[i];\n const right = segments[i + 1];\n if (left.endMs < right.startMs) return { left, right };\n }\n};\n\nconst computeTailTime = (series: ISeriesState, now: number): number => {\n const gap = findNearestGap(series.ranges);\n if (gap) {\n return series.direction === 'backward' ? gap.right.startMs : gap.left.endMs;\n }\n\n const first = series.ranges[0];\n const mostRecent = series.ranges[series.ranges.length - 1];\n if (series.direction === 'backward') {\n return series.union_start_ms ?? first?.startMs ?? mostRecent?.startMs ?? now;\n }\n\n const windowMs = series.last_window_ms ?? CONFIG.defaultForwardSeedWindowMs;\n const start = series.union_start_ms ?? Math.max(0, now - windowMs);\n return Math.max(0, start - windowMs);\n};\n\nconst computeRequestTime = (series: ISeriesState, kind: IJobKind): number => {\n const now = Date.now();\n if (series.direction === 'backward') {\n if (kind === 'head') return applyOverlapToRequestTime(series, now);\n return applyOverlapToRequestTime(series, computeTailTime(series, now));\n }\n\n const windowMs = series.last_window_ms ?? CONFIG.defaultForwardSeedWindowMs;\n if (kind === 'head') {\n if (series.union_end_ms !== undefined) return applyOverlapToRequestTime(series, series.union_end_ms);\n return applyOverlapToRequestTime(series, Math.max(0, now - windowMs));\n }\n return applyOverlapToRequestTime(series, computeTailTime(series, now));\n};\n\nconst requestIngest = async (series: ISeriesState, time: number): Promise<ISeriesIngestResult> => {\n if (series.seriesType === 'ohlc') {\n const req: IIngestOHLCRequest = {\n product_id: series.product_id,\n duration: series.duration ?? '',\n direction: series.direction,\n time,\n };\n return terminal.client.requestForResponseData<IIngestOHLCRequest, ISeriesIngestResult>('IngestOHLC', req);\n }\n\n const req: IIngestInterestRateRequest = {\n product_id: series.product_id,\n direction: series.direction,\n time,\n };\n return terminal.client.requestForResponseData<IIngestInterestRateRequest, ISeriesIngestResult>(\n 'IngestInterestRate',\n req,\n );\n};\n\nconst executeJob = async (capState: ICapabilityState, job: IJob) => {\n const series = mapSeriesKeyToState.get(job.seriesKey);\n if (!series) return;\n\n if (job.kind === 'head') capState.pendingHead.delete(job.seriesKey);\n else capState.pendingTail.delete(job.seriesKey);\n\n try {\n // make sure each request overlaps existing ranges\n const time = computeRequestTime(series, job.kind);\n const result = await requestIngest(series, time);\n\n capState.backoffMs = 0;\n capState.nextEligibleAt = 0;\n\n if (!result.range) {\n capState.backoffMs = computeBackoffMs(capState.backoffMs);\n capState.nextEligibleAt = Date.now() + capState.backoffMs;\n scheduleSeries(series);\n return;\n }\n\n const startMs = Date.parse(result.range.start_time);\n const endMs = Date.parse(result.range.end_time);\n if (!isNaN(startMs) && !isNaN(endMs) && endMs > startMs) {\n series.last_window_ms = endMs - startMs;\n }\n\n const merged = await mergeRangesAndGetUnion(series.series_id, series.table_name);\n series.ranges = merged.segments;\n if (merged.union) {\n series.union_start_ms = merged.union.startMs;\n series.union_end_ms = merged.union.endMs;\n }\n\n scheduleSeries(series);\n } catch (e) {\n capState.backoffMs = computeBackoffMs(capState.backoffMs);\n capState.nextEligibleAt = Date.now() + capState.backoffMs;\n console.warn(\n formatTime(Date.now()),\n '[VEX][SeriesData]CapFailed',\n `cap=${capState.capKey}`,\n `backoff_ms=${capState.backoffMs}`,\n `${e}`,\n );\n scheduleSeries(series);\n }\n};\n\nconst computeGlobalHeadBacklog = (): number => {\n let total = 0;\n for (const s of mapCapKeyToState.values()) {\n total += s.headQueue.size();\n }\n return total;\n};\n\nconst pickNextRunnableCap = (now: number): ICapabilityState | undefined => {\n if (capabilities.length === 0) return;\n const n = capabilities.length;\n for (let i = 0; i < n; i++) {\n // Round-robin pick\n const cap = capabilities[capRunIndex++ % n];\n const capState = getOrCreateCapState(cap.capKey);\n if (capState.inflight) continue;\n if (capState.nextEligibleAt > now) continue;\n if (capState.headQueue.size() === 0 && capState.tailQueue.size() === 0) continue;\n return capState;\n }\n};\n\nconst dequeueFromCap = (\n capState: ICapabilityState,\n canRunTail: boolean,\n): { job: IJob; kind: IJobKind } | undefined => {\n const head = capState.headQueue.dequeue();\n if (head) return { job: head, kind: 'head' };\n if (!canRunTail) return;\n const tail = capState.tailQueue.dequeue();\n if (!tail) return;\n return { job: tail, kind: 'tail' };\n};\n\nconst scanProductsOnce = async () => {\n if (capabilities.length === 0) return;\n\n const now = Date.now();\n const cap = capabilities[scanIndex++ % capabilities.length];\n if (cap.nextScanAt > now) return;\n\n const where = [\n `product_id LIKE ${escapeSQL(`${cap.product_id_prefix}%`)}`,\n onlyProductIdPrefix ? `product_id LIKE ${escapeSQL(`${onlyProductIdPrefix}%`)}` : '',\n cap.seriesType === 'interest_rate' ? `COALESCE(no_interest_rate, false) = false` : '',\n ]\n .filter(Boolean)\n .join(' AND ');\n\n const rows = await requestSQL<{ product_id: string }[]>(\n terminal,\n `\n SELECT product_id\n FROM product\n WHERE ${where}\n ORDER BY product_id ASC\n `,\n );\n cap.nextScanAt = now + CONFIG.scanFullLoopIntervalMs;\n\n for (const row of rows) {\n if (cap.seriesType === 'ohlc') {\n for (const duration of cap.duration_list ?? []) {\n const series = getOrCreateSeriesState({\n capKey: cap.capKey,\n seriesType: 'ohlc',\n product_id: row.product_id,\n duration,\n direction: cap.direction,\n });\n scheduleSeries(series);\n }\n } else {\n const series = getOrCreateSeriesState({\n capKey: cap.capKey,\n seriesType: 'interest_rate',\n product_id: row.product_id,\n direction: cap.direction,\n });\n scheduleSeries(series);\n }\n }\n};\n\nconst tick = async () => {\n if (!isEnabled) return;\n\n try {\n await scanProductsOnce();\n } catch (e) {\n console.error(formatTime(Date.now()), '[VEX][SeriesData]ScanFailed', `${e}`);\n }\n\n const now = Date.now();\n while (inflight < CONFIG.maxInflight) {\n const capState = pickNextRunnableCap(now);\n if (!capState) return;\n\n const globalHeadBacklog = computeGlobalHeadBacklog();\n const canRunTail =\n globalHeadBacklog < CONFIG.tailOnlyWhenGlobalHeadBelow && capState.headQueue.size() === 0;\n const next = dequeueFromCap(capState, canRunTail);\n if (!next) return;\n\n capState.inflight = true;\n inflight++;\n executeJob(capState, next.job).finally(() => {\n capState.inflight = false;\n inflight--;\n });\n }\n};\n\nif (!isEnabled) {\n console.info(formatTime(Date.now()), '[VEX][SeriesData]Disabled', 'VEX_SERIES_DATA_ENABLED!=1');\n} else {\n terminal.server.provideService('VEX/SeriesData/Peek', {}, async () => {\n const now = Date.now();\n const caps = capabilities.map((cap) => {\n const s = getOrCreateCapState(cap.capKey);\n return {\n capKey: cap.capKey,\n method: cap.method,\n product_id_prefix: cap.product_id_prefix,\n direction: cap.direction,\n head_queue_size: s.headQueue.size(),\n tail_queue_size: s.tailQueue.size(),\n inflight: s.inflight,\n backoff_ms: s.backoffMs,\n nextEligibleAt: s.nextEligibleAt > now ? formatTime(s.nextEligibleAt) : undefined,\n };\n });\n return {\n res: {\n code: 0,\n message: 'OK',\n data: {\n enabled: true,\n only_product_id_prefix: onlyProductIdPrefix || undefined,\n inflight,\n cap_count: capabilities.length,\n global_head_backlog: computeGlobalHeadBacklog(),\n series_count: mapSeriesKeyToState.size,\n caps: caps.slice(0, 50),\n },\n },\n };\n });\n\n // Setup trace log\n timer(0, LOG_QUEUE_INTERVAL_MS).subscribe(() => {\n const now = Date.now();\n const caps = capabilities\n .map((cap) => {\n const s = getOrCreateCapState(cap.capKey);\n return {\n capKey: cap.capKey,\n head: s.headQueue.size(),\n tail: s.tailQueue.size(),\n inflight: s.inflight,\n backoffMs: s.backoffMs,\n nextEligibleAt: s.nextEligibleAt,\n };\n })\n .filter((x) => x.inflight || x.head > 0 || x.tail > 0 || x.nextEligibleAt > now)\n .slice(0, 20)\n .map(\n (x) =>\n `cap=${x.capKey} head=${x.head} tail=${x.tail} inflight=${x.inflight ? 1 : 0} backoff_ms=${\n x.backoffMs\n }${x.nextEligibleAt > now ? ` next=${formatTime(x.nextEligibleAt)}` : ''}`,\n );\n\n console.info(\n formatTime(now),\n '[VEX][SeriesData]Queues',\n `inflight=${inflight}`,\n `cap_count=${capabilities.length}`,\n `global_head_backlog=${computeGlobalHeadBacklog()}`,\n `series_count=${mapSeriesKeyToState.size}`,\n caps.length ? `caps=[${caps.join(' | ')}]` : 'caps=[]',\n );\n });\n\n terminal.terminalInfos$\n .pipe(\n mergeMap((terminalInfos) =>\n from(terminalInfos).pipe(\n mergeMap((terminalInfo) =>\n from(Object.values(terminalInfo.serviceInfo || {})).pipe(\n filter(\n (serviceInfo) =>\n serviceInfo.method === 'IngestOHLC' || serviceInfo.method === 'IngestInterestRate',\n ),\n map((serviceInfo): ICapability | undefined => {\n try {\n if (serviceInfo.method === 'IngestOHLC') {\n const meta = parseOHLCServiceMetadataFromSchema(serviceInfo.schema);\n const capKey = encodePath('IngestOHLC', meta.product_id_prefix, meta.direction);\n const existing = mapCapKeyToCapability.get(capKey);\n const duration_list = [...new Set(meta.duration_list)].sort();\n if (existing) {\n existing.duration_list = duration_list;\n return existing;\n }\n return {\n capKey,\n method: 'IngestOHLC',\n seriesType: 'ohlc',\n product_id_prefix: meta.product_id_prefix,\n direction: meta.direction,\n duration_list,\n nextScanAt: 0,\n };\n }\n\n const meta = parseInterestRateServiceMetadataFromSchema(serviceInfo.schema);\n const capKey = encodePath('IngestInterestRate', meta.product_id_prefix, meta.direction);\n const existing = mapCapKeyToCapability.get(capKey);\n if (existing) return existing;\n return {\n capKey,\n method: 'IngestInterestRate',\n seriesType: 'interest_rate',\n product_id_prefix: meta.product_id_prefix,\n direction: meta.direction,\n nextScanAt: 0,\n };\n } catch {\n console.info(\n formatTime(Date.now()),\n '[VEX][SeriesData]ParseServiceMetadataFailed',\n `method=${serviceInfo.method}`,\n `terminal_id=${terminalInfo.terminal_id}`,\n );\n return;\n }\n }),\n filter((x): x is Exclude<typeof x, undefined> => !!x),\n ),\n ),\n toArray(),\n tap((nextCaps) => {\n const nextMap = new Map<string, ICapability>();\n for (const cap of nextCaps) {\n nextMap.set(cap.capKey, cap);\n }\n mapCapKeyToCapability.clear();\n nextMap.forEach((v, k) => mapCapKeyToCapability.set(k, v));\n capabilities.length = 0;\n nextMap.forEach((v) => capabilities.push(v));\n }),\n ),\n ),\n )\n .subscribe();\n\n defer(() => from(tick()))\n .pipe(\n catchError((e) => {\n console.error(formatTime(Date.now()), '[VEX][SeriesData]TickError', `${e}`);\n return EMPTY;\n }),\n repeat({ delay: CONFIG.tickIntervalMs }),\n )\n .subscribe();\n}\n"]}
|
package/lib/credential.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
interface IExchangeCredential {
|
|
1
|
+
export interface IExchangeCredential {
|
|
2
2
|
type: string;
|
|
3
3
|
payload: any;
|
|
4
4
|
}
|
|
@@ -17,5 +17,4 @@ export declare const getCredentialBySecretId: (sign: string) => Promise<{
|
|
|
17
17
|
credential: IExchangeCredential;
|
|
18
18
|
credentialId: string;
|
|
19
19
|
}>;
|
|
20
|
-
export {};
|
|
21
20
|
//# sourceMappingURL=credential.d.ts.map
|