Skip to content

Commit cc41c41

Browse files
authored
Revert "Fix race condition while establishing connection due to multiplexing in ODSP Driver" (microsoft#23078)
Reverts microsoft#23060 We're seeing a huge increase in errors in our odsp tests against both prod and dogfood starting with the first run after this PR was merged, so reverting as the probable culprit until we can investigate further.
1 parent 0185a08 commit cc41c41

File tree

3 files changed

+3
-91
lines changed

3 files changed

+3
-91
lines changed

packages/drivers/odsp-driver/src/odspDocumentDeltaConnection.ts

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -634,33 +634,15 @@ export class OdspDocumentDeltaConnection extends DocumentDeltaConnection {
634634
}
635635
});
636636

637-
const p = new Deferred<void>();
638-
// Due to socket reuse(multiplexing), we can get "disconnect" event from other clients in the socket reference.
639-
// So, a race condition could happen, where this client is establishing connection and listening for "connect_document_success"
640-
// on the socket among other events, but we get "disconnect" event on the socket reference from other clients, in which case,
641-
// we dispose connection object and stop listening to further events on the socket. Due to this we get stuck as the connection
642-
// is not yet established and so we don't return any connection object to the client(connection manager). So, we remain stuck.
643-
// In order to handle this, listen for the "disconnect" event and reject the promise with the error so that the caller can
644-
// know and handle the error.
645-
this.on("disconnect", (reason: IAnyDriverError) => {
646-
if (!p.isCompleted) {
647-
p.reject(reason);
648-
}
649-
});
650-
651-
super
652-
.initialize(connectMessage, timeout)
653-
.then(() => p.resolve())
654-
.catch((error) => p.reject(error));
655-
656-
await p.promise.finally(() => {
637+
await super.initialize(connectMessage, timeout).finally(() => {
657638
this.logger.sendTelemetryEvent({
658639
eventName: "ConnectionAttemptInfo",
659640
...this.getConnectionDetailsProps(),
660641
});
661642
});
662643
}
663644

645+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
664646
protected addTrackedListener(event: string, listener: (...args: any[]) => void): void {
665647
// override some event listeners in order to support multiple documents/clients over the same websocket
666648
switch (event) {

packages/drivers/odsp-driver/src/test/socketTests/socketMock.ts

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,6 @@ export interface IMockSocketConnectResponse {
4242
}
4343
| {
4444
eventToEmit: "connect_timeout";
45-
}
46-
| {
47-
eventToEmit: undefined;
4845
};
4946
}
5047

@@ -55,7 +52,7 @@ export interface IMockSocketConnectResponse {
5552
export class ClientSocketMock extends TypedEventEmitter<SocketMockEvents> {
5653
public disconnected = false;
5754
constructor(
58-
private mockSocketConnectResponse: IMockSocketConnectResponse = {
55+
private readonly mockSocketConnectResponse: IMockSocketConnectResponse = {
5956
connect_document: { eventToEmit: "connect_document_success" },
6057
},
6158
) {
@@ -107,16 +104,6 @@ export class ClientSocketMock extends TypedEventEmitter<SocketMockEvents> {
107104
this.emit("server_disconnect", socketError, clientId);
108105
}
109106

110-
/**
111-
* Use this to set connect response when the socket is reused.
112-
* @param connectResponse - response to be send on connect event.
113-
*/
114-
public setMockSocketConnectResponseForReuse(
115-
connectResponse: IMockSocketConnectResponse,
116-
): void {
117-
this.mockSocketConnectResponse = connectResponse;
118-
}
119-
120107
public emit(eventName: string, ...args: unknown[]): boolean {
121108
switch (eventName) {
122109
case "connect_document": {

packages/drivers/odsp-driver/src/test/socketTests/socketTests.spec.ts

Lines changed: 0 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -490,61 +490,4 @@ describe("OdspDocumentDeltaConnection tests", () => {
490490
"1 get_ops_response listener should exiist",
491491
);
492492
});
493-
494-
it("Multiple connection objects should handle server_disconnect event when the second client is still waiting for connection to complete", async () => {
495-
socket = new ClientSocketMock();
496-
const connection1 = await mockSocket(socket as unknown as Socket, async () =>
497-
OdspDocumentDeltaConnection.create(
498-
tenantId,
499-
documentId,
500-
token,
501-
client,
502-
webSocketUrl,
503-
logger,
504-
60000,
505-
epochTracker,
506-
socketReferenceKeyPrefix,
507-
),
508-
);
509-
510-
socket.setMockSocketConnectResponseForReuse({
511-
connect_document: { eventToEmit: undefined },
512-
});
513-
let connection2Fails = false;
514-
let errorReceived: IAnyDriverError | undefined;
515-
const connection2 = mockSocket(socket as unknown as Socket, async () =>
516-
OdspDocumentDeltaConnection.create(
517-
tenantId,
518-
documentId,
519-
token,
520-
client,
521-
webSocketUrl,
522-
logger,
523-
60000,
524-
epochTracker,
525-
socketReferenceKeyPrefix,
526-
),
527-
).catch((error: IAnyDriverError) => {
528-
connection2Fails = true;
529-
errorReceived = error;
530-
});
531-
let disconnectedEvent1 = false;
532-
533-
const errorToThrow = { message: "OdspSocketError", code: 400 };
534-
connection1.on("disconnect", (reason: IAnyDriverError) => {
535-
disconnectedEvent1 = true;
536-
});
537-
538-
socket.sendServerDisconnectEvent(errorToThrow);
539-
540-
assert(disconnectedEvent1, "disconnect event should happen on first object");
541-
542-
assert(socket !== undefined && !socket.connected, "socket should be disconnected");
543-
checkListenerCount(socket);
544-
await connection2;
545-
assert(connection2Fails, "connection2 should fail");
546-
assert(errorReceived?.message.includes("server_disconnect"), "message should be correct");
547-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any
548-
assert((errorReceived as any).statusCode === 400, "status code should be correct");
549-
});
550493
});

0 commit comments

Comments
 (0)