fix: serialize rpc requests, no eager rewrites
This commit is contained in:
@@ -11,7 +11,6 @@ import {
|
|||||||
type OrchestratorResponse,
|
type OrchestratorResponse,
|
||||||
parseRequestLine,
|
parseRequestLine,
|
||||||
type RpcBridgeResponse,
|
type RpcBridgeResponse,
|
||||||
type RpcClientMessage,
|
|
||||||
type RpcReadyResponse,
|
type RpcReadyResponse,
|
||||||
type RpcRequest,
|
type RpcRequest,
|
||||||
type RpcStreamRequest,
|
type RpcStreamRequest,
|
||||||
@@ -38,7 +37,7 @@ export interface IpcRequestHandler {
|
|||||||
onUiRequest: (request: RpcExtensionUIRequest) => void,
|
onUiRequest: (request: RpcExtensionUIRequest) => void,
|
||||||
):
|
):
|
||||||
| {
|
| {
|
||||||
handleRequest(request: RpcClientMessage): Promise<void>;
|
handleRequest(request: RpcRequest["command"] | { type: "extension_ui_response" }): Promise<void>;
|
||||||
close(): void;
|
close(): void;
|
||||||
}
|
}
|
||||||
| undefined;
|
| undefined;
|
||||||
@@ -94,6 +93,7 @@ export async function startIpcServer(handler: IpcRequestHandler): Promise<Server
|
|||||||
}
|
}
|
||||||
|
|
||||||
socket.write(encodeMessage(response));
|
socket.write(encodeMessage(response));
|
||||||
|
let rpcRequestQueue = Promise.resolve();
|
||||||
socket.on("data", (rpcChunk: Buffer | string) => {
|
socket.on("data", (rpcChunk: Buffer | string) => {
|
||||||
buffer += rpcChunk.toString();
|
buffer += rpcChunk.toString();
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@@ -106,20 +106,29 @@ export async function startIpcServer(handler: IpcRequestHandler): Promise<Server
|
|||||||
if (!rpcLine) {
|
if (!rpcLine) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
void (async () => {
|
rpcRequestQueue = rpcRequestQueue
|
||||||
try {
|
.then(async () => {
|
||||||
const rpcRequest = JSON.parse(rpcLine) as RpcClientMessage;
|
try {
|
||||||
await rpcStream.handleRequest(rpcRequest);
|
await rpcStream.handleRequest(JSON.parse(rpcLine));
|
||||||
} catch (rpcError) {
|
} catch (rpcError: unknown) {
|
||||||
|
socket.write(
|
||||||
|
encodeMessage({
|
||||||
|
type: "error",
|
||||||
|
ok: false,
|
||||||
|
error: rpcError instanceof Error ? rpcError.message : String(rpcError),
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((rpcError: Error) => {
|
||||||
socket.write(
|
socket.write(
|
||||||
encodeMessage({
|
encodeMessage({
|
||||||
type: "error",
|
type: "error",
|
||||||
ok: false,
|
ok: false,
|
||||||
error: rpcError instanceof Error ? rpcError.message : String(rpcError),
|
error: rpcError.message,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
});
|
||||||
})();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
socket.once("close", () => rpcStream.close());
|
socket.once("close", () => rpcStream.close());
|
||||||
@@ -128,7 +137,7 @@ export async function startIpcServer(handler: IpcRequestHandler): Promise<Server
|
|||||||
|
|
||||||
const response = await handler(request);
|
const response = await handler(request);
|
||||||
socket.end(encodeMessage(response));
|
socket.end(encodeMessage(response));
|
||||||
} catch (error) {
|
} catch (error: unknown) {
|
||||||
const response: ErrorResponse = {
|
const response: ErrorResponse = {
|
||||||
type: "error",
|
type: "error",
|
||||||
ok: false,
|
ok: false,
|
||||||
|
|||||||
@@ -9,21 +9,31 @@ import { supervisor } from "./supervisor.ts";
|
|||||||
export async function serve(): Promise<void> {
|
export async function serve(): Promise<void> {
|
||||||
const socketPath = getSocketPath();
|
const socketPath = getSocketPath();
|
||||||
mkdirSync(dirname(socketPath), { recursive: true });
|
mkdirSync(dirname(socketPath), { recursive: true });
|
||||||
await supervisor.recoverAfterRestart();
|
|
||||||
if (isRadiusEnabled()) {
|
|
||||||
const machine = await radiusPresence.start();
|
|
||||||
console.log(`radius integration enabled: ${socketPath} -> ${getRadiusOrchestratorBaseUrl()}`);
|
|
||||||
if (machine) {
|
|
||||||
console.log(`radius machine id: ${machine.id}`);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log("radius integration disabled: login radius in ~/.pi/agent/auth.json or set PI_RADIUS_API_KEY");
|
|
||||||
}
|
|
||||||
const server = await startIpcServer(
|
const server = await startIpcServer(
|
||||||
Object.assign(handleIpcRequest, {
|
Object.assign(handleIpcRequest, {
|
||||||
openRpcStream,
|
openRpcStream,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await supervisor.recoverAfterRestart();
|
||||||
|
if (isRadiusEnabled()) {
|
||||||
|
const machine = await radiusPresence.start();
|
||||||
|
console.log(`radius integration enabled: ${socketPath} -> ${getRadiusOrchestratorBaseUrl()}`);
|
||||||
|
if (machine) {
|
||||||
|
console.log(`radius machine id: ${machine.id}`);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log("radius integration disabled: login radius in ~/.pi/agent/auth.json or set PI_RADIUS_API_KEY");
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
server.close();
|
||||||
|
if (existsSync(socketPath)) {
|
||||||
|
unlinkSync(socketPath);
|
||||||
|
}
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
console.log(`orchestrator listening on ${socketPath}`);
|
console.log(`orchestrator listening on ${socketPath}`);
|
||||||
|
|
||||||
let shutdownPromise: Promise<void> | undefined;
|
let shutdownPromise: Promise<void> | undefined;
|
||||||
|
|||||||
Reference in New Issue
Block a user