@zk-tech/bedrock 0.1.5 → 0.2.1-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assert/index.cjs +9 -9
- package/dist/assert/index.cjs.map +1 -1
- package/dist/assert/index.d.cts +5 -5
- package/dist/assert/index.d.ts +5 -5
- package/dist/assert/index.js +6 -6
- package/dist/assert/index.js.map +1 -1
- package/dist/async/index.cjs +2 -2
- package/dist/async/index.cjs.map +1 -1
- package/dist/async/index.js +2 -2
- package/dist/async/index.js.map +1 -1
- package/dist/cache/index.cjs.map +1 -1
- package/dist/cache/index.js.map +1 -1
- package/dist/di/index.cjs +26 -26
- package/dist/di/index.cjs.map +1 -1
- package/dist/di/index.js +26 -26
- package/dist/di/index.js.map +1 -1
- package/dist/dispose/index.cjs +3 -3
- package/dist/dispose/index.cjs.map +1 -1
- package/dist/dispose/index.js +3 -3
- package/dist/dispose/index.js.map +1 -1
- package/dist/error/index.cjs +18 -18
- package/dist/error/index.cjs.map +1 -1
- package/dist/error/index.d.cts +2 -2
- package/dist/error/index.d.ts +2 -2
- package/dist/error/index.js +18 -18
- package/dist/error/index.js.map +1 -1
- package/dist/event/index.cjs +3 -3
- package/dist/event/index.cjs.map +1 -1
- package/dist/event/index.js +3 -3
- package/dist/event/index.js.map +1 -1
- package/dist/json/index.cjs +3 -3
- package/dist/json/index.cjs.map +1 -1
- package/dist/json/index.js +3 -3
- package/dist/json/index.js.map +1 -1
- package/dist/launch/index.cjs +5 -5
- package/dist/launch/index.cjs.map +1 -1
- package/dist/launch/index.js +5 -5
- package/dist/launch/index.js.map +1 -1
- package/dist/lock/index.cjs +14 -14
- package/dist/lock/index.cjs.map +1 -1
- package/dist/lock/index.js +14 -14
- package/dist/lock/index.js.map +1 -1
- package/dist/objects/index.cjs +3 -3
- package/dist/objects/index.cjs.map +1 -1
- package/dist/objects/index.js +3 -3
- package/dist/objects/index.js.map +1 -1
- package/dist/promise/index.cjs +8 -8
- package/dist/promise/index.cjs.map +1 -1
- package/dist/promise/index.js +8 -8
- package/dist/promise/index.js.map +1 -1
- package/dist/scheduler/index.cjs +15 -15
- package/dist/scheduler/index.cjs.map +1 -1
- package/dist/scheduler/index.d.cts +5 -5
- package/dist/scheduler/index.d.ts +5 -5
- package/dist/scheduler/index.js +13 -13
- package/dist/scheduler/index.js.map +1 -1
- package/dist/sprintf/index.cjs +4 -4
- package/dist/sprintf/index.cjs.map +1 -1
- package/dist/sprintf/index.js +4 -4
- package/dist/sprintf/index.js.map +1 -1
- package/dist/undo-redo-stack/index.cjs.map +1 -1
- package/dist/undo-redo-stack/index.js.map +1 -1
- package/dist/worker/index.cjs +7 -7
- package/dist/worker/index.cjs.map +1 -1
- package/dist/worker/index.d.cts +1 -1
- package/dist/worker/index.d.ts +1 -1
- package/dist/worker/index.js +7 -7
- package/dist/worker/index.js.map +1 -1
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/assert/assert.ts","../../src/launch/abstract-job.ts","../../src/di/base.ts","../../src/di/instantiation-service.interface.ts","../../src/launch/cost-recorder.ts","../../src/launch/job-scheduler.ts"],"names":["JobScheduler"],"mappings":"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","file":"index.cjs","sourcesContent":["function abort(reason: string): never {\n throw new Error(`lvAssert(${reason})`);\n}\n\n/**\n * 断言表达式为真\n * @param expr \n * @param reason \n */\nexport function lvAssert(expr: unknown, reason?: string): asserts expr {\n if (!expr) {\n abort(reason ?? '#expr is false');\n }\n}\n\n/**\n * 断言deadcode路径\n * @param reason \n */\nexport function lvAssertNotHere(reason?: string): never {\n abort(reason ?? 'unreachable code flow');\n}\n\n/**\n * 断言类型不可达\n * @param member \n * @param message \n */\nexport function lvAssertNever(member: never, message = 'Illegal value:'): never {\n abort(`${message}: ${member}`);\n}\n\n/**\n * 断言变量为null或者undefined\n * @param val \n * @param reason \n */\nexport function lvAssertNotNil<T>(val: T, reason?: string): asserts val is NonNullable<T> {\n if (val === null || val === undefined) {\n abort(reason ?? '#val is nil');\n }\n}\n","import { Barrier } from '@/async';\n\nexport abstract class AbstractJob<T, K extends T = T> {\n protected abstract _name: string;\n protected _store: Map<K, Barrier[]> = new Map();\n\n get name() {\n return this._name;\n }\n\n shouldWait(phase: K) {\n const barriers = this._store.get(phase);\n if (!barriers?.length) {\n return false;\n }\n return true;\n }\n\n wait(phase: K): Promise<void> {\n try {\n const barriers = this._store.get(phase);\n if (!barriers?.length) {\n return Promise.resolve();\n }\n return Promise.all(barriers.map((barrier) => barrier.wait())) as unknown as Promise<void>;\n } finally {\n // 执行之后就清空,确保失败或cancel态时可以重复 prepare.\n this._store.delete(phase);\n }\n }\n\n prepare(phase: K) {\n this._executePhase(phase);\n }\n\n protected _setBarrier(phase: K, barrier: Barrier) {\n if (!this._store.has(phase)) {\n this._store.set(phase, []);\n }\n const barriers = this._store.get(phase)!;\n barriers.push(barrier);\n }\n\n protected abstract _executePhase(phase: K): void;\n}\n","// service特征标识\nexport type BrandedService = { _serviceBrand: undefined };\n\n//\n// 服务唯一标识符(编译时生成)\n// 需要DI进行注入的服务必须拥有该标识符\n// 本质上是一个参数装饰器\n//\nexport interface ServiceIdentifier<T> {\n (...args: any[]): void;\n type: T;\n}\n\n// 获取服务的视图接口\nexport interface ServicesAccessor {\n get: <T>(id: ServiceIdentifier<T>) => T;\n}\n\n// 服务唯一标识符存储\nconst serviceIds = new Map<string, ServiceIdentifier<any>>();\n\nexport const DI_TARGET = '$di$target';\nexport const DI_DEPENDENCIES = '$di$dependencies';\n\n// 获取某个服务的依赖\n// 因为服务依赖关系会存放在构造函数的属性上\nexport function getServiceDependencies(ctor: any): { id: ServiceIdentifier<any>; index: number }[] {\n return ctor[DI_DEPENDENCIES] || [];\n}\n\n// 更新服务依赖依赖关系\nfunction setServiceDependency(id: ServiceIdentifier<any>, ctor: any, index: number): void {\n if (ctor[DI_TARGET] === ctor) {\n ctor[DI_DEPENDENCIES].push({ id, index });\n } else {\n ctor[DI_DEPENDENCIES] = [{ id, index }];\n ctor[DI_TARGET] = ctor;\n }\n}\n\n//\n// 创建服务唯一标识符\n// 传入服务ID,返回一个参数装饰器\n// 参数装饰器会记录A需要\n// const IFooServiceId = createDecorator<FooService>('FooService');\n//\n// class Bar\n// constructor(@IFooServiceId a: IFooService) // IFooService是接口声明\n//\nexport function createDecorator<T>(serviceId: string): ServiceIdentifier<T> {\n if (serviceIds.has(serviceId)) {\n return serviceIds.get(serviceId)!;\n }\n\n const id = function (target: any, key: string, index: number): any {\n if (arguments.length !== 3) {\n throw new Error('@IServiceName-decorator can only be used to decorate a parameter');\n }\n setServiceDependency(id, target, index);\n } as any;\n\n id.toString = () => serviceId;\n\n serviceIds.set(serviceId, id);\n return id;\n}\n\n// TODO(niurouwan): 补一下注释和例子\nexport function refineServiceDecorator<T1, T extends T1>(\n serviceIdentifier: ServiceIdentifier<T1>,\n): ServiceIdentifier<T> {\n return serviceIdentifier as ServiceIdentifier<T>;\n}\n","import type { BrandedService, ServicesAccessor } from './base';\nimport { createDecorator } from './base';\nimport type { SyncDescriptor0 } from './descriptor';\nimport type { ServiceCollection } from './service-collection';\n\nexport type GetLeadingNonServiceArgs<TArgs extends any[]> = TArgs extends []\n ? []\n : TArgs extends [...infer TFirst, BrandedService]\n ? GetLeadingNonServiceArgs<TFirst>\n : TArgs;\n\nexport interface IInstantiationService {\n readonly _serviceBrand: undefined;\n\n /**\n * Synchronously creates an instance that is denoted by the descriptor\n */\n createInstance: {\n <T>(descriptor: SyncDescriptor0<T>): T;\n <Ctor extends new (...args: any[]) => any, R extends InstanceType<Ctor>>(\n ctor: Ctor,\n ...args: GetLeadingNonServiceArgs<ConstructorParameters<Ctor>>\n ): R;\n };\n\n /**\n * Calls a function with a service accessor.\n */\n invokeFunction: <R, TS extends any[] = []>(\n fn: (accessor: ServicesAccessor, ...args: TS) => R,\n ...args: TS\n ) => R;\n\n /**\n * Creates a child of this service which inherits all current services\n * and adds/overwrites the given services.\n */\n createChild: (services: ServiceCollection) => IInstantiationService;\n\n /**\n * 生命周期归属该DI上下文的服务进行销毁\n */\n dispose: () => void;\n}\n\nexport const IInstantiationService = createDecorator<IInstantiationService>('instantiation');\n","// lifecycle -> cost\n// 启动流程lifecycle某个阶段对应的耗时\ntype Trace = Record<string | number, number>;\n\nexport class CostRecorder {\n // 每个job在不同阶段的耗时\n private _jobCost: Record<string, Trace> = {};\n\n record(jobName: string, lifecycle: string | number, cost: number) {\n if (!this._jobCost[jobName]) {\n this._jobCost[jobName] = {};\n }\n if (!this._jobCost[jobName][lifecycle]) {\n this._jobCost[jobName][lifecycle] = 0;\n }\n this._jobCost[jobName][lifecycle] += cost;\n }\n\n toString() {\n return JSON.stringify(this._jobCost);\n }\n}\n","import { IInstantiationService, type GetLeadingNonServiceArgs } from '@/di';\nimport { lvAssert, lvAssertNotHere } from '@/assert';\nimport type { AbstractJob } from './abstract-job';\nimport { CostRecorder } from './cost-recorder';\n\nclass JobDescriptor<T, K extends T> {\n readonly ctor: new (...args: any[]) => AbstractJob<T, K>;\n readonly staticArguments: any[];\n\n constructor(ctor: new (...args: any[]) => AbstractJob<T, K>, args: any[]) {\n this.ctor = ctor;\n this.staticArguments = args;\n }\n}\n\nexport class JobScheduler<T, K extends T = T> {\n private readonly _jobPools: Map<string, AbstractJob<T, K>> = new Map();\n private readonly _costRecorder = new CostRecorder();\n private readonly _unconstructedJobs: Map<K, JobDescriptor<AbstractJob<T, K>, any>[]> = new Map();\n\n constructor(\n private _currentPhase: K,\n @IInstantiationService private readonly _instantiationService: IInstantiationService,\n ) {}\n\n get currentPhase() {\n return this._currentPhase;\n }\n\n /**\n * 按需添加一个job,job会在phase时刻才进行实例化\n * @param phase job实例化时机\n * @param ctor job构造函数\n * @param args job构造静态参数\n */\n registerJob<Ctor extends new (...args: any[]) => AbstractJob<T, K>>(\n phase: K,\n ctor: Ctor,\n ...args: GetLeadingNonServiceArgs<ConstructorParameters<Ctor>>\n ) {\n if (!this._unconstructedJobs.has(phase)) {\n this._unconstructedJobs.set(phase, [new JobDescriptor(ctor, args)]);\n } else {\n this._unconstructedJobs.get(phase)!.push(new JobDescriptor(ctor, args));\n }\n }\n\n /**\n * 添加一个构造好的job\n * @param job 任务\n */\n addJob(job: AbstractJob<T, K>) {\n lvAssert(!this._jobPools.has(job.name), 'cant duplicate add job.');\n this._jobPools.set(job.name, job);\n }\n\n removeJob(jobName: string) {\n this._jobPools.delete(jobName);\n }\n\n prepare(phase: K) {\n const descriptors = this._unconstructedJobs.get(phase) ?? [];\n for (const d of descriptors) {\n this.addJob(this._instantiationService.createInstance(d.ctor, ...d.staticArguments));\n }\n let shouldWait = false;\n this._unconstructedJobs.delete(phase);\n for (const [, job] of this._jobPools) {\n const start = Date.now();\n job.prepare(phase);\n this._costRecorder.record(job.name, phase as number | string, Date.now() - start);\n\n if (job.shouldWait(phase)) {\n shouldWait = true;\n }\n }\n\n return shouldWait;\n }\n\n getCost() {\n return this._costRecorder.toString();\n }\n\n /**\n * 推进到目标阶段,要求目标阶段没有需要等待的任务\n * @param phase 目标阶段\n */\n advanceToPhase(phase: K) {\n for (const [, job] of this._jobPools) {\n if (job.shouldWait(phase)) {\n lvAssertNotHere(`exists job should wait, job name: ${job.name}, phase: ${phase}`);\n }\n }\n\n this._currentPhase = phase;\n }\n\n async wait(phase: K) {\n const jobPromises: Promise<void>[] = [];\n for (const [, job] of this._jobPools) {\n if (!job.shouldWait(phase)) {\n continue;\n }\n jobPromises.push(\n (() => {\n const start = Date.now();\n return job.wait(phase).then(() => {\n this._costRecorder.record(job.name, phase as number | string, Date.now() - start);\n });\n })(),\n );\n }\n\n await Promise.all(jobPromises);\n this._currentPhase = phase;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/assert/assert.ts","../../src/launch/abstract-job.ts","../../src/di/base.ts","../../src/di/instantiation-service.interface.ts","../../src/launch/cost-recorder.ts","../../src/launch/job-scheduler.ts"],"names":["JobScheduler"],"mappings":"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","file":"index.cjs","sourcesContent":["function abort(reason: string): never {\n throw new Error(`zkAssert(${reason})`);\n}\n\n/**\n * 断言表达式为真\n * @param expr \n * @param reason \n */\nexport function zkAssert(expr: unknown, reason?: string): asserts expr {\n if (!expr) {\n abort(reason ?? '#expr is false');\n }\n}\n\n/**\n * 断言deadcode路径\n * @param reason \n */\nexport function zkAssertNotHere(reason?: string): never {\n abort(reason ?? 'unreachable code flow');\n}\n\n/**\n * 断言类型不可达\n * @param member \n * @param message \n */\nexport function zkAssertNever(member: never, message = 'Illegal value:'): never {\n abort(`${message}: ${member}`);\n}\n\n/**\n * 断言变量为null或者undefined\n * @param val \n * @param reason \n */\nexport function zkAssertNotNil<T>(val: T, reason?: string): asserts val is NonNullable<T> {\n if (val === null || val === undefined) {\n abort(reason ?? '#val is nil');\n }\n}\n","import { Barrier } from '@/async';\n\nexport abstract class AbstractJob<T, K extends T = T> {\n protected abstract _name: string;\n protected _store: Map<K, Barrier[]> = new Map();\n\n get name() {\n return this._name;\n }\n\n shouldWait(phase: K) {\n const barriers = this._store.get(phase);\n if (!barriers?.length) {\n return false;\n }\n return true;\n }\n\n wait(phase: K): Promise<void> {\n try {\n const barriers = this._store.get(phase);\n if (!barriers?.length) {\n return Promise.resolve();\n }\n return Promise.all(barriers.map((barrier) => barrier.wait())) as unknown as Promise<void>;\n } finally {\n // 执行之后就清空,确保失败或cancel态时可以重复 prepare.\n this._store.delete(phase);\n }\n }\n\n prepare(phase: K) {\n this._executePhase(phase);\n }\n\n protected _setBarrier(phase: K, barrier: Barrier) {\n if (!this._store.has(phase)) {\n this._store.set(phase, []);\n }\n const barriers = this._store.get(phase)!;\n barriers.push(barrier);\n }\n\n protected abstract _executePhase(phase: K): void;\n}\n","// service特征标识\nexport type BrandedService = { _serviceBrand: undefined };\n\n//\n// 服务唯一标识符(编译时生成)\n// 需要DI进行注入的服务必须拥有该标识符\n// 本质上是一个参数装饰器\n//\nexport interface ServiceIdentifier<T> {\n (...args: any[]): void;\n type: T;\n}\n\n// 获取服务的视图接口\nexport interface ServicesAccessor {\n get: <T>(id: ServiceIdentifier<T>) => T;\n}\n\n// 服务唯一标识符存储\nconst serviceIds = new Map<string, ServiceIdentifier<any>>();\n\nexport const DI_TARGET = '$di$target';\nexport const DI_DEPENDENCIES = '$di$dependencies';\n\n// 获取某个服务的依赖\n// 因为服务依赖关系会存放在构造函数的属性上\nexport function getServiceDependencies(ctor: any): { id: ServiceIdentifier<any>; index: number }[] {\n return ctor[DI_DEPENDENCIES] || [];\n}\n\n// 更新服务依赖依赖关系\nfunction setServiceDependency(id: ServiceIdentifier<any>, ctor: any, index: number): void {\n if (ctor[DI_TARGET] === ctor) {\n ctor[DI_DEPENDENCIES].push({ id, index });\n } else {\n ctor[DI_DEPENDENCIES] = [{ id, index }];\n ctor[DI_TARGET] = ctor;\n }\n}\n\n//\n// 创建服务唯一标识符\n// 传入服务ID,返回一个参数装饰器\n// 参数装饰器会记录A需要\n// const IFooServiceId = createDecorator<FooService>('FooService');\n//\n// class Bar\n// constructor(@IFooServiceId a: IFooService) // IFooService是接口声明\n//\nexport function createDecorator<T>(serviceId: string): ServiceIdentifier<T> {\n if (serviceIds.has(serviceId)) {\n return serviceIds.get(serviceId)!;\n }\n\n const id = function (target: any, key: string, index: number): any {\n if (arguments.length !== 3) {\n throw new Error('@IServiceName-decorator can only be used to decorate a parameter');\n }\n setServiceDependency(id, target, index);\n } as any;\n\n id.toString = () => serviceId;\n\n serviceIds.set(serviceId, id);\n return id;\n}\n\n// TODO(niurouwan): 补一下注释和例子\nexport function refineServiceDecorator<T1, T extends T1>(\n serviceIdentifier: ServiceIdentifier<T1>,\n): ServiceIdentifier<T> {\n return serviceIdentifier as ServiceIdentifier<T>;\n}\n","import type { BrandedService, ServicesAccessor } from './base';\nimport { createDecorator } from './base';\nimport type { SyncDescriptor0 } from './descriptor';\nimport type { ServiceCollection } from './service-collection';\n\nexport type GetLeadingNonServiceArgs<TArgs extends any[]> = TArgs extends []\n ? []\n : TArgs extends [...infer TFirst, BrandedService]\n ? GetLeadingNonServiceArgs<TFirst>\n : TArgs;\n\nexport interface IInstantiationService {\n readonly _serviceBrand: undefined;\n\n /**\n * Synchronously creates an instance that is denoted by the descriptor\n */\n createInstance: {\n <T>(descriptor: SyncDescriptor0<T>): T;\n <Ctor extends new (...args: any[]) => any, R extends InstanceType<Ctor>>(\n ctor: Ctor,\n ...args: GetLeadingNonServiceArgs<ConstructorParameters<Ctor>>\n ): R;\n };\n\n /**\n * Calls a function with a service accessor.\n */\n invokeFunction: <R, TS extends any[] = []>(\n fn: (accessor: ServicesAccessor, ...args: TS) => R,\n ...args: TS\n ) => R;\n\n /**\n * Creates a child of this service which inherits all current services\n * and adds/overwrites the given services.\n */\n createChild: (services: ServiceCollection) => IInstantiationService;\n\n /**\n * 生命周期归属该DI上下文的服务进行销毁\n */\n dispose: () => void;\n}\n\nexport const IInstantiationService = createDecorator<IInstantiationService>('instantiation');\n","// lifecycle -> cost\n// 启动流程lifecycle某个阶段对应的耗时\ntype Trace = Record<string | number, number>;\n\nexport class CostRecorder {\n // 每个job在不同阶段的耗时\n private _jobCost: Record<string, Trace> = {};\n\n record(jobName: string, lifecycle: string | number, cost: number) {\n if (!this._jobCost[jobName]) {\n this._jobCost[jobName] = {};\n }\n if (!this._jobCost[jobName][lifecycle]) {\n this._jobCost[jobName][lifecycle] = 0;\n }\n this._jobCost[jobName][lifecycle] += cost;\n }\n\n toString() {\n return JSON.stringify(this._jobCost);\n }\n}\n","import { IInstantiationService, type GetLeadingNonServiceArgs } from '@/di';\nimport { zkAssert, zkAssertNotHere } from '@/assert';\nimport type { AbstractJob } from './abstract-job';\nimport { CostRecorder } from './cost-recorder';\n\nclass JobDescriptor<T, K extends T> {\n readonly ctor: new (...args: any[]) => AbstractJob<T, K>;\n readonly staticArguments: any[];\n\n constructor(ctor: new (...args: any[]) => AbstractJob<T, K>, args: any[]) {\n this.ctor = ctor;\n this.staticArguments = args;\n }\n}\n\nexport class JobScheduler<T, K extends T = T> {\n private readonly _jobPools: Map<string, AbstractJob<T, K>> = new Map();\n private readonly _costRecorder = new CostRecorder();\n private readonly _unconstructedJobs: Map<K, JobDescriptor<AbstractJob<T, K>, any>[]> = new Map();\n\n constructor(\n private _currentPhase: K,\n @IInstantiationService private readonly _instantiationService: IInstantiationService,\n ) {}\n\n get currentPhase() {\n return this._currentPhase;\n }\n\n /**\n * 按需添加一个job,job会在phase时刻才进行实例化\n * @param phase job实例化时机\n * @param ctor job构造函数\n * @param args job构造静态参数\n */\n registerJob<Ctor extends new (...args: any[]) => AbstractJob<T, K>>(\n phase: K,\n ctor: Ctor,\n ...args: GetLeadingNonServiceArgs<ConstructorParameters<Ctor>>\n ) {\n if (!this._unconstructedJobs.has(phase)) {\n this._unconstructedJobs.set(phase, [new JobDescriptor(ctor, args)]);\n } else {\n this._unconstructedJobs.get(phase)!.push(new JobDescriptor(ctor, args));\n }\n }\n\n /**\n * 添加一个构造好的job\n * @param job 任务\n */\n addJob(job: AbstractJob<T, K>) {\n zkAssert(!this._jobPools.has(job.name), 'cant duplicate add job.');\n this._jobPools.set(job.name, job);\n }\n\n removeJob(jobName: string) {\n this._jobPools.delete(jobName);\n }\n\n prepare(phase: K) {\n const descriptors = this._unconstructedJobs.get(phase) ?? [];\n for (const d of descriptors) {\n this.addJob(this._instantiationService.createInstance(d.ctor, ...d.staticArguments));\n }\n let shouldWait = false;\n this._unconstructedJobs.delete(phase);\n for (const [, job] of this._jobPools) {\n const start = Date.now();\n job.prepare(phase);\n this._costRecorder.record(job.name, phase as number | string, Date.now() - start);\n\n if (job.shouldWait(phase)) {\n shouldWait = true;\n }\n }\n\n return shouldWait;\n }\n\n getCost() {\n return this._costRecorder.toString();\n }\n\n /**\n * 推进到目标阶段,要求目标阶段没有需要等待的任务\n * @param phase 目标阶段\n */\n advanceToPhase(phase: K) {\n for (const [, job] of this._jobPools) {\n if (job.shouldWait(phase)) {\n zkAssertNotHere(`exists job should wait, job name: ${job.name}, phase: ${phase}`);\n }\n }\n\n this._currentPhase = phase;\n }\n\n async wait(phase: K) {\n const jobPromises: Promise<void>[] = [];\n for (const [, job] of this._jobPools) {\n if (!job.shouldWait(phase)) {\n continue;\n }\n jobPromises.push(\n (() => {\n const start = Date.now();\n return job.wait(phase).then(() => {\n this._costRecorder.record(job.name, phase as number | string, Date.now() - start);\n });\n })(),\n );\n }\n\n await Promise.all(jobPromises);\n this._currentPhase = phase;\n }\n}\n"]}
|
package/dist/launch/index.js
CHANGED
|
@@ -10,14 +10,14 @@ var __decorateParam = (index, decorator) => (target, key) => decorator(target, k
|
|
|
10
10
|
|
|
11
11
|
// src/assert/assert.ts
|
|
12
12
|
function abort(reason) {
|
|
13
|
-
throw new Error(`
|
|
13
|
+
throw new Error(`zkAssert(${reason})`);
|
|
14
14
|
}
|
|
15
|
-
function
|
|
15
|
+
function zkAssert(expr, reason) {
|
|
16
16
|
if (!expr) {
|
|
17
17
|
abort(reason);
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
|
-
function
|
|
20
|
+
function zkAssertNotHere(reason) {
|
|
21
21
|
abort(reason ?? "unreachable code flow");
|
|
22
22
|
}
|
|
23
23
|
|
|
@@ -145,7 +145,7 @@ var JobScheduler = class {
|
|
|
145
145
|
* @param job 任务
|
|
146
146
|
*/
|
|
147
147
|
addJob(job) {
|
|
148
|
-
|
|
148
|
+
zkAssert(!this._jobPools.has(job.name), "cant duplicate add job.");
|
|
149
149
|
this._jobPools.set(job.name, job);
|
|
150
150
|
}
|
|
151
151
|
removeJob(jobName) {
|
|
@@ -178,7 +178,7 @@ var JobScheduler = class {
|
|
|
178
178
|
advanceToPhase(phase) {
|
|
179
179
|
for (const [, job] of this._jobPools) {
|
|
180
180
|
if (job.shouldWait(phase)) {
|
|
181
|
-
|
|
181
|
+
zkAssertNotHere(`exists job should wait, job name: ${job.name}, phase: ${phase}`);
|
|
182
182
|
}
|
|
183
183
|
}
|
|
184
184
|
this._currentPhase = phase;
|
package/dist/launch/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/assert/assert.ts","../../src/launch/abstract-job.ts","../../src/di/base.ts","../../src/di/instantiation-service.interface.ts","../../src/launch/cost-recorder.ts","../../src/launch/job-scheduler.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["function abort(reason: string): never {\n throw new Error(`lvAssert(${reason})`);\n}\n\n/**\n * 断言表达式为真\n * @param expr \n * @param reason \n */\nexport function lvAssert(expr: unknown, reason?: string): asserts expr {\n if (!expr) {\n abort(reason ?? '#expr is false');\n }\n}\n\n/**\n * 断言deadcode路径\n * @param reason \n */\nexport function lvAssertNotHere(reason?: string): never {\n abort(reason ?? 'unreachable code flow');\n}\n\n/**\n * 断言类型不可达\n * @param member \n * @param message \n */\nexport function lvAssertNever(member: never, message = 'Illegal value:'): never {\n abort(`${message}: ${member}`);\n}\n\n/**\n * 断言变量为null或者undefined\n * @param val \n * @param reason \n */\nexport function lvAssertNotNil<T>(val: T, reason?: string): asserts val is NonNullable<T> {\n if (val === null || val === undefined) {\n abort(reason ?? '#val is nil');\n }\n}\n","import { Barrier } from '@/async';\n\nexport abstract class AbstractJob<T, K extends T = T> {\n protected abstract _name: string;\n protected _store: Map<K, Barrier[]> = new Map();\n\n get name() {\n return this._name;\n }\n\n shouldWait(phase: K) {\n const barriers = this._store.get(phase);\n if (!barriers?.length) {\n return false;\n }\n return true;\n }\n\n wait(phase: K): Promise<void> {\n try {\n const barriers = this._store.get(phase);\n if (!barriers?.length) {\n return Promise.resolve();\n }\n return Promise.all(barriers.map((barrier) => barrier.wait())) as unknown as Promise<void>;\n } finally {\n // 执行之后就清空,确保失败或cancel态时可以重复 prepare.\n this._store.delete(phase);\n }\n }\n\n prepare(phase: K) {\n this._executePhase(phase);\n }\n\n protected _setBarrier(phase: K, barrier: Barrier) {\n if (!this._store.has(phase)) {\n this._store.set(phase, []);\n }\n const barriers = this._store.get(phase)!;\n barriers.push(barrier);\n }\n\n protected abstract _executePhase(phase: K): void;\n}\n","// service特征标识\nexport type BrandedService = { _serviceBrand: undefined };\n\n//\n// 服务唯一标识符(编译时生成)\n// 需要DI进行注入的服务必须拥有该标识符\n// 本质上是一个参数装饰器\n//\nexport interface ServiceIdentifier<T> {\n (...args: any[]): void;\n type: T;\n}\n\n// 获取服务的视图接口\nexport interface ServicesAccessor {\n get: <T>(id: ServiceIdentifier<T>) => T;\n}\n\n// 服务唯一标识符存储\nconst serviceIds = new Map<string, ServiceIdentifier<any>>();\n\nexport const DI_TARGET = '$di$target';\nexport const DI_DEPENDENCIES = '$di$dependencies';\n\n// 获取某个服务的依赖\n// 因为服务依赖关系会存放在构造函数的属性上\nexport function getServiceDependencies(ctor: any): { id: ServiceIdentifier<any>; index: number }[] {\n return ctor[DI_DEPENDENCIES] || [];\n}\n\n// 更新服务依赖依赖关系\nfunction setServiceDependency(id: ServiceIdentifier<any>, ctor: any, index: number): void {\n if (ctor[DI_TARGET] === ctor) {\n ctor[DI_DEPENDENCIES].push({ id, index });\n } else {\n ctor[DI_DEPENDENCIES] = [{ id, index }];\n ctor[DI_TARGET] = ctor;\n }\n}\n\n//\n// 创建服务唯一标识符\n// 传入服务ID,返回一个参数装饰器\n// 参数装饰器会记录A需要\n// const IFooServiceId = createDecorator<FooService>('FooService');\n//\n// class Bar\n// constructor(@IFooServiceId a: IFooService) // IFooService是接口声明\n//\nexport function createDecorator<T>(serviceId: string): ServiceIdentifier<T> {\n if (serviceIds.has(serviceId)) {\n return serviceIds.get(serviceId)!;\n }\n\n const id = function (target: any, key: string, index: number): any {\n if (arguments.length !== 3) {\n throw new Error('@IServiceName-decorator can only be used to decorate a parameter');\n }\n setServiceDependency(id, target, index);\n } as any;\n\n id.toString = () => serviceId;\n\n serviceIds.set(serviceId, id);\n return id;\n}\n\n// TODO(niurouwan): 补一下注释和例子\nexport function refineServiceDecorator<T1, T extends T1>(\n serviceIdentifier: ServiceIdentifier<T1>,\n): ServiceIdentifier<T> {\n return serviceIdentifier as ServiceIdentifier<T>;\n}\n","import type { BrandedService, ServicesAccessor } from './base';\nimport { createDecorator } from './base';\nimport type { SyncDescriptor0 } from './descriptor';\nimport type { ServiceCollection } from './service-collection';\n\nexport type GetLeadingNonServiceArgs<TArgs extends any[]> = TArgs extends []\n ? []\n : TArgs extends [...infer TFirst, BrandedService]\n ? GetLeadingNonServiceArgs<TFirst>\n : TArgs;\n\nexport interface IInstantiationService {\n readonly _serviceBrand: undefined;\n\n /**\n * Synchronously creates an instance that is denoted by the descriptor\n */\n createInstance: {\n <T>(descriptor: SyncDescriptor0<T>): T;\n <Ctor extends new (...args: any[]) => any, R extends InstanceType<Ctor>>(\n ctor: Ctor,\n ...args: GetLeadingNonServiceArgs<ConstructorParameters<Ctor>>\n ): R;\n };\n\n /**\n * Calls a function with a service accessor.\n */\n invokeFunction: <R, TS extends any[] = []>(\n fn: (accessor: ServicesAccessor, ...args: TS) => R,\n ...args: TS\n ) => R;\n\n /**\n * Creates a child of this service which inherits all current services\n * and adds/overwrites the given services.\n */\n createChild: (services: ServiceCollection) => IInstantiationService;\n\n /**\n * 生命周期归属该DI上下文的服务进行销毁\n */\n dispose: () => void;\n}\n\nexport const IInstantiationService = createDecorator<IInstantiationService>('instantiation');\n","// lifecycle -> cost\n// 启动流程lifecycle某个阶段对应的耗时\ntype Trace = Record<string | number, number>;\n\nexport class CostRecorder {\n // 每个job在不同阶段的耗时\n private _jobCost: Record<string, Trace> = {};\n\n record(jobName: string, lifecycle: string | number, cost: number) {\n if (!this._jobCost[jobName]) {\n this._jobCost[jobName] = {};\n }\n if (!this._jobCost[jobName][lifecycle]) {\n this._jobCost[jobName][lifecycle] = 0;\n }\n this._jobCost[jobName][lifecycle] += cost;\n }\n\n toString() {\n return JSON.stringify(this._jobCost);\n }\n}\n","import { IInstantiationService, type GetLeadingNonServiceArgs } from '@/di';\nimport { lvAssert, lvAssertNotHere } from '@/assert';\nimport type { AbstractJob } from './abstract-job';\nimport { CostRecorder } from './cost-recorder';\n\nclass JobDescriptor<T, K extends T> {\n readonly ctor: new (...args: any[]) => AbstractJob<T, K>;\n readonly staticArguments: any[];\n\n constructor(ctor: new (...args: any[]) => AbstractJob<T, K>, args: any[]) {\n this.ctor = ctor;\n this.staticArguments = args;\n }\n}\n\nexport class JobScheduler<T, K extends T = T> {\n private readonly _jobPools: Map<string, AbstractJob<T, K>> = new Map();\n private readonly _costRecorder = new CostRecorder();\n private readonly _unconstructedJobs: Map<K, JobDescriptor<AbstractJob<T, K>, any>[]> = new Map();\n\n constructor(\n private _currentPhase: K,\n @IInstantiationService private readonly _instantiationService: IInstantiationService,\n ) {}\n\n get currentPhase() {\n return this._currentPhase;\n }\n\n /**\n * 按需添加一个job,job会在phase时刻才进行实例化\n * @param phase job实例化时机\n * @param ctor job构造函数\n * @param args job构造静态参数\n */\n registerJob<Ctor extends new (...args: any[]) => AbstractJob<T, K>>(\n phase: K,\n ctor: Ctor,\n ...args: GetLeadingNonServiceArgs<ConstructorParameters<Ctor>>\n ) {\n if (!this._unconstructedJobs.has(phase)) {\n this._unconstructedJobs.set(phase, [new JobDescriptor(ctor, args)]);\n } else {\n this._unconstructedJobs.get(phase)!.push(new JobDescriptor(ctor, args));\n }\n }\n\n /**\n * 添加一个构造好的job\n * @param job 任务\n */\n addJob(job: AbstractJob<T, K>) {\n lvAssert(!this._jobPools.has(job.name), 'cant duplicate add job.');\n this._jobPools.set(job.name, job);\n }\n\n removeJob(jobName: string) {\n this._jobPools.delete(jobName);\n }\n\n prepare(phase: K) {\n const descriptors = this._unconstructedJobs.get(phase) ?? [];\n for (const d of descriptors) {\n this.addJob(this._instantiationService.createInstance(d.ctor, ...d.staticArguments));\n }\n let shouldWait = false;\n this._unconstructedJobs.delete(phase);\n for (const [, job] of this._jobPools) {\n const start = Date.now();\n job.prepare(phase);\n this._costRecorder.record(job.name, phase as number | string, Date.now() - start);\n\n if (job.shouldWait(phase)) {\n shouldWait = true;\n }\n }\n\n return shouldWait;\n }\n\n getCost() {\n return this._costRecorder.toString();\n }\n\n /**\n * 推进到目标阶段,要求目标阶段没有需要等待的任务\n * @param phase 目标阶段\n */\n advanceToPhase(phase: K) {\n for (const [, job] of this._jobPools) {\n if (job.shouldWait(phase)) {\n lvAssertNotHere(`exists job should wait, job name: ${job.name}, phase: ${phase}`);\n }\n }\n\n this._currentPhase = phase;\n }\n\n async wait(phase: K) {\n const jobPromises: Promise<void>[] = [];\n for (const [, job] of this._jobPools) {\n if (!job.shouldWait(phase)) {\n continue;\n }\n jobPromises.push(\n (() => {\n const start = Date.now();\n return job.wait(phase).then(() => {\n this._costRecorder.record(job.name, phase as number | string, Date.now() - start);\n });\n })(),\n );\n }\n\n await Promise.all(jobPromises);\n this._currentPhase = phase;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/assert/assert.ts","../../src/launch/abstract-job.ts","../../src/di/base.ts","../../src/di/instantiation-service.interface.ts","../../src/launch/cost-recorder.ts","../../src/launch/job-scheduler.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["function abort(reason: string): never {\n throw new Error(`zkAssert(${reason})`);\n}\n\n/**\n * 断言表达式为真\n * @param expr \n * @param reason \n */\nexport function zkAssert(expr: unknown, reason?: string): asserts expr {\n if (!expr) {\n abort(reason ?? '#expr is false');\n }\n}\n\n/**\n * 断言deadcode路径\n * @param reason \n */\nexport function zkAssertNotHere(reason?: string): never {\n abort(reason ?? 'unreachable code flow');\n}\n\n/**\n * 断言类型不可达\n * @param member \n * @param message \n */\nexport function zkAssertNever(member: never, message = 'Illegal value:'): never {\n abort(`${message}: ${member}`);\n}\n\n/**\n * 断言变量为null或者undefined\n * @param val \n * @param reason \n */\nexport function zkAssertNotNil<T>(val: T, reason?: string): asserts val is NonNullable<T> {\n if (val === null || val === undefined) {\n abort(reason ?? '#val is nil');\n }\n}\n","import { Barrier } from '@/async';\n\nexport abstract class AbstractJob<T, K extends T = T> {\n protected abstract _name: string;\n protected _store: Map<K, Barrier[]> = new Map();\n\n get name() {\n return this._name;\n }\n\n shouldWait(phase: K) {\n const barriers = this._store.get(phase);\n if (!barriers?.length) {\n return false;\n }\n return true;\n }\n\n wait(phase: K): Promise<void> {\n try {\n const barriers = this._store.get(phase);\n if (!barriers?.length) {\n return Promise.resolve();\n }\n return Promise.all(barriers.map((barrier) => barrier.wait())) as unknown as Promise<void>;\n } finally {\n // 执行之后就清空,确保失败或cancel态时可以重复 prepare.\n this._store.delete(phase);\n }\n }\n\n prepare(phase: K) {\n this._executePhase(phase);\n }\n\n protected _setBarrier(phase: K, barrier: Barrier) {\n if (!this._store.has(phase)) {\n this._store.set(phase, []);\n }\n const barriers = this._store.get(phase)!;\n barriers.push(barrier);\n }\n\n protected abstract _executePhase(phase: K): void;\n}\n","// service特征标识\nexport type BrandedService = { _serviceBrand: undefined };\n\n//\n// 服务唯一标识符(编译时生成)\n// 需要DI进行注入的服务必须拥有该标识符\n// 本质上是一个参数装饰器\n//\nexport interface ServiceIdentifier<T> {\n (...args: any[]): void;\n type: T;\n}\n\n// 获取服务的视图接口\nexport interface ServicesAccessor {\n get: <T>(id: ServiceIdentifier<T>) => T;\n}\n\n// 服务唯一标识符存储\nconst serviceIds = new Map<string, ServiceIdentifier<any>>();\n\nexport const DI_TARGET = '$di$target';\nexport const DI_DEPENDENCIES = '$di$dependencies';\n\n// 获取某个服务的依赖\n// 因为服务依赖关系会存放在构造函数的属性上\nexport function getServiceDependencies(ctor: any): { id: ServiceIdentifier<any>; index: number }[] {\n return ctor[DI_DEPENDENCIES] || [];\n}\n\n// 更新服务依赖依赖关系\nfunction setServiceDependency(id: ServiceIdentifier<any>, ctor: any, index: number): void {\n if (ctor[DI_TARGET] === ctor) {\n ctor[DI_DEPENDENCIES].push({ id, index });\n } else {\n ctor[DI_DEPENDENCIES] = [{ id, index }];\n ctor[DI_TARGET] = ctor;\n }\n}\n\n//\n// 创建服务唯一标识符\n// 传入服务ID,返回一个参数装饰器\n// 参数装饰器会记录A需要\n// const IFooServiceId = createDecorator<FooService>('FooService');\n//\n// class Bar\n// constructor(@IFooServiceId a: IFooService) // IFooService是接口声明\n//\nexport function createDecorator<T>(serviceId: string): ServiceIdentifier<T> {\n if (serviceIds.has(serviceId)) {\n return serviceIds.get(serviceId)!;\n }\n\n const id = function (target: any, key: string, index: number): any {\n if (arguments.length !== 3) {\n throw new Error('@IServiceName-decorator can only be used to decorate a parameter');\n }\n setServiceDependency(id, target, index);\n } as any;\n\n id.toString = () => serviceId;\n\n serviceIds.set(serviceId, id);\n return id;\n}\n\n// TODO(niurouwan): 补一下注释和例子\nexport function refineServiceDecorator<T1, T extends T1>(\n serviceIdentifier: ServiceIdentifier<T1>,\n): ServiceIdentifier<T> {\n return serviceIdentifier as ServiceIdentifier<T>;\n}\n","import type { BrandedService, ServicesAccessor } from './base';\nimport { createDecorator } from './base';\nimport type { SyncDescriptor0 } from './descriptor';\nimport type { ServiceCollection } from './service-collection';\n\nexport type GetLeadingNonServiceArgs<TArgs extends any[]> = TArgs extends []\n ? []\n : TArgs extends [...infer TFirst, BrandedService]\n ? GetLeadingNonServiceArgs<TFirst>\n : TArgs;\n\nexport interface IInstantiationService {\n readonly _serviceBrand: undefined;\n\n /**\n * Synchronously creates an instance that is denoted by the descriptor\n */\n createInstance: {\n <T>(descriptor: SyncDescriptor0<T>): T;\n <Ctor extends new (...args: any[]) => any, R extends InstanceType<Ctor>>(\n ctor: Ctor,\n ...args: GetLeadingNonServiceArgs<ConstructorParameters<Ctor>>\n ): R;\n };\n\n /**\n * Calls a function with a service accessor.\n */\n invokeFunction: <R, TS extends any[] = []>(\n fn: (accessor: ServicesAccessor, ...args: TS) => R,\n ...args: TS\n ) => R;\n\n /**\n * Creates a child of this service which inherits all current services\n * and adds/overwrites the given services.\n */\n createChild: (services: ServiceCollection) => IInstantiationService;\n\n /**\n * 生命周期归属该DI上下文的服务进行销毁\n */\n dispose: () => void;\n}\n\nexport const IInstantiationService = createDecorator<IInstantiationService>('instantiation');\n","// lifecycle -> cost\n// 启动流程lifecycle某个阶段对应的耗时\ntype Trace = Record<string | number, number>;\n\nexport class CostRecorder {\n // 每个job在不同阶段的耗时\n private _jobCost: Record<string, Trace> = {};\n\n record(jobName: string, lifecycle: string | number, cost: number) {\n if (!this._jobCost[jobName]) {\n this._jobCost[jobName] = {};\n }\n if (!this._jobCost[jobName][lifecycle]) {\n this._jobCost[jobName][lifecycle] = 0;\n }\n this._jobCost[jobName][lifecycle] += cost;\n }\n\n toString() {\n return JSON.stringify(this._jobCost);\n }\n}\n","import { IInstantiationService, type GetLeadingNonServiceArgs } from '@/di';\nimport { zkAssert, zkAssertNotHere } from '@/assert';\nimport type { AbstractJob } from './abstract-job';\nimport { CostRecorder } from './cost-recorder';\n\nclass JobDescriptor<T, K extends T> {\n readonly ctor: new (...args: any[]) => AbstractJob<T, K>;\n readonly staticArguments: any[];\n\n constructor(ctor: new (...args: any[]) => AbstractJob<T, K>, args: any[]) {\n this.ctor = ctor;\n this.staticArguments = args;\n }\n}\n\nexport class JobScheduler<T, K extends T = T> {\n private readonly _jobPools: Map<string, AbstractJob<T, K>> = new Map();\n private readonly _costRecorder = new CostRecorder();\n private readonly _unconstructedJobs: Map<K, JobDescriptor<AbstractJob<T, K>, any>[]> = new Map();\n\n constructor(\n private _currentPhase: K,\n @IInstantiationService private readonly _instantiationService: IInstantiationService,\n ) {}\n\n get currentPhase() {\n return this._currentPhase;\n }\n\n /**\n * 按需添加一个job,job会在phase时刻才进行实例化\n * @param phase job实例化时机\n * @param ctor job构造函数\n * @param args job构造静态参数\n */\n registerJob<Ctor extends new (...args: any[]) => AbstractJob<T, K>>(\n phase: K,\n ctor: Ctor,\n ...args: GetLeadingNonServiceArgs<ConstructorParameters<Ctor>>\n ) {\n if (!this._unconstructedJobs.has(phase)) {\n this._unconstructedJobs.set(phase, [new JobDescriptor(ctor, args)]);\n } else {\n this._unconstructedJobs.get(phase)!.push(new JobDescriptor(ctor, args));\n }\n }\n\n /**\n * 添加一个构造好的job\n * @param job 任务\n */\n addJob(job: AbstractJob<T, K>) {\n zkAssert(!this._jobPools.has(job.name), 'cant duplicate add job.');\n this._jobPools.set(job.name, job);\n }\n\n removeJob(jobName: string) {\n this._jobPools.delete(jobName);\n }\n\n prepare(phase: K) {\n const descriptors = this._unconstructedJobs.get(phase) ?? [];\n for (const d of descriptors) {\n this.addJob(this._instantiationService.createInstance(d.ctor, ...d.staticArguments));\n }\n let shouldWait = false;\n this._unconstructedJobs.delete(phase);\n for (const [, job] of this._jobPools) {\n const start = Date.now();\n job.prepare(phase);\n this._costRecorder.record(job.name, phase as number | string, Date.now() - start);\n\n if (job.shouldWait(phase)) {\n shouldWait = true;\n }\n }\n\n return shouldWait;\n }\n\n getCost() {\n return this._costRecorder.toString();\n }\n\n /**\n * 推进到目标阶段,要求目标阶段没有需要等待的任务\n * @param phase 目标阶段\n */\n advanceToPhase(phase: K) {\n for (const [, job] of this._jobPools) {\n if (job.shouldWait(phase)) {\n zkAssertNotHere(`exists job should wait, job name: ${job.name}, phase: ${phase}`);\n }\n }\n\n this._currentPhase = phase;\n }\n\n async wait(phase: K) {\n const jobPromises: Promise<void>[] = [];\n for (const [, job] of this._jobPools) {\n if (!job.shouldWait(phase)) {\n continue;\n }\n jobPromises.push(\n (() => {\n const start = Date.now();\n return job.wait(phase).then(() => {\n this._costRecorder.record(job.name, phase as number | string, Date.now() - start);\n });\n })(),\n );\n }\n\n await Promise.all(jobPromises);\n this._currentPhase = phase;\n }\n}\n"]}
|
package/dist/lock/index.cjs
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
// src/assert/assert.ts
|
|
4
4
|
function abort(reason) {
|
|
5
|
-
throw new Error(`
|
|
5
|
+
throw new Error(`zkAssert(${reason})`);
|
|
6
6
|
}
|
|
7
|
-
function
|
|
7
|
+
function zkAssert(expr, reason) {
|
|
8
8
|
if (!expr) {
|
|
9
9
|
abort("#expr is false");
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
|
-
function
|
|
12
|
+
function zkAssertNotNil(val, reason) {
|
|
13
13
|
if (val === null || val === void 0) {
|
|
14
14
|
abort("#val is nil");
|
|
15
15
|
}
|
|
@@ -351,11 +351,11 @@ var Capability = class {
|
|
|
351
351
|
return this._status;
|
|
352
352
|
}
|
|
353
353
|
acquire() {
|
|
354
|
-
|
|
354
|
+
zkAssert(this._status === 0 /* Unlocked */);
|
|
355
355
|
this._status = 1 /* Locked */;
|
|
356
356
|
}
|
|
357
357
|
release() {
|
|
358
|
-
|
|
358
|
+
zkAssert(this._status === 1 /* Locked */);
|
|
359
359
|
this._status = 0 /* Unlocked */;
|
|
360
360
|
this._onUnlocked.fire();
|
|
361
361
|
}
|
|
@@ -380,7 +380,7 @@ var SharedCapability = class {
|
|
|
380
380
|
this._counter++;
|
|
381
381
|
}
|
|
382
382
|
release() {
|
|
383
|
-
|
|
383
|
+
zkAssert(this._counter > 0);
|
|
384
384
|
this._counter--;
|
|
385
385
|
if (this._counter === 0) {
|
|
386
386
|
this._status = 0 /* Unlocked */;
|
|
@@ -442,7 +442,7 @@ var SharedMutex = class {
|
|
|
442
442
|
* 解除写锁
|
|
443
443
|
*/
|
|
444
444
|
unLock() {
|
|
445
|
-
|
|
445
|
+
zkAssertNotNil(this._writer);
|
|
446
446
|
this._writer.release();
|
|
447
447
|
}
|
|
448
448
|
/**
|
|
@@ -476,9 +476,9 @@ var SharedMutex = class {
|
|
|
476
476
|
* 解除读锁
|
|
477
477
|
*/
|
|
478
478
|
unLockShared() {
|
|
479
|
-
|
|
479
|
+
zkAssertNotNil(this._reader);
|
|
480
480
|
if (this._writer) {
|
|
481
|
-
|
|
481
|
+
zkAssert(this._writer.status === 0 /* Unlocked */);
|
|
482
482
|
}
|
|
483
483
|
this._reader.release();
|
|
484
484
|
}
|
|
@@ -492,7 +492,7 @@ var SharedMutex = class {
|
|
|
492
492
|
* 写者进入第一道门
|
|
493
493
|
*/
|
|
494
494
|
_writerEnterGate1(resolve) {
|
|
495
|
-
|
|
495
|
+
zkAssert(!this._writer);
|
|
496
496
|
this._writer = new Capability();
|
|
497
497
|
if (this._readerCount > 0) {
|
|
498
498
|
listenOnce(this._reader.onUnlocked)(() => {
|
|
@@ -506,11 +506,11 @@ var SharedMutex = class {
|
|
|
506
506
|
* 写者进入第二道门
|
|
507
507
|
*/
|
|
508
508
|
_writerEnterGate2(resolve) {
|
|
509
|
-
|
|
510
|
-
|
|
509
|
+
zkAssertNotNil(this._writer);
|
|
510
|
+
zkAssert(this._readerCount === 0);
|
|
511
511
|
this._writer.acquire();
|
|
512
512
|
listenOnce(this._writer.onUnlocked)(() => {
|
|
513
|
-
|
|
513
|
+
zkAssertNotNil(this._writer);
|
|
514
514
|
this._writer = void 0;
|
|
515
515
|
this._moveForward();
|
|
516
516
|
});
|
|
@@ -520,7 +520,7 @@ var SharedMutex = class {
|
|
|
520
520
|
* 读者进入第一道门
|
|
521
521
|
*/
|
|
522
522
|
_readerEnterGate1(resolve) {
|
|
523
|
-
|
|
523
|
+
zkAssert(!this._writer);
|
|
524
524
|
this._waitingReader = void 0;
|
|
525
525
|
if (!this._reader) {
|
|
526
526
|
this._reader = new SharedCapability();
|
package/dist/lock/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/assert/assert.ts","../../src/dispose/disposable-t.ts","../../src/dispose/disposable-utils.ts","../../src/dispose/timer.ts","../../src/structure/linked-list.ts","../../src/event/disposable-linked-list.ts","../../src/event/error-handler.ts","../../src/event/emitter.ts","../../src/event/once.ts","../../src/lock/capability.ts","../../src/lock/semaphore.ts","../../src/lock/shared-mutex.ts","../../src/lock/utils.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["function abort(reason: string): never {\n throw new Error(`lvAssert(${reason})`);\n}\n\n/**\n * 断言表达式为真\n * @param expr \n * @param reason \n */\nexport function lvAssert(expr: unknown, reason?: string): asserts expr {\n if (!expr) {\n abort(reason ?? '#expr is false');\n }\n}\n\n/**\n * 断言deadcode路径\n * @param reason \n */\nexport function lvAssertNotHere(reason?: string): never {\n abort(reason ?? 'unreachable code flow');\n}\n\n/**\n * 断言类型不可达\n * @param member \n * @param message \n */\nexport function lvAssertNever(member: never, message = 'Illegal value:'): never {\n abort(`${message}: ${member}`);\n}\n\n/**\n * 断言变量为null或者undefined\n * @param val \n * @param reason \n */\nexport function lvAssertNotNil<T>(val: T, reason?: string): asserts val is NonNullable<T> {\n if (val === null || val === undefined) {\n abort(reason ?? '#val is nil');\n }\n}\n","import { Logger } from '@/_internal/logger';\nimport { lvAssertNotNil } from '@/assert';\nimport { DisposableStore } from './disposable-store';\nimport type { IDisposable } from './dispose-base';\nimport { BRANCH_DISPOSE } from './logger';\nimport { MARK_AS_DISPOSED, SET_PARENT_OF_DISPOSABLE, TRACK_DISPOSABLE } from './tracker';\n\n//\n// Disposable基类\n//\n// 自动添加DisposableStore,提供默认的dispose和register方法\n//\nexport abstract class Disposable implements IDisposable {\n protected readonly _store = new DisposableStore();\n\n constructor() {\n TRACK_DISPOSABLE(this);\n SET_PARENT_OF_DISPOSABLE(this._store, this);\n }\n\n // 销毁该节点和所有的子节点\n dispose(): void {\n MARK_AS_DISPOSED(this);\n BRANCH_DISPOSE(this.constructor.name, this._store.constructor.name);\n\n this._store.dispose();\n }\n\n // 挂载子节点\n protected _register<T extends IDisposable>(o: T): T {\n if ((o as unknown as Disposable) === this) {\n throw new Error('Cannot register a disposable on itself!');\n }\n return this._store.add(o);\n }\n}\n\n/**\n * 容器类\n * 提供一个容器,容器内部的IDisposable对象可以切换更新,每次更新的时候,旧的IDisposable对象会自动进行dispose\n *\n * 使用方式:\n * class Foo {\n * private readonly _barRef: MutableDisposable;\n *\n * toggle() {\n * this._barRef.setValue(new Bar());\n * }\n *\n * doSomething() {\n * this._barRef.value.xxx();\n * }\n * }\n */\nexport class MutableDisposable<T extends IDisposable> implements IDisposable {\n private _value?: T;\n private _isDisposed = false;\n\n constructor(value?: T) {\n TRACK_DISPOSABLE(this);\n this.value = value;\n }\n\n get value(): T | undefined {\n return this._isDisposed ? undefined : this._value;\n }\n\n set value(value: T | undefined) {\n if (this._isDisposed || value === this._value) {\n return;\n }\n\n this._value?.dispose();\n if (value) {\n SET_PARENT_OF_DISPOSABLE(value, this);\n }\n this._value = value;\n }\n\n clear(): void {\n this.value = undefined;\n }\n\n dispose(): void {\n this._isDisposed = true;\n MARK_AS_DISPOSED(this);\n this._value?.dispose();\n this._value = undefined;\n }\n\n release(): T | undefined {\n const oldValue = this._value;\n this._value = undefined;\n if (oldValue) {\n SET_PARENT_OF_DISPOSABLE(oldValue, null);\n }\n return oldValue;\n }\n}\n\n/**\n * 容器类\n * 通过该容器进行dispose试,可以保证内部的IDisposable一会进行一次dispose\n * 本质是一种防御性质的处理,如果需要使用时,最好有明确的理由\n */\nexport class SafeDisposable<T extends IDisposable> implements IDisposable {\n private _value?: T;\n\n constructor(value: T) {\n this._value = value;\n TRACK_DISPOSABLE(this);\n }\n\n get value(): T | undefined {\n return this._value;\n }\n\n isEmpty() {\n return this._value === undefined;\n }\n\n dispose() {\n if (!this._value) {\n return;\n }\n this._value.dispose();\n this._value = undefined;\n MARK_AS_DISPOSED(this);\n }\n}\n\n/**\n * 容器类\n * 引用计数容器,当引用为0时自动执行dispose\n * 注意:初始计数为1,默认构造的地方自动获得引用,如果在栈上构造,记得最后调用release\n *\n * 使用实例:\n * class Foo {\n * private _bar: RefCountedDisposable = new RefCountedDisposable(new Bar());\n *\n * getBar() {\n * this._bar.acquire();\n * return this._bar;\n * }\n * }\n *\n * // 如果在栈上构造\n * const bar = new RefCountedDisposable(new Bar());\n * makeFoo(bar);\n * makeFoo(bar);\n * bar.release();\n */\nexport class RefCountedDisposable<T extends IDisposable> implements IDisposable {\n private _counter: number = 1;\n private _value?: T;\n\n constructor(value: T) {\n this._value = value;\n TRACK_DISPOSABLE(this);\n }\n\n get value(): T | undefined {\n return this._value;\n }\n\n acquire() {\n if (!this._value) {\n return this;\n }\n this._counter++;\n return this;\n }\n\n release() {\n if (--this._counter === 0) {\n this._value!.dispose();\n this._value = undefined;\n MARK_AS_DISPOSED(this);\n }\n return this;\n }\n\n dispose() {\n this.release();\n }\n}\n\n/**\n * 容器类,表示了一个T生命周期的转移\n *\n * 由于js引用传递的特性,正常情况下,我们默认为传递过来的对象不具备dispose权利\n * class Foo extends Disposable {\n * private readonly _bar = new Bar();\n *\n * constructor(\n * thirdparty: Thirdparty,\n * ) {\n * this._register(this._bar); // class内部构造的,具备dispose权利\n * this._register(thirdparty); // ❌,很少会直接这么写,除非能很确定存在生命周期转移\n * }\n *\n * constructor(\n * thirdparty: TransferDisposable<Thirdparty>, // ✅,明确表示了我依赖了Thirdparty,但是该对象生命周期要归我所有\n * ) {\n * this._register(this._bar);\n * this._register(thirdparty.release()); // ✅,可以直接register\n * }\n * }\n *\n * 注意:\n * 不同于C++中的unique_ptr,该class只作用于转移场景。\n * 所以class理论上只在栈上出现,不应该在堆上存在。\n * 如果出现了需要在堆上存储的场景,可以联系架构侧\n */\nexport class TransferDisposable<T extends IDisposable> extends Disposable {\n private _val?: T;\n\n constructor(val: T) {\n super();\n\n this._val = val;\n }\n\n release() {\n // 只能release一次\n lvAssertNotNil(this._val);\n const v = this._val;\n this._val = undefined;\n return v;\n }\n\n dispose(): void {\n // 虽然它有dispose,但是不应该被执行,应该直接被gc才对\n Logger.warn(new Error('TransferDisposable call dispose.'));\n this._val?.dispose();\n super.dispose();\n }\n}\n","import { SafeDisposable, TransferDisposable } from './disposable-t';\nimport { EmptyDispose, type IDisposable } from './dispose-base';\nimport { MARK_AS_LEAKED } from './tracker';\n\nexport function makeSafeDisposable(fn: (...args: any) => any) {\n const disposable = new SafeDisposable({\n dispose: fn,\n });\n return disposable;\n}\n\nexport function makeEmptyDisposable() {\n return EmptyDispose;\n}\n\n// 忽略dispose\nexport function ignoreDispose(x: IDisposable) {\n MARK_AS_LEAKED(x);\n}\n\n// 判断一个thing是否是disposable\nexport function isDisposable<E = any>(thing: E): thing is E & IDisposable {\n return typeof (thing as IDisposable).dispose === 'function' && (thing as IDisposable).dispose.length === 0;\n}\n\nexport function makeTransferDisposable<T extends IDisposable>(val: T) {\n return new TransferDisposable(val);\n}\n","import type { IDisposable } from './dispose-base';\nimport { makeSafeDisposable } from './disposable-utils';\n\nexport function setDisposableTimeout(fn: (...args: any[]) => void, timeout: number): IDisposable {\n const handle = setTimeout(() => {\n fn();\n }, timeout);\n return makeSafeDisposable(() => clearTimeout(handle));\n}\n\nexport function setDisposableInterval(fn: (...args: any[]) => void, timeout: number): IDisposable {\n const handle = setInterval(() => {\n fn();\n }, timeout);\n return makeSafeDisposable(() => clearInterval(handle));\n}\n","class ListNode<T> {\n constructor(\n public value: T,\n public next: ListNode<T> | null = null,\n public prev: ListNode<T> | null = null,\n ) {}\n}\n\nexport class LinkedList<T> {\n protected _head: ListNode<T> | null = null;\n protected _tail: ListNode<T> | null = null;\n protected _count = 0;\n\n public get size(): number {\n return this._count;\n }\n\n public get firstNode(): ListNode<T> | null {\n return this._head;\n }\n\n public isEmpty(): boolean {\n return this._head === null;\n }\n\n public clear(): void {\n let current = this._head;\n while (current !== null) {\n const next = current.next;\n current.prev = null;\n current.next = null;\n current = next;\n }\n\n this._head = null;\n this._tail = null;\n this._count = 0;\n }\n\n public unshift(value: T): LinkedList<T> {\n const node = new ListNode(value);\n\n if (this.isEmpty()) {\n this._head = node;\n this._tail = node;\n } else {\n const oldHead = this._head;\n this._head = node;\n node.next = oldHead;\n oldHead!.prev = node;\n }\n\n this._count++;\n return this;\n }\n\n public push(value: T): LinkedList<T> {\n const node = new ListNode(value);\n\n if (this.isEmpty()) {\n this._head = node;\n this._tail = node;\n } else {\n const oldTail = this._tail;\n this._tail = node;\n node.prev = oldTail;\n oldTail!.next = node;\n }\n\n this._count++;\n return this;\n }\n\n public shift(): T | null {\n if (this.isEmpty()) {\n return null;\n }\n\n const node = this._head!;\n const value = node.value;\n this._remove(node);\n return value;\n }\n\n public pop(): T | null {\n if (this.isEmpty()) {\n return null;\n }\n\n const node = this._tail!;\n const value = node.value;\n this._remove(node);\n return value;\n }\n\n public toArray(): T[] {\n const result: T[] = [];\n for (const value of this) {\n result.push(value);\n }\n return result;\n }\n\n public *[Symbol.iterator](): Iterator<T> {\n let current = this._head;\n while (current !== null) {\n yield current.value;\n current = current.next;\n }\n }\n\n protected _remove(node: ListNode<T>): void {\n // 如果节点已经被移除(prev 和 next 都为 null),直接返回\n if (node.prev === null && node.next === null && node !== this._head && node !== this._tail) {\n return;\n }\n\n // 更新链表头尾指针\n if (node === this._head) {\n this._head = node.next;\n if (this._head) {\n this._head.prev = null;\n }\n }\n if (node === this._tail) {\n this._tail = node.prev;\n if (this._tail) {\n this._tail.next = null;\n }\n }\n\n // 更新相邻节点的引用\n if (node.prev) {\n node.prev.next = node.next;\n }\n if (node.next) {\n node.next.prev = node.prev;\n }\n\n // 清理被移除节点的引用\n node.prev = null;\n node.next = null;\n this._count--;\n }\n}\n","import { LinkedList } from '@/structure/linked-list';\n\nexport class DisposableLinkedList<T> extends LinkedList<T> {\n unshiftAndGetDisposableNode(value: T): () => void {\n this.unshift(value);\n\n const node = this._head!;\n let hasRemoved = false;\n return (): void => {\n if (!hasRemoved) {\n hasRemoved = true;\n super._remove(node);\n }\n };\n }\n\n pushAndGetDisposableNode(value: T): () => void {\n this.push(value);\n\n const node = this._tail!;\n let hasRemoved = false;\n return (): void => {\n if (!hasRemoved) {\n hasRemoved = true;\n super._remove(node);\n }\n };\n }\n}\n","/**\n * 针对未捕获的错误,异步抛出,不阻塞事件响应主流程\n * 默认模式\n */\nexport function asyncUnexpectedError(e: any): void {\n setTimeout(() => {\n throw e;\n }, 0);\n}\n\n/**\n * 针对未捕获的错误,同步抛出,阻塞事件响应主流程\n */\nexport function syncUnexpectedError(e: any): void {\n throw e;\n}\n\n/**\n * 针对未捕获的错误,静默掉,不进行处理\n */\n// eslint-disable-next-line @typescript-eslint/no-empty-function\nexport function ignoreUnexpectedError(e: any): void {}\n","import { makeSafeDisposable } from '@/dispose';\nimport type { IDisposable } from '@/dispose';\nimport { DisposableLinkedList } from './disposable-linked-list';\nimport { asyncUnexpectedError } from './error-handler';\n\nexport interface EmitterOptions {\n onAddListener?: (...args: any) => any;\n onRemoveListener?: (...args: any) => any;\n onListenerError?: (e: any) => void;\n}\n\n//\n// 事件监听中的回调实体\n//\nclass Listener<TArgs extends any[]> {\n private readonly _callback: (...args: TArgs) => void;\n private readonly _callbackThis: any | undefined;\n\n constructor(callback: (...args: TArgs) => void, callbackThis: any | undefined) {\n this._callback = callback;\n this._callbackThis = callbackThis;\n }\n\n invoke(...args: TArgs): void {\n this._callback.call(this._callbackThis, ...args);\n }\n}\n\n//\n// 存放在EventDeliveryQueue中的元素\n//\nclass EventDeliveryQueueElement<TArgs extends any[]> {\n readonly emitter: Emitter<TArgs>;\n readonly listener: Listener<TArgs>;\n readonly event: TArgs;\n constructor(emitter: Emitter<TArgs>, listener: Listener<TArgs>, event: TArgs) {\n this.emitter = emitter;\n this.listener = listener;\n this.event = event;\n }\n}\n\nexport class EventDeliveryQueue {\n protected _queue = new DisposableLinkedList<EventDeliveryQueueElement<any>>();\n\n constructor(private readonly _onListenerError: (e: unknown) => void = asyncUnexpectedError) {}\n\n get size(): number {\n return this._queue.size;\n }\n\n push<TArgs extends any[]>(emitter: Emitter<TArgs>, listener: Listener<TArgs>, event: TArgs): void {\n this._queue.push(new EventDeliveryQueueElement(emitter, listener, event));\n }\n\n clear<TArgs extends any[]>(emitter: Emitter<TArgs>): void {\n const newQueue = new DisposableLinkedList<EventDeliveryQueueElement<TArgs>>();\n for (const element of this._queue) {\n if (element.emitter !== emitter) {\n newQueue.push(element);\n }\n }\n this._queue = newQueue;\n }\n\n deliver(): void {\n while (this._queue.size > 0) {\n const element = this._queue.shift()!;\n try {\n element.listener.invoke(...element.event);\n } catch (e) {\n this._onListenerError(e);\n }\n }\n }\n}\n\nexport interface Event<T extends any[]> {\n (listener: (...args: T) => any, thisArgs?: any): IDisposable;\n}\n\nexport class Emitter<TArgs extends any[]> {\n protected _listeners?: DisposableLinkedList<Listener<TArgs>>;\n private readonly _options?: EmitterOptions;\n private _disposed = false;\n private _event?: Event<TArgs>;\n private _deliveryQueue?: EventDeliveryQueue;\n\n constructor(options?: EmitterOptions) {\n this._options = options;\n }\n\n get event(): Event<TArgs> {\n if (this._event) {\n return this._event;\n }\n\n this._event = (callback: (...args: TArgs) => any, thisArgs?: any): IDisposable => {\n const listener = new Listener(callback, thisArgs);\n\n if (!this._listeners) {\n this._listeners = new DisposableLinkedList();\n }\n\n const removeListener = this._listeners.pushAndGetDisposableNode(listener);\n\n if (this._options?.onAddListener) {\n this._options.onAddListener(this, callback, thisArgs);\n }\n\n // 生成可销毁函数返回\n const result = () => {\n if (!this._disposed) {\n removeListener();\n if (this._options?.onRemoveListener) {\n this._options.onRemoveListener(this, callback, thisArgs);\n }\n }\n };\n\n return makeSafeDisposable(result);\n };\n\n return this._event;\n }\n\n dispose(): void {\n if (this._disposed) {\n return;\n }\n this._disposed = true;\n this._listeners?.clear();\n this._deliveryQueue?.clear(this);\n }\n\n fire(...event: TArgs): void {\n if (!this._listeners || this._listeners.size === 0) {\n return;\n }\n // 绝大部分场景事件只会有一个监听器,针对性进行性能优化,没必要构造DeliveryQueue结构\n if (this._listeners.size === 1) {\n const listener = this._listeners.firstNode!;\n try {\n listener.value.invoke(...event);\n } catch (e) {\n if (this._options?.onListenerError) {\n this._options.onListenerError(e);\n } else {\n asyncUnexpectedError(e);\n }\n }\n return;\n }\n\n this._deliveryQueue ??= new EventDeliveryQueue(this._options?.onListenerError);\n\n for (const listener of this._listeners) {\n this._deliveryQueue.push(this, listener, event);\n }\n this._deliveryQueue.deliver();\n }\n}\n","import type { Event } from './emitter';\nimport type { IDisposable } from '@/dispose';\n\n// 辅助能力:只监听某个事件一次\nexport function listenOnce<TArgs extends any[]>(event: Event<TArgs>): Event<TArgs> {\n return (listener, thisArgs = null) => {\n let didFire = false;\n // 必须这样写,事件可能同步触发\n // eslint-disable-next-line no-undef-init\n let result: IDisposable | undefined = undefined;\n result = event((...args) => {\n if (didFire) {\n return;\n } else if (result) {\n result.dispose();\n } else {\n didFire = true;\n }\n\n return listener.call(thisArgs, ...args);\n }, null);\n\n if (didFire) {\n result.dispose();\n }\n\n return result;\n };\n}\n","import { lvAssert } from '@/assert';\nimport { Emitter, type Event } from '@/event';\n\n//\n// 资源对应的是标准库中的 unsigned state 以及相关的位运算\n// 我们用两个具体的Capability结构实现(Capability命名来源于标准库)\n//\n\n/**\n * 资源状态\n */\nexport enum CapabilityStatus {\n Unlocked,\n Locked,\n}\n\n/**\n * 独享的资源\n *\n * acquire 获取控制权\n * release 释放控制权\n */\nexport class Capability {\n public onUnlocked: Event<[]>;\n\n private readonly _onUnlocked = new Emitter<[]>();\n private _status = CapabilityStatus.Unlocked;\n\n constructor() {\n this.onUnlocked = this._onUnlocked.event;\n }\n\n get status(): CapabilityStatus {\n return this._status;\n }\n\n public acquire(): void {\n lvAssert(this._status === CapabilityStatus.Unlocked);\n this._status = CapabilityStatus.Locked;\n }\n\n public release(): void {\n lvAssert(this._status === CapabilityStatus.Locked);\n this._status = CapabilityStatus.Unlocked;\n this._onUnlocked.fire();\n }\n}\n\n/**\n * 共享的资源\n *\n * acquire 获取控制权\n * release 释放控制权\n */\nexport class SharedCapability {\n public onUnlocked: Event<[]>;\n\n private readonly _onUnlocked = new Emitter<[]>();\n private _status = CapabilityStatus.Unlocked;\n private _counter = 0;\n\n constructor() {\n this.onUnlocked = this._onUnlocked.event;\n }\n\n get status(): CapabilityStatus {\n return this._status;\n }\n\n get counter(): number {\n return this._counter;\n }\n\n public acquire() {\n if (this._status === CapabilityStatus.Unlocked) {\n this._status = CapabilityStatus.Locked;\n }\n this._counter++;\n }\n\n public release() {\n lvAssert(this._counter > 0);\n this._counter--;\n if (this._counter === 0) {\n this._status = CapabilityStatus.Unlocked;\n this._onUnlocked.fire();\n }\n }\n}\n","import type { Event } from '@/event';\nimport { Emitter } from '@/event';\n\n/**\n * 信号\n *\n * 用来模拟标准库的condition_variable\n * 提供监听某个信号被激活的能力\n */\nexport class Semaphore {\n public onActive: Event<[]>;\n private readonly _onActive = new Emitter<[]>();\n\n constructor() {\n this.onActive = this._onActive.event;\n }\n\n public notify(): void {\n this._onActive.fire();\n }\n}\n","import { lvAssert, lvAssertNotNil } from '@/assert';\nimport { listenOnce } from '@/event';\nimport { SharedCapability, Capability, CapabilityStatus } from './capability';\nimport { Semaphore } from './semaphore';\n\n/**\n * 提供读写能力的共享互斥量\n *\n * 参考C++17标准库双门思想实现\n * 接口也与标准库保持一致\n * 方法内部禁止promise,只可以对外暴露promise\n *\n * 核心\n * - 写写互斥,读写互斥,读读可重入\n *\n * 使用举例:\n * class Foo {\n * private _mutex = new SharedMutex();\n *\n * async add() {\n * // 上写锁\n * await this._mutex.lock();\n * // ...write something\n * this._mutex.unlock();\n * }\n *\n * async getSomething1() {\n * // 上读锁\n * await this._mutex.lockShared();\n * try {\n * return xxx;\n * } finally {\n * this._mutex.unlockShared();\n * }\n * }\n *\n * async getSomething2() {\n * // 上读锁\n * await this._mutex.lockShared();\n * try {\n * return xxx;\n * } finally {\n * this._mutex.unlockShared();\n * }\n * }\n * }\n */\nexport class SharedMutex {\n // 在第一道门外等待的写者\n private readonly _waitingWriters: Semaphore[] = [];\n\n // 已经通过了第一道门的写者\n // 如果在第二道门外等待,状态为sharedLocked\n // 如果已经进入到第二道门内拿到了锁,状态为locked\n private _writer?: Capability;\n\n // 在第一道门外等待的读者\n private _waitingReader?: Semaphore;\n\n // 拿到锁的读者\n private _reader?: SharedCapability;\n\n /**\n * 是否被锁住\n */\n public isLocked() {\n return this._writer || this._readerCount !== 0;\n }\n\n /**\n * 等待并获取写锁\n */\n public lock(): Promise<void> {\n return new Promise<void>((resolve) => {\n // 第一道门\n if (this._writer) {\n // 如果已经有写者进入了,其他写者等待\n const token = new Semaphore();\n this._waitingWriters.push(token);\n token.onActive(() => {\n this._writerEnterGate1(resolve);\n });\n } else {\n this._writerEnterGate1(resolve);\n }\n });\n }\n\n /**\n * 尝试获取写锁,立刻返回结果\n */\n public tryLock(): boolean {\n if (this._writer || this._readerCount > 0) {\n return false;\n }\n // 这里不需要await,一定可以上锁\n this.lock();\n return true;\n }\n\n /**\n * 解除写锁\n */\n public unLock(): void {\n lvAssertNotNil(this._writer);\n\n // 打开第一道门\n this._writer.release();\n }\n\n /**\n * 等待并获取读锁\n */\n public lockShared(): Promise<void> {\n return new Promise<void>((resolve) => {\n // 读者只需要进第一道门\n if (this._writer) {\n // 如果有写者已经进入了第一道门,读者等待\n if (!this._waitingReader) {\n this._waitingReader = new Semaphore();\n }\n this._waitingReader.onActive(() => {\n this._readerEnterGate1(resolve);\n });\n } else {\n this._readerEnterGate1(resolve);\n }\n });\n }\n\n /**\n * 尝试获取读锁,立刻返回结果\n */\n public tryLockShared(): boolean {\n if (this._writer) {\n return false;\n }\n // 不需要await,一定可以上锁\n this.lockShared();\n return true;\n }\n\n /**\n * 解除读锁\n */\n public unLockShared(): void {\n lvAssertNotNil(this._reader);\n if (this._writer) {\n // TODO(niurouwan): 暂时保留,方便验证,稳定后可以去掉\n lvAssert(this._writer.status === CapabilityStatus.Unlocked);\n }\n\n this._reader.release();\n }\n\n /**\n * 获取当前读者数量\n */\n private get _readerCount(): number {\n return this._reader ? this._reader.counter : 0;\n }\n\n /**\n * 写者进入第一道门\n */\n private _writerEnterGate1(resolve: () => void): void {\n lvAssert(!this._writer);\n // 确定写者,关第一道门\n this._writer = new Capability();\n\n // 第二道门\n // 等待所有读者出去\n if (this._readerCount > 0) {\n listenOnce(this._reader!.onUnlocked)(() => {\n this._writerEnterGate2(resolve);\n });\n } else {\n this._writerEnterGate2(resolve);\n }\n }\n\n /**\n * 写者进入第二道门\n */\n private _writerEnterGate2(resolve: () => void): void {\n lvAssertNotNil(this._writer);\n lvAssert(this._readerCount === 0);\n\n // 成功加锁\n this._writer.acquire();\n listenOnce(this._writer.onUnlocked)(() => {\n lvAssertNotNil(this._writer);\n // 不再持有\n this._writer = undefined;\n this._moveForward();\n });\n resolve();\n }\n\n /**\n * 读者进入第一道门\n */\n private _readerEnterGate1(resolve: () => void): void {\n lvAssert(!this._writer);\n\n // 门外等待的读者清除\n this._waitingReader = undefined;\n\n if (!this._reader) {\n this._reader = new SharedCapability();\n this._reader.acquire();\n listenOnce(this._reader.onUnlocked)(() => {\n this._moveForward();\n });\n } else {\n this._reader.acquire();\n }\n resolve();\n }\n\n /**\n * 锁释放时推进流程\n */\n private _moveForward(): void {\n // 如果有写者在等待在第二道门前面,那么此时推进的一定是读锁释放,直接return即可\n if (this._writer) {\n return;\n }\n\n // 写者优先,优先通知在第一道门前面的写者\n if (this._waitingWriters.length > 0) {\n const semaphore = this._waitingWriters.shift()!;\n semaphore.notify();\n return;\n }\n\n // 最后通知第一道门前面的读者\n if (this._waitingReader) {\n this._waitingReader.notify();\n }\n }\n}\n","import type { IDisposable } from '@/dispose';\nimport { setDisposableTimeout } from '@/dispose';\nimport type { SharedMutex } from './shared-mutex';\n\nexport interface IUnlockable extends IDisposable {\n unlock: () => void;\n}\n\n/**\n * 转移独占锁\n */\nexport async function transferLock(mutex: SharedMutex, timeout?: number): Promise<IUnlockable> {\n await mutex.lock();\n let didUnlock = false;\n let timerDisposable: IDisposable | undefined;\n\n if (timeout !== undefined) {\n timerDisposable = setDisposableTimeout(() => {\n if (!didUnlock) {\n mutex.unLock();\n didUnlock = true;\n }\n }, timeout);\n }\n\n const unlock = () => {\n timerDisposable?.dispose();\n if (!didUnlock) {\n mutex.unLock();\n didUnlock = true;\n }\n };\n\n return {\n dispose: unlock,\n unlock,\n };\n}\n\n/**\n * 尝试转移独占锁\n */\nexport function tryTransferLock(mutex: SharedMutex, timeout?: number): IUnlockable | undefined {\n if (!mutex.tryLock()) {\n return;\n }\n let didUnlock = false;\n let timerDisposable: IDisposable | undefined;\n\n if (timeout !== undefined) {\n timerDisposable = setDisposableTimeout(() => {\n if (!didUnlock) {\n mutex.unLock();\n didUnlock = true;\n }\n }, timeout);\n }\n\n const unlock = () => {\n timerDisposable?.dispose();\n if (!didUnlock) {\n mutex.unLock();\n didUnlock = true;\n }\n };\n\n return {\n dispose: unlock,\n unlock,\n };\n}\n\n/**\n * 转移共享锁\n */\nexport async function transferSharedLock(mutex: SharedMutex, timeout?: number): Promise<IUnlockable> {\n await mutex.lockShared();\n let didUnlock = false;\n let timerDisposable: IDisposable | undefined;\n\n if (timeout !== undefined) {\n timerDisposable = setDisposableTimeout(() => {\n if (!didUnlock) {\n mutex.unLockShared();\n didUnlock = true;\n }\n }, timeout);\n }\n\n const unlock = () => {\n timerDisposable?.dispose();\n if (!didUnlock) {\n mutex.unLockShared();\n didUnlock = true;\n }\n };\n\n return {\n dispose: unlock,\n unlock,\n };\n}\n\n/**\n * 尝试转移共享锁\n */\nexport function tryTransferSharedLock(mutex: SharedMutex, timeout?: number): IUnlockable | undefined {\n if (!mutex.tryLockShared()) {\n return;\n }\n let didUnlock = false;\n let timerDisposable: IDisposable | undefined;\n\n if (timeout !== undefined) {\n timerDisposable = setDisposableTimeout(() => {\n if (!didUnlock) {\n mutex.unLockShared();\n didUnlock = true;\n }\n }, timeout);\n }\n\n const unlock = () => {\n timerDisposable?.dispose();\n if (!didUnlock) {\n mutex.unLockShared();\n didUnlock = true;\n }\n };\n\n return {\n dispose: unlock,\n unlock,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/assert/assert.ts","../../src/dispose/disposable-t.ts","../../src/dispose/disposable-utils.ts","../../src/dispose/timer.ts","../../src/structure/linked-list.ts","../../src/event/disposable-linked-list.ts","../../src/event/error-handler.ts","../../src/event/emitter.ts","../../src/event/once.ts","../../src/lock/capability.ts","../../src/lock/semaphore.ts","../../src/lock/shared-mutex.ts","../../src/lock/utils.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["function abort(reason: string): never {\n throw new Error(`zkAssert(${reason})`);\n}\n\n/**\n * 断言表达式为真\n * @param expr \n * @param reason \n */\nexport function zkAssert(expr: unknown, reason?: string): asserts expr {\n if (!expr) {\n abort(reason ?? '#expr is false');\n }\n}\n\n/**\n * 断言deadcode路径\n * @param reason \n */\nexport function zkAssertNotHere(reason?: string): never {\n abort(reason ?? 'unreachable code flow');\n}\n\n/**\n * 断言类型不可达\n * @param member \n * @param message \n */\nexport function zkAssertNever(member: never, message = 'Illegal value:'): never {\n abort(`${message}: ${member}`);\n}\n\n/**\n * 断言变量为null或者undefined\n * @param val \n * @param reason \n */\nexport function zkAssertNotNil<T>(val: T, reason?: string): asserts val is NonNullable<T> {\n if (val === null || val === undefined) {\n abort(reason ?? '#val is nil');\n }\n}\n","import { Logger } from '@/_internal/logger';\nimport { zkAssertNotNil } from '@/assert';\nimport { DisposableStore } from './disposable-store';\nimport type { IDisposable } from './dispose-base';\nimport { BRANCH_DISPOSE } from './logger';\nimport { MARK_AS_DISPOSED, SET_PARENT_OF_DISPOSABLE, TRACK_DISPOSABLE } from './tracker';\n\n//\n// Disposable基类\n//\n// 自动添加DisposableStore,提供默认的dispose和register方法\n//\nexport abstract class Disposable implements IDisposable {\n protected readonly _store = new DisposableStore();\n\n constructor() {\n TRACK_DISPOSABLE(this);\n SET_PARENT_OF_DISPOSABLE(this._store, this);\n }\n\n // 销毁该节点和所有的子节点\n dispose(): void {\n MARK_AS_DISPOSED(this);\n BRANCH_DISPOSE(this.constructor.name, this._store.constructor.name);\n\n this._store.dispose();\n }\n\n // 挂载子节点\n protected _register<T extends IDisposable>(o: T): T {\n if ((o as unknown as Disposable) === this) {\n throw new Error('Cannot register a disposable on itself!');\n }\n return this._store.add(o);\n }\n}\n\n/**\n * 容器类\n * 提供一个容器,容器内部的IDisposable对象可以切换更新,每次更新的时候,旧的IDisposable对象会自动进行dispose\n *\n * 使用方式:\n * class Foo {\n * private readonly _barRef: MutableDisposable;\n *\n * toggle() {\n * this._barRef.setValue(new Bar());\n * }\n *\n * doSomething() {\n * this._barRef.value.xxx();\n * }\n * }\n */\nexport class MutableDisposable<T extends IDisposable> implements IDisposable {\n private _value?: T;\n private _isDisposed = false;\n\n constructor(value?: T) {\n TRACK_DISPOSABLE(this);\n this.value = value;\n }\n\n get value(): T | undefined {\n return this._isDisposed ? undefined : this._value;\n }\n\n set value(value: T | undefined) {\n if (this._isDisposed || value === this._value) {\n return;\n }\n\n this._value?.dispose();\n if (value) {\n SET_PARENT_OF_DISPOSABLE(value, this);\n }\n this._value = value;\n }\n\n clear(): void {\n this.value = undefined;\n }\n\n dispose(): void {\n this._isDisposed = true;\n MARK_AS_DISPOSED(this);\n this._value?.dispose();\n this._value = undefined;\n }\n\n release(): T | undefined {\n const oldValue = this._value;\n this._value = undefined;\n if (oldValue) {\n SET_PARENT_OF_DISPOSABLE(oldValue, null);\n }\n return oldValue;\n }\n}\n\n/**\n * 容器类\n * 通过该容器进行dispose试,可以保证内部的IDisposable一会进行一次dispose\n * 本质是一种防御性质的处理,如果需要使用时,最好有明确的理由\n */\nexport class SafeDisposable<T extends IDisposable> implements IDisposable {\n private _value?: T;\n\n constructor(value: T) {\n this._value = value;\n TRACK_DISPOSABLE(this);\n }\n\n get value(): T | undefined {\n return this._value;\n }\n\n isEmpty() {\n return this._value === undefined;\n }\n\n dispose() {\n if (!this._value) {\n return;\n }\n this._value.dispose();\n this._value = undefined;\n MARK_AS_DISPOSED(this);\n }\n}\n\n/**\n * 容器类\n * 引用计数容器,当引用为0时自动执行dispose\n * 注意:初始计数为1,默认构造的地方自动获得引用,如果在栈上构造,记得最后调用release\n *\n * 使用实例:\n * class Foo {\n * private _bar: RefCountedDisposable = new RefCountedDisposable(new Bar());\n *\n * getBar() {\n * this._bar.acquire();\n * return this._bar;\n * }\n * }\n *\n * // 如果在栈上构造\n * const bar = new RefCountedDisposable(new Bar());\n * makeFoo(bar);\n * makeFoo(bar);\n * bar.release();\n */\nexport class RefCountedDisposable<T extends IDisposable> implements IDisposable {\n private _counter: number = 1;\n private _value?: T;\n\n constructor(value: T) {\n this._value = value;\n TRACK_DISPOSABLE(this);\n }\n\n get value(): T | undefined {\n return this._value;\n }\n\n acquire() {\n if (!this._value) {\n return this;\n }\n this._counter++;\n return this;\n }\n\n release() {\n if (--this._counter === 0) {\n this._value!.dispose();\n this._value = undefined;\n MARK_AS_DISPOSED(this);\n }\n return this;\n }\n\n dispose() {\n this.release();\n }\n}\n\n/**\n * 容器类,表示了一个T生命周期的转移\n *\n * 由于js引用传递的特性,正常情况下,我们默认为传递过来的对象不具备dispose权利\n * class Foo extends Disposable {\n * private readonly _bar = new Bar();\n *\n * constructor(\n * thirdparty: Thirdparty,\n * ) {\n * this._register(this._bar); // class内部构造的,具备dispose权利\n * this._register(thirdparty); // ❌,很少会直接这么写,除非能很确定存在生命周期转移\n * }\n *\n * constructor(\n * thirdparty: TransferDisposable<Thirdparty>, // ✅,明确表示了我依赖了Thirdparty,但是该对象生命周期要归我所有\n * ) {\n * this._register(this._bar);\n * this._register(thirdparty.release()); // ✅,可以直接register\n * }\n * }\n *\n * 注意:\n * 不同于C++中的unique_ptr,该class只作用于转移场景。\n * 所以class理论上只在栈上出现,不应该在堆上存在。\n * 如果出现了需要在堆上存储的场景,可以联系架构侧\n */\nexport class TransferDisposable<T extends IDisposable> extends Disposable {\n private _val?: T;\n\n constructor(val: T) {\n super();\n\n this._val = val;\n }\n\n release() {\n // 只能release一次\n zkAssertNotNil(this._val);\n const v = this._val;\n this._val = undefined;\n return v;\n }\n\n dispose(): void {\n // 虽然它有dispose,但是不应该被执行,应该直接被gc才对\n Logger.warn(new Error('TransferDisposable call dispose.'));\n this._val?.dispose();\n super.dispose();\n }\n}\n","import { SafeDisposable, TransferDisposable } from './disposable-t';\nimport { EmptyDispose, type IDisposable } from './dispose-base';\nimport { MARK_AS_LEAKED } from './tracker';\n\nexport function makeSafeDisposable(fn: (...args: any) => any) {\n const disposable = new SafeDisposable({\n dispose: fn,\n });\n return disposable;\n}\n\nexport function makeEmptyDisposable() {\n return EmptyDispose;\n}\n\n// 忽略dispose\nexport function ignoreDispose(x: IDisposable) {\n MARK_AS_LEAKED(x);\n}\n\n// 判断一个thing是否是disposable\nexport function isDisposable<E = any>(thing: E): thing is E & IDisposable {\n return typeof (thing as IDisposable).dispose === 'function' && (thing as IDisposable).dispose.length === 0;\n}\n\nexport function makeTransferDisposable<T extends IDisposable>(val: T) {\n return new TransferDisposable(val);\n}\n","import type { IDisposable } from './dispose-base';\nimport { makeSafeDisposable } from './disposable-utils';\n\nexport function setDisposableTimeout(fn: (...args: any[]) => void, timeout: number): IDisposable {\n const handle = setTimeout(() => {\n fn();\n }, timeout);\n return makeSafeDisposable(() => clearTimeout(handle));\n}\n\nexport function setDisposableInterval(fn: (...args: any[]) => void, timeout: number): IDisposable {\n const handle = setInterval(() => {\n fn();\n }, timeout);\n return makeSafeDisposable(() => clearInterval(handle));\n}\n","class ListNode<T> {\n constructor(\n public value: T,\n public next: ListNode<T> | null = null,\n public prev: ListNode<T> | null = null,\n ) {}\n}\n\nexport class LinkedList<T> {\n protected _head: ListNode<T> | null = null;\n protected _tail: ListNode<T> | null = null;\n protected _count = 0;\n\n public get size(): number {\n return this._count;\n }\n\n public get firstNode(): ListNode<T> | null {\n return this._head;\n }\n\n public isEmpty(): boolean {\n return this._head === null;\n }\n\n public clear(): void {\n let current = this._head;\n while (current !== null) {\n const next = current.next;\n current.prev = null;\n current.next = null;\n current = next;\n }\n\n this._head = null;\n this._tail = null;\n this._count = 0;\n }\n\n public unshift(value: T): LinkedList<T> {\n const node = new ListNode(value);\n\n if (this.isEmpty()) {\n this._head = node;\n this._tail = node;\n } else {\n const oldHead = this._head;\n this._head = node;\n node.next = oldHead;\n oldHead!.prev = node;\n }\n\n this._count++;\n return this;\n }\n\n public push(value: T): LinkedList<T> {\n const node = new ListNode(value);\n\n if (this.isEmpty()) {\n this._head = node;\n this._tail = node;\n } else {\n const oldTail = this._tail;\n this._tail = node;\n node.prev = oldTail;\n oldTail!.next = node;\n }\n\n this._count++;\n return this;\n }\n\n public shift(): T | null {\n if (this.isEmpty()) {\n return null;\n }\n\n const node = this._head!;\n const value = node.value;\n this._remove(node);\n return value;\n }\n\n public pop(): T | null {\n if (this.isEmpty()) {\n return null;\n }\n\n const node = this._tail!;\n const value = node.value;\n this._remove(node);\n return value;\n }\n\n public toArray(): T[] {\n const result: T[] = [];\n for (const value of this) {\n result.push(value);\n }\n return result;\n }\n\n public *[Symbol.iterator](): Iterator<T> {\n let current = this._head;\n while (current !== null) {\n yield current.value;\n current = current.next;\n }\n }\n\n protected _remove(node: ListNode<T>): void {\n // 如果节点已经被移除(prev 和 next 都为 null),直接返回\n if (node.prev === null && node.next === null && node !== this._head && node !== this._tail) {\n return;\n }\n\n // 更新链表头尾指针\n if (node === this._head) {\n this._head = node.next;\n if (this._head) {\n this._head.prev = null;\n }\n }\n if (node === this._tail) {\n this._tail = node.prev;\n if (this._tail) {\n this._tail.next = null;\n }\n }\n\n // 更新相邻节点的引用\n if (node.prev) {\n node.prev.next = node.next;\n }\n if (node.next) {\n node.next.prev = node.prev;\n }\n\n // 清理被移除节点的引用\n node.prev = null;\n node.next = null;\n this._count--;\n }\n}\n","import { LinkedList } from '@/structure/linked-list';\n\nexport class DisposableLinkedList<T> extends LinkedList<T> {\n unshiftAndGetDisposableNode(value: T): () => void {\n this.unshift(value);\n\n const node = this._head!;\n let hasRemoved = false;\n return (): void => {\n if (!hasRemoved) {\n hasRemoved = true;\n super._remove(node);\n }\n };\n }\n\n pushAndGetDisposableNode(value: T): () => void {\n this.push(value);\n\n const node = this._tail!;\n let hasRemoved = false;\n return (): void => {\n if (!hasRemoved) {\n hasRemoved = true;\n super._remove(node);\n }\n };\n }\n}\n","/**\n * 针对未捕获的错误,异步抛出,不阻塞事件响应主流程\n * 默认模式\n */\nexport function asyncUnexpectedError(e: any): void {\n setTimeout(() => {\n throw e;\n }, 0);\n}\n\n/**\n * 针对未捕获的错误,同步抛出,阻塞事件响应主流程\n */\nexport function syncUnexpectedError(e: any): void {\n throw e;\n}\n\n/**\n * 针对未捕获的错误,静默掉,不进行处理\n */\n// eslint-disable-next-line @typescript-eslint/no-empty-function\nexport function ignoreUnexpectedError(e: any): void {}\n","import { makeSafeDisposable } from '@/dispose';\nimport type { IDisposable } from '@/dispose';\nimport { DisposableLinkedList } from './disposable-linked-list';\nimport { asyncUnexpectedError } from './error-handler';\n\nexport interface EmitterOptions {\n onAddListener?: (...args: any) => any;\n onRemoveListener?: (...args: any) => any;\n onListenerError?: (e: any) => void;\n}\n\n//\n// 事件监听中的回调实体\n//\nclass Listener<TArgs extends any[]> {\n private readonly _callback: (...args: TArgs) => void;\n private readonly _callbackThis: any | undefined;\n\n constructor(callback: (...args: TArgs) => void, callbackThis: any | undefined) {\n this._callback = callback;\n this._callbackThis = callbackThis;\n }\n\n invoke(...args: TArgs): void {\n this._callback.call(this._callbackThis, ...args);\n }\n}\n\n//\n// 存放在EventDeliveryQueue中的元素\n//\nclass EventDeliveryQueueElement<TArgs extends any[]> {\n readonly emitter: Emitter<TArgs>;\n readonly listener: Listener<TArgs>;\n readonly event: TArgs;\n constructor(emitter: Emitter<TArgs>, listener: Listener<TArgs>, event: TArgs) {\n this.emitter = emitter;\n this.listener = listener;\n this.event = event;\n }\n}\n\nexport class EventDeliveryQueue {\n protected _queue = new DisposableLinkedList<EventDeliveryQueueElement<any>>();\n\n constructor(private readonly _onListenerError: (e: unknown) => void = asyncUnexpectedError) {}\n\n get size(): number {\n return this._queue.size;\n }\n\n push<TArgs extends any[]>(emitter: Emitter<TArgs>, listener: Listener<TArgs>, event: TArgs): void {\n this._queue.push(new EventDeliveryQueueElement(emitter, listener, event));\n }\n\n clear<TArgs extends any[]>(emitter: Emitter<TArgs>): void {\n const newQueue = new DisposableLinkedList<EventDeliveryQueueElement<TArgs>>();\n for (const element of this._queue) {\n if (element.emitter !== emitter) {\n newQueue.push(element);\n }\n }\n this._queue = newQueue;\n }\n\n deliver(): void {\n while (this._queue.size > 0) {\n const element = this._queue.shift()!;\n try {\n element.listener.invoke(...element.event);\n } catch (e) {\n this._onListenerError(e);\n }\n }\n }\n}\n\nexport interface Event<T extends any[]> {\n (listener: (...args: T) => any, thisArgs?: any): IDisposable;\n}\n\nexport class Emitter<TArgs extends any[]> {\n protected _listeners?: DisposableLinkedList<Listener<TArgs>>;\n private readonly _options?: EmitterOptions;\n private _disposed = false;\n private _event?: Event<TArgs>;\n private _deliveryQueue?: EventDeliveryQueue;\n\n constructor(options?: EmitterOptions) {\n this._options = options;\n }\n\n get event(): Event<TArgs> {\n if (this._event) {\n return this._event;\n }\n\n this._event = (callback: (...args: TArgs) => any, thisArgs?: any): IDisposable => {\n const listener = new Listener(callback, thisArgs);\n\n if (!this._listeners) {\n this._listeners = new DisposableLinkedList();\n }\n\n const removeListener = this._listeners.pushAndGetDisposableNode(listener);\n\n if (this._options?.onAddListener) {\n this._options.onAddListener(this, callback, thisArgs);\n }\n\n // 生成可销毁函数返回\n const result = () => {\n if (!this._disposed) {\n removeListener();\n if (this._options?.onRemoveListener) {\n this._options.onRemoveListener(this, callback, thisArgs);\n }\n }\n };\n\n return makeSafeDisposable(result);\n };\n\n return this._event;\n }\n\n dispose(): void {\n if (this._disposed) {\n return;\n }\n this._disposed = true;\n this._listeners?.clear();\n this._deliveryQueue?.clear(this);\n }\n\n fire(...event: TArgs): void {\n if (!this._listeners || this._listeners.size === 0) {\n return;\n }\n // 绝大部分场景事件只会有一个监听器,针对性进行性能优化,没必要构造DeliveryQueue结构\n if (this._listeners.size === 1) {\n const listener = this._listeners.firstNode!;\n try {\n listener.value.invoke(...event);\n } catch (e) {\n if (this._options?.onListenerError) {\n this._options.onListenerError(e);\n } else {\n asyncUnexpectedError(e);\n }\n }\n return;\n }\n\n this._deliveryQueue ??= new EventDeliveryQueue(this._options?.onListenerError);\n\n for (const listener of this._listeners) {\n this._deliveryQueue.push(this, listener, event);\n }\n this._deliveryQueue.deliver();\n }\n}\n","import type { Event } from './emitter';\nimport type { IDisposable } from '@/dispose';\n\n// 辅助能力:只监听某个事件一次\nexport function listenOnce<TArgs extends any[]>(event: Event<TArgs>): Event<TArgs> {\n return (listener, thisArgs = null) => {\n let didFire = false;\n // 必须这样写,事件可能同步触发\n // eslint-disable-next-line no-undef-init\n let result: IDisposable | undefined = undefined;\n result = event((...args) => {\n if (didFire) {\n return;\n } else if (result) {\n result.dispose();\n } else {\n didFire = true;\n }\n\n return listener.call(thisArgs, ...args);\n }, null);\n\n if (didFire) {\n result.dispose();\n }\n\n return result;\n };\n}\n","import { zkAssert } from '@/assert';\nimport { Emitter, type Event } from '@/event';\n\n//\n// 资源对应的是标准库中的 unsigned state 以及相关的位运算\n// 我们用两个具体的Capability结构实现(Capability命名来源于标准库)\n//\n\n/**\n * 资源状态\n */\nexport enum CapabilityStatus {\n Unlocked,\n Locked,\n}\n\n/**\n * 独享的资源\n *\n * acquire 获取控制权\n * release 释放控制权\n */\nexport class Capability {\n public onUnlocked: Event<[]>;\n\n private readonly _onUnlocked = new Emitter<[]>();\n private _status = CapabilityStatus.Unlocked;\n\n constructor() {\n this.onUnlocked = this._onUnlocked.event;\n }\n\n get status(): CapabilityStatus {\n return this._status;\n }\n\n public acquire(): void {\n zkAssert(this._status === CapabilityStatus.Unlocked);\n this._status = CapabilityStatus.Locked;\n }\n\n public release(): void {\n zkAssert(this._status === CapabilityStatus.Locked);\n this._status = CapabilityStatus.Unlocked;\n this._onUnlocked.fire();\n }\n}\n\n/**\n * 共享的资源\n *\n * acquire 获取控制权\n * release 释放控制权\n */\nexport class SharedCapability {\n public onUnlocked: Event<[]>;\n\n private readonly _onUnlocked = new Emitter<[]>();\n private _status = CapabilityStatus.Unlocked;\n private _counter = 0;\n\n constructor() {\n this.onUnlocked = this._onUnlocked.event;\n }\n\n get status(): CapabilityStatus {\n return this._status;\n }\n\n get counter(): number {\n return this._counter;\n }\n\n public acquire() {\n if (this._status === CapabilityStatus.Unlocked) {\n this._status = CapabilityStatus.Locked;\n }\n this._counter++;\n }\n\n public release() {\n zkAssert(this._counter > 0);\n this._counter--;\n if (this._counter === 0) {\n this._status = CapabilityStatus.Unlocked;\n this._onUnlocked.fire();\n }\n }\n}\n","import type { Event } from '@/event';\nimport { Emitter } from '@/event';\n\n/**\n * 信号\n *\n * 用来模拟标准库的condition_variable\n * 提供监听某个信号被激活的能力\n */\nexport class Semaphore {\n public onActive: Event<[]>;\n private readonly _onActive = new Emitter<[]>();\n\n constructor() {\n this.onActive = this._onActive.event;\n }\n\n public notify(): void {\n this._onActive.fire();\n }\n}\n","import { zkAssert, zkAssertNotNil } from '@/assert';\nimport { listenOnce } from '@/event';\nimport { SharedCapability, Capability, CapabilityStatus } from './capability';\nimport { Semaphore } from './semaphore';\n\n/**\n * 提供读写能力的共享互斥量\n *\n * 参考C++17标准库双门思想实现\n * 接口也与标准库保持一致\n * 方法内部禁止promise,只可以对外暴露promise\n *\n * 核心\n * - 写写互斥,读写互斥,读读可重入\n *\n * 使用举例:\n * class Foo {\n * private _mutex = new SharedMutex();\n *\n * async add() {\n * // 上写锁\n * await this._mutex.lock();\n * // ...write something\n * this._mutex.unlock();\n * }\n *\n * async getSomething1() {\n * // 上读锁\n * await this._mutex.lockShared();\n * try {\n * return xxx;\n * } finally {\n * this._mutex.unlockShared();\n * }\n * }\n *\n * async getSomething2() {\n * // 上读锁\n * await this._mutex.lockShared();\n * try {\n * return xxx;\n * } finally {\n * this._mutex.unlockShared();\n * }\n * }\n * }\n */\nexport class SharedMutex {\n // 在第一道门外等待的写者\n private readonly _waitingWriters: Semaphore[] = [];\n\n // 已经通过了第一道门的写者\n // 如果在第二道门外等待,状态为sharedLocked\n // 如果已经进入到第二道门内拿到了锁,状态为locked\n private _writer?: Capability;\n\n // 在第一道门外等待的读者\n private _waitingReader?: Semaphore;\n\n // 拿到锁的读者\n private _reader?: SharedCapability;\n\n /**\n * 是否被锁住\n */\n public isLocked() {\n return this._writer || this._readerCount !== 0;\n }\n\n /**\n * 等待并获取写锁\n */\n public lock(): Promise<void> {\n return new Promise<void>((resolve) => {\n // 第一道门\n if (this._writer) {\n // 如果已经有写者进入了,其他写者等待\n const token = new Semaphore();\n this._waitingWriters.push(token);\n token.onActive(() => {\n this._writerEnterGate1(resolve);\n });\n } else {\n this._writerEnterGate1(resolve);\n }\n });\n }\n\n /**\n * 尝试获取写锁,立刻返回结果\n */\n public tryLock(): boolean {\n if (this._writer || this._readerCount > 0) {\n return false;\n }\n // 这里不需要await,一定可以上锁\n this.lock();\n return true;\n }\n\n /**\n * 解除写锁\n */\n public unLock(): void {\n zkAssertNotNil(this._writer);\n\n // 打开第一道门\n this._writer.release();\n }\n\n /**\n * 等待并获取读锁\n */\n public lockShared(): Promise<void> {\n return new Promise<void>((resolve) => {\n // 读者只需要进第一道门\n if (this._writer) {\n // 如果有写者已经进入了第一道门,读者等待\n if (!this._waitingReader) {\n this._waitingReader = new Semaphore();\n }\n this._waitingReader.onActive(() => {\n this._readerEnterGate1(resolve);\n });\n } else {\n this._readerEnterGate1(resolve);\n }\n });\n }\n\n /**\n * 尝试获取读锁,立刻返回结果\n */\n public tryLockShared(): boolean {\n if (this._writer) {\n return false;\n }\n // 不需要await,一定可以上锁\n this.lockShared();\n return true;\n }\n\n /**\n * 解除读锁\n */\n public unLockShared(): void {\n zkAssertNotNil(this._reader);\n if (this._writer) {\n // TODO(niurouwan): 暂时保留,方便验证,稳定后可以去掉\n zkAssert(this._writer.status === CapabilityStatus.Unlocked);\n }\n\n this._reader.release();\n }\n\n /**\n * 获取当前读者数量\n */\n private get _readerCount(): number {\n return this._reader ? this._reader.counter : 0;\n }\n\n /**\n * 写者进入第一道门\n */\n private _writerEnterGate1(resolve: () => void): void {\n zkAssert(!this._writer);\n // 确定写者,关第一道门\n this._writer = new Capability();\n\n // 第二道门\n // 等待所有读者出去\n if (this._readerCount > 0) {\n listenOnce(this._reader!.onUnlocked)(() => {\n this._writerEnterGate2(resolve);\n });\n } else {\n this._writerEnterGate2(resolve);\n }\n }\n\n /**\n * 写者进入第二道门\n */\n private _writerEnterGate2(resolve: () => void): void {\n zkAssertNotNil(this._writer);\n zkAssert(this._readerCount === 0);\n\n // 成功加锁\n this._writer.acquire();\n listenOnce(this._writer.onUnlocked)(() => {\n zkAssertNotNil(this._writer);\n // 不再持有\n this._writer = undefined;\n this._moveForward();\n });\n resolve();\n }\n\n /**\n * 读者进入第一道门\n */\n private _readerEnterGate1(resolve: () => void): void {\n zkAssert(!this._writer);\n\n // 门外等待的读者清除\n this._waitingReader = undefined;\n\n if (!this._reader) {\n this._reader = new SharedCapability();\n this._reader.acquire();\n listenOnce(this._reader.onUnlocked)(() => {\n this._moveForward();\n });\n } else {\n this._reader.acquire();\n }\n resolve();\n }\n\n /**\n * 锁释放时推进流程\n */\n private _moveForward(): void {\n // 如果有写者在等待在第二道门前面,那么此时推进的一定是读锁释放,直接return即可\n if (this._writer) {\n return;\n }\n\n // 写者优先,优先通知在第一道门前面的写者\n if (this._waitingWriters.length > 0) {\n const semaphore = this._waitingWriters.shift()!;\n semaphore.notify();\n return;\n }\n\n // 最后通知第一道门前面的读者\n if (this._waitingReader) {\n this._waitingReader.notify();\n }\n }\n}\n","import type { IDisposable } from '@/dispose';\nimport { setDisposableTimeout } from '@/dispose';\nimport type { SharedMutex } from './shared-mutex';\n\nexport interface IUnlockable extends IDisposable {\n unlock: () => void;\n}\n\n/**\n * 转移独占锁\n */\nexport async function transferLock(mutex: SharedMutex, timeout?: number): Promise<IUnlockable> {\n await mutex.lock();\n let didUnlock = false;\n let timerDisposable: IDisposable | undefined;\n\n if (timeout !== undefined) {\n timerDisposable = setDisposableTimeout(() => {\n if (!didUnlock) {\n mutex.unLock();\n didUnlock = true;\n }\n }, timeout);\n }\n\n const unlock = () => {\n timerDisposable?.dispose();\n if (!didUnlock) {\n mutex.unLock();\n didUnlock = true;\n }\n };\n\n return {\n dispose: unlock,\n unlock,\n };\n}\n\n/**\n * 尝试转移独占锁\n */\nexport function tryTransferLock(mutex: SharedMutex, timeout?: number): IUnlockable | undefined {\n if (!mutex.tryLock()) {\n return;\n }\n let didUnlock = false;\n let timerDisposable: IDisposable | undefined;\n\n if (timeout !== undefined) {\n timerDisposable = setDisposableTimeout(() => {\n if (!didUnlock) {\n mutex.unLock();\n didUnlock = true;\n }\n }, timeout);\n }\n\n const unlock = () => {\n timerDisposable?.dispose();\n if (!didUnlock) {\n mutex.unLock();\n didUnlock = true;\n }\n };\n\n return {\n dispose: unlock,\n unlock,\n };\n}\n\n/**\n * 转移共享锁\n */\nexport async function transferSharedLock(mutex: SharedMutex, timeout?: number): Promise<IUnlockable> {\n await mutex.lockShared();\n let didUnlock = false;\n let timerDisposable: IDisposable | undefined;\n\n if (timeout !== undefined) {\n timerDisposable = setDisposableTimeout(() => {\n if (!didUnlock) {\n mutex.unLockShared();\n didUnlock = true;\n }\n }, timeout);\n }\n\n const unlock = () => {\n timerDisposable?.dispose();\n if (!didUnlock) {\n mutex.unLockShared();\n didUnlock = true;\n }\n };\n\n return {\n dispose: unlock,\n unlock,\n };\n}\n\n/**\n * 尝试转移共享锁\n */\nexport function tryTransferSharedLock(mutex: SharedMutex, timeout?: number): IUnlockable | undefined {\n if (!mutex.tryLockShared()) {\n return;\n }\n let didUnlock = false;\n let timerDisposable: IDisposable | undefined;\n\n if (timeout !== undefined) {\n timerDisposable = setDisposableTimeout(() => {\n if (!didUnlock) {\n mutex.unLockShared();\n didUnlock = true;\n }\n }, timeout);\n }\n\n const unlock = () => {\n timerDisposable?.dispose();\n if (!didUnlock) {\n mutex.unLockShared();\n didUnlock = true;\n }\n };\n\n return {\n dispose: unlock,\n unlock,\n };\n}\n"]}
|
package/dist/lock/index.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
// src/assert/assert.ts
|
|
2
2
|
function abort(reason) {
|
|
3
|
-
throw new Error(`
|
|
3
|
+
throw new Error(`zkAssert(${reason})`);
|
|
4
4
|
}
|
|
5
|
-
function
|
|
5
|
+
function zkAssert(expr, reason) {
|
|
6
6
|
if (!expr) {
|
|
7
7
|
abort("#expr is false");
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
|
-
function
|
|
10
|
+
function zkAssertNotNil(val, reason) {
|
|
11
11
|
if (val === null || val === void 0) {
|
|
12
12
|
abort("#val is nil");
|
|
13
13
|
}
|
|
@@ -349,11 +349,11 @@ var Capability = class {
|
|
|
349
349
|
return this._status;
|
|
350
350
|
}
|
|
351
351
|
acquire() {
|
|
352
|
-
|
|
352
|
+
zkAssert(this._status === 0 /* Unlocked */);
|
|
353
353
|
this._status = 1 /* Locked */;
|
|
354
354
|
}
|
|
355
355
|
release() {
|
|
356
|
-
|
|
356
|
+
zkAssert(this._status === 1 /* Locked */);
|
|
357
357
|
this._status = 0 /* Unlocked */;
|
|
358
358
|
this._onUnlocked.fire();
|
|
359
359
|
}
|
|
@@ -378,7 +378,7 @@ var SharedCapability = class {
|
|
|
378
378
|
this._counter++;
|
|
379
379
|
}
|
|
380
380
|
release() {
|
|
381
|
-
|
|
381
|
+
zkAssert(this._counter > 0);
|
|
382
382
|
this._counter--;
|
|
383
383
|
if (this._counter === 0) {
|
|
384
384
|
this._status = 0 /* Unlocked */;
|
|
@@ -440,7 +440,7 @@ var SharedMutex = class {
|
|
|
440
440
|
* 解除写锁
|
|
441
441
|
*/
|
|
442
442
|
unLock() {
|
|
443
|
-
|
|
443
|
+
zkAssertNotNil(this._writer);
|
|
444
444
|
this._writer.release();
|
|
445
445
|
}
|
|
446
446
|
/**
|
|
@@ -474,9 +474,9 @@ var SharedMutex = class {
|
|
|
474
474
|
* 解除读锁
|
|
475
475
|
*/
|
|
476
476
|
unLockShared() {
|
|
477
|
-
|
|
477
|
+
zkAssertNotNil(this._reader);
|
|
478
478
|
if (this._writer) {
|
|
479
|
-
|
|
479
|
+
zkAssert(this._writer.status === 0 /* Unlocked */);
|
|
480
480
|
}
|
|
481
481
|
this._reader.release();
|
|
482
482
|
}
|
|
@@ -490,7 +490,7 @@ var SharedMutex = class {
|
|
|
490
490
|
* 写者进入第一道门
|
|
491
491
|
*/
|
|
492
492
|
_writerEnterGate1(resolve) {
|
|
493
|
-
|
|
493
|
+
zkAssert(!this._writer);
|
|
494
494
|
this._writer = new Capability();
|
|
495
495
|
if (this._readerCount > 0) {
|
|
496
496
|
listenOnce(this._reader.onUnlocked)(() => {
|
|
@@ -504,11 +504,11 @@ var SharedMutex = class {
|
|
|
504
504
|
* 写者进入第二道门
|
|
505
505
|
*/
|
|
506
506
|
_writerEnterGate2(resolve) {
|
|
507
|
-
|
|
508
|
-
|
|
507
|
+
zkAssertNotNil(this._writer);
|
|
508
|
+
zkAssert(this._readerCount === 0);
|
|
509
509
|
this._writer.acquire();
|
|
510
510
|
listenOnce(this._writer.onUnlocked)(() => {
|
|
511
|
-
|
|
511
|
+
zkAssertNotNil(this._writer);
|
|
512
512
|
this._writer = void 0;
|
|
513
513
|
this._moveForward();
|
|
514
514
|
});
|
|
@@ -518,7 +518,7 @@ var SharedMutex = class {
|
|
|
518
518
|
* 读者进入第一道门
|
|
519
519
|
*/
|
|
520
520
|
_readerEnterGate1(resolve) {
|
|
521
|
-
|
|
521
|
+
zkAssert(!this._writer);
|
|
522
522
|
this._waitingReader = void 0;
|
|
523
523
|
if (!this._reader) {
|
|
524
524
|
this._reader = new SharedCapability();
|