@delight-rpc/long-running-procedure 0.5.0
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/LICENSE +21 -0
- package/README.md +141 -0
- package/lib/contract.d.ts +15 -0
- package/lib/contract.js +9 -0
- package/lib/contract.js.map +1 -0
- package/lib/index.d.ts +6 -0
- package/lib/index.js +7 -0
- package/lib/index.js.map +1 -0
- package/lib/long-running-procedure/event-hub.d.ts +17 -0
- package/lib/long-running-procedure/event-hub.js +44 -0
- package/lib/long-running-procedure/event-hub.js.map +1 -0
- package/lib/long-running-procedure/index.d.ts +21 -0
- package/lib/long-running-procedure/index.js +103 -0
- package/lib/long-running-procedure/index.js.map +1 -0
- package/lib/long-running-procedure-caller.d.ts +7 -0
- package/lib/long-running-procedure-caller.js +26 -0
- package/lib/long-running-procedure-caller.js.map +1 -0
- package/lib/long-running-procedure-polling-caller.d.ts +8 -0
- package/lib/long-running-procedure-polling-caller.js +40 -0
- package/lib/long-running-procedure-polling-caller.js.map +1 -0
- package/lib/memory-store.d.ts +8 -0
- package/lib/memory-store.js +18 -0
- package/lib/memory-store.js.map +1 -0
- package/lib/types.d.ts +14 -0
- package/lib/types.js +7 -0
- package/lib/types.js.map +1 -0
- package/package.json +67 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022 BlackGlory <woshenmedoubuzhidao@blackglory.me>
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# long-running-procedure
|
|
2
|
+
## Install
|
|
3
|
+
```sh
|
|
4
|
+
npm install --save @delight-rpc/long-running-procedure
|
|
5
|
+
# or
|
|
6
|
+
yarn add @delight-rpc/long-running-procedure
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## API
|
|
10
|
+
```ts
|
|
11
|
+
enum CallState {
|
|
12
|
+
Pending
|
|
13
|
+
, Settled
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface ILongRunningProcedure<Args extends any[], Result> {
|
|
17
|
+
/**
|
|
18
|
+
* 调用此过程.
|
|
19
|
+
*
|
|
20
|
+
* @returns 该调用的id.
|
|
21
|
+
*/
|
|
22
|
+
call(args: Args): Awaitable<string>
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* 中断一个还未完成的调用.
|
|
26
|
+
* 如果该调用已经完成或调用不存在, 该函数会静默失败.
|
|
27
|
+
*/
|
|
28
|
+
abort(id: string): Awaitable<Nullish>
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* 返回调用的状态.
|
|
32
|
+
*
|
|
33
|
+
* @throws {CallNotFound}
|
|
34
|
+
*/
|
|
35
|
+
getState(id: string): Awaitable<CallState>
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* 获取调用的结果, 如果调用尚未完成, 则会阻塞直到完成.
|
|
39
|
+
*
|
|
40
|
+
* @throws {CallNotFound}
|
|
41
|
+
*/
|
|
42
|
+
getResult(id: string): Awaitable<Result>
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* 删除一个已经完成的调用, 这会导致与该调用相关的信息被删除.
|
|
46
|
+
* 如果该调用还未完成, 则该操作会抛出错误.
|
|
47
|
+
* 如果该调用已经删除, 则该操作会静默失败.
|
|
48
|
+
*/
|
|
49
|
+
remove(id: string): Awaitable<Nullish>
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
class CallNotFound extends CustomError {}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### LongRunningProcedure
|
|
56
|
+
```ts
|
|
57
|
+
class LongRunningProcedure<Args extends unknown[], Result, Error>
|
|
58
|
+
implements ILongRunningProcedure<Args, Result> {
|
|
59
|
+
/**
|
|
60
|
+
* 超时和TTL的存在是为了减缓错误的实现耗尽存储空间的速度.
|
|
61
|
+
*
|
|
62
|
+
* @param timeout 调用的超时时间(毫秒), 超时的调用会被自动中断.
|
|
63
|
+
* @param timeToLive 调用从完成开始计算的存活时间(毫秒), 超出存活时间的调用会被删除.
|
|
64
|
+
*/
|
|
65
|
+
constructor(
|
|
66
|
+
procedure: (...args: [...Args, AbortSignal]) => PromiseLike<Result>
|
|
67
|
+
, options?: {
|
|
68
|
+
store?: Store<Result, Error>
|
|
69
|
+
timeout?: number
|
|
70
|
+
timeToLive?: number
|
|
71
|
+
}
|
|
72
|
+
)
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Caller
|
|
77
|
+
```ts
|
|
78
|
+
interface ILongRunningProcedureCaller<Args extends unknown[], Result> {
|
|
79
|
+
call(...args: [...args: Args, signal: AbortSignal]): Promise<Result>
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
#### LongRunningProcedureCaller
|
|
84
|
+
```ts
|
|
85
|
+
/**
|
|
86
|
+
* 以长连接方式接收长时运行过程的结果, 结果会尽快返回.
|
|
87
|
+
* 请注意, 在一些信道上维持长连接需要付出成本.
|
|
88
|
+
*/
|
|
89
|
+
class LongRunningProcedureCaller<Args extends unknown[], Result>
|
|
90
|
+
implements ILongRunningProcedureCaller<Args, Result> {
|
|
91
|
+
constructor(procedure: ILongRunningProcedure<Args, Result>)
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
#### LongRunningProcedurePollingCaller
|
|
96
|
+
```ts
|
|
97
|
+
/**
|
|
98
|
+
* 以轮询方式接收长时运行过程的结果, 这无法尽快返回结果.
|
|
99
|
+
* 请注意, 视轮询间隔, 可能会造成很多被浪费的请求.
|
|
100
|
+
*/
|
|
101
|
+
class LongRunningProcedurePollingCaller<Args extends unknown[], Result>
|
|
102
|
+
implements ILongRunningProcedureCaller<Args, Result> {
|
|
103
|
+
constructor(
|
|
104
|
+
procedure: ILongRunningProcedure<Args, Result>
|
|
105
|
+
, pollingInterval: number
|
|
106
|
+
)
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Store
|
|
111
|
+
```ts
|
|
112
|
+
enum StoreItemState {
|
|
113
|
+
Pending
|
|
114
|
+
, Resolved
|
|
115
|
+
, Rejected
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
interface Store<Result, Error> {
|
|
119
|
+
set(
|
|
120
|
+
id: string
|
|
121
|
+
, value:
|
|
122
|
+
| [StoreItemState.Pending]
|
|
123
|
+
| [StoreItemState.Resolved, Result]
|
|
124
|
+
| [StoreItemState.Rejected, Error]
|
|
125
|
+
, timeToLive?: number
|
|
126
|
+
): Awaitable<Nullish>
|
|
127
|
+
|
|
128
|
+
get(id: string): Awaitable<Nullable<
|
|
129
|
+
| [StoreItemState.Pending]
|
|
130
|
+
| [StoreItemState.Resolved, Result]
|
|
131
|
+
| [StoreItemState.Rejected, Error]
|
|
132
|
+
>>
|
|
133
|
+
|
|
134
|
+
delete(id: string): Awaitable<Nullish>
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
#### MemoryStore
|
|
139
|
+
```ts
|
|
140
|
+
class MemoryStore<Result, Error> implements Store<Result, Error> {}
|
|
141
|
+
```
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { CustomError } from '@blackglory/errors';
|
|
2
|
+
import { Awaitable, Nullish } from '@blackglory/prelude';
|
|
3
|
+
export declare enum CallState {
|
|
4
|
+
Pending = 0,
|
|
5
|
+
Settled = 1
|
|
6
|
+
}
|
|
7
|
+
export interface ILongRunningProcedure<Args extends any[], Result> {
|
|
8
|
+
call(args: Args): Awaitable<string>;
|
|
9
|
+
abort(id: string): Awaitable<Nullish>;
|
|
10
|
+
getState(id: string): Awaitable<CallState>;
|
|
11
|
+
getResult(id: string): Awaitable<Result>;
|
|
12
|
+
remove(id: string): Awaitable<Nullish>;
|
|
13
|
+
}
|
|
14
|
+
export declare class CallNotFound extends CustomError {
|
|
15
|
+
}
|
package/lib/contract.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { CustomError } from '@blackglory/errors';
|
|
2
|
+
export var CallState;
|
|
3
|
+
(function (CallState) {
|
|
4
|
+
CallState[CallState["Pending"] = 0] = "Pending";
|
|
5
|
+
CallState[CallState["Settled"] = 1] = "Settled";
|
|
6
|
+
})(CallState = CallState || (CallState = {}));
|
|
7
|
+
export class CallNotFound extends CustomError {
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=contract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract.js","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAGhD,MAAM,CAAN,IAAY,SAGX;AAHD,WAAY,SAAS;IACnB,+CAAO,CAAA;IACP,+CAAO,CAAA;AACT,CAAC,EAHW,SAAS,GAAT,SAAS,KAAT,SAAS,QAGpB;AAsCD,MAAM,OAAO,YAAa,SAAQ,WAAW;CAAG"}
|
package/lib/index.d.ts
ADDED
package/lib/index.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export * from './contract.js';
|
|
2
|
+
export * from './types.js';
|
|
3
|
+
export * from './long-running-procedure-caller.js';
|
|
4
|
+
export * from './long-running-procedure-polling-caller.js';
|
|
5
|
+
export * from './long-running-procedure/index.js';
|
|
6
|
+
export * from './memory-store.js';
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAA;AAC7B,cAAc,YAAY,CAAA;AAC1B,cAAc,oCAAoC,CAAA;AAClD,cAAc,4CAA4C,CAAA;AAC1D,cAAc,mCAAmC,CAAA;AACjD,cAAc,mBAAmB,CAAA"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare enum Event {
|
|
2
|
+
Settled = 0,
|
|
3
|
+
Removed = 1
|
|
4
|
+
}
|
|
5
|
+
type EventToArgs = {
|
|
6
|
+
[Event.Settled]: [];
|
|
7
|
+
[Event.Removed]: [];
|
|
8
|
+
};
|
|
9
|
+
export declare class EventHub {
|
|
10
|
+
private idToEmitter;
|
|
11
|
+
waitFor(id: string, event: keyof EventToArgs, abortSignal?: AbortSignal): Promise<void>;
|
|
12
|
+
on<T extends Event>(id: string, event: T, listener: (...args: EventToArgs[T]) => void): () => void;
|
|
13
|
+
once<T extends Event>(id: string, event: T, listener: (...args: EventToArgs[T]) => void): () => void;
|
|
14
|
+
emit<T extends Event>(id: string, event: T, ...args: EventToArgs[T]): void;
|
|
15
|
+
removeAllListeners(id: string): void;
|
|
16
|
+
}
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Emitter } from '@blackglory/structures';
|
|
2
|
+
import { waitForEmitter } from '@blackglory/wait-for';
|
|
3
|
+
export var Event;
|
|
4
|
+
(function (Event) {
|
|
5
|
+
Event[Event["Settled"] = 0] = "Settled";
|
|
6
|
+
Event[Event["Removed"] = 1] = "Removed";
|
|
7
|
+
})(Event = Event || (Event = {}));
|
|
8
|
+
export class EventHub {
|
|
9
|
+
constructor() {
|
|
10
|
+
this.idToEmitter = new Map();
|
|
11
|
+
}
|
|
12
|
+
async waitFor(id, event, abortSignal) {
|
|
13
|
+
if (!this.idToEmitter.has(id)) {
|
|
14
|
+
this.idToEmitter.set(id, new Emitter());
|
|
15
|
+
}
|
|
16
|
+
const emitter = this.idToEmitter.get(id);
|
|
17
|
+
await waitForEmitter(emitter, event, abortSignal);
|
|
18
|
+
}
|
|
19
|
+
on(id, event, listener) {
|
|
20
|
+
if (!this.idToEmitter.has(id)) {
|
|
21
|
+
this.idToEmitter.set(id, new Emitter());
|
|
22
|
+
}
|
|
23
|
+
const emitter = this.idToEmitter.get(id);
|
|
24
|
+
return emitter.on(event, listener);
|
|
25
|
+
}
|
|
26
|
+
once(id, event, listener) {
|
|
27
|
+
if (!this.idToEmitter.has(id)) {
|
|
28
|
+
this.idToEmitter.set(id, new Emitter());
|
|
29
|
+
}
|
|
30
|
+
const emitter = this.idToEmitter.get(id);
|
|
31
|
+
return emitter.once(event, listener);
|
|
32
|
+
}
|
|
33
|
+
emit(id, event, ...args) {
|
|
34
|
+
var _a;
|
|
35
|
+
(_a = this.idToEmitter.get(id)) === null || _a === void 0 ? void 0 : _a.emit(event, ...args);
|
|
36
|
+
}
|
|
37
|
+
removeAllListeners(id) {
|
|
38
|
+
const emitter = this.idToEmitter.get(id);
|
|
39
|
+
if (emitter) {
|
|
40
|
+
emitter.removeAllListeners(Event.Settled);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=event-hub.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-hub.js","sourceRoot":"","sources":["../../src/long-running-procedure/event-hub.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAA;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAErD,MAAM,CAAN,IAAY,KAGX;AAHD,WAAY,KAAK;IACf,uCAAO,CAAA;IACP,uCAAO,CAAA;AACT,CAAC,EAHW,KAAK,GAAL,KAAK,KAAL,KAAK,QAGhB;AAOD,MAAM,OAAO,QAAQ;IAArB;QACU,gBAAW,GAAsC,IAAI,GAAG,EAAE,CAAA;IAuDpE,CAAC;IArDC,KAAK,CAAC,OAAO,CACX,EAAU,EACV,KAAwB,EACxB,WAAyB;QAEzB,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;YAC7B,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,OAAO,EAAE,CAAC,CAAA;SACxC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAE,CAAA;QACzC,MAAM,cAAc,CAAC,OAAO,EAAE,KAAK,EAAE,WAAW,CAAC,CAAA;IACnD,CAAC;IAED,EAAE,CACA,EAAU,EACV,KAAQ,EACR,QAA2C;QAE3C,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;YAC7B,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,OAAO,EAAE,CAAC,CAAA;SACxC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAE,CAAA;QACzC,OAAO,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;IACpC,CAAC;IAED,IAAI,CACF,EAAU,EACV,KAAQ,EACR,QAA2C;QAE3C,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;YAC7B,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,OAAO,EAAE,CAAC,CAAA;SACxC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAE,CAAA;QACzC,OAAO,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;IACtC,CAAC;IAED,IAAI,CACF,EAAU,EACV,KAAQ,EACR,GAAG,IAAoB;;QAEvB,MAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,0CAAE,IAAI,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,CAAA;IAChD,CAAC;IAED,kBAAkB,CAAC,EAAU;QAC3B,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QACxC,IAAI,OAAO,EAAE;YACX,OAAO,CAAC,kBAAkB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;SAC1C;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ILongRunningProcedure, CallState } from '@src/contract.js';
|
|
2
|
+
import { Store } from '@src/types.js';
|
|
3
|
+
export declare class LongRunningProcedure<Args extends unknown[], Result, Error> implements ILongRunningProcedure<Args, Result> {
|
|
4
|
+
private procedure;
|
|
5
|
+
private eventHub;
|
|
6
|
+
private idToAbortController;
|
|
7
|
+
private store;
|
|
8
|
+
private timeout?;
|
|
9
|
+
private timeToLive?;
|
|
10
|
+
constructor(procedure: (...args: [...Args, AbortSignal]) => PromiseLike<Result>, { store, timeToLive, timeout }?: {
|
|
11
|
+
store?: Store<Result, Error>;
|
|
12
|
+
timeout?: number;
|
|
13
|
+
timeToLive?: number;
|
|
14
|
+
});
|
|
15
|
+
call(args: Args): Promise<string>;
|
|
16
|
+
abort(id: string): null;
|
|
17
|
+
getState(id: string): Promise<CallState>;
|
|
18
|
+
getResult(id: string): Promise<Result>;
|
|
19
|
+
remove(id: string): Promise<null>;
|
|
20
|
+
private createId;
|
|
21
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { nanoid } from 'nanoid';
|
|
2
|
+
import { CallState, CallNotFound } from '@src/contract.js';
|
|
3
|
+
import { toResultPromise } from 'return-style';
|
|
4
|
+
import { AbortController } from 'extra-abort';
|
|
5
|
+
import { EventHub, Event } from './event-hub.js';
|
|
6
|
+
import { setTimeout } from 'extra-timers';
|
|
7
|
+
import { StoreItemState } from '@src/types.js';
|
|
8
|
+
import { MemoryStore } from '@src/memory-store.js';
|
|
9
|
+
export class LongRunningProcedure {
|
|
10
|
+
constructor(procedure, { store = new MemoryStore(), timeToLive, timeout } = {}) {
|
|
11
|
+
this.procedure = procedure;
|
|
12
|
+
this.eventHub = new EventHub();
|
|
13
|
+
this.idToAbortController = new Map();
|
|
14
|
+
this.store = store;
|
|
15
|
+
this.timeToLive = timeToLive;
|
|
16
|
+
this.timeout = timeout;
|
|
17
|
+
}
|
|
18
|
+
async call(args) {
|
|
19
|
+
const id = this.createId();
|
|
20
|
+
const controller = new AbortController();
|
|
21
|
+
this.idToAbortController.set(id, controller);
|
|
22
|
+
await this.store.set(id, [StoreItemState.Pending], this.timeout);
|
|
23
|
+
queueMicrotask(async () => {
|
|
24
|
+
const result = await toResultPromise(this.procedure(...args, controller.signal));
|
|
25
|
+
const item = await this.store.get(id);
|
|
26
|
+
if (item) {
|
|
27
|
+
if (result.isOk()) {
|
|
28
|
+
await this.store.set(id, [StoreItemState.Resolved, result.unwrap()], this.timeToLive);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
await this.store.set(id, [StoreItemState.Rejected, result.unwrapErr()], this.timeToLive);
|
|
32
|
+
}
|
|
33
|
+
if (this.timeToLive) {
|
|
34
|
+
const cancelTimeout = setTimeout(this.timeToLive, () => this.remove(id));
|
|
35
|
+
this.eventHub.once(id, Event.Removed, cancelTimeout);
|
|
36
|
+
}
|
|
37
|
+
this.eventHub.emit(id, Event.Settled);
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
return id;
|
|
41
|
+
}
|
|
42
|
+
abort(id) {
|
|
43
|
+
var _a;
|
|
44
|
+
(_a = this.idToAbortController.get(id)) === null || _a === void 0 ? void 0 : _a.abort();
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
async getState(id) {
|
|
48
|
+
const item = await this.store.get(id);
|
|
49
|
+
if (item) {
|
|
50
|
+
const [state] = item;
|
|
51
|
+
switch (state) {
|
|
52
|
+
case StoreItemState.Pending: return CallState.Pending;
|
|
53
|
+
case StoreItemState.Resolved:
|
|
54
|
+
case StoreItemState.Rejected:
|
|
55
|
+
return CallState.Settled;
|
|
56
|
+
default:
|
|
57
|
+
throw new Error(`Unknown store state ${state}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
throw new CallNotFound();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
async getResult(id) {
|
|
65
|
+
const item = await this.store.get(id);
|
|
66
|
+
if (item) {
|
|
67
|
+
const [state, value] = item;
|
|
68
|
+
switch (state) {
|
|
69
|
+
case StoreItemState.Pending: {
|
|
70
|
+
const controller = this.idToAbortController.get(id);
|
|
71
|
+
await this.eventHub.waitFor(id, Event.Settled, controller.signal);
|
|
72
|
+
return await this.getResult(id);
|
|
73
|
+
}
|
|
74
|
+
case StoreItemState.Resolved: return value;
|
|
75
|
+
case StoreItemState.Rejected: throw value;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
throw new CallNotFound();
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
async remove(id) {
|
|
83
|
+
const item = await this.store.get(id);
|
|
84
|
+
if (item) {
|
|
85
|
+
const [state] = item;
|
|
86
|
+
switch (state) {
|
|
87
|
+
case StoreItemState.Pending: throw new Error('The call is still pending');
|
|
88
|
+
case StoreItemState.Resolved:
|
|
89
|
+
case StoreItemState.Rejected: {
|
|
90
|
+
this.eventHub.emit(id, Event.Removed);
|
|
91
|
+
this.eventHub.removeAllListeners(id);
|
|
92
|
+
this.idToAbortController.delete(id);
|
|
93
|
+
await this.store.delete(id);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
createId() {
|
|
100
|
+
return nanoid();
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/long-running-procedure/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ILongRunningProcedure } from './contract.js';
|
|
2
|
+
import { ILongRunningProcedureCaller } from './types.js';
|
|
3
|
+
export declare class LongRunningProcedureCaller<Args extends unknown[], Result> implements ILongRunningProcedureCaller<Args, Result> {
|
|
4
|
+
private procedure;
|
|
5
|
+
constructor(procedure: ILongRunningProcedure<Args, Result>);
|
|
6
|
+
call(...args: [...args: Args, signal: AbortSignal]): Promise<Result>;
|
|
7
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export class LongRunningProcedureCaller {
|
|
2
|
+
constructor(procedure) {
|
|
3
|
+
this.procedure = procedure;
|
|
4
|
+
}
|
|
5
|
+
async call(...args) {
|
|
6
|
+
const realArgs = args.slice(0, args.length - 1);
|
|
7
|
+
const signal = args[args.length - 1];
|
|
8
|
+
signal.throwIfAborted();
|
|
9
|
+
const id = await this.procedure.call(realArgs);
|
|
10
|
+
try {
|
|
11
|
+
if (signal.aborted) {
|
|
12
|
+
await this.procedure.abort(id);
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
signal.addEventListener('abort', async () => {
|
|
16
|
+
await this.procedure.abort(id);
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
return await this.procedure.getResult(id);
|
|
20
|
+
}
|
|
21
|
+
finally {
|
|
22
|
+
await this.procedure.remove(id);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=long-running-procedure-caller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"long-running-procedure-caller.js","sourceRoot":"","sources":["../src/long-running-procedure-caller.ts"],"names":[],"mappings":"AAOA,MAAM,OAAO,0BAA0B;IAErC,YAAoB,SAA8C;QAA9C,cAAS,GAAT,SAAS,CAAqC;IAAG,CAAC;IAEtE,KAAK,CAAC,IAAI,CAAC,GAAG,IAA0C;QACtD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC,CAAS,CAAA;QACvD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAgB,CAAA;QACnD,MAAM,CAAC,cAAc,EAAE,CAAA;QAEvB,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QAC9C,IAAI;YACF,IAAI,MAAM,CAAC,OAAO,EAAE;gBAClB,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;aAC/B;iBAAM;gBACL,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,KAAK,IAAI,EAAE;oBAC1C,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;gBAChC,CAAC,CAAC,CAAA;aACH;YAED,OAAO,MAAM,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,CAAC,CAAA;SAC1C;gBAAS;YACR,MAAM,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;SAChC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ILongRunningProcedure } from './contract.js';
|
|
2
|
+
import { ILongRunningProcedureCaller } from './types.js';
|
|
3
|
+
export declare class LongRunningProcedurePollingCaller<Args extends unknown[], Result> implements ILongRunningProcedureCaller<Args, Result> {
|
|
4
|
+
private procedure;
|
|
5
|
+
private pollingInterval;
|
|
6
|
+
constructor(procedure: ILongRunningProcedure<Args, Result>, pollingInterval: number);
|
|
7
|
+
call(...args: [...args: Args, signal: AbortSignal]): Promise<Result>;
|
|
8
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { delay } from 'extra-promise';
|
|
2
|
+
import { CallState } from './contract.js';
|
|
3
|
+
export class LongRunningProcedurePollingCaller {
|
|
4
|
+
constructor(procedure, pollingInterval) {
|
|
5
|
+
this.procedure = procedure;
|
|
6
|
+
this.pollingInterval = pollingInterval;
|
|
7
|
+
}
|
|
8
|
+
async call(...args) {
|
|
9
|
+
const realArgs = args.slice(0, args.length - 1);
|
|
10
|
+
const signal = args[args.length - 1];
|
|
11
|
+
signal.throwIfAborted();
|
|
12
|
+
const id = await this.procedure.call(realArgs);
|
|
13
|
+
try {
|
|
14
|
+
if (signal.aborted) {
|
|
15
|
+
await this.procedure.abort(id);
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
signal.addEventListener('abort', async () => {
|
|
19
|
+
await this.procedure.abort(id);
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
while (true) {
|
|
23
|
+
const state = await this.procedure.getState(id);
|
|
24
|
+
switch (state) {
|
|
25
|
+
case CallState.Pending: {
|
|
26
|
+
await delay(this.pollingInterval);
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
case CallState.Settled: {
|
|
30
|
+
return await this.procedure.getResult(id);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
finally {
|
|
36
|
+
await this.procedure.remove(id);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=long-running-procedure-polling-caller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"long-running-procedure-polling-caller.js","sourceRoot":"","sources":["../src/long-running-procedure-polling-caller.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AACrC,OAAO,EAAyB,SAAS,EAAE,MAAM,eAAe,CAAA;AAOhE,MAAM,OAAO,iCAAiC;IAE5C,YACU,SAA8C,EAC9C,eAAuB;QADvB,cAAS,GAAT,SAAS,CAAqC;QAC9C,oBAAe,GAAf,eAAe,CAAQ;IAC9B,CAAC;IAEJ,KAAK,CAAC,IAAI,CAAC,GAAG,IAA0C;QACtD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC,CAAS,CAAA;QACvD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAgB,CAAA;QACnD,MAAM,CAAC,cAAc,EAAE,CAAA;QAEvB,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QAC9C,IAAI;YACF,IAAI,MAAM,CAAC,OAAO,EAAE;gBAClB,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;aAC/B;iBAAM;gBACL,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,KAAK,IAAI,EAAE;oBAC1C,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;gBAChC,CAAC,CAAC,CAAA;aACH;YAED,OAAO,IAAI,EAAE;gBACX,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;gBAE/C,QAAQ,KAAK,EAAE;oBACb,KAAK,SAAS,CAAC,OAAO,CAAC,CAAC;wBACtB,MAAM,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAA;wBACjC,MAAK;qBACN;oBACD,KAAK,SAAS,CAAC,OAAO,CAAC,CAAC;wBACtB,OAAO,MAAM,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,CAAC,CAAA;qBAC1C;iBACF;aACF;SACF;gBAAS;YACR,MAAM,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;SAChC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Awaitable, Nullish, Nullable } from '@blackglory/prelude';
|
|
2
|
+
import { Store, StoreItemState } from './types.js';
|
|
3
|
+
export declare class MemoryStore<Result, Error> implements Store<Result, Error> {
|
|
4
|
+
private map;
|
|
5
|
+
set(id: string, value: [StoreItemState.Pending] | [StoreItemState.Resolved, Result] | [StoreItemState.Rejected, Error], timeToLive?: number): null;
|
|
6
|
+
get(id: string): Awaitable<Nullable<[StoreItemState.Pending] | [StoreItemState.Resolved, Result] | [StoreItemState.Rejected, Error]>>;
|
|
7
|
+
delete(id: string): Awaitable<Nullish>;
|
|
8
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ExpirableMap } from '@blackglory/structures';
|
|
2
|
+
export class MemoryStore {
|
|
3
|
+
constructor() {
|
|
4
|
+
this.map = new ExpirableMap();
|
|
5
|
+
}
|
|
6
|
+
set(id, value, timeToLive) {
|
|
7
|
+
this.map.set(id, value, timeToLive);
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
get(id) {
|
|
11
|
+
return this.map.get(id);
|
|
12
|
+
}
|
|
13
|
+
delete(id) {
|
|
14
|
+
this.map.delete(id);
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=memory-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-store.js","sourceRoot":"","sources":["../src/memory-store.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAA;AAGrD,MAAM,OAAO,WAAW;IAAxB;QACU,QAAG,GAAG,IAAI,YAAY,EAK3B,CAAA;IA4BL,CAAC;IA1BC,GAAG,CACD,EAAU,EACV,KAGkC,EAClC,UAAmB;QAEnB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,UAAU,CAAC,CAAA;QAEnC,OAAO,IAAI,CAAA;IACb,CAAC;IAED,GAAG,CAAC,EAAU;QAKZ,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IACzB,CAAC;IAED,MAAM,CAAC,EAAU;QACf,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;QAEnB,OAAO,IAAI,CAAA;IACb,CAAC;CACF"}
|
package/lib/types.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Awaitable, Nullable, Nullish } from '@blackglory/prelude';
|
|
2
|
+
export declare enum StoreItemState {
|
|
3
|
+
Pending = 0,
|
|
4
|
+
Resolved = 1,
|
|
5
|
+
Rejected = 2
|
|
6
|
+
}
|
|
7
|
+
export interface Store<Result, Error> {
|
|
8
|
+
set(id: string, value: [StoreItemState.Pending] | [StoreItemState.Resolved, Result] | [StoreItemState.Rejected, Error], timeToLive?: number): Awaitable<Nullish>;
|
|
9
|
+
get(id: string): Awaitable<Nullable<[StoreItemState.Pending] | [StoreItemState.Resolved, Result] | [StoreItemState.Rejected, Error]>>;
|
|
10
|
+
delete(id: string): Awaitable<Nullish>;
|
|
11
|
+
}
|
|
12
|
+
export interface ILongRunningProcedureCaller<Args extends unknown[], Result> {
|
|
13
|
+
call(...args: [...args: Args, signal: AbortSignal]): Promise<Result>;
|
|
14
|
+
}
|
package/lib/types.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export var StoreItemState;
|
|
2
|
+
(function (StoreItemState) {
|
|
3
|
+
StoreItemState[StoreItemState["Pending"] = 0] = "Pending";
|
|
4
|
+
StoreItemState[StoreItemState["Resolved"] = 1] = "Resolved";
|
|
5
|
+
StoreItemState[StoreItemState["Rejected"] = 2] = "Rejected";
|
|
6
|
+
})(StoreItemState = StoreItemState || (StoreItemState = {}));
|
|
7
|
+
//# sourceMappingURL=types.js.map
|
package/lib/types.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAEA,MAAM,CAAN,IAAY,cAIX;AAJD,WAAY,cAAc;IACxB,yDAAO,CAAA;IACP,2DAAQ,CAAA;IACR,2DAAQ,CAAA;AACV,CAAC,EAJW,cAAc,GAAd,cAAc,KAAd,cAAc,QAIzB"}
|
package/package.json
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@delight-rpc/long-running-procedure",
|
|
3
|
+
"version": "0.5.0",
|
|
4
|
+
"description": "",
|
|
5
|
+
"files": [
|
|
6
|
+
"lib"
|
|
7
|
+
],
|
|
8
|
+
"type": "module",
|
|
9
|
+
"main": "lib/index.js",
|
|
10
|
+
"types": "lib/index.d.ts",
|
|
11
|
+
"sideEffects": false,
|
|
12
|
+
"repository": "git@github.com:delight-rpc/long-running-procedure.git",
|
|
13
|
+
"author": "BlackGlory <woshenmedoubuzhidao@blackglory.me>",
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"engines": {
|
|
16
|
+
"node": ">=16"
|
|
17
|
+
},
|
|
18
|
+
"scripts": {
|
|
19
|
+
"prepare": "ts-patch install -s",
|
|
20
|
+
"lint": "eslint --ext .js,.jsx,.ts,.tsx --quiet src __tests__",
|
|
21
|
+
"test": "cross-env NODE_OPTIONS=--experimental-vm-modules jest --runInBand --no-cache --config jest.config.cjs",
|
|
22
|
+
"test:debug": "cross-env NODE_OPTIONS=--experimental-vm-modules node --inspect-brk node_modules/.bin/jest --runInBand --config jest.config.cjs",
|
|
23
|
+
"test:coverage": "cross-env NODE_OPTIONS=--experimental-vm-modules jest --runInBand --coverage --config jest.config.cjs",
|
|
24
|
+
"prepublishOnly": "run-s prepare clean build",
|
|
25
|
+
"clean": "rimraf lib",
|
|
26
|
+
"build": "tsc --project tsconfig.build.json",
|
|
27
|
+
"release": "standard-version"
|
|
28
|
+
},
|
|
29
|
+
"husky": {
|
|
30
|
+
"hooks": {
|
|
31
|
+
"pre-commit": "run-s prepare lint build test",
|
|
32
|
+
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@blackglory/jest-resolver": "^0.3.0",
|
|
37
|
+
"@commitlint/cli": "^17.4.4",
|
|
38
|
+
"@commitlint/config-conventional": "^17.4.4",
|
|
39
|
+
"@types/jest": "^29.5.0",
|
|
40
|
+
"@typescript-eslint/eslint-plugin": "^5.55.0",
|
|
41
|
+
"@typescript-eslint/parser": "^5.55.0",
|
|
42
|
+
"cross-env": "^7.0.3",
|
|
43
|
+
"eslint": "^8.36.0",
|
|
44
|
+
"husky": "4",
|
|
45
|
+
"jest": "^29.5.0",
|
|
46
|
+
"jest-resolve": "^29.5.0",
|
|
47
|
+
"npm-run-all": "^4.1.5",
|
|
48
|
+
"rimraf": "^3.0.2",
|
|
49
|
+
"standard-version": "^9.3.2",
|
|
50
|
+
"ts-jest": "^29.0.5",
|
|
51
|
+
"ts-patch": "^2.1.0",
|
|
52
|
+
"tslib": "^2.5.0",
|
|
53
|
+
"typescript": "5.0.2",
|
|
54
|
+
"typescript-transform-paths": "^3.4.6"
|
|
55
|
+
},
|
|
56
|
+
"dependencies": {
|
|
57
|
+
"@blackglory/errors": "^3.0.0",
|
|
58
|
+
"@blackglory/prelude": "^0.3.1",
|
|
59
|
+
"@blackglory/structures": "^0.13.3",
|
|
60
|
+
"@blackglory/wait-for": "^0.7.3",
|
|
61
|
+
"extra-abort": "^0.3.2",
|
|
62
|
+
"extra-promise": "^6.0.5",
|
|
63
|
+
"extra-timers": "^0.2.5",
|
|
64
|
+
"nanoid": "4.0.1",
|
|
65
|
+
"return-style": "^3.0.0"
|
|
66
|
+
}
|
|
67
|
+
}
|