@rivetkit/engine-runner 2.0.33 → 2.0.34-rc.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rivetkit/engine-runner",
3
- "version": "2.0.33",
3
+ "version": "2.0.34-rc.2",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist",
@@ -21,7 +21,8 @@
21
21
  "uuid": "^12.0.0",
22
22
  "pino": "^9.9.5",
23
23
  "ws": "^8.18.3",
24
- "@rivetkit/engine-runner-protocol": "2.0.33"
24
+ "@rivetkit/virtual-websocket": "2.0.33",
25
+ "@rivetkit/engine-runner-protocol": "2.0.34-rc.2"
25
26
  },
26
27
  "devDependencies": {
27
28
  "@types/node": "^22.18.1",
package/src/mod.ts CHANGED
@@ -201,7 +201,7 @@ export class Runner {
201
201
  #actors: Map<string, RunnerActor> = new Map();
202
202
 
203
203
  // WebSocket
204
- __pegboardWebSocket?: WebSocket;
204
+ #pegboardWebSocket?: WebSocket;
205
205
  runnerId?: string;
206
206
  #started: boolean = false;
207
207
  #shutdown: boolean = false;
@@ -528,8 +528,8 @@ export class Runner {
528
528
  this.#kvRequests.clear();
529
529
 
530
530
  // Close WebSocket
531
- if (this.__webSocketReady()) {
532
- const pegboardWebSocket = this.__pegboardWebSocket;
531
+ const pegboardWebSocket = this.getPegboardWebSocketIfReady();
532
+ if (pegboardWebSocket) {
533
533
  if (immediate) {
534
534
  // Stop immediately
535
535
  pegboardWebSocket.close(1000, "pegboard.runner_shutdown");
@@ -590,7 +590,7 @@ export class Runner {
590
590
  // the runner has already shut down
591
591
  this.log?.debug({
592
592
  msg: "no runner WebSocket to shutdown or already closed",
593
- readyState: this.__pegboardWebSocket?.readyState,
593
+ readyState: this.#pegboardWebSocket?.readyState,
594
594
  });
595
595
  }
596
596
 
@@ -715,8 +715,21 @@ export class Runner {
715
715
  protocols.push(`rivet_token.${this.config.token}`);
716
716
 
717
717
  const WS = await importWebSocket();
718
+
719
+ // Assertion to clear previous WebSocket
720
+ if (
721
+ this.#pegboardWebSocket &&
722
+ (this.#pegboardWebSocket.readyState === WS.CONNECTING ||
723
+ this.#pegboardWebSocket.readyState === WS.OPEN)
724
+ ) {
725
+ this.log?.error(
726
+ "found duplicate pegboardWebSocket, closing previous",
727
+ );
728
+ this.#pegboardWebSocket.close(1000, "duplicate_websocket");
729
+ }
730
+
718
731
  const ws = new WS(this.pegboardUrl, protocols) as any as WebSocket;
719
- this.__pegboardWebSocket = ws;
732
+ this.#pegboardWebSocket = ws;
720
733
 
721
734
  this.log?.info({
722
735
  msg: "connecting",
@@ -1621,7 +1634,7 @@ export class Runner {
1621
1634
 
1622
1635
  this.#kvRequests.set(requestId, requestEntry);
1623
1636
 
1624
- if (this.__webSocketReady()) {
1637
+ if (this.getPegboardWebSocketIfReady()) {
1625
1638
  // Send immediately
1626
1639
  this.#sendSingleKvRequest(requestId);
1627
1640
  }
@@ -1654,7 +1667,7 @@ export class Runner {
1654
1667
  }
1655
1668
 
1656
1669
  #processUnsentKvRequests() {
1657
- if (!this.__webSocketReady()) {
1670
+ if (!this.getPegboardWebSocketIfReady()) {
1658
1671
  return;
1659
1672
  }
1660
1673
 
@@ -1672,13 +1685,15 @@ export class Runner {
1672
1685
  }
1673
1686
 
1674
1687
  /** Asserts WebSocket exists and is ready. */
1675
- __webSocketReady(): this is this & {
1676
- __pegboardWebSocket: NonNullable<Runner["__pegboardWebSocket"]>;
1677
- } {
1678
- return (
1679
- !!this.__pegboardWebSocket &&
1680
- this.__pegboardWebSocket.readyState === 1
1681
- );
1688
+ getPegboardWebSocketIfReady(): WebSocket | undefined {
1689
+ if (
1690
+ !!this.#pegboardWebSocket &&
1691
+ this.#pegboardWebSocket.readyState === 1
1692
+ ) {
1693
+ return this.#pegboardWebSocket;
1694
+ } else {
1695
+ return undefined;
1696
+ }
1682
1697
  }
1683
1698
 
1684
1699
  __sendToServer(message: protocol.ToServer) {
@@ -1688,8 +1703,9 @@ export class Runner {
1688
1703
  });
1689
1704
 
1690
1705
  const encoded = protocol.encodeToServer(message);
1691
- if (this.__webSocketReady()) {
1692
- this.__pegboardWebSocket.send(encoded);
1706
+ const pegboardWebSocket = this.getPegboardWebSocketIfReady();
1707
+ if (pegboardWebSocket) {
1708
+ pegboardWebSocket.send(encoded);
1693
1709
  } else {
1694
1710
  this.log?.error({
1695
1711
  msg: "WebSocket not available or not open for sending data",
@@ -1781,6 +1797,13 @@ export class Runner {
1781
1797
  msg: `Scheduling reconnect attempt ${this.#reconnectAttempt + 1} in ${delay}ms`,
1782
1798
  });
1783
1799
 
1800
+ if (this.#reconnectTimeout) {
1801
+ this.log?.info(
1802
+ "clearing previous reconnect timeout in schedule reconnect",
1803
+ );
1804
+ clearTimeout(this.#reconnectTimeout);
1805
+ }
1806
+
1784
1807
  this.#reconnectTimeout = setTimeout(() => {
1785
1808
  if (!this.#shutdown) {
1786
1809
  this.#reconnectAttempt++;
package/src/tunnel.ts CHANGED
@@ -395,11 +395,11 @@ export class Tunnel {
395
395
  this.addRequestToActor(gatewayId, requestId, actorId);
396
396
 
397
397
  // Call WebSocket handler. This handler will add event listeners
398
- // for `open`, etc.
398
+ // for `open`, etc. Pass the VirtualWebSocket (not the adapter) to the actor.
399
399
  await this.#runner.config.websocket(
400
400
  this.#runner,
401
401
  actorId,
402
- adapter,
402
+ adapter.websocket,
403
403
  gatewayId,
404
404
  requestId,
405
405
  request,
@@ -478,7 +478,7 @@ export class Tunnel {
478
478
  messageKind: protocol.ToServerTunnelMessageKind,
479
479
  ) {
480
480
  // Buffer message if not connected
481
- if (!this.#runner.__webSocketReady()) {
481
+ if (!this.#runner.getPegboardWebSocketIfReady()) {
482
482
  this.log?.debug({
483
483
  msg: "buffering tunnel message, socket not connected to engine",
484
484
  requestId: idToStr(requestId),
@@ -917,7 +917,7 @@ export class Tunnel {
917
917
  ) {
918
918
  // NOTE: This method is safe to be async since we will not receive any
919
919
  // further WebSocket events until we send a ToServerWebSocketOpen
920
- // tunnel message. We can do any async logic we need to between thoes two events.
920
+ // tunnel message. We can do any async logic we need to between those two events.
921
921
  //
922
922
  // Sending a ToServerWebSocketClose will terminate the WebSocket early.
923
923