@lodestar/api 1.49.0-dev.ceea36c6f2 → 1.49.0-dev.d4c0ee61ef
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.
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { ChainForkConfig } from "@lodestar/config";
|
|
2
2
|
import { ApplicationMethods, FastifyRoutes } from "../../utils/server/index.js";
|
|
3
3
|
import { Endpoints } from "../routes/events.js";
|
|
4
|
+
/**
|
|
5
|
+
* A stream with no events otherwise exceeds the idle timeout of a reverse proxy or consumer, commonly 60 seconds,
|
|
6
|
+
* and events are not replayed. https://html.spec.whatwg.org/multipage/server-sent-events.html#authoring-notes
|
|
7
|
+
*/
|
|
8
|
+
export declare const SSE_KEEP_ALIVE_INTERVAL_MS = 15000;
|
|
4
9
|
export declare function getRoutes(config: ChainForkConfig, methods: ApplicationMethods<Endpoints>): FastifyRoutes<Endpoints>;
|
|
5
10
|
export declare function serializeSSEEvent(chunk: {
|
|
6
11
|
event: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../../src/beacon/server/events.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,eAAe,EAAC,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAW,kBAAkB,EAAE,aAAa,EAAsB,MAAM,6BAA6B,CAAC;AAC7G,OAAO,EAAC,SAAS,EAA6C,MAAM,qBAAqB,CAAC;AAE1F,wBAAgB,SAAS,CAAC,MAAM,EAAE,eAAe,EAAE,OAAO,EAAE,kBAAkB,CAAC,SAAS,CAAC,GAAG,aAAa,CAAC,SAAS,CAAC,
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../../src/beacon/server/events.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,eAAe,EAAC,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAW,kBAAkB,EAAE,aAAa,EAAsB,MAAM,6BAA6B,CAAC;AAC7G,OAAO,EAAC,SAAS,EAA6C,MAAM,qBAAqB,CAAC;AAE1F;;;GAGG;AACH,eAAO,MAAM,0BAA0B,QAAS,CAAC;AAGjD,wBAAgB,SAAS,CAAC,MAAM,EAAE,eAAe,EAAE,OAAO,EAAE,kBAAkB,CAAC,SAAS,CAAC,GAAG,aAAa,CAAC,SAAS,CAAC,CAgFnH;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAC,GAAG,MAAM,CAE/E"}
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { ApiError, createFastifyRoutes } from "../../utils/server/index.js";
|
|
2
2
|
import { eventTypes, getDefinitions, getEventSerdes } from "../routes/events.js";
|
|
3
|
+
/**
|
|
4
|
+
* A stream with no events otherwise exceeds the idle timeout of a reverse proxy or consumer, commonly 60 seconds,
|
|
5
|
+
* and events are not replayed. https://html.spec.whatwg.org/multipage/server-sent-events.html#authoring-notes
|
|
6
|
+
*/
|
|
7
|
+
export const SSE_KEEP_ALIVE_INTERVAL_MS = 15_000;
|
|
8
|
+
const SSE_KEEP_ALIVE_COMMENT = ":\n\n";
|
|
3
9
|
export function getRoutes(config, methods) {
|
|
4
10
|
const eventSerdes = getEventSerdes(config);
|
|
5
11
|
const serverRoutes = createFastifyRoutes(getDefinitions(config), methods);
|
|
@@ -15,6 +21,7 @@ export function getRoutes(config, methods) {
|
|
|
15
21
|
}
|
|
16
22
|
}
|
|
17
23
|
const controller = new AbortController();
|
|
24
|
+
let keepAliveTimer;
|
|
18
25
|
try {
|
|
19
26
|
// Add injected headers from other plugins. This is required for fastify-cors for example
|
|
20
27
|
// From: https://github.com/NodeFactoryIo/fastify-sse-v2/blob/b1686a979fbf655fb9936c0560294a0c094734d4/src/plugin.ts
|
|
@@ -31,6 +38,12 @@ export function getRoutes(config, methods) {
|
|
|
31
38
|
// infinitely buffering it. http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffering
|
|
32
39
|
// Source: https://stackoverflow.com/questions/13672743/eventsource-server-sent-events-through-nginx
|
|
33
40
|
res.raw.setHeader("X-Accel-Buffering", "no");
|
|
41
|
+
keepAliveTimer = setInterval(() => {
|
|
42
|
+
if (!res.raw.writableEnded && !res.raw.destroyed)
|
|
43
|
+
res.raw.write(SSE_KEEP_ALIVE_COMMENT);
|
|
44
|
+
}, SSE_KEEP_ALIVE_INTERVAL_MS);
|
|
45
|
+
// Headers are otherwise only sent with the first event, a reverse proxy times out waiting for them
|
|
46
|
+
res.raw.flushHeaders();
|
|
34
47
|
await new Promise((resolve, reject) => {
|
|
35
48
|
void methods.eventstream({
|
|
36
49
|
topics: req.query.topics,
|
|
@@ -57,6 +70,7 @@ export function getRoutes(config, methods) {
|
|
|
57
70
|
});
|
|
58
71
|
}
|
|
59
72
|
finally {
|
|
73
|
+
clearInterval(keepAliveTimer);
|
|
60
74
|
controller.abort();
|
|
61
75
|
// Always end the response. If an error is thrown after the headers were sent, fastify can
|
|
62
76
|
// no longer write a status code and would leave the socket open, the client then waits
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../../src/beacon/server/events.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,QAAQ,EAAqC,mBAAmB,EAAC,MAAM,6BAA6B,CAAC;AAC7G,OAAO,EAAY,UAAU,EAAE,cAAc,EAAE,cAAc,EAAC,MAAM,qBAAqB,CAAC;AAE1F,MAAM,UAAU,SAAS,CAAC,MAAuB,EAAE,OAAsC;IACvF,MAAM,WAAW,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IAC3C,MAAM,YAAY,GAAG,mBAAmB,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC;IAE1E,OAAO;QACL,2CAA2C;QAC3C,WAAW,EAAE;YACX,GAAG,YAAY,CAAC,WAAW;YAC3B,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;gBAC1B,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;gBACvD,KAAK,MAAM,KAAK,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;oBACrC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;wBAC5B,MAAM,IAAI,QAAQ,CAAC,GAAG,EAAE,kBAAkB,KAAK,EAAE,CAAC,CAAC;oBACrD,CAAC;gBACH,CAAC;gBAED,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../../src/beacon/server/events.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"bugs": {
|
|
12
12
|
"url": "https://github.com/ChainSafe/lodestar/issues"
|
|
13
13
|
},
|
|
14
|
-
"version": "1.49.0-dev.
|
|
14
|
+
"version": "1.49.0-dev.d4c0ee61ef",
|
|
15
15
|
"type": "module",
|
|
16
16
|
"exports": {
|
|
17
17
|
".": {
|
|
@@ -76,10 +76,10 @@
|
|
|
76
76
|
"dependencies": {
|
|
77
77
|
"@chainsafe/persistent-merkle-tree": "^1.3.1",
|
|
78
78
|
"@chainsafe/ssz": "^1.8.0",
|
|
79
|
-
"@lodestar/config": "^1.49.0-dev.
|
|
80
|
-
"@lodestar/params": "^1.49.0-dev.
|
|
81
|
-
"@lodestar/types": "^1.49.0-dev.
|
|
82
|
-
"@lodestar/utils": "^1.49.0-dev.
|
|
79
|
+
"@lodestar/config": "^1.49.0-dev.d4c0ee61ef",
|
|
80
|
+
"@lodestar/params": "^1.49.0-dev.d4c0ee61ef",
|
|
81
|
+
"@lodestar/types": "^1.49.0-dev.d4c0ee61ef",
|
|
82
|
+
"@lodestar/utils": "^1.49.0-dev.d4c0ee61ef",
|
|
83
83
|
"eventsource": "^2.0.2",
|
|
84
84
|
"qs": "^6.14.2"
|
|
85
85
|
},
|
|
@@ -96,5 +96,5 @@
|
|
|
96
96
|
"api",
|
|
97
97
|
"blockchain"
|
|
98
98
|
],
|
|
99
|
-
"gitHead": "
|
|
99
|
+
"gitHead": "2b85143520ae47a36abacdbc9668dc43327cd2d6"
|
|
100
100
|
}
|
|
@@ -2,6 +2,13 @@ import {ChainForkConfig} from "@lodestar/config";
|
|
|
2
2
|
import {ApiError, ApplicationMethods, FastifyRoutes, createFastifyRoutes} from "../../utils/server/index.js";
|
|
3
3
|
import {Endpoints, eventTypes, getDefinitions, getEventSerdes} from "../routes/events.js";
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* A stream with no events otherwise exceeds the idle timeout of a reverse proxy or consumer, commonly 60 seconds,
|
|
7
|
+
* and events are not replayed. https://html.spec.whatwg.org/multipage/server-sent-events.html#authoring-notes
|
|
8
|
+
*/
|
|
9
|
+
export const SSE_KEEP_ALIVE_INTERVAL_MS = 15_000;
|
|
10
|
+
const SSE_KEEP_ALIVE_COMMENT = ":\n\n";
|
|
11
|
+
|
|
5
12
|
export function getRoutes(config: ChainForkConfig, methods: ApplicationMethods<Endpoints>): FastifyRoutes<Endpoints> {
|
|
6
13
|
const eventSerdes = getEventSerdes(config);
|
|
7
14
|
const serverRoutes = createFastifyRoutes(getDefinitions(config), methods);
|
|
@@ -19,6 +26,7 @@ export function getRoutes(config: ChainForkConfig, methods: ApplicationMethods<E
|
|
|
19
26
|
}
|
|
20
27
|
|
|
21
28
|
const controller = new AbortController();
|
|
29
|
+
let keepAliveTimer: NodeJS.Timeout | undefined;
|
|
22
30
|
|
|
23
31
|
try {
|
|
24
32
|
// Add injected headers from other plugins. This is required for fastify-cors for example
|
|
@@ -37,6 +45,13 @@ export function getRoutes(config: ChainForkConfig, methods: ApplicationMethods<E
|
|
|
37
45
|
// Source: https://stackoverflow.com/questions/13672743/eventsource-server-sent-events-through-nginx
|
|
38
46
|
res.raw.setHeader("X-Accel-Buffering", "no");
|
|
39
47
|
|
|
48
|
+
keepAliveTimer = setInterval(() => {
|
|
49
|
+
if (!res.raw.writableEnded && !res.raw.destroyed) res.raw.write(SSE_KEEP_ALIVE_COMMENT);
|
|
50
|
+
}, SSE_KEEP_ALIVE_INTERVAL_MS);
|
|
51
|
+
|
|
52
|
+
// Headers are otherwise only sent with the first event, a reverse proxy times out waiting for them
|
|
53
|
+
res.raw.flushHeaders();
|
|
54
|
+
|
|
40
55
|
await new Promise<void>((resolve, reject) => {
|
|
41
56
|
void methods.eventstream({
|
|
42
57
|
topics: req.query.topics,
|
|
@@ -64,6 +79,7 @@ export function getRoutes(config: ChainForkConfig, methods: ApplicationMethods<E
|
|
|
64
79
|
req.socket.once("end", () => resolve());
|
|
65
80
|
});
|
|
66
81
|
} finally {
|
|
82
|
+
clearInterval(keepAliveTimer);
|
|
67
83
|
controller.abort();
|
|
68
84
|
// Always end the response. If an error is thrown after the headers were sent, fastify can
|
|
69
85
|
// no longer write a status code and would leave the socket open, the client then waits
|