Skip to content

Commit 1daf6c1

Browse files
Fix: 업데이트 조인 순서 적용
1 parent 53f2626 commit 1daf6c1

1 file changed

Lines changed: 39 additions & 5 deletions

File tree

src/collaboration/infrastructure/gateway/collaboration.gateway.ts

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,18 +33,19 @@ export class CollaborationGateway
3333

3434
private readonly logger = new Logger(CollaborationGateway.name);
3535
private flushTimeouts = new Map<string, NodeJS.Timeout>();
36+
private joiningClients = new Set<string>(); // join 처리 중인 clientId
3637

3738
constructor(
3839
private readonly yjsDocumentService: YjsDocumentService,
3940
private readonly collaborationUseCase: CollaborationUseCase,
4041
) {}
4142

4243
handleConnection(client: Socket) {
43-
this.logger.log(`Client connected: ${client.id}`);
44+
this.logger.log(`[클라이언트 연결] clientId=${client.id}`);
4445
}
4546

4647
async handleDisconnect(client: Socket) {
47-
this.logger.log(`Client disconnected: ${client.id}`);
48+
this.logger.log(`[클라이언트 연결 해제] clientId=${client.id}`);
4849
await this.removeClientFromAllCardsets(client);
4950
}
5051

@@ -55,9 +56,12 @@ export class CollaborationGateway
5556
@MessageBody() data: { cardsetId: string },
5657
) {
5758
const { cardsetId } = data;
58-
this.logger.log(`User ${user.userId} joining cardset ${cardsetId}`);
59+
this.logger.log(
60+
`[cardset 입장] userId=${user.userId}, cardsetId=${cardsetId}, clientId=${client.id}`,
61+
);
5962

6063
try {
64+
this.joiningClients.add(client.id);
6165
void client.join(`cardset:${cardsetId}`);
6266

6367
await this.yjsDocumentService.registerClient(cardsetId, client.id);
@@ -78,6 +82,7 @@ export class CollaborationGateway
7882
const state = Y.encodeStateAsUpdate(doc);
7983
client.emit('sync', { cardsetId, update: Array.from(state) });
8084

85+
this.joiningClients.delete(client.id);
8186
this.logger.log(`User ${user.userId} joined cardset ${cardsetId}`);
8287
} catch (error) {
8388
this.logger.error('Error joining cardset:', error);
@@ -88,6 +93,7 @@ export class CollaborationGateway
8893
errorStack: error instanceof Error ? error.stack : undefined,
8994
});
9095

96+
this.joiningClients.delete(client.id);
9197
try {
9298
const emptyDoc = new Y.Doc();
9399
const state = Y.encodeStateAsUpdate(emptyDoc);
@@ -113,7 +119,9 @@ export class CollaborationGateway
113119
) {
114120
try {
115121
const { cardsetId } = data;
116-
this.logger.log(`User ${user.userId} leaving cardset ${cardsetId}`);
122+
this.logger.log(
123+
`[cardset 퇴장] userId=${user.userId}, cardsetId=${cardsetId}, clientId=${client.id}`,
124+
);
117125

118126
void client.leave(`cardset:${cardsetId}`);
119127
await this.yjsDocumentService.unregisterClient(cardsetId, client.id);
@@ -134,6 +142,9 @@ export class CollaborationGateway
134142
payload: { cardsetId: string; awareness: number[] },
135143
) {
136144
const { cardsetId, awareness } = payload;
145+
this.logger.log(
146+
`[awareness 브로드캐스트] cardsetId=${cardsetId}, clientId=${client.id}, awarenessSize=${awareness.length}`,
147+
);
137148
client.to(`cardset:${cardsetId}`).emit('awareness', {
138149
data: { cardsetId, awareness: new Uint8Array(awareness) },
139150
});
@@ -148,9 +159,16 @@ export class CollaborationGateway
148159
try {
149160
const { cardsetId, update } = data;
150161
this.logger.log(
151-
`Sync request from user ${user.userId} for cardset ${cardsetId}`,
162+
`[update 수신] userId=${user.userId}, cardsetId=${cardsetId}, clientId=${client.id}, updateSize=${update?.length ?? 0}`,
152163
);
153164

165+
if (this.joiningClients.has(client.id)) {
166+
this.logger.warn(
167+
`[update 무시] join 처리 중 - clientId=${client.id}, cardsetId=${cardsetId}`,
168+
);
169+
return;
170+
}
171+
154172
if (!update) {
155173
client.emit('error', { message: 'Update data is required' });
156174
return;
@@ -185,6 +203,9 @@ export class CollaborationGateway
185203

186204
private async loadDocumentFromDBOrCreate(cardsetId: string): Promise<Y.Doc> {
187205
const numericCardsetId = Number(cardsetId);
206+
this.logger.log(
207+
`[DB에서 문서 로드 시도] cardsetId=${cardsetId}, numericCardsetId=${numericCardsetId}`,
208+
);
188209

189210
try {
190211
const doc =
@@ -214,6 +235,7 @@ export class CollaborationGateway
214235
}
215236

216237
private async createNewDocument(cardsetId: string): Promise<Y.Doc> {
238+
this.logger.log(`[새 문서 생성] cardsetId=${cardsetId}`);
217239
const doc = new Y.Doc();
218240
this.logger.log(`Created new Yjs document for cardset ${cardsetId}`);
219241
await this.yjsDocumentService
@@ -228,6 +250,9 @@ export class CollaborationGateway
228250

229251
private async removeClientFromAllCardsets(client: Socket) {
230252
const cardsets = await this.yjsDocumentService.getClientCardsets(client.id);
253+
this.logger.log(
254+
`[클라이언트 전체 cardset 제거] clientId=${client.id}, cardsets=${JSON.stringify(cardsets)}`,
255+
);
231256
if (cardsets.length === 0) return;
232257

233258
for (const cardsetId of cardsets) {
@@ -242,6 +267,9 @@ export class CollaborationGateway
242267
}
243268

244269
private scheduleFlush(cardsetId: string) {
270+
this.logger.log(
271+
`[flush 예약] cardsetId=${cardsetId}, delayMs=${CollaborationGateway.FLUSH_DELAY_MS}`,
272+
);
245273
if (this.flushTimeouts.has(cardsetId)) return;
246274
const timeout = setTimeout(() => {
247275
this.flushTimeouts.delete(cardsetId);
@@ -253,6 +281,9 @@ export class CollaborationGateway
253281

254282
private clearScheduledFlush(cardsetId: string) {
255283
const timeout = this.flushTimeouts.get(cardsetId);
284+
this.logger.log(
285+
`[flush 예약 취소] cardsetId=${cardsetId}, hadScheduled=${!!timeout}`,
286+
);
256287
if (timeout) {
257288
clearTimeout(timeout);
258289
this.flushTimeouts.delete(cardsetId);
@@ -262,6 +293,9 @@ export class CollaborationGateway
262293
private async flushCardset(cardsetId: string) {
263294
const activeCount =
264295
await this.yjsDocumentService.getActiveClientCount(cardsetId);
296+
this.logger.log(
297+
`[cardset flush 실행] cardsetId=${cardsetId}, activeCount=${activeCount}`,
298+
);
265299
if (activeCount > 0) return;
266300

267301
try {

0 commit comments

Comments
 (0)