@yuants/app-virtual-exchange 0.18.6 → 0.18.7

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.
Files changed (92) hide show
  1. package/dist/app-virtual-exchange.d.ts +1 -0
  2. package/dist/credential.js.map +1 -1
  3. package/dist/legacy-services.js.map +1 -1
  4. package/dist/position.js.map +1 -1
  5. package/dist/quote/__tests__/implementations.test.js +1 -1
  6. package/dist/quote/__tests__/implementations.test.js.map +1 -1
  7. package/dist/quote/benchmark/ForkedQuoteStateComparisonTest.js.map +1 -1
  8. package/dist/quote/benchmark/PerformanceTester.js.map +1 -1
  9. package/dist/quote/benchmark/QuoteStateComparisonTest.js.map +1 -1
  10. package/dist/quote/benchmark/QuoteStateTestRunner.js.map +1 -1
  11. package/dist/quote/benchmark/index.js.map +1 -1
  12. package/dist/quote/benchmark/test-helpers.js.map +1 -1
  13. package/dist/quote/benchmark/worker.js.map +1 -1
  14. package/dist/quote/implementations/v0.js.map +1 -1
  15. package/dist/quote/implementations/v1.js.map +1 -1
  16. package/dist/quote/implementations/v2.js.map +1 -1
  17. package/dist/quote/implementations/v3.js +1 -1
  18. package/dist/quote/implementations/v3.js.map +1 -1
  19. package/dist/quote/scheduler.js.map +1 -1
  20. package/dist/quote/service.js.map +1 -1
  21. package/dist/quote/state.benchmark.js.map +1 -1
  22. package/dist/series-collector/backwards-interest-rate.js.map +1 -1
  23. package/dist/series-collector/backwards-ohlc.js.map +1 -1
  24. package/dist/series-collector/discovery.js.map +1 -1
  25. package/dist/series-collector/forwards-interest-rate.js.map +1 -1
  26. package/dist/series-collector/forwards-ohlc.js.map +1 -1
  27. package/dist/series-collector/patch-interest-rate.js.map +1 -1
  28. package/dist/series-collector/patch-ohlc.js.map +1 -1
  29. package/dist/series-collector/setup.js.map +1 -1
  30. package/dist/series-data/fifo-queue.js.map +1 -1
  31. package/dist/series-data/scheduler.js.map +1 -1
  32. package/lib/credential.d.ts.map +1 -1
  33. package/lib/credential.js.map +1 -1
  34. package/lib/legacy-services.js.map +1 -1
  35. package/lib/position.d.ts.map +1 -1
  36. package/lib/position.js.map +1 -1
  37. package/lib/quote/__tests__/implementations.test.js +1 -1
  38. package/lib/quote/__tests__/implementations.test.js.map +1 -1
  39. package/lib/quote/benchmark/ForkedQuoteStateComparisonTest.js.map +1 -1
  40. package/lib/quote/benchmark/PerformanceTester.d.ts +0 -1
  41. package/lib/quote/benchmark/PerformanceTester.d.ts.map +1 -1
  42. package/lib/quote/benchmark/PerformanceTester.js.map +1 -1
  43. package/lib/quote/benchmark/QuoteStateComparisonTest.js.map +1 -1
  44. package/lib/quote/benchmark/QuoteStateTestRunner.js.map +1 -1
  45. package/lib/quote/benchmark/index.js +2 -2
  46. package/lib/quote/benchmark/index.js.map +1 -1
  47. package/lib/quote/benchmark/test-helpers.js +4 -5
  48. package/lib/quote/benchmark/test-helpers.js.map +1 -1
  49. package/lib/quote/benchmark/worker.js.map +1 -1
  50. package/lib/quote/implementations/v0.js +1 -2
  51. package/lib/quote/implementations/v0.js.map +1 -1
  52. package/lib/quote/implementations/v1.js.map +1 -1
  53. package/lib/quote/implementations/v2.js.map +1 -1
  54. package/lib/quote/implementations/v3.js +1 -1
  55. package/lib/quote/implementations/v3.js.map +1 -1
  56. package/lib/quote/scheduler.d.ts.map +1 -1
  57. package/lib/quote/scheduler.js.map +1 -1
  58. package/lib/quote/service.js.map +1 -1
  59. package/lib/quote/state.benchmark.js.map +1 -1
  60. package/lib/quote/types.d.ts +2 -2
  61. package/lib/quote/types.d.ts.map +1 -1
  62. package/lib/series-collector/backwards-interest-rate.d.ts +1 -2
  63. package/lib/series-collector/backwards-interest-rate.d.ts.map +1 -1
  64. package/lib/series-collector/backwards-interest-rate.js.map +1 -1
  65. package/lib/series-collector/backwards-ohlc.d.ts +1 -2
  66. package/lib/series-collector/backwards-ohlc.d.ts.map +1 -1
  67. package/lib/series-collector/backwards-ohlc.js.map +1 -1
  68. package/lib/series-collector/discovery.js.map +1 -1
  69. package/lib/series-collector/forwards-interest-rate.d.ts +1 -2
  70. package/lib/series-collector/forwards-interest-rate.d.ts.map +1 -1
  71. package/lib/series-collector/forwards-interest-rate.js.map +1 -1
  72. package/lib/series-collector/forwards-ohlc.d.ts +1 -2
  73. package/lib/series-collector/forwards-ohlc.d.ts.map +1 -1
  74. package/lib/series-collector/forwards-ohlc.js.map +1 -1
  75. package/lib/series-collector/patch-interest-rate.d.ts +1 -2
  76. package/lib/series-collector/patch-interest-rate.d.ts.map +1 -1
  77. package/lib/series-collector/patch-interest-rate.js.map +1 -1
  78. package/lib/series-collector/patch-ohlc.d.ts +1 -2
  79. package/lib/series-collector/patch-ohlc.d.ts.map +1 -1
  80. package/lib/series-collector/patch-ohlc.js.map +1 -1
  81. package/lib/series-collector/setup.js.map +1 -1
  82. package/lib/series-collector/sql-helpers.d.ts.map +1 -1
  83. package/lib/series-data/fifo-queue.d.ts.map +1 -1
  84. package/lib/series-data/fifo-queue.js.map +1 -1
  85. package/lib/series-data/scheduler.js.map +1 -1
  86. package/lib/tsdoc-metadata.json +11 -0
  87. package/package.json +42 -42
  88. package/temp/app-virtual-exchange.api.json +193 -0
  89. package/temp/app-virtual-exchange.api.md +9 -0
  90. package/temp/build/typescript/ts_KjrfbUqK.json +1 -0
  91. package/temp/test/jest/haste-map-76b16e3ab892e2fd05068740b7223d57-a6c52f003baf5bf33cffc52364f3bd7a-4ce9ff2cd20d69bbaecd1543c7e32e02 +0 -0
  92. 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":"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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
+ {"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../../src/quote/scheduler.ts"],"names":[],"mappings":";;;AACA,+CAA2G;AAC3G,+CAA4C;AAC5C,yCAAuD;AACvD,+BAAiE;AACjE,mCAAqC;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,CAAC;QAC7D,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC5C,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC;IACjB,CAAC;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;AACU,QAAA,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,CAAC;QAC/B,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;IAClC,CAAC;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;AAEK,MAAM,SAAS,GAAG,CAAC,UAAkB,EAAE,KAAkB,EAAE,EAAE;IAClE,MAAM,gBAAgB,GAAG,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;IAElD,MAAM,OAAO,GAAG,IAAA,kBAAU,EAAC,UAAU,EAAE,KAAK,CAAC,CAAC;IAC9C,MAAM,QAAQ,GAAG,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC/C,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,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,aAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnB,CAAC;SAAM,CAAC;QACN,QAAQ,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;QAC7C,QAAQ,CAAC,QAAQ,GAAG,IAAI,CAAC;IAC3B,CAAC;IAED,YAAY,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC,CAAC;IACtD,sBAAsB,CAAC,gBAAgB,CAAC,CAAC;AAC3C,CAAC,CAAC;AAvBW,QAAA,SAAS,aAuBpB;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,CAAC;QAClC,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;IACL,CAAC;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,CAAC;QACZ,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,CAAC;YACrF,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,CAAC;gBAC5B,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC;oBAAE,SAAS;gBAC5C,MAAM,IAAI,GAAG,gBAAgB,CAAC,GAAG,CAAC,IAAA,kBAAU,EAAC,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;YAC1B,CAAC;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;QACjE,CAAC;QAED,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAEzC,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE,CAAC;YAChC,IAAI,CAAC,KAAK,EAAE,CAAC;YACb,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QAC1B,CAAC;QAED,MAAM,GAAG,GAAG,MAAM,WAAW,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAyB,CAAA,CAAC,CAAC;QAChG,kBAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAEvB,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE,CAAC;YAChC,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;YACzB,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;QACxB,CAAC;QAED,KAAK,MAAM,UAAU,IAAI,eAAe,EAAE,CAAC;YACzC,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,CAAC;gBAC9B,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YACxB,CAAC;YACD,IAAI,WAAW,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;gBAC3B,UAAU,CAAC,oBAAoB,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;gBACnD,SAAS;YACX,CAAC;YACD,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;gBACxC,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;gBACnC,WAAW,CAAC,UAAU,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;YACnD,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,QAAQ,GAAG,mBAAQ,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,CAAC;QACnB,OAAO,CAAC,IAAI,CACV,IAAA,kBAAU,EAAC,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;IACJ,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC,CAAC;AAEF,QAAQ,CAAC,cAAc;KACpB,IAAI,CACH,IAAA,eAAQ,EAAC,CAAC,aAAa,EAAE,EAAE,CACzB,IAAA,WAAI,EAAC,aAAa,CAAC,CAAC,IAAI,CACtB,IAAA,eAAQ,EAAC,CAAC,YAAY,EAAE,EAAE,CACxB,IAAA,WAAI,EAAC,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CACtD,IAAA,aAAM,EAAC,CAAC,WAAW,EAAE,EAAE,CAAC,WAAW,CAAC,MAAM,KAAK,WAAW,CAAC,EAC3D,IAAA,UAAG,EAAC,CAAC,WAAW,EAA6B,EAAE;;IAC7C,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAA,8CAAmC,EAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QACrE,MAAM,gBAAgB,GAAG,IAAA,kBAAU,EACjC,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;IACJ,CAAC;IAAC,WAAM,CAAC,CAAA,CAAC;AACZ,CAAC,CAAC,EACF,IAAA,aAAM,EAAC,CAAC,CAAC,EAAqC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CACtD,CACF,EACD,IAAA,cAAO,GAAE,EACT,IAAA,UAAG,EAAC,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 +1 @@
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
+ {"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,+FAA4F;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;QACpC,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;KACR;IAED,gBAAgB;IAChB,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IAClC,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;IAE7C,MAAM,oBAAoB,GAAG,IAAI,+DAA8B,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;IAEvF,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE;QAC5B,MAAM,oBAAoB,CAAC,sBAAsB,EAAE,CAAC;KACrD;SAAM;QACL,MAAM,oBAAoB,CAAC,sBAAsB,EAAE,CAAC;KACrD;AACH,CAAC;AAED,kBAAkB;AAClB,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE;IAC3B,IAAI,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;CAC7B","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
+ {"version":3,"file":"state.benchmark.js","sourceRoot":"","sources":["../../src/quote/state.benchmark.ts"],"names":[],"mappings":";;AAAA,+FAA4F;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,+DAA8B,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,6 +1,6 @@
1
1
  import { IQuote } from '@yuants/data-quote';
2
2
  import { IQuoteServiceMetadata } from '@yuants/exchange';
3
- export declare type IQuoteKey = Exclude<keyof IQuote, 'datasource_id' | 'product_id' | 'updated_at'>;
3
+ export type IQuoteKey = Exclude<keyof IQuote, 'datasource_id' | 'product_id' | 'updated_at'>;
4
4
  /**
5
5
  * 用于批量更新的数据结构
6
6
  * 结构为:
@@ -21,7 +21,7 @@ export declare type IQuoteKey = Exclude<keyof IQuote, 'datasource_id' | 'product
21
21
  * ```
22
22
  * @public
23
23
  */
24
- export declare type IQuoteUpdateAction = Record<string, Partial<Record<IQuoteKey, [value: string, updated_at: number]>>>;
24
+ export type IQuoteUpdateAction = Record<string, Partial<Record<IQuoteKey, [value: string, updated_at: number]>>>;
25
25
  export interface IQuoteState {
26
26
  update: (action: IQuoteUpdateAction) => void;
27
27
  dumpAsObject: () => IQuoteUpdateAction;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/quote/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAEzD,oBAAY,SAAS,GAAG,OAAO,CAAC,MAAM,MAAM,EAAE,eAAe,GAAG,YAAY,GAAG,YAAY,CAAC,CAAC;AAE7F;;;;;;;;;;;;;;;;;;;GAmBG;AACH,oBAAY,kBAAkB,GAAG,MAAM,CACrC,MAAM,EACN,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,CAChE,CAAC;AACF,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,CAAC,MAAM,EAAE,kBAAkB,KAAK,IAAI,CAAC;IAC7C,YAAY,EAAE,MAAM,kBAAkB,CAAC;IACvC,aAAa,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;IACtF,MAAM,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,UAAU,EAAE,MAAM,KAAK,kBAAkB,CAAC;IAC/F;;;;;;OAMG;IACH,YAAY,EAAE,CAAC,CAAC,SAAS,SAAS,EAChC,WAAW,EAAE,MAAM,EAAE,EACrB,MAAM,EAAE,CAAC,EAAE,KACR,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;CACxC;AAED,MAAM,WAAW,sBAAsB;IACrC,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,qBAAqB,CAAC;IAC5B,uBAAuB,EAAE,GAAG,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;CAC9D;AAED,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,SAAS,CAAC;CAClB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/quote/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAEzD,MAAM,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,MAAM,EAAE,eAAe,GAAG,YAAY,GAAG,YAAY,CAAC,CAAC;AAE7F;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,MAAM,kBAAkB,GAAG,MAAM,CACrC,MAAM,EACN,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,CAChE,CAAC;AACF,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,CAAC,MAAM,EAAE,kBAAkB,KAAK,IAAI,CAAC;IAC7C,YAAY,EAAE,MAAM,kBAAkB,CAAC;IACvC,aAAa,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;IACtF,MAAM,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,UAAU,EAAE,MAAM,KAAK,kBAAkB,CAAC;IAC/F;;;;;;OAMG;IACH,YAAY,EAAE,CAAC,CAAC,SAAS,SAAS,EAChC,WAAW,EAAE,MAAM,EAAE,EACrB,MAAM,EAAE,CAAC,EAAE,KACR,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;CACxC;AAED,MAAM,WAAW,sBAAsB;IACrC,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,qBAAqB,CAAC;IAC5B,uBAAuB,EAAE,GAAG,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;CAC9D;AAED,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,SAAS,CAAC;CAClB"}
@@ -1,3 +1,2 @@
1
- /// <reference types="node" />
2
- export declare const handleIngestInterestRateBackward: (product_id: string, direction: 'forward' | 'backward', signal: AbortSignal) => Promise<void>;
1
+ export declare const handleIngestInterestRateBackward: (product_id: string, direction: "forward" | "backward", signal: AbortSignal) => Promise<void>;
3
2
  //# sourceMappingURL=backwards-interest-rate.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"backwards-interest-rate.d.ts","sourceRoot":"","sources":["../../src/series-collector/backwards-interest-rate.ts"],"names":[],"mappings":";AAUA,eAAO,MAAM,gCAAgC,eAC/B,MAAM,aACP,SAAS,GAAG,UAAU,UACzB,WAAW,kBA0CpB,CAAC"}
1
+ {"version":3,"file":"backwards-interest-rate.d.ts","sourceRoot":"","sources":["../../src/series-collector/backwards-interest-rate.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,gCAAgC,GAC3C,YAAY,MAAM,EAClB,WAAW,SAAS,GAAG,UAAU,EACjC,QAAQ,WAAW,kBA0CpB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"backwards-interest-rate.js","sourceRoot":"","sources":["../../src/series-collector/backwards-interest-rate.ts"],"names":[],"mappings":";;;AACA,+CAA4C;AAC5C,yCAA2C;AAC3C,+CAAkE;AAElE,MAAM,QAAQ,GAAG,mBAAQ,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;AAEnF,MAAM,gCAAgC,GAAG,KAAK,EACnD,UAAkB,EAClB,SAAiC,EACjC,MAAmB,EACnB,EAAE;;IACF,IAAI,GAA+B,CAAC;IACpC,IAAI,SAAS,KAAK,UAAU,EAAE;QAC5B,MAAM,SAAS,GAAG,MAAM,IAAA,+CAAiC,EAAC,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;KACH;SAAM;QACL,GAAG,GAAG;YACJ,UAAU,EAAE,UAAU;YACtB,SAAS,EAAE,SAAS;YACpB,IAAI,EAAE,CAAC;SACR,CAAC;KACH;IAED,OAAO,CAAC,IAAI,CACV,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,2CAA2C,EAC3C,SAAS,EACT,cAAc,GAAG,CAAC,UAAU,eAAe,GAAG,CAAC,SAAS,UAAU,IAAA,kBAAU,EAAC,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,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,2CAA2C,EAC3C,QAAQ,EACR,aAAa,UAAU,oBAAoB,GAAG,CAAC,WAAW,gBAAgB,IAAA,kBAAU,EAClF,MAAA,MAAA,GAAG,CAAC,KAAK,0CAAE,UAAU,mCAAI,GAAG,CAC7B,cAAc,IAAA,kBAAU,EAAC,MAAA,MAAA,GAAG,CAAC,KAAK,0CAAE,QAAQ,mCAAI,GAAG,CAAC,EAAE,CACxD,CAAC;AACJ,CAAC,CAAC;AA7CW,QAAA,gCAAgC,oCA6C3C","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
+ {"version":3,"file":"backwards-interest-rate.js","sourceRoot":"","sources":["../../src/series-collector/backwards-interest-rate.ts"],"names":[],"mappings":";;;AACA,+CAA4C;AAC5C,yCAA2C;AAC3C,+CAAkE;AAElE,MAAM,QAAQ,GAAG,mBAAQ,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;AAEnF,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,IAAA,+CAAiC,EAAC,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,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,2CAA2C,EAC3C,SAAS,EACT,cAAc,GAAG,CAAC,UAAU,eAAe,GAAG,CAAC,SAAS,UAAU,IAAA,kBAAU,EAAC,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,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,2CAA2C,EAC3C,QAAQ,EACR,aAAa,UAAU,oBAAoB,GAAG,CAAC,WAAW,gBAAgB,IAAA,kBAAU,EAClF,MAAA,MAAA,GAAG,CAAC,KAAK,0CAAE,UAAU,mCAAI,GAAG,CAC7B,cAAc,IAAA,kBAAU,EAAC,MAAA,MAAA,GAAG,CAAC,KAAK,0CAAE,QAAQ,mCAAI,GAAG,CAAC,EAAE,CACxD,CAAC;AACJ,CAAC,CAAC;AA7CW,QAAA,gCAAgC,oCA6C3C","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,3 +1,2 @@
1
- /// <reference types="node" />
2
- export declare const handleIngestOHLCBackward: (series_id: string, direction: 'forward' | 'backward', signal: AbortSignal) => Promise<void>;
1
+ export declare const handleIngestOHLCBackward: (series_id: string, direction: "forward" | "backward", signal: AbortSignal) => Promise<void>;
3
2
  //# sourceMappingURL=backwards-ohlc.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"backwards-ohlc.d.ts","sourceRoot":"","sources":["../../src/series-collector/backwards-ohlc.ts"],"names":[],"mappings":";AAiBA,eAAO,MAAM,wBAAwB,cACxB,MAAM,aACN,SAAS,GAAG,UAAU,UACzB,WAAW,kBA0DpB,CAAC"}
1
+ {"version":3,"file":"backwards-ohlc.d.ts","sourceRoot":"","sources":["../../src/series-collector/backwards-ohlc.ts"],"names":[],"mappings":"AAiBA,eAAO,MAAM,wBAAwB,GACnC,WAAW,MAAM,EACjB,WAAW,SAAS,GAAG,UAAU,EACjC,QAAQ,WAAW,kBA0DpB,CAAC"}
@@ -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,iDAAuD;AAEvD,+CAA4C;AAC5C,qCAAoD;AACpD,yCAA2C;AAE3C,MAAM,QAAQ,GAAG,mBAAQ,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;AAE1E,MAAM,wBAAwB,GAAG,KAAK,EAC3C,SAAiB,EACjB,SAAiC,EACjC,MAAmB,EACnB,EAAE;;IACF,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,IAAA,8BAAkB,EAAC,SAAS,CAAC,CAAC;IAE/D,IAAI,GAAuB,CAAC;IAC5B,IAAI,SAAS,KAAK,UAAU,EAAE;QAC5B,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,IAAA,gBAAU,EAK/B,QAAQ,EACR,8DAA8D,IAAA,eAAS,EACrE,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;KACH;SAAM;QACL,UAAU;QACV,GAAG,GAAG;YACJ,UAAU;YACV,QAAQ;YACR,SAAS;YACT,IAAI,EAAE,CAAC;SACR,CAAC;KACH;IAED,OAAO,CAAC,IAAI,CACV,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,mCAAmC,EACnC,SAAS,EACT,cAAc,GAAG,CAAC,UAAU,cAAc,GAAG,CAAC,QAAQ,eAAe,GAAG,CAAC,SAAS,UAAU,IAAA,kBAAU,EACpG,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,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,mCAAmC,EACnC,UAAU,EACV,aAAa,SAAS,oBAAoB,GAAG,CAAC,WAAW,gBAAgB,IAAA,kBAAU,EACjF,MAAA,MAAA,GAAG,CAAC,KAAK,0CAAE,UAAU,mCAAI,GAAG,CAC7B,cAAc,IAAA,kBAAU,EAAC,MAAA,MAAA,GAAG,CAAC,KAAK,0CAAE,QAAQ,mCAAI,GAAG,CAAC,EAAE,CACxD,CAAC;AACJ,CAAC,CAAC;AA7DW,QAAA,wBAAwB,4BA6DnC","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
+ {"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,iDAAuD;AAEvD,+CAA4C;AAC5C,qCAAoD;AACpD,yCAA2C;AAE3C,MAAM,QAAQ,GAAG,mBAAQ,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;AAE1E,MAAM,wBAAwB,GAAG,KAAK,EAC3C,SAAiB,EACjB,SAAiC,EACjC,MAAmB,EACnB,EAAE;;IACF,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,IAAA,8BAAkB,EAAC,SAAS,CAAC,CAAC;IAE/D,IAAI,GAAuB,CAAC;IAC5B,IAAI,SAAS,KAAK,UAAU,EAAE,CAAC;QAC7B,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,IAAA,gBAAU,EAK/B,QAAQ,EACR,8DAA8D,IAAA,eAAS,EACrE,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,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,mCAAmC,EACnC,SAAS,EACT,cAAc,GAAG,CAAC,UAAU,cAAc,GAAG,CAAC,QAAQ,eAAe,GAAG,CAAC,SAAS,UAAU,IAAA,kBAAU,EACpG,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,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,mCAAmC,EACnC,UAAU,EACV,aAAa,SAAS,oBAAoB,GAAG,CAAC,WAAW,gBAAgB,IAAA,kBAAU,EACjF,MAAA,MAAA,GAAG,CAAC,KAAK,0CAAE,UAAU,mCAAI,GAAG,CAC7B,cAAc,IAAA,kBAAU,EAAC,MAAA,MAAA,GAAG,CAAC,KAAK,0CAAE,QAAQ,mCAAI,GAAG,CAAC,EAAE,CACxD,CAAC;AACJ,CAAC,CAAC;AA7DW,QAAA,wBAAwB,4BA6DnC","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,iDAAuD;AACvD,+CAI0B;AAC1B,+CAA4C;AAC5C,qCAAyC;AAEzC,MAAM,QAAQ,GAAG,mBAAQ,CAAC,WAAW,EAAE,CAAC;AAExC;;;GAGG;AACI,MAAM,yBAAyB,GAAG,KAAK,IAAI,EAAE;IAClD,MAAM,WAAW,GAAG,MAAM,IAAA,gBAAU,EAClC,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;QACjD,KAAK,MAAM,WAAW,IAAI,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,WAAW,IAAI,EAAE,CAAC,EAAE;YACvE,IAAI,WAAW,CAAC,MAAM,KAAK,oBAAoB;gBAAE,SAAS;YAC1D,IAAI;gBACF,MAAM,IAAI,GAAG,IAAA,qDAA0C,EAAC,WAAW,CAAC,MAAM,CAAC,CAAC;gBAE5E,KAAK,MAAM,EAAE,UAAU,EAAE,IAAI,WAAW,EAAE;oBACxC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,iBAAiB,CAAC;wBAAE,SAAS;oBAC7D,UAAU,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;iBAC5C;aACF;oBAAS;aACT;SACF;KACF;IAED,OAAO,UAAU,CAAC;AACpB,CAAC,CAAC;AAxBW,QAAA,yBAAyB,6BAwBpC;AAEF;;;GAGG;AACI,MAAM,iBAAiB,GAAG,KAAK,IAAI,EAAE;IAC1C,MAAM,WAAW,GAAG,MAAM,IAAA,gBAAU,EAA2B,QAAQ,EAAE,gCAAgC,CAAC,CAAC;IAE3G,MAAM,UAAU,GAAG,IAAI,GAAG,EAAkC,CAAC;IAC7D,KAAK,MAAM,YAAY,IAAI,QAAQ,CAAC,aAAa,EAAE;QACjD,KAAK,MAAM,WAAW,IAAI,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,WAAW,IAAI,EAAE,CAAC,EAAE;YACvE,IAAI,WAAW,CAAC,MAAM,KAAK,YAAY;gBAAE,SAAS;YAClD,IAAI;gBACF,MAAM,IAAI,GAAG,IAAA,6CAAkC,EAAC,WAAW,CAAC,MAAM,CAAC,CAAC;gBAEpE,KAAK,MAAM,EAAE,UAAU,EAAE,IAAI,WAAW,EAAE;oBACxC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,iBAAiB,CAAC;wBAAE,SAAS;oBAC7D,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,aAAa,EAAE;wBACzC,MAAM,SAAS,GAAG,IAAA,8BAAkB,EAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;wBAC3D,UAAU,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;qBAC3C;iBACF;aACF;oBAAS;aACT;SACF;KACF;IAED,OAAO,UAAU,CAAC;AACpB,CAAC,CAAC;AAvBW,QAAA,iBAAiB,qBAuB5B","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
+ {"version":3,"file":"discovery.js","sourceRoot":"","sources":["../../src/series-collector/discovery.ts"],"names":[],"mappings":";;;AAAA,iDAAuD;AACvD,+CAI0B;AAC1B,+CAA4C;AAC5C,qCAAyC;AAEzC,MAAM,QAAQ,GAAG,mBAAQ,CAAC,WAAW,EAAE,CAAC;AAExC;;;GAGG;AACI,MAAM,yBAAyB,GAAG,KAAK,IAAI,EAAE;IAClD,MAAM,WAAW,GAAG,MAAM,IAAA,gBAAU,EAClC,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,IAAA,qDAA0C,EAAC,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;AAxBW,QAAA,yBAAyB,6BAwBpC;AAEF;;;GAGG;AACI,MAAM,iBAAiB,GAAG,KAAK,IAAI,EAAE;IAC1C,MAAM,WAAW,GAAG,MAAM,IAAA,gBAAU,EAA2B,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,IAAA,6CAAkC,EAAC,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,IAAA,8BAAkB,EAAC,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;AAvBW,QAAA,iBAAiB,qBAuB5B","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,3 +1,2 @@
1
- /// <reference types="node" />
2
- export declare const handleIngestInterestRateForward: (product_id: string, direction: 'forward' | 'backward', signal: AbortSignal) => Promise<void>;
1
+ export declare const handleIngestInterestRateForward: (product_id: string, direction: "forward" | "backward", signal: AbortSignal) => Promise<void>;
3
2
  //# sourceMappingURL=forwards-interest-rate.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"forwards-interest-rate.d.ts","sourceRoot":"","sources":["../../src/series-collector/forwards-interest-rate.ts"],"names":[],"mappings":";AAWA,eAAO,MAAM,+BAA+B,eAC9B,MAAM,aACP,SAAS,GAAG,UAAU,UACzB,WAAW,kBA2CpB,CAAC"}
1
+ {"version":3,"file":"forwards-interest-rate.d.ts","sourceRoot":"","sources":["../../src/series-collector/forwards-interest-rate.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,+BAA+B,GAC1C,YAAY,MAAM,EAClB,WAAW,SAAS,GAAG,UAAU,EACjC,QAAQ,WAAW,kBA2CpB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"forwards-interest-rate.js","sourceRoot":"","sources":["../../src/series-collector/forwards-interest-rate.ts"],"names":[],"mappings":";;;AACA,+CAA4C;AAC5C,yCAA2C;AAC3C,+CAA+D;AAE/D,MAAM,QAAQ,GAAG,mBAAQ,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;AAElF,MAAM,+BAA+B,GAAG,KAAK,EAClD,UAAkB,EAClB,SAAiC,EACjC,MAAmB,EACnB,EAAE;;IACF,IAAI,GAA+B,CAAC;IACpC,IAAI,SAAS,KAAK,SAAS,EAAE;QAC3B,MAAM,OAAO,GAAG,MAAM,IAAA,4CAA8B,EAAC,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;KACH;SAAM;QACL,WAAW;QACX,GAAG,GAAG;YACJ,UAAU;YACV,SAAS,EAAE,UAAU;YACrB,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE;SACjB,CAAC;KACH;IAED,OAAO,CAAC,IAAI,CACV,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,0CAA0C,EAC1C,SAAS,EACT,cAAc,GAAG,CAAC,UAAU,eAAe,GAAG,CAAC,SAAS,UAAU,IAAA,kBAAU,EAAC,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,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,0CAA0C,EAC1C,QAAQ,EACR,aAAa,UAAU,oBAAoB,GAAG,CAAC,WAAW,gBAAgB,IAAA,kBAAU,EAClF,MAAA,MAAA,GAAG,CAAC,KAAK,0CAAE,UAAU,mCAAI,GAAG,CAC7B,cAAc,IAAA,kBAAU,EAAC,MAAA,MAAA,GAAG,CAAC,KAAK,0CAAE,QAAQ,mCAAI,GAAG,CAAC,EAAE,CACxD,CAAC;AACJ,CAAC,CAAC;AA9CW,QAAA,+BAA+B,mCA8C1C","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
+ {"version":3,"file":"forwards-interest-rate.js","sourceRoot":"","sources":["../../src/series-collector/forwards-interest-rate.ts"],"names":[],"mappings":";;;AACA,+CAA4C;AAC5C,yCAA2C;AAC3C,+CAA+D;AAE/D,MAAM,QAAQ,GAAG,mBAAQ,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;AAElF,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,IAAA,4CAA8B,EAAC,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,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,0CAA0C,EAC1C,SAAS,EACT,cAAc,GAAG,CAAC,UAAU,eAAe,GAAG,CAAC,SAAS,UAAU,IAAA,kBAAU,EAAC,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,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,0CAA0C,EAC1C,QAAQ,EACR,aAAa,UAAU,oBAAoB,GAAG,CAAC,WAAW,gBAAgB,IAAA,kBAAU,EAClF,MAAA,MAAA,GAAG,CAAC,KAAK,0CAAE,UAAU,mCAAI,GAAG,CAC7B,cAAc,IAAA,kBAAU,EAAC,MAAA,MAAA,GAAG,CAAC,KAAK,0CAAE,QAAQ,mCAAI,GAAG,CAAC,EAAE,CACxD,CAAC;AACJ,CAAC,CAAC;AA9CW,QAAA,+BAA+B,mCA8C1C","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,3 +1,2 @@
1
- /// <reference types="node" />
2
- export declare const handleIngestOHLCForward: (series_id: string, direction: 'forward' | 'backward', signal: AbortSignal) => Promise<void>;
1
+ export declare const handleIngestOHLCForward: (series_id: string, direction: "forward" | "backward", signal: AbortSignal) => Promise<void>;
3
2
  //# sourceMappingURL=forwards-ohlc.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"forwards-ohlc.d.ts","sourceRoot":"","sources":["../../src/series-collector/forwards-ohlc.ts"],"names":[],"mappings":";AAiBA,eAAO,MAAM,uBAAuB,cACvB,MAAM,aACN,SAAS,GAAG,UAAU,UACzB,WAAW,kBA0DpB,CAAC"}
1
+ {"version":3,"file":"forwards-ohlc.d.ts","sourceRoot":"","sources":["../../src/series-collector/forwards-ohlc.ts"],"names":[],"mappings":"AAiBA,eAAO,MAAM,uBAAuB,GAClC,WAAW,MAAM,EACjB,WAAW,SAAS,GAAG,UAAU,EACjC,QAAQ,WAAW,kBA0DpB,CAAC"}
@@ -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,iDAAuD;AAEvD,+CAA4C;AAC5C,qCAAoD;AACpD,yCAA2C;AAE3C,MAAM,QAAQ,GAAG,mBAAQ,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;AAEzE,MAAM,uBAAuB,GAAG,KAAK,EAC1C,SAAiB,EACjB,SAAiC,EACjC,MAAmB,EACnB,EAAE;;IACF,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,IAAA,8BAAkB,EAAC,SAAS,CAAC,CAAC;IAC/D,IAAI,GAAuB,CAAC;IAC5B,IAAI,SAAS,KAAK,SAAS,EAAE;QAC3B,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,IAAA,gBAAU,EAK/B,QAAQ,EACR,4DAA4D,IAAA,eAAS,EACnE,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;KACH;SAAM;QACL,WAAW;QACX,GAAG,GAAG;YACJ,UAAU;YACV,QAAQ;YACR,SAAS;YACT,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE;SACjB,CAAC;KACH;IAED,OAAO,CAAC,IAAI,CACV,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,kCAAkC,EAClC,SAAS,EACT,cAAc,GAAG,CAAC,UAAU,cAAc,GAAG,CAAC,QAAQ,eAAe,GAAG,CAAC,SAAS,UAAU,IAAA,kBAAU,EACpG,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,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,kCAAkC,EAClC,UAAU,EACV,aAAa,SAAS,oBAAoB,GAAG,CAAC,WAAW,gBAAgB,IAAA,kBAAU,EACjF,MAAA,MAAA,GAAG,CAAC,KAAK,0CAAE,UAAU,mCAAI,GAAG,CAC7B,cAAc,IAAA,kBAAU,EAAC,MAAA,MAAA,GAAG,CAAC,KAAK,0CAAE,QAAQ,mCAAI,GAAG,CAAC,EAAE,CACxD,CAAC;AACJ,CAAC,CAAC;AA7DW,QAAA,uBAAuB,2BA6DlC","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
+ {"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,iDAAuD;AAEvD,+CAA4C;AAC5C,qCAAoD;AACpD,yCAA2C;AAE3C,MAAM,QAAQ,GAAG,mBAAQ,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;AAEzE,MAAM,uBAAuB,GAAG,KAAK,EAC1C,SAAiB,EACjB,SAAiC,EACjC,MAAmB,EACnB,EAAE;;IACF,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,IAAA,8BAAkB,EAAC,SAAS,CAAC,CAAC;IAC/D,IAAI,GAAuB,CAAC;IAC5B,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,IAAA,gBAAU,EAK/B,QAAQ,EACR,4DAA4D,IAAA,eAAS,EACnE,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,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,kCAAkC,EAClC,SAAS,EACT,cAAc,GAAG,CAAC,UAAU,cAAc,GAAG,CAAC,QAAQ,eAAe,GAAG,CAAC,SAAS,UAAU,IAAA,kBAAU,EACpG,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,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,kCAAkC,EAClC,UAAU,EACV,aAAa,SAAS,oBAAoB,GAAG,CAAC,WAAW,gBAAgB,IAAA,kBAAU,EACjF,MAAA,MAAA,GAAG,CAAC,KAAK,0CAAE,UAAU,mCAAI,GAAG,CAC7B,cAAc,IAAA,kBAAU,EAAC,MAAA,MAAA,GAAG,CAAC,KAAK,0CAAE,QAAQ,mCAAI,GAAG,CAAC,EAAE,CACxD,CAAC;AACJ,CAAC,CAAC;AA7DW,QAAA,uBAAuB,2BA6DlC","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,3 +1,2 @@
1
- /// <reference types="node" />
2
- export declare const handleInterestRatePatch: (product_id: string, direction: 'forward' | 'backward', signal: AbortSignal) => Promise<void>;
1
+ export declare const handleInterestRatePatch: (product_id: string, direction: "forward" | "backward", signal: AbortSignal) => Promise<void>;
3
2
  //# sourceMappingURL=patch-interest-rate.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"patch-interest-rate.d.ts","sourceRoot":"","sources":["../../src/series-collector/patch-interest-rate.ts"],"names":[],"mappings":";AAYA,eAAO,MAAM,uBAAuB,eACtB,MAAM,aACP,SAAS,GAAG,UAAU,UACzB,WAAW,kBAmFpB,CAAC"}
1
+ {"version":3,"file":"patch-interest-rate.d.ts","sourceRoot":"","sources":["../../src/series-collector/patch-interest-rate.ts"],"names":[],"mappings":"AAYA,eAAO,MAAM,uBAAuB,GAClC,YAAY,MAAM,EAClB,WAAW,SAAS,GAAG,UAAU,EACjC,QAAQ,WAAW,kBAmFpB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"patch-interest-rate.js","sourceRoot":"","sources":["../../src/series-collector/patch-interest-rate.ts"],"names":[],"mappings":";;;AACA,+CAA4C;AAC5C,qCAAoD;AACpD,yCAA2C;AAE3C,MAAM,QAAQ,GAAG,mBAAQ,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;AAChB,MAAM,uBAAuB,GAAG,KAAK,EAC1C,UAAkB,EAClB,SAAiC,EACjC,MAAmB,EACnB,EAAE;;IACF,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,IAAA,gBAAU,EAC/B,QAAQ,EACR;;;;;;;;;;;wBAWoB,IAAA,eAAS,EAAC,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,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,wCAAwC,EACxC,SAAS,EACT,UAAU,UAAU,UAAU,IAAA,kBAAU,EAAC,YAAY,CAAC,QAAQ,IAAA,kBAAU,EAAC,UAAU,CAAC,EAAE,CACvF,CAAC;IAEF,IAAI,GAA+B,CAAC;IAEpC,IAAI,SAAS,KAAK,SAAS,EAAE;QAC3B,gBAAgB;QAChB,GAAG,GAAG;YACJ,UAAU,EAAE,UAAU;YACtB,SAAS,EAAE,SAAkB;YAC7B,IAAI,EAAE,YAAY;SACnB,CAAC;KACH;SAAM;QACL,iBAAiB;QACjB,GAAG,GAAG;YACJ,UAAU,EAAE,UAAU;YACtB,SAAS,EAAE,UAAmB;YAC9B,IAAI,EAAE,UAAU;SACjB,CAAC;KACH;IAED,OAAO,CAAC,IAAI,CACV,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,wCAAwC,EACxC,UAAU,EACV,cAAc,EACd,aAAa,GAAG,CAAC,SAAS,UAAU,IAAA,kBAAU,EAAC,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,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,wCAAwC,EACxC,UAAU,EACV,qBAAqB,EACrB,kBAAkB,GAAG,CAAC,WAAW,gBAAgB,IAAA,kBAAU,EACzD,MAAA,MAAA,GAAG,CAAC,KAAK,0CAAE,UAAU,mCAAI,GAAG,CAC7B,cAAc,IAAA,kBAAU,EAAC,MAAA,MAAA,GAAG,CAAC,KAAK,0CAAE,QAAQ,mCAAI,GAAG,CAAC,EAAE,CACxD,CAAC;AACJ,CAAC,CAAC;AAtFW,QAAA,uBAAuB,2BAsFlC","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
+ {"version":3,"file":"patch-interest-rate.js","sourceRoot":"","sources":["../../src/series-collector/patch-interest-rate.ts"],"names":[],"mappings":";;;AACA,+CAA4C;AAC5C,qCAAoD;AACpD,yCAA2C;AAE3C,MAAM,QAAQ,GAAG,mBAAQ,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;AAChB,MAAM,uBAAuB,GAAG,KAAK,EAC1C,UAAkB,EAClB,SAAiC,EACjC,MAAmB,EACnB,EAAE;;IACF,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,IAAA,gBAAU,EAC/B,QAAQ,EACR;;;;;;;;;;;wBAWoB,IAAA,eAAS,EAAC,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,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,wCAAwC,EACxC,SAAS,EACT,UAAU,UAAU,UAAU,IAAA,kBAAU,EAAC,YAAY,CAAC,QAAQ,IAAA,kBAAU,EAAC,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,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,wCAAwC,EACxC,UAAU,EACV,cAAc,EACd,aAAa,GAAG,CAAC,SAAS,UAAU,IAAA,kBAAU,EAAC,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,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,wCAAwC,EACxC,UAAU,EACV,qBAAqB,EACrB,kBAAkB,GAAG,CAAC,WAAW,gBAAgB,IAAA,kBAAU,EACzD,MAAA,MAAA,GAAG,CAAC,KAAK,0CAAE,UAAU,mCAAI,GAAG,CAC7B,cAAc,IAAA,kBAAU,EAAC,MAAA,MAAA,GAAG,CAAC,KAAK,0CAAE,QAAQ,mCAAI,GAAG,CAAC,EAAE,CACxD,CAAC;AACJ,CAAC,CAAC;AAtFW,QAAA,uBAAuB,2BAsFlC","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,3 +1,2 @@
1
- /// <reference types="node" />
2
- export declare const handleIngestOHLCPatch: (series_id: string, direction: 'forward' | 'backward', signal: AbortSignal) => Promise<void>;
1
+ export declare const handleIngestOHLCPatch: (series_id: string, direction: "forward" | "backward", signal: AbortSignal) => Promise<void>;
3
2
  //# sourceMappingURL=patch-ohlc.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"patch-ohlc.d.ts","sourceRoot":"","sources":["../../src/series-collector/patch-ohlc.ts"],"names":[],"mappings":";AAaA,eAAO,MAAM,qBAAqB,cACrB,MAAM,aACN,SAAS,GAAG,UAAU,UACzB,WAAW,kBAuFpB,CAAC"}
1
+ {"version":3,"file":"patch-ohlc.d.ts","sourceRoot":"","sources":["../../src/series-collector/patch-ohlc.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,qBAAqB,GAChC,WAAW,MAAM,EACjB,WAAW,SAAS,GAAG,UAAU,EACjC,QAAQ,WAAW,kBAuFpB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"patch-ohlc.js","sourceRoot":"","sources":["../../src/series-collector/patch-ohlc.ts"],"names":[],"mappings":";;;AAAA,iDAAuD;AAEvD,+CAA4C;AAC5C,qCAAoD;AACpD,yCAA2C;AAE3C,MAAM,QAAQ,GAAG,mBAAQ,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;AAChB,MAAM,qBAAqB,GAAG,KAAK,EACxC,SAAiB,EACjB,SAAiC,EACjC,MAAmB,EACnB,EAAE;;IACF,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,IAAA,gBAAU,EAC/B,QAAQ,EACR;;;;;;;;;;;wBAWoB,IAAA,eAAS,EAAC,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,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,gCAAgC,EAChC,SAAS,EACT,UAAU,SAAS,UAAU,IAAA,kBAAU,EAAC,YAAY,CAAC,QAAQ,IAAA,kBAAU,EAAC,UAAU,CAAC,EAAE,CACtF,CAAC;IAEF,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,IAAA,8BAAkB,EAAC,SAAS,CAAC,CAAC;IAE/D,IAAI,GAAuB,CAAC;IAE5B,IAAI,SAAS,KAAK,SAAS,EAAE;QAC3B,gBAAgB;QAChB,GAAG,GAAG;YACJ,UAAU,EAAE,UAAU;YACtB,QAAQ;YACR,SAAS,EAAE,SAAkB;YAC7B,IAAI,EAAE,YAAY;SACnB,CAAC;KACH;SAAM;QACL,iBAAiB;QACjB,GAAG,GAAG;YACJ,UAAU,EAAE,UAAU;YACtB,QAAQ;YACR,SAAS,EAAE,UAAmB;YAC9B,IAAI,EAAE,UAAU;SACjB,CAAC;KACH;IAED,OAAO,CAAC,IAAI,CACV,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,gCAAgC,EAChC,SAAS,EACT,cAAc,EACd,aAAa,GAAG,CAAC,SAAS,UAAU,IAAA,kBAAU,EAAC,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,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,gCAAgC,EAChC,SAAS,EACT,qBAAqB,EACrB,kBAAkB,GAAG,CAAC,WAAW,gBAAgB,IAAA,kBAAU,EACzD,MAAA,MAAA,GAAG,CAAC,KAAK,0CAAE,UAAU,mCAAI,GAAG,CAC7B,cAAc,IAAA,kBAAU,EAAC,MAAA,MAAA,GAAG,CAAC,KAAK,0CAAE,QAAQ,mCAAI,GAAG,CAAC,EAAE,CACxD,CAAC;AACJ,CAAC,CAAC;AA1FW,QAAA,qBAAqB,yBA0FhC","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
+ {"version":3,"file":"patch-ohlc.js","sourceRoot":"","sources":["../../src/series-collector/patch-ohlc.ts"],"names":[],"mappings":";;;AAAA,iDAAuD;AAEvD,+CAA4C;AAC5C,qCAAoD;AACpD,yCAA2C;AAE3C,MAAM,QAAQ,GAAG,mBAAQ,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;AAChB,MAAM,qBAAqB,GAAG,KAAK,EACxC,SAAiB,EACjB,SAAiC,EACjC,MAAmB,EACnB,EAAE;;IACF,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,IAAA,gBAAU,EAC/B,QAAQ,EACR;;;;;;;;;;;wBAWoB,IAAA,eAAS,EAAC,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,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,gCAAgC,EAChC,SAAS,EACT,UAAU,SAAS,UAAU,IAAA,kBAAU,EAAC,YAAY,CAAC,QAAQ,IAAA,kBAAU,EAAC,UAAU,CAAC,EAAE,CACtF,CAAC;IAEF,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,IAAA,8BAAkB,EAAC,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,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,gCAAgC,EAChC,SAAS,EACT,cAAc,EACd,aAAa,GAAG,CAAC,SAAS,UAAU,IAAA,kBAAU,EAAC,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,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,gCAAgC,EAChC,SAAS,EACT,qBAAqB,EACrB,kBAAkB,GAAG,CAAC,WAAW,gBAAgB,IAAA,kBAAU,EACzD,MAAA,MAAA,GAAG,CAAC,KAAK,0CAAE,UAAU,mCAAI,GAAG,CAC7B,cAAc,IAAA,kBAAU,EAAC,MAAA,MAAA,GAAG,CAAC,KAAK,0CAAE,QAAQ,mCAAI,GAAG,CAAC,EAAE,CACxD,CAAC;AACJ,CAAC,CAAC;AA1FW,QAAA,qBAAqB,yBA0FhC","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,yCAAoE;AACpE,uEAA6E;AAC7E,qDAA4D;AAC5D,2CAA2E;AAC3E,qEAA2E;AAC3E,mDAA0D;AAC1D,+DAAgE;AAChE,6CAAqD;AAErD,MAAM,GAAG,GAAG;IACV,IAAI,EAAE;QACJ,IAAI,EAAE,6BAAiB;QACvB,OAAO,EAAE,uCAAuB;QAChC,QAAQ,EAAE,yCAAwB;QAClC,KAAK,EAAE,kCAAqB;KAC7B;IACD,YAAY,EAAE;QACZ,IAAI,EAAE,qCAAyB;QAC/B,OAAO,EAAE,wDAA+B;QACxC,QAAQ,EAAE,0DAAgC;QAC1C,KAAK,EAAE,6CAAuB;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;QACpD,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC;QAC5B,KAAK,MAAM,IAAI,IAAI,CAAC,SAAS,EAAE,UAAU,EAAE,OAAO,CAAU,EAAE;YAC5D,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;YAChC,CAAC,KAAK,IAAI,EAAE;gBACV,OAAO,IAAI,EAAE;oBACX,MAAM,IAAA,mBAAW,EAAC,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;oBACxD,IAAI;wBACF,MAAM,KAAK,GAAG,MAAM,IAAI,EAAE,CAAC;wBAE3B,qEAAqE;wBACrE,MAAM,MAAM,GAAG,IAAI,GAAG,EAA8C,CAAC;wBACrE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;4BACxB,MAAM,CAAC,aAAa,CAAC,GAAG,IAAA,kBAAU,EAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;4BAC5C,IAAI,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;4BACtC,IAAI,CAAC,KAAK,EAAE;gCACV,KAAK,GAAG,EAAE,CAAC;gCACX,MAAM,CAAC,GAAG,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;6BAClC;4BACD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;yBAClB;wBAED,MAAM,OAAO,CAAC,GAAG,CACf,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,aAAa,EAAE,KAAK,CAAC,EAAE,EAAE;4BAChE,KAAK,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC,IAAI,KAAK,EAAE;gCAC1C,MAAM,IAAA,mBAAW,EAAC,GAAG,IAAI,IAAI,IAAI,IAAI,aAAa,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;gCACzE,MAAM,OAAO,CAAC,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;oCACxD,OAAO,CAAC,IAAI,CACV,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,qBAAqB,IAAI,KAAK,IAAI,GAAG,EACrC,SAAS,EACT,OAAO,EACP,GAAG,CACJ,CAAC;gCACJ,CAAC,CAAC,CAAC;6BACJ;wBACH,CAAC,CAAC,CACH,CAAC;qBACH;oBAAC,OAAO,CAAC,EAAE,GAAE;iBACf;YACH,CAAC,CAAC,EAAE,CAAC;SACN;KACF;AACH,CAAC,CAAC,EAAE,CAAC","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
+ {"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":"sql-helpers.d.ts","sourceRoot":"","sources":["../../src/series-collector/sql-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAG5C;;;;;GAKG;AACH,eAAO,MAAM,8BAA8B,aAAc,QAAQ,cAAc,MAAM,oBAUxC,CAAC;AAE9C,eAAO,MAAM,iCAAiC,aAAc,QAAQ,cAAc,MAAM,oBAUzC,CAAC;AAEhD,eAAO,MAAM,sBAAsB,aAAc,QAAQ,aAAa,MAAM,oBAU/B,CAAC"}
1
+ {"version":3,"file":"sql-helpers.d.ts","sourceRoot":"","sources":["../../src/series-collector/sql-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAG5C;;;;;GAKG;AACH,eAAO,MAAM,8BAA8B,GAAI,UAAU,QAAQ,EAAE,YAAY,MAAM,oBAUxC,CAAC;AAE9C,eAAO,MAAM,iCAAiC,GAAI,UAAU,QAAQ,EAAE,YAAY,MAAM,oBAUzC,CAAC;AAEhD,eAAO,MAAM,sBAAsB,GAAI,UAAU,QAAQ,EAAE,WAAW,MAAM,oBAU/B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"fifo-queue.d.ts","sourceRoot":"","sources":["../../src/series-data/fifo-queue.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,MAAM,CAAC,CAAC;IACvB,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;IAC7B,IAAI,EAAE,MAAM,MAAM,CAAC;IACnB,QAAQ,EAAE,CAAC,KAAK,CAAC,EAAE,MAAM,KAAK,CAAC,EAAE,CAAC;CACnC;AAED,eAAO,MAAM,eAAe,oBAuB3B,CAAC"}
1
+ {"version":3,"file":"fifo-queue.d.ts","sourceRoot":"","sources":["../../src/series-data/fifo-queue.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,MAAM,CAAC,CAAC;IACvB,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;IAC7B,IAAI,EAAE,MAAM,MAAM,CAAC;IACnB,QAAQ,EAAE,CAAC,KAAK,CAAC,EAAE,MAAM,KAAK,CAAC,EAAE,CAAC;CACnC;AAED,eAAO,MAAM,eAAe,GAAI,CAAC,OAAK,MAAM,CAAC,CAAC,CAuB7C,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"fifo-queue.js","sourceRoot":"","sources":["../../src/series-data/fifo-queue.ts"],"names":[],"mappings":";;;AAOO,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;gBAC1C,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC1B,IAAI,GAAG,CAAC,CAAC;aACV;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;AAvBW,QAAA,eAAe,mBAuB1B","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
+ {"version":3,"file":"fifo-queue.js","sourceRoot":"","sources":["../../src/series-data/fifo-queue.ts"],"names":[],"mappings":";;;AAOO,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;AAvBW,QAAA,eAAe,mBAuB1B","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"]}