File size: 2,263 Bytes
4440aec
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import { formatError } from "../../server-utils.js";
import {
  classifyGatewayStaleInstall,
  GATEWAY_STALE_INSTALL_CLOSE_REASON,
} from "../../stale-install.js";
import type { GatewayConnectionFrame } from "../connection-transport.js";
import type { GatewayWsMessageHandlerParams } from "./message-handler-types.js";

export function attachGatewayWsMessageHandlerOnDemand(params: GatewayWsMessageHandlerParams): void {
  const queued: GatewayConnectionFrame[] = [];
  const queueMessage = (data: GatewayConnectionFrame) => {
    if (queued.length >= 16) {
      params.setCloseCause("message-handler-loading-overflow", { queuedFrames: queued.length });
      params.close(1008, "gateway message handler loading");
      return;
    }
    queued.push(data);
  };
  params.socket.on("message", queueMessage);
  void params.connectionWork
    .track(async () => {
      const { attachGatewayWsMessageHandler } = await import("./message-handler.js");
      params.socket.off("message", queueMessage);
      if (params.isClosed() || params.connectionWork.isClosing) {
        return;
      }
      const receive = attachGatewayWsMessageHandler(params);
      for (const data of queued) {
        receive(data);
      }
    })
    .catch((error: unknown) => {
      params.socket.off("message", queueMessage);
      const formattedError = formatError(error);
      const staleInstall = classifyGatewayStaleInstall(error);
      if (staleInstall) {
        params.setCloseCause("message-handler-load-failed", {
          error: formattedError,
          staleInstall: true,
          restartCommand: staleInstall.restartCommand,
        });
        params.logWsControl.error(
          `failed to load ws message handler because the OpenClaw installation changed while the Gateway was running conn=${params.connId}; run: ${staleInstall.restartCommand}; error: ${formattedError}`,
        );
        params.close(1011, GATEWAY_STALE_INSTALL_CLOSE_REASON);
        return;
      }
      params.setCloseCause("message-handler-load-failed", { error: formattedError });
      params.logWsControl.error(
        `failed to load ws message handler conn=${params.connId}: ${formattedError}`,
      );
      params.close(1011, "gateway message handler unavailable");
    });
}