@push-rpc/next 2.0.6 → 2.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/dist/client/HttpClient.js +5 -1
- package/dist/client/HttpClient.js.map +1 -1
- package/dist/client/RemoteSubscriptions.d.ts +5 -0
- package/dist/client/RemoteSubscriptions.js +54 -14
- package/dist/client/RemoteSubscriptions.js.map +1 -1
- package/dist/client/RpcClientImpl.js +5 -0
- package/dist/client/RpcClientImpl.js.map +1 -1
- package/package.json +1 -1
- package/src/client/HttpClient.ts +7 -1
- package/src/client/RemoteSubscriptions.ts +77 -27
- package/src/client/RpcClientImpl.ts +5 -0
- package/tests/subscriptions.ts +121 -0
package/README.md
CHANGED
|
@@ -29,6 +29,7 @@ triggers.
|
|
|
29
29
|
|
|
30
30
|
- [important] Importing index.js from the root of the package will import node's http package. Not good for clients.
|
|
31
31
|
- Browser sockets don't have 'ping' event. Need to find a different way to detect connection loss.
|
|
32
|
+
- Перевірити, що throttling працює відразу для всіх підписників
|
|
32
33
|
|
|
33
34
|
## Features
|
|
34
35
|
|
|
@@ -37,5 +38,5 @@ triggers.
|
|
|
37
38
|
- Based on HTTP, easy to integrate with existing infrastructure
|
|
38
39
|
- Gradually upgradeable - WS is only used when you need subscriptions
|
|
39
40
|
- Supports compressed HTTP requests.
|
|
40
|
-
- Server runs on Node.JS, client runs in the Node.JS/Browser/ReactNative.
|
|
41
|
-
supported.
|
|
41
|
+
- Server runs on Node.JS, client runs in the Node.JS/Browser/ReactNative. For RN some extra setup is required (
|
|
42
|
+
document). Bun/Deno should also work, but not officially supported.
|
|
@@ -22,9 +22,10 @@ class HttpClient {
|
|
|
22
22
|
return `${this.url}/${itemName}`;
|
|
23
23
|
}
|
|
24
24
|
async httpRequest(method, itemName, params, callTimeout, headers) {
|
|
25
|
+
const itemUrl = this.getItemUrl(itemName);
|
|
25
26
|
try {
|
|
26
27
|
const { signal, finished } = timeoutSignal(callTimeout);
|
|
27
|
-
const response = await fetch(
|
|
28
|
+
const response = await fetch(itemUrl, {
|
|
28
29
|
method,
|
|
29
30
|
headers: {
|
|
30
31
|
"Content-Type": "application/json",
|
|
@@ -54,6 +55,9 @@ class HttpClient {
|
|
|
54
55
|
}
|
|
55
56
|
}
|
|
56
57
|
catch (e) {
|
|
58
|
+
if (e.message == "Error" || !e.message) {
|
|
59
|
+
e.message = `Error ${e.code} while ${itemUrl}`;
|
|
60
|
+
}
|
|
57
61
|
if (e.message == "fetch failed" && e.cause) {
|
|
58
62
|
e = e.cause;
|
|
59
63
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HttpClient.js","sourceRoot":"","sources":["../../src/client/HttpClient.ts"],"names":[],"mappings":";;;AAAA,sCAAqD;AACrD,8CAA6D;AAE7D,MAAa,UAAU;IACrB,YACU,GAAW,EACX,QAAgB,EAChB,UAAiD;QAFjD,QAAG,GAAH,GAAG,CAAQ;QACX,aAAQ,GAAR,QAAQ,CAAQ;QAChB,eAAU,GAAV,UAAU,CAAuC;IACxD,CAAC;IAEJ,KAAK,CAAC,IAAI,CAAC,QAAgB,EAAE,MAAiB,EAAE,WAAmB;QACjE,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC,CAAA;IACzF,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,QAAgB,EAAE,MAAiB,EAAE,WAAmB;QACtE,OAAO,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC,CAAA;IACxF,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,QAAgB,EAAE,MAAiB,EAAE,WAAmB;QACxE,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC,CAAA;IACzF,CAAC;IAEO,UAAU,CAAC,QAAgB;QACjC,OAAO,GAAG,IAAI,CAAC,GAAG,IAAI,QAAQ,EAAE,CAAA;IAClC,CAAC;IAEO,KAAK,CAAC,WAAW,CACvB,MAAgC,EAChC,QAAgB,EAChB,MAAiB,EACjB,WAAmB,EACnB,OAA+B;QAE/B,IAAI,CAAC;YACH,MAAM,EAAC,MAAM,EAAE,QAAQ,EAAC,GAAG,aAAa,CAAC,WAAW,CAAC,CAAA;YAErD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"HttpClient.js","sourceRoot":"","sources":["../../src/client/HttpClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
export declare class RemoteSubscriptions {
|
|
2
2
|
unsubscribe(itemName: string, parameters: unknown[], consumer: (d: unknown) => void): boolean;
|
|
3
3
|
addSubscription(itemName: string, parameters: unknown[], consumer: (d: unknown) => void): void;
|
|
4
|
+
pause(itemName: string, parameters: unknown[]): void;
|
|
5
|
+
unpause(itemName: string, parameters: unknown[]): void;
|
|
6
|
+
flushQueue(itemName: string, parameters: unknown[]): void;
|
|
7
|
+
emptyQueue(itemName: string, parameters: unknown[]): void;
|
|
4
8
|
private removeSubscription;
|
|
5
9
|
getCached(itemName: string, parameters: unknown[]): unknown | undefined;
|
|
6
10
|
consume(itemName: string, parameters: unknown[], data: unknown): void;
|
|
@@ -9,5 +13,6 @@ export declare class RemoteSubscriptions {
|
|
|
9
13
|
parameters: unknown[],
|
|
10
14
|
consumers: Array<(d: unknown) => void>
|
|
11
15
|
]>;
|
|
16
|
+
private getFilterSubscriptions;
|
|
12
17
|
private byItem;
|
|
13
18
|
}
|
|
@@ -18,10 +18,41 @@ class RemoteSubscriptions {
|
|
|
18
18
|
parameters,
|
|
19
19
|
cached: null,
|
|
20
20
|
consumers: [],
|
|
21
|
+
queue: [],
|
|
21
22
|
};
|
|
22
23
|
itemSubscriptions.byParameters.set(parametersKey, parameterSubscriptions);
|
|
23
24
|
parameterSubscriptions.consumers.push(consumer);
|
|
24
25
|
}
|
|
26
|
+
pause(itemName, parameters) {
|
|
27
|
+
const filterSubscriptions = this.getFilterSubscriptions(itemName, parameters);
|
|
28
|
+
if (!filterSubscriptions)
|
|
29
|
+
return;
|
|
30
|
+
filterSubscriptions.paused = true;
|
|
31
|
+
}
|
|
32
|
+
unpause(itemName, parameters) {
|
|
33
|
+
const filterSubscriptions = this.getFilterSubscriptions(itemName, parameters);
|
|
34
|
+
if (!filterSubscriptions)
|
|
35
|
+
return;
|
|
36
|
+
filterSubscriptions.paused = false;
|
|
37
|
+
}
|
|
38
|
+
flushQueue(itemName, parameters) {
|
|
39
|
+
const filterSubscriptions = this.getFilterSubscriptions(itemName, parameters);
|
|
40
|
+
if (!filterSubscriptions)
|
|
41
|
+
return;
|
|
42
|
+
filterSubscriptions.queue.forEach((data) => {
|
|
43
|
+
filterSubscriptions.cached = data;
|
|
44
|
+
filterSubscriptions.consumers.forEach((consumer) => {
|
|
45
|
+
consumer(data);
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
filterSubscriptions.queue = [];
|
|
49
|
+
}
|
|
50
|
+
emptyQueue(itemName, parameters) {
|
|
51
|
+
const filterSubscriptions = this.getFilterSubscriptions(itemName, parameters);
|
|
52
|
+
if (!filterSubscriptions)
|
|
53
|
+
return;
|
|
54
|
+
filterSubscriptions.queue = [];
|
|
55
|
+
}
|
|
25
56
|
removeSubscription(itemName, parametersKey, consumer) {
|
|
26
57
|
const itemSubscriptions = this.byItem.get(itemName);
|
|
27
58
|
if (!itemSubscriptions)
|
|
@@ -43,25 +74,24 @@ class RemoteSubscriptions {
|
|
|
43
74
|
return false;
|
|
44
75
|
}
|
|
45
76
|
getCached(itemName, parameters) {
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
if (!itemSubscriptions)
|
|
77
|
+
const filterSubscriptions = this.getFilterSubscriptions(itemName, parameters);
|
|
78
|
+
if (!filterSubscriptions)
|
|
49
79
|
return;
|
|
50
|
-
|
|
51
|
-
return filterSubscriptions?.cached;
|
|
80
|
+
return filterSubscriptions.cached;
|
|
52
81
|
}
|
|
53
82
|
consume(itemName, parameters, data) {
|
|
54
|
-
const
|
|
55
|
-
const itemSubscriptions = this.byItem.get(itemName);
|
|
56
|
-
if (!itemSubscriptions)
|
|
57
|
-
return;
|
|
58
|
-
const filterSubscriptions = itemSubscriptions.byParameters.get(parametersKey);
|
|
83
|
+
const filterSubscriptions = this.getFilterSubscriptions(itemName, parameters);
|
|
59
84
|
if (!filterSubscriptions)
|
|
60
85
|
return;
|
|
61
|
-
filterSubscriptions.
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
86
|
+
if (filterSubscriptions.paused) {
|
|
87
|
+
filterSubscriptions.queue.push(data);
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
filterSubscriptions.cached = data;
|
|
91
|
+
filterSubscriptions.consumers.forEach((consumer) => {
|
|
92
|
+
consumer(data);
|
|
93
|
+
});
|
|
94
|
+
}
|
|
65
95
|
}
|
|
66
96
|
getAllSubscriptions() {
|
|
67
97
|
const result = [];
|
|
@@ -72,6 +102,16 @@ class RemoteSubscriptions {
|
|
|
72
102
|
}
|
|
73
103
|
return result;
|
|
74
104
|
}
|
|
105
|
+
getFilterSubscriptions(itemName, parameters) {
|
|
106
|
+
const parametersKey = getParametersKey(parameters);
|
|
107
|
+
const itemSubscriptions = this.byItem.get(itemName);
|
|
108
|
+
if (!itemSubscriptions)
|
|
109
|
+
return;
|
|
110
|
+
const filterSubscriptions = itemSubscriptions.byParameters.get(parametersKey);
|
|
111
|
+
if (!filterSubscriptions)
|
|
112
|
+
return;
|
|
113
|
+
return filterSubscriptions;
|
|
114
|
+
}
|
|
75
115
|
}
|
|
76
116
|
exports.RemoteSubscriptions = RemoteSubscriptions;
|
|
77
117
|
function getParametersKey(parameters) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RemoteSubscriptions.js","sourceRoot":"","sources":["../../src/client/RemoteSubscriptions.ts"],"names":[],"mappings":";;;AAAA,8CAA8C;AAE9C,MAAa,mBAAmB;IAAhC;
|
|
1
|
+
{"version":3,"file":"RemoteSubscriptions.js","sourceRoot":"","sources":["../../src/client/RemoteSubscriptions.ts"],"names":[],"mappings":"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"}
|
|
@@ -25,10 +25,15 @@ class RpcClientImpl {
|
|
|
25
25
|
await this.connection.connect();
|
|
26
26
|
try {
|
|
27
27
|
this.remoteSubscriptions.addSubscription(itemName, parameters, consumer);
|
|
28
|
+
this.remoteSubscriptions.pause(itemName, parameters);
|
|
28
29
|
const data = await this.invoke(itemName, rpc_js_1.InvocationType.Subscribe, (...parameters) => this.httpClient.subscribe(itemName, parameters, callOptions?.timeout ?? this.options.callTimeout), parameters);
|
|
30
|
+
this.remoteSubscriptions.unpause(itemName, parameters);
|
|
29
31
|
this.remoteSubscriptions.consume(itemName, parameters, data);
|
|
32
|
+
this.remoteSubscriptions.flushQueue(itemName, parameters);
|
|
30
33
|
}
|
|
31
34
|
catch (e) {
|
|
35
|
+
this.remoteSubscriptions.unpause(itemName, parameters);
|
|
36
|
+
this.remoteSubscriptions.emptyQueue(itemName, parameters);
|
|
32
37
|
await this.unsubscribe(itemName, parameters, consumer);
|
|
33
38
|
throw e;
|
|
34
39
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RpcClientImpl.js","sourceRoot":"","sources":["../../src/client/RpcClientImpl.ts"],"names":[],"mappings":";;;AAAA,sCAA2E;AAC3E,mDAA0C;AAC1C,qEAA4D;AAC5D,qEAA4D;AAC5D,mCAA6B;AAC7B,2CAAmE;AAEnE,0DAAsD;AAEtD,MAAa,aAAa;IACxB,YACE,GAAW,EACM,OAA+B;QAA/B,YAAO,GAAP,OAAO,CAAwB;QA2BjC,aAAQ,GAAG,IAAA,eAAM,GAAE,CAAA;QA8C5B,SAAI,GAAG,CACb,QAAgB,EAChB,UAAqB,EACrB,WAAyB,EACP,EAAE;YACpB,OAAO,IAAI,CAAC,MAAM,CAChB,QAAQ,EACR,uBAAc,CAAC,IAAI,EACnB,CAAC,GAAG,UAAU,EAAE,EAAE,CAChB,IAAI,CAAC,UAAU,CAAC,IAAI,CAClB,QAAQ,EACR,UAAU,EACV,WAAW,EAAE,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,WAAW,CACjD,EACH,UAAU,CACX,CAAA;QACH,CAAC,CAAA;QAEO,cAAS,GAAG,KAAK,EACvB,QAAgB,EAChB,UAAqB,EACrB,QAA8B,EAC9B,WAAyB,EACV,EAAE;YACjB,MAAM,MAAM,GAAG,IAAI,CAAC,mBAAmB,CAAC,SAAS,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;YAEvE,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBACzB,QAAQ,CAAC,MAAM,CAAC,CAAA;YAClB,CAAC;YAED,oEAAoE;YACpE,mFAAmF;YACnF,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAA;YAE/B,IAAI,CAAC;gBACH,IAAI,CAAC,mBAAmB,CAAC,eAAe,CAAC,QAAQ,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"RpcClientImpl.js","sourceRoot":"","sources":["../../src/client/RpcClientImpl.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/client/HttpClient.ts
CHANGED
|
@@ -31,10 +31,12 @@ export class HttpClient {
|
|
|
31
31
|
callTimeout: number,
|
|
32
32
|
headers: Record<string, string>
|
|
33
33
|
): Promise<unknown> {
|
|
34
|
+
const itemUrl = this.getItemUrl(itemName)
|
|
35
|
+
|
|
34
36
|
try {
|
|
35
37
|
const {signal, finished} = timeoutSignal(callTimeout)
|
|
36
38
|
|
|
37
|
-
const response = await fetch(
|
|
39
|
+
const response = await fetch(itemUrl, {
|
|
38
40
|
method,
|
|
39
41
|
headers: {
|
|
40
42
|
"Content-Type": "application/json",
|
|
@@ -72,6 +74,10 @@ export class HttpClient {
|
|
|
72
74
|
return res
|
|
73
75
|
}
|
|
74
76
|
} catch (e: any) {
|
|
77
|
+
if (e.message == "Error" || !e.message) {
|
|
78
|
+
e.message = `Error ${e.code} while ${itemUrl}`
|
|
79
|
+
}
|
|
80
|
+
|
|
75
81
|
if (e.message == "fetch failed" && e.cause) {
|
|
76
82
|
e = e.cause
|
|
77
83
|
}
|
|
@@ -12,15 +12,54 @@ export class RemoteSubscriptions {
|
|
|
12
12
|
this.byItem.set(itemName, itemSubscriptions)
|
|
13
13
|
|
|
14
14
|
const parametersKey = getParametersKey(parameters)
|
|
15
|
-
const parameterSubscriptions = itemSubscriptions.byParameters.get(
|
|
15
|
+
const parameterSubscriptions: ParametersSubscription = itemSubscriptions.byParameters.get(
|
|
16
|
+
parametersKey
|
|
17
|
+
) || {
|
|
16
18
|
parameters,
|
|
17
19
|
cached: null,
|
|
18
20
|
consumers: [],
|
|
21
|
+
queue: [],
|
|
19
22
|
}
|
|
23
|
+
|
|
20
24
|
itemSubscriptions.byParameters.set(parametersKey, parameterSubscriptions)
|
|
21
25
|
parameterSubscriptions.consumers.push(consumer)
|
|
22
26
|
}
|
|
23
27
|
|
|
28
|
+
pause(itemName: string, parameters: unknown[]) {
|
|
29
|
+
const filterSubscriptions = this.getFilterSubscriptions(itemName, parameters)
|
|
30
|
+
if (!filterSubscriptions) return
|
|
31
|
+
|
|
32
|
+
filterSubscriptions.paused = true
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
unpause(itemName: string, parameters: unknown[]) {
|
|
36
|
+
const filterSubscriptions = this.getFilterSubscriptions(itemName, parameters)
|
|
37
|
+
if (!filterSubscriptions) return
|
|
38
|
+
|
|
39
|
+
filterSubscriptions.paused = false
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
flushQueue(itemName: string, parameters: unknown[]) {
|
|
43
|
+
const filterSubscriptions = this.getFilterSubscriptions(itemName, parameters)
|
|
44
|
+
if (!filterSubscriptions) return
|
|
45
|
+
|
|
46
|
+
filterSubscriptions.queue.forEach((data) => {
|
|
47
|
+
filterSubscriptions.cached = data
|
|
48
|
+
filterSubscriptions.consumers.forEach((consumer) => {
|
|
49
|
+
consumer(data)
|
|
50
|
+
})
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
filterSubscriptions.queue = []
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
emptyQueue(itemName: string, parameters: unknown[]) {
|
|
57
|
+
const filterSubscriptions = this.getFilterSubscriptions(itemName, parameters)
|
|
58
|
+
if (!filterSubscriptions) return
|
|
59
|
+
|
|
60
|
+
filterSubscriptions.queue = []
|
|
61
|
+
}
|
|
62
|
+
|
|
24
63
|
private removeSubscription(
|
|
25
64
|
itemName: string,
|
|
26
65
|
parametersKey: string,
|
|
@@ -51,30 +90,24 @@ export class RemoteSubscriptions {
|
|
|
51
90
|
}
|
|
52
91
|
|
|
53
92
|
getCached(itemName: string, parameters: unknown[]): unknown | undefined {
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
const itemSubscriptions = this.byItem.get(itemName)
|
|
57
|
-
if (!itemSubscriptions) return
|
|
58
|
-
|
|
59
|
-
const filterSubscriptions = itemSubscriptions.byParameters.get(parametersKey)
|
|
93
|
+
const filterSubscriptions = this.getFilterSubscriptions(itemName, parameters)
|
|
94
|
+
if (!filterSubscriptions) return
|
|
60
95
|
|
|
61
|
-
return filterSubscriptions
|
|
96
|
+
return filterSubscriptions.cached
|
|
62
97
|
}
|
|
63
98
|
|
|
64
99
|
consume(itemName: string, parameters: unknown[], data: unknown) {
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
const itemSubscriptions = this.byItem.get(itemName)
|
|
68
|
-
if (!itemSubscriptions) return
|
|
69
|
-
|
|
70
|
-
const filterSubscriptions = itemSubscriptions.byParameters.get(parametersKey)
|
|
71
|
-
|
|
100
|
+
const filterSubscriptions = this.getFilterSubscriptions(itemName, parameters)
|
|
72
101
|
if (!filterSubscriptions) return
|
|
73
102
|
|
|
74
|
-
filterSubscriptions.
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
103
|
+
if (filterSubscriptions.paused) {
|
|
104
|
+
filterSubscriptions.queue.push(data)
|
|
105
|
+
} else {
|
|
106
|
+
filterSubscriptions.cached = data
|
|
107
|
+
filterSubscriptions.consumers.forEach((consumer) => {
|
|
108
|
+
consumer(data)
|
|
109
|
+
})
|
|
110
|
+
}
|
|
78
111
|
}
|
|
79
112
|
|
|
80
113
|
getAllSubscriptions(): Array<
|
|
@@ -91,18 +124,35 @@ export class RemoteSubscriptions {
|
|
|
91
124
|
return result
|
|
92
125
|
}
|
|
93
126
|
|
|
127
|
+
private getFilterSubscriptions(
|
|
128
|
+
itemName: string,
|
|
129
|
+
parameters: unknown[]
|
|
130
|
+
): ParametersSubscription | undefined {
|
|
131
|
+
const parametersKey = getParametersKey(parameters)
|
|
132
|
+
|
|
133
|
+
const itemSubscriptions = this.byItem.get(itemName)
|
|
134
|
+
if (!itemSubscriptions) return
|
|
135
|
+
|
|
136
|
+
const filterSubscriptions = itemSubscriptions.byParameters.get(parametersKey)
|
|
137
|
+
if (!filterSubscriptions) return
|
|
138
|
+
|
|
139
|
+
return filterSubscriptions
|
|
140
|
+
}
|
|
141
|
+
|
|
94
142
|
private byItem: Map<string, ItemSubscription> = new Map()
|
|
95
143
|
}
|
|
96
144
|
|
|
97
145
|
type ItemSubscription = {
|
|
98
|
-
byParameters: Map<
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
146
|
+
byParameters: Map<string, ParametersSubscription>
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
type ParametersSubscription = {
|
|
150
|
+
parameters: unknown[]
|
|
151
|
+
cached: unknown
|
|
152
|
+
consumers: Array<(d: unknown) => void>
|
|
153
|
+
|
|
154
|
+
paused: boolean
|
|
155
|
+
queue: unknown[]
|
|
106
156
|
}
|
|
107
157
|
|
|
108
158
|
function getParametersKey(parameters: unknown[]) {
|
|
@@ -119,6 +119,7 @@ export class RpcClientImpl<S extends Services<S>> implements RpcClient {
|
|
|
119
119
|
|
|
120
120
|
try {
|
|
121
121
|
this.remoteSubscriptions.addSubscription(itemName, parameters, consumer)
|
|
122
|
+
this.remoteSubscriptions.pause(itemName, parameters)
|
|
122
123
|
|
|
123
124
|
const data = await this.invoke(
|
|
124
125
|
itemName,
|
|
@@ -132,8 +133,12 @@ export class RpcClientImpl<S extends Services<S>> implements RpcClient {
|
|
|
132
133
|
parameters
|
|
133
134
|
)
|
|
134
135
|
|
|
136
|
+
this.remoteSubscriptions.unpause(itemName, parameters)
|
|
135
137
|
this.remoteSubscriptions.consume(itemName, parameters, data)
|
|
138
|
+
this.remoteSubscriptions.flushQueue(itemName, parameters)
|
|
136
139
|
} catch (e) {
|
|
140
|
+
this.remoteSubscriptions.unpause(itemName, parameters)
|
|
141
|
+
this.remoteSubscriptions.emptyQueue(itemName, parameters)
|
|
137
142
|
await this.unsubscribe(itemName, parameters, consumer)
|
|
138
143
|
throw e
|
|
139
144
|
}
|
package/tests/subscriptions.ts
CHANGED
|
@@ -472,4 +472,125 @@ describe("Subscriptions", () => {
|
|
|
472
472
|
assert.equal(testClient!._allSubscriptions().length, 0)
|
|
473
473
|
assert.equal(testServer!._allSubscriptions().length, 0)
|
|
474
474
|
}).timeout(5000)
|
|
475
|
+
|
|
476
|
+
it("missing update in case of concurrent subscribe/trigger", async () => {
|
|
477
|
+
const delay = 50
|
|
478
|
+
|
|
479
|
+
const services = await startTestServer({
|
|
480
|
+
test: {
|
|
481
|
+
async longOp() {
|
|
482
|
+
await adelay(delay)
|
|
483
|
+
return 1
|
|
484
|
+
},
|
|
485
|
+
},
|
|
486
|
+
})
|
|
487
|
+
|
|
488
|
+
const client = await createTestClient<typeof services>({
|
|
489
|
+
callTimeout: 2 * delay,
|
|
490
|
+
})
|
|
491
|
+
|
|
492
|
+
let received = 0
|
|
493
|
+
|
|
494
|
+
client.test.longOp.subscribe((val) => {
|
|
495
|
+
console.log("got ", val)
|
|
496
|
+
|
|
497
|
+
received = val
|
|
498
|
+
})
|
|
499
|
+
|
|
500
|
+
await adelay(20)
|
|
501
|
+
services.test.longOp.trigger(undefined, 2)
|
|
502
|
+
|
|
503
|
+
await adelay(2 * delay)
|
|
504
|
+
|
|
505
|
+
assert.equal(received, 2)
|
|
506
|
+
})
|
|
507
|
+
|
|
508
|
+
it.skip("two concurrent subscribes and trigger", async () => {
|
|
509
|
+
const delay = 50
|
|
510
|
+
|
|
511
|
+
const services = await startTestServer({
|
|
512
|
+
test: {
|
|
513
|
+
async longOp() {
|
|
514
|
+
await adelay(delay)
|
|
515
|
+
return 1
|
|
516
|
+
},
|
|
517
|
+
},
|
|
518
|
+
})
|
|
519
|
+
|
|
520
|
+
const client = await createTestClient<typeof services>({
|
|
521
|
+
callTimeout: 2 * delay,
|
|
522
|
+
})
|
|
523
|
+
|
|
524
|
+
let receivedA = 0
|
|
525
|
+
let receivedB = 0
|
|
526
|
+
|
|
527
|
+
client.test.longOp.subscribe((val) => {
|
|
528
|
+
console.log("gotA", val)
|
|
529
|
+
receivedA = val
|
|
530
|
+
})
|
|
531
|
+
|
|
532
|
+
client.test.longOp.subscribe((val) => {
|
|
533
|
+
console.log("gotB", val)
|
|
534
|
+
receivedB = val
|
|
535
|
+
})
|
|
536
|
+
|
|
537
|
+
await adelay(20)
|
|
538
|
+
services.test.longOp.trigger(undefined, 2)
|
|
539
|
+
|
|
540
|
+
await adelay(2 * delay)
|
|
541
|
+
|
|
542
|
+
assert.equal(receivedA, 2)
|
|
543
|
+
assert.equal(receivedB, 2)
|
|
544
|
+
})
|
|
545
|
+
|
|
546
|
+
it("clear queue on subscription failure", async () => {
|
|
547
|
+
const delay = 50
|
|
548
|
+
|
|
549
|
+
let invocation = 0
|
|
550
|
+
const services = await startTestServer({
|
|
551
|
+
test: {
|
|
552
|
+
async longOp(): Promise<number> {
|
|
553
|
+
await adelay(delay)
|
|
554
|
+
if (invocation++ == 1) {
|
|
555
|
+
throw new Error("AA")
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
return 1
|
|
559
|
+
},
|
|
560
|
+
},
|
|
561
|
+
})
|
|
562
|
+
|
|
563
|
+
const client = await createTestClient<typeof services>({
|
|
564
|
+
callTimeout: 2 * delay,
|
|
565
|
+
})
|
|
566
|
+
|
|
567
|
+
let received = 0
|
|
568
|
+
|
|
569
|
+
client.test.longOp.subscribe((val) => {
|
|
570
|
+
received = val
|
|
571
|
+
})
|
|
572
|
+
|
|
573
|
+
await adelay(1.5 * delay)
|
|
574
|
+
|
|
575
|
+
client.test.longOp
|
|
576
|
+
.subscribe((val) => {
|
|
577
|
+
received = val
|
|
578
|
+
})
|
|
579
|
+
.catch((e) => {
|
|
580
|
+
// ok
|
|
581
|
+
})
|
|
582
|
+
|
|
583
|
+
await adelay(20)
|
|
584
|
+
services.test.longOp.trigger(undefined, 2) // this should be skipped
|
|
585
|
+
|
|
586
|
+
await adelay(1.5 * delay - 20)
|
|
587
|
+
|
|
588
|
+
client.test.longOp.subscribe((val) => {
|
|
589
|
+
received = val
|
|
590
|
+
})
|
|
591
|
+
|
|
592
|
+
await adelay(1.5 * delay)
|
|
593
|
+
|
|
594
|
+
assert.equal(received, 1)
|
|
595
|
+
})
|
|
475
596
|
})
|