Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 105 additions & 0 deletions packages/client-runtime/src/connection/supervisor.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2023,6 +2023,111 @@ describe("EnvironmentSupervisor routes", () => {
}),
);

it.effect("keeps the live session until a better route that answered has connected", () =>
Effect.gen(function* () {
const lanReachable = yield* Ref.make(false);
const releasesAtLanAttempt = yield* Deferred.make<number>();
const harness = yield* makeHarness({
checkRoute: (route) =>
route.target._tag === "BearerConnectionTarget"
? Ref.get(lanReachable).pipe(
Effect.map((reachable) => (reachable ? "answered" : "silent")),
)
: Effect.succeed("unchecked"),
prepare: (_attempt, target): Effect.Effect<PreparedConnection, ConnectionAttemptError> =>
target._tag === "BearerConnectionTarget"
? Ref.get(harness.releaseCount).pipe(
Effect.flatMap((releases) => Deferred.succeed(releasesAtLanAttempt, releases)),
Effect.andThen(Effect.fail(transient("WebSocket upgrade failed."))),
)
: Effect.succeed(preparedFor(target)),
});
const supervisor = yield* EnvironmentSupervisor.make(LAN_THEN_RELAY_ENTRY, {
initiallyDesired: true,
}).pipe(Effect.provide(harness.dependencies));

yield* awaitState(
supervisor.state,
(state) => state.phase === "connected" && state.generation === 1,
);
yield* Ref.set(lanReachable, true);
yield* TestClock.adjust("60 seconds");

expect(yield* Deferred.await(releasesAtLanAttempt)).toBe(0);
}),
);

it.effect("moves to a learned LAN route that borrows a plain HTTP pairing's token", () =>
Effect.gen(function* () {
const publicTarget = new BearerConnectionTarget({
environmentId: TARGET.environmentId,
label: TARGET.label,
connectionId: "bearer:public",
});
const learnedLanTarget = new BearerConnectionTarget({
environmentId: TARGET.environmentId,
label: TARGET.label,
connectionId: `learned:${TARGET.environmentId}:http://192.168.1.10:3773@bearer:public`,
});
const entry: ConnectionCatalogEntry = {
target: learnedLanTarget,
profile: Option.some(
new BearerConnectionProfile({
connectionId: learnedLanTarget.connectionId,
environmentId: TARGET.environmentId,
label: TARGET.label,
httpBaseUrl: "http://192.168.1.10:3773/",
wsBaseUrl: "ws://192.168.1.10:3773/",
learned: true,
}),
),
alternateRoutes: [
{
target: publicTarget,
profile: Option.some(
new BearerConnectionProfile({
connectionId: publicTarget.connectionId,
environmentId: TARGET.environmentId,
label: TARGET.label,
httpBaseUrl: "http://203.0.113.5:3773/",
wsBaseUrl: "ws://203.0.113.5:3773/",
}),
),
},
],
enabled: true,
};
const lanReachable = yield* Ref.make(false);
const harness = yield* makeHarness({
checkRoute: (route) =>
route.target === learnedLanTarget
? Ref.get(lanReachable).pipe(
Effect.map((reachable) => (reachable ? "answered" : "silent")),
)
: Effect.succeed("answered"),
prepare: (_attempt, target) => Effect.succeed(preparedFor(target)),
});
const supervisor = yield* EnvironmentSupervisor.make(entry, {
initiallyDesired: true,
}).pipe(Effect.provide(harness.dependencies));

yield* awaitState(
supervisor.state,
(state) => state.phase === "connected" && state.generation === 1,
);
yield* Ref.set(lanReachable, true);
yield* TestClock.adjust("60 seconds");

yield* awaitState(
supervisor.state,
(state) => state.phase === "connected" && state.generation === 2,
);
expect(Option.getOrThrow(yield* SubscriptionRef.get(supervisor.prepared)).target).toBe(
learnedLanTarget,
);
}),
);

it.effect("keeps checking a LAN route every minute when it answers but cannot be prepared", () =>
Effect.gen(function* () {
const lanPreflights = yield* Ref.make(0);
Expand Down
Loading
Loading