Skip to content

Commit bb8ecab

Browse files
authored
fix: SharedStateManager sometimes tries to join channels too early (#351)
1 parent 2863c7e commit bb8ecab

File tree

2 files changed

+24
-12
lines changed

2 files changed

+24
-12
lines changed

src/lib/shared_state/adapter.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,20 @@ export class AtuinSharedStateAdapter<T extends SharableState> implements SharedS
5959
}
6060

6161
public async init() {
62-
const socketManager = SocketManager.get();
63-
this.channel = socketManager.channel(`shared-state:${this.stateId}`);
6462
this.logger = new Logger(`PhoenixSharedStateAdapter: ${this.stateId}`);
65-
this.unsub = this.channel.on(Event.UPDATE, this.handleUpdate);
63+
const socketManager = SocketManager.get();
64+
65+
socketManager.onConnect(() => {
66+
this.channel = socketManager.channel(`shared-state:${this.stateId}`);
67+
this.unsub = this.channel.on(Event.UPDATE, this.handleUpdate);
68+
});
6669
}
6770

6871
public async ensureConnected() {
72+
if (!this.channel) {
73+
throw new Error("Channel not yet initialized");
74+
}
75+
6976
if (this.channel!.state === "joined" || this.channel!.state === "joining") return;
7077

7178
try {
@@ -81,6 +88,10 @@ export class AtuinSharedStateAdapter<T extends SharableState> implements SharedS
8188
}
8289

8390
public resync(last_known_version: Version): Promise<ResyncPayload<T>> {
91+
if (!this.channel) {
92+
throw new Error("Channel not yet initialized");
93+
}
94+
8495
return this.channel!.push<ResyncRequest>(Event.RESYNC_REQ, { last_known_version }).receive<
8596
ResyncPayload<T>
8697
>();
@@ -89,7 +100,7 @@ export class AtuinSharedStateAdapter<T extends SharableState> implements SharedS
89100
public destroy() {
90101
this.logger!.debug("Shutting down");
91102
this.unsub?.();
92-
this.channel!.leave();
103+
this.channel?.leave();
93104
this.emitter.clearListeners();
94105
}
95106

src/lib/shared_state/manager.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
import { useStore } from "@/state/store";
1515
import { ConnectionState } from "@/state/store/user_state";
1616
import { Rc } from "@binarymuse/ts-stdlib";
17+
import { timeoutPromise } from "../utils";
1718

1819
function applyOptimisticUpdates<T>(data: T, updates: Array<OptimisticUpdate>) {
1920
for (const update of updates) {
@@ -230,14 +231,14 @@ export class SharedStateManager<T extends SharableState> {
230231
(state) => state.connectionState,
231232
(connectionState) => {
232233
if (connectionState === ConnectionState.Online) {
233-
this.adapter
234-
.ensureConnected()
235-
.then(() => {
236-
this.resync();
237-
})
238-
.catch((_err) => {
239-
this.logger.error("Failed to ensure channel connection");
240-
});
234+
// onConnect is async on the next tick, so wait a small amount of time to init
235+
timeoutPromise(100, undefined).then(() => {
236+
return this.adapter.ensureConnected()
237+
}).then(() => {
238+
return this.resync();
239+
}).catch((err) => {
240+
this.logger.error("Failed to ensure channel connection and resync:", err);
241+
});
241242
}
242243
},
243244
{

0 commit comments

Comments
 (0)