From 2596d399b139c69771764ddc5d491d7393f7f8b5 Mon Sep 17 00:00:00 2001 From: goldm0ng Date: Mon, 1 Sep 2025 00:08:24 +0900 Subject: [PATCH 01/16] =?UTF-8?q?feat:=20SSE=20=EC=9A=B4=EC=98=81=20?= =?UTF-8?q?=EC=83=81=ED=83=9C=20=EC=A0=95=EC=9D=98=20Enum=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../allcll/backend/support/sse/SseStatus.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 src/main/java/kr/allcll/backend/support/sse/SseStatus.java diff --git a/src/main/java/kr/allcll/backend/support/sse/SseStatus.java b/src/main/java/kr/allcll/backend/support/sse/SseStatus.java new file mode 100644 index 00000000..66742214 --- /dev/null +++ b/src/main/java/kr/allcll/backend/support/sse/SseStatus.java @@ -0,0 +1,18 @@ +package kr.allcll.backend.support.sse; + +public enum SseStatus { + LIVE("실시간 여석을 제공중이에요"), + PRESEAT("preseat 여석을 이용해주세요"), + IDLE("실시간 여석 제공 전이에요. 서비스가 시작되면 알림을 드릴게요."), + ERROR("2025-09-02 까지 서비스 점검 중이에요"); + + private final String message; + + SseStatus(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } +} From 66b6bed210876cb9e7b25e151dac354a70409a7c Mon Sep 17 00:00:00 2001 From: goldm0ng Date: Mon, 1 Sep 2025 00:09:07 +0900 Subject: [PATCH 02/16] =?UTF-8?q?feat:=20SSE=20=EC=9A=B4=EC=98=81=20?= =?UTF-8?q?=EC=83=81=ED=83=9C=20=EC=9D=91=EB=8B=B5=20DTO=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../allcll/backend/support/sse/dto/SseStatusResponse.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/kr/allcll/backend/support/sse/dto/SseStatusResponse.java b/src/main/java/kr/allcll/backend/support/sse/dto/SseStatusResponse.java index c31c3ac7..787fda58 100644 --- a/src/main/java/kr/allcll/backend/support/sse/dto/SseStatusResponse.java +++ b/src/main/java/kr/allcll/backend/support/sse/dto/SseStatusResponse.java @@ -1,9 +1,11 @@ package kr.allcll.backend.support.sse.dto; public record SseStatusResponse( - boolean isConnected + String status, + String message ) { - public static SseStatusResponse of(boolean isConnected) { - return new SseStatusResponse(isConnected); + + public static SseStatusResponse of(String status, String message) { + return new SseStatusResponse(status, message); } } From 7dd19ce6aba323191981d6cb41141412c4016d65 Mon Sep 17 00:00:00 2001 From: goldm0ng Date: Mon, 1 Sep 2025 00:10:11 +0900 Subject: [PATCH 03/16] =?UTF-8?q?feat:=20SSE=20=EC=9A=B4=EC=98=81=20?= =?UTF-8?q?=EC=83=81=ED=83=9C=20=EC=A0=84=EC=86=A1=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backend/support/sse/SseService.java | 32 ++++++++++++++++--- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/src/main/java/kr/allcll/backend/support/sse/SseService.java b/src/main/java/kr/allcll/backend/support/sse/SseService.java index 14999795..d5e20db5 100644 --- a/src/main/java/kr/allcll/backend/support/sse/SseService.java +++ b/src/main/java/kr/allcll/backend/support/sse/SseService.java @@ -15,12 +15,14 @@ public class SseService { private final SseEmitterStorage sseEmitterStorage; + private volatile SseStatus currentStatus = SseStatus.IDLE; public SseEmitter connect(String token) { SseEmitter sseEmitter = createSseEmitter(); sseEmitterStorage.add(token, sseEmitter); SseEventBuilder initialEvent = SseEventBuilderFactory.createInitialEvent(); sendEvent(sseEmitter, initialEvent); + sendStatusEvent(sseEmitter); return sseEmitter; } @@ -42,6 +44,13 @@ public void propagate(String token, String eventName, Object data) { }); } + public void updateStatus(SseStatus newStatus) { + if (this.currentStatus != newStatus) { + this.currentStatus = newStatus; + propagateStatus(); + } + } + private void sendEvent(SseEmitter sseEmitter, SseEventBuilder eventBuilder) { try { sseEmitter.send(eventBuilder); @@ -51,12 +60,25 @@ private void sendEvent(SseEmitter sseEmitter, SseEventBuilder eventBuilder) { } } - public List getConnectedTokens() { - return sseEmitterStorage.getUserTokens().stream().toList(); + private void sendStatusEvent(SseEmitter sseEmitter) { + SseStatusResponse sseStatusResponse = SseStatusResponse.of(currentStatus.name().toLowerCase(), + currentStatus.getMessage()); + + SseEventBuilder eventBuilder = SseEventBuilderFactory.create("status", sseStatusResponse); + sendEvent(sseEmitter, eventBuilder); + } + + private void propagateStatus() { + SseStatusResponse statusResponse = SseStatusResponse.of(currentStatus.name().toLowerCase(), + currentStatus.getMessage()); + + sseEmitterStorage.getEmitters().forEach(emitter -> { + SseEventBuilder eventBuilder = SseEventBuilderFactory.create("status", statusResponse); + sendEvent(emitter, eventBuilder); + }); } - public SseStatusResponse isConnected(String token) { - boolean isConnected = sseEmitterStorage.getEmitter(token).isPresent(); - return SseStatusResponse.of(isConnected); + public List getConnectedTokens() { + return sseEmitterStorage.getUserTokens().stream().toList(); } } From 8121323c1d9099d80c10fad57983529ff712e6ec Mon Sep 17 00:00:00 2001 From: goldm0ng Date: Mon, 1 Sep 2025 00:12:09 +0900 Subject: [PATCH 04/16] =?UTF-8?q?feat:=20SSE=20=EC=9A=B4=EC=98=81=20?= =?UTF-8?q?=EC=83=81=ED=83=9C=20=EB=B3=80=EA=B2=BD=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backend/admin/preseat/AdminPreSeatService.java | 6 +++++- .../kr/allcll/backend/admin/seat/AdminSeatService.java | 10 +++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/main/java/kr/allcll/backend/admin/preseat/AdminPreSeatService.java b/src/main/java/kr/allcll/backend/admin/preseat/AdminPreSeatService.java index 9aeaa9ce..adf59391 100644 --- a/src/main/java/kr/allcll/backend/admin/preseat/AdminPreSeatService.java +++ b/src/main/java/kr/allcll/backend/admin/preseat/AdminPreSeatService.java @@ -3,6 +3,8 @@ import java.time.LocalDate; import java.util.List; import kr.allcll.backend.admin.preseat.dto.PreSeatResponse; +import kr.allcll.backend.support.sse.SseService; +import kr.allcll.backend.support.sse.SseStatus; import kr.allcll.crawler.client.SeatClient; import kr.allcll.crawler.client.model.SeatResponse; import kr.allcll.crawler.client.payload.SeatPayload; @@ -22,13 +24,14 @@ @RequiredArgsConstructor public class AdminPreSeatService { + private final SseService sseService; private final SeatClient seatClient; private final Credentials credentials; private final AllPreSeatBuffer allPreSeatBuffer; private final CrawlerSubjectRepository crawlerSubjectRepository; - public void getAllPreSeat(String userId) { + sseService.updateStatus(SseStatus.PRESEAT); Credential credential = credentials.findByUserId(userId); List crawlerSubjects = crawlerSubjectRepository.findAllBySemesterAt(CrawlerSemester.now()); for (CrawlerSubject crawlerSubject : crawlerSubjects) { @@ -52,6 +55,7 @@ private void sendExternalPreSeatsRequest(CrawlerSubject crawlerSubject, Credenti } catch (CrawlerAllcllException e) { log.error( "[여석] 외부 API 호출에 실패했습니다. PreSeat: " + crawlerSubject.getCuriNo() + "-" + crawlerSubject.getClassName()); + sseService.updateStatus(SseStatus.ERROR); } } diff --git a/src/main/java/kr/allcll/backend/admin/seat/AdminSeatService.java b/src/main/java/kr/allcll/backend/admin/seat/AdminSeatService.java index 91ef518b..d5736950 100644 --- a/src/main/java/kr/allcll/backend/admin/seat/AdminSeatService.java +++ b/src/main/java/kr/allcll/backend/admin/seat/AdminSeatService.java @@ -6,6 +6,8 @@ import java.util.concurrent.atomic.AtomicLong; import kr.allcll.backend.admin.seat.dto.ChangeSubjectsResponse; import kr.allcll.backend.admin.seat.dto.SeatStatusResponse; +import kr.allcll.backend.support.sse.SseService; +import kr.allcll.backend.support.sse.SseStatus; import kr.allcll.crawler.client.SeatClient; import kr.allcll.crawler.client.model.SeatResponse; import kr.allcll.crawler.client.payload.SeatPayload; @@ -25,7 +27,9 @@ @RequiredArgsConstructor public class AdminSeatService { + private final AtomicLong lastSuccessCrawlingTime = new AtomicLong(0); private static final long RECENT_CRAWLING_SUCCESS_THRESHOLD_MS = 3_000; + private final SeatClient seatClient; private final Credentials credentials; private final TargetSubjectStorage targetSubjectStorage; @@ -34,15 +38,17 @@ public class AdminSeatService { private final SjptProperties sjptProperties; private final ChangeDetector changeDetector; private final AllSeatBuffer allSeatBuffer; - private final AtomicLong lastSuccessCrawlingTime = new AtomicLong(0); + private final SseService sseService; public void getAllSeatPeriodically(String userId) { + sseService.updateStatus(SseStatus.LIVE); Credential credential = credentials.findByUserId(userId); fetchPinSeat(credential); fetchGeneralSeat(credential); } public void getSeasonSeatPeriodically(String userId) { + sseService.updateStatus(SseStatus.LIVE); Credential credential = credentials.findByUserId(userId); fetchPinSeat(credential); fetchGeneralSeat(credential); @@ -50,6 +56,7 @@ public void getSeasonSeatPeriodically(String userId) { public void cancelSeatScheduling() { seatScheduler.cancelAll(); + sseService.updateStatus(SseStatus.IDLE); } public SeatStatusResponse getSeatCrawlerStatus() { @@ -125,6 +132,7 @@ private void sendExternalRequestWithOutDetect(CrawlerSubject crawlerSubject, Cre } catch (CrawlerAllcllException e) { log.error( "[여석] 외부 API 호출에 실패했습니다. 과목: " + crawlerSubject.getCuriNo() + "-" + crawlerSubject.getClassName()); + sseService.updateStatus(SseStatus.ERROR); } } From 3fffe0281d7b71e558e213089fa7abbe1dde6841 Mon Sep 17 00:00:00 2001 From: goldm0ng Date: Mon, 1 Sep 2025 00:26:41 +0900 Subject: [PATCH 05/16] =?UTF-8?q?test:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EA=B9=A8=EC=A7=80=EB=8A=94=20=EB=AC=B8=EC=A0=9C=20=ED=95=B4?= =?UTF-8?q?=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/kr/allcll/backend/support/sse/SseServiceTest.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/test/java/kr/allcll/backend/support/sse/SseServiceTest.java b/src/test/java/kr/allcll/backend/support/sse/SseServiceTest.java index ceaba2ab..085bed0e 100644 --- a/src/test/java/kr/allcll/backend/support/sse/SseServiceTest.java +++ b/src/test/java/kr/allcll/backend/support/sse/SseServiceTest.java @@ -53,6 +53,7 @@ void sseConnectionTest() { // then SseTestHelper.assertResponseContainsMessage(response, "success"); + SseTestHelper.assertResponseContainsMessage(response, "idle"); } @DisplayName("동시에 여러 클라이언트와 SSE 연결을 유지하고, 모두에게 메시지를 전달한다.") @@ -86,6 +87,10 @@ void ssePropagationTest() { + "data:success\n" + "\n" + "retry:1000\n" + + "event:status\n" + + "data:{\"status\":\"idle\",\"message\":\"실시간 여석 제공 전이에요. 서비스가 시작되면 알림을 드릴게요.\"}\n" + + "\n" + + "retry:1000\n" + "event:message\n" + "data:\"Hello, SSE!\"\n" + "\n"; From b9eecbd3fdc3dec4be357ec80b7cfe903dfb39d3 Mon Sep 17 00:00:00 2001 From: goldm0ng Date: Mon, 15 Sep 2025 20:27:47 +0900 Subject: [PATCH 06/16] =?UTF-8?q?refactor:=20=EA=B0=80=EB=8F=85=EC=84=B1?= =?UTF-8?q?=20=EB=B0=8F=20=EC=BD=94=EB=93=9C=20=EC=95=88=EC=A0=95=EC=84=B1?= =?UTF-8?q?=EC=9D=84=20=EC=9C=84=ED=95=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/kr/allcll/backend/support/sse/SseService.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/kr/allcll/backend/support/sse/SseService.java b/src/main/java/kr/allcll/backend/support/sse/SseService.java index d5e20db5..dbce033f 100644 --- a/src/main/java/kr/allcll/backend/support/sse/SseService.java +++ b/src/main/java/kr/allcll/backend/support/sse/SseService.java @@ -2,6 +2,7 @@ import java.io.IOException; import java.util.List; +import java.util.Objects; import kr.allcll.backend.support.sse.dto.SseStatusResponse; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -45,10 +46,11 @@ public void propagate(String token, String eventName, Object data) { } public void updateStatus(SseStatus newStatus) { - if (this.currentStatus != newStatus) { - this.currentStatus = newStatus; - propagateStatus(); + if (Objects.equals(this.currentStatus, newStatus)) { + return; } + this.currentStatus = newStatus; + propagateStatus(); } private void sendEvent(SseEmitter sseEmitter, SseEventBuilder eventBuilder) { From 9fd96f4140c68a232b288afbd78c1c2ba30dd4d5 Mon Sep 17 00:00:00 2001 From: goldm0ng Date: Mon, 15 Sep 2025 20:37:07 +0900 Subject: [PATCH 07/16] =?UTF-8?q?refactor:=20=EC=82=AC=EC=9A=A9=EC=9E=90?= =?UTF-8?q?=20=EC=95=88=EB=82=B4=20=EB=AC=B8=EA=B5=AC=20=ED=91=9C=ED=98=84?= =?UTF-8?q?=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/kr/allcll/backend/support/sse/SseStatus.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/kr/allcll/backend/support/sse/SseStatus.java b/src/main/java/kr/allcll/backend/support/sse/SseStatus.java index 66742214..3e25abca 100644 --- a/src/main/java/kr/allcll/backend/support/sse/SseStatus.java +++ b/src/main/java/kr/allcll/backend/support/sse/SseStatus.java @@ -1,10 +1,10 @@ package kr.allcll.backend.support.sse; public enum SseStatus { - LIVE("실시간 여석을 제공중이에요"), - PRESEAT("preseat 여석을 이용해주세요"), - IDLE("실시간 여석 제공 전이에요. 서비스가 시작되면 알림을 드릴게요."), - ERROR("2025-09-02 까지 서비스 점검 중이에요"); + LIVE("과목의 여석을 실시간으로 볼 수 있어요."), + PRESEAT("전체 학년 여석 탭을 이용해 주세요."), + IDLE("과목 실시간 여석 제공 전이에요. 서비스가 시작되면 알림을 드릴게요."), + ERROR("서비스 점검 중이에요. 조금만 기다려주세요."); private final String message; From d72fd31d0bc47d221a287a0f38673319a575a834 Mon Sep 17 00:00:00 2001 From: goldm0ng Date: Mon, 22 Sep 2025 20:32:51 +0900 Subject: [PATCH 08/16] =?UTF-8?q?refactor:=20=EA=B0=9D=EC=B2=B4=20?= =?UTF-8?q?=EC=97=AD=ED=95=A0=EC=9D=84=20=EB=82=B4=ED=8F=AC=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EB=84=A4=EC=9D=B4=EB=B0=8D=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../seat/SeatStreamStatus.java} | 6 +++--- .../admin/seat/dto/SeatStreamStatusResponse.java | 11 +++++++++++ 2 files changed, 14 insertions(+), 3 deletions(-) rename src/main/java/kr/allcll/backend/{support/sse/SseStatus.java => admin/seat/SeatStreamStatus.java} (80%) create mode 100644 src/main/java/kr/allcll/backend/admin/seat/dto/SeatStreamStatusResponse.java diff --git a/src/main/java/kr/allcll/backend/support/sse/SseStatus.java b/src/main/java/kr/allcll/backend/admin/seat/SeatStreamStatus.java similarity index 80% rename from src/main/java/kr/allcll/backend/support/sse/SseStatus.java rename to src/main/java/kr/allcll/backend/admin/seat/SeatStreamStatus.java index 3e25abca..50dbae6b 100644 --- a/src/main/java/kr/allcll/backend/support/sse/SseStatus.java +++ b/src/main/java/kr/allcll/backend/admin/seat/SeatStreamStatus.java @@ -1,6 +1,6 @@ -package kr.allcll.backend.support.sse; +package kr.allcll.backend.admin.seat; -public enum SseStatus { +public enum SeatStreamStatus { LIVE("과목의 여석을 실시간으로 볼 수 있어요."), PRESEAT("전체 학년 여석 탭을 이용해 주세요."), IDLE("과목 실시간 여석 제공 전이에요. 서비스가 시작되면 알림을 드릴게요."), @@ -8,7 +8,7 @@ public enum SseStatus { private final String message; - SseStatus(String message) { + SeatStreamStatus(String message) { this.message = message; } diff --git a/src/main/java/kr/allcll/backend/admin/seat/dto/SeatStreamStatusResponse.java b/src/main/java/kr/allcll/backend/admin/seat/dto/SeatStreamStatusResponse.java new file mode 100644 index 00000000..55839431 --- /dev/null +++ b/src/main/java/kr/allcll/backend/admin/seat/dto/SeatStreamStatusResponse.java @@ -0,0 +1,11 @@ +package kr.allcll.backend.admin.seat.dto; + +public record SeatStreamStatusResponse( + String status, + String message +) { + + public static SeatStreamStatusResponse of(String status, String message) { + return new SeatStreamStatusResponse(status, message); + } +} From 43c3d1fefe6415d513ca35eac07f6a98a476743c Mon Sep 17 00:00:00 2001 From: goldm0ng Date: Mon, 22 Sep 2025 20:35:21 +0900 Subject: [PATCH 09/16] =?UTF-8?q?feat:=20SeatStream=20=EC=83=81=ED=83=9C?= =?UTF-8?q?=20=EA=B4=80=EB=A6=AC=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/seat/SeatStreamStatusStore.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 src/main/java/kr/allcll/backend/admin/seat/SeatStreamStatusStore.java diff --git a/src/main/java/kr/allcll/backend/admin/seat/SeatStreamStatusStore.java b/src/main/java/kr/allcll/backend/admin/seat/SeatStreamStatusStore.java new file mode 100644 index 00000000..ff2e9af5 --- /dev/null +++ b/src/main/java/kr/allcll/backend/admin/seat/SeatStreamStatusStore.java @@ -0,0 +1,21 @@ +package kr.allcll.backend.admin.seat; + +import org.springframework.stereotype.Component; + +@Component +public class SeatStreamStatusStore { + + private volatile SeatStreamStatus currentStatus; + + public SeatStreamStatusStore() { + this.currentStatus = SeatStreamStatus.IDLE; + } + + public SeatStreamStatus getCurrentStatus() { + return currentStatus; + } + + public void updateCurrentStatus(SeatStreamStatus newStatus) { + this.currentStatus = newStatus; + } +} From c5ddc3b7c3e42cad9180cf761530d7c1a759b518 Mon Sep 17 00:00:00 2001 From: goldm0ng Date: Mon, 22 Sep 2025 20:37:41 +0900 Subject: [PATCH 10/16] =?UTF-8?q?feat:=20=EA=B0=9D=EC=B2=B4=EC=9D=98=20?= =?UTF-8?q?=EC=B1=85=EC=9E=84=20=EB=B6=84=EB=A6=AC=EC=97=90=20=EB=94=B0?= =?UTF-8?q?=EB=A5=B8=20=EB=A9=94=EC=84=9C=EB=93=9C=EC=9D=98=20=ED=8C=A8?= =?UTF-8?q?=ED=82=A4=EC=A7=80=20=EC=9D=B4=EB=8F=99=20=EB=B0=8F=20Service?= =?UTF-8?q?=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/seat/SeatStreamStatusService.java | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 src/main/java/kr/allcll/backend/admin/seat/SeatStreamStatusService.java diff --git a/src/main/java/kr/allcll/backend/admin/seat/SeatStreamStatusService.java b/src/main/java/kr/allcll/backend/admin/seat/SeatStreamStatusService.java new file mode 100644 index 00000000..919bba5d --- /dev/null +++ b/src/main/java/kr/allcll/backend/admin/seat/SeatStreamStatusService.java @@ -0,0 +1,34 @@ +package kr.allcll.backend.admin.seat; + +import java.util.Objects; +import kr.allcll.backend.admin.seat.dto.SeatStreamStatusResponse; +import kr.allcll.backend.support.sse.SseEventBuilderFactory; +import kr.allcll.backend.support.sse.SseService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class SeatStreamStatusService { + + private final SseService sseService; + public final SeatStreamStatusStore seatStreamStatusStore; + + public void updateStatus(SeatStreamStatus newStatus) { + SeatStreamStatus currentStatus = seatStreamStatusStore.getCurrentStatus(); + if (Objects.equals(currentStatus, newStatus)) { + return; + } + seatStreamStatusStore.updateCurrentStatus(newStatus); + + SeatStreamStatusResponse sseStatusResponse = getSeatStreamStatusResponse(newStatus); + sseService.propagate(SseEventBuilderFactory.EVENT_SEAT_STREAM_STATUS, sseStatusResponse); + } + + private SeatStreamStatusResponse getSeatStreamStatusResponse(SeatStreamStatus newStatus) { + return SeatStreamStatusResponse.of( + newStatus.name().toLowerCase(), + newStatus.getMessage() + ); + } +} From 8cee796589ce3f686c29a93f0615b057c0306f8d Mon Sep 17 00:00:00 2001 From: goldm0ng Date: Mon, 22 Sep 2025 20:40:36 +0900 Subject: [PATCH 11/16] =?UTF-8?q?refactor:=20=EA=B8=B0=EC=A1=B4=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=EC=9D=98=20=ED=8C=A8=ED=82=A4?= =?UTF-8?q?=EC=A7=80=20=EC=9D=B4=EB=8F=99=EC=97=90=20=EB=94=B0=EB=A5=B8=20?= =?UTF-8?q?SseService=20=ED=99=95=EC=9E=A5=20=EA=B0=80=EB=8A=A5=20?= =?UTF-8?q?=ED=98=95=ED=83=9C=20=EB=B3=B4=EC=A1=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../support/sse/SseEventBuilderFactory.java | 23 ++++++++++- .../backend/support/sse/SseService.java | 40 +++++-------------- 2 files changed, 32 insertions(+), 31 deletions(-) diff --git a/src/main/java/kr/allcll/backend/support/sse/SseEventBuilderFactory.java b/src/main/java/kr/allcll/backend/support/sse/SseEventBuilderFactory.java index 11f87985..f676a95c 100644 --- a/src/main/java/kr/allcll/backend/support/sse/SseEventBuilderFactory.java +++ b/src/main/java/kr/allcll/backend/support/sse/SseEventBuilderFactory.java @@ -4,6 +4,8 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import kr.allcll.backend.admin.seat.SeatStreamStatus; +import kr.allcll.backend.admin.seat.dto.SeatStreamStatusResponse; import org.springframework.http.MediaType; import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; import org.springframework.web.servlet.mvc.method.annotation.SseEmitter.SseEventBuilder; @@ -12,6 +14,9 @@ public class SseEventBuilderFactory { private static final ObjectMapper objectMapper = new ObjectMapper(); + public static final String EVENT_CONNECTION = "connection"; + public static final String EVENT_SEAT_STREAM_STATUS = "status"; + private static final long RECONNECT_TIME_MILLIS = 1000L; static { @@ -32,10 +37,26 @@ public static SseEventBuilder create(String eventName, Object value) { public static SseEventBuilder createInitialEvent() { return baseEvent() - .name("connection") + .name(EVENT_CONNECTION) .data("success", MediaType.TEXT_PLAIN); } + public static SseEventBuilder createInitialSeatStreamStatusEvent(SeatStreamStatus seatStreamStatus) { + SeatStreamStatusResponse seatStreamStatusResponse = SeatStreamStatusResponse.of( + seatStreamStatus.name().toLowerCase(), + seatStreamStatus.getMessage() + ); + + try { + String sseEvent = objectMapper.writeValueAsString(seatStreamStatusResponse); + return baseEvent() + .name(EVENT_SEAT_STREAM_STATUS) + .data(sseEvent, MediaType.APPLICATION_JSON); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + } + private static SseEventBuilder baseEvent() { return SseEmitter.event() .reconnectTime(RECONNECT_TIME_MILLIS); diff --git a/src/main/java/kr/allcll/backend/support/sse/SseService.java b/src/main/java/kr/allcll/backend/support/sse/SseService.java index dbce033f..24949773 100644 --- a/src/main/java/kr/allcll/backend/support/sse/SseService.java +++ b/src/main/java/kr/allcll/backend/support/sse/SseService.java @@ -2,8 +2,8 @@ import java.io.IOException; import java.util.List; -import java.util.Objects; -import kr.allcll.backend.support.sse.dto.SseStatusResponse; +import kr.allcll.backend.admin.seat.SeatStreamStatus; +import kr.allcll.backend.admin.seat.SeatStreamStatusStore; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -16,14 +16,20 @@ public class SseService { private final SseEmitterStorage sseEmitterStorage; - private volatile SseStatus currentStatus = SseStatus.IDLE; + private final SeatStreamStatusStore seatStreamStatusStore; public SseEmitter connect(String token) { SseEmitter sseEmitter = createSseEmitter(); sseEmitterStorage.add(token, sseEmitter); + SseEventBuilder initialEvent = SseEventBuilderFactory.createInitialEvent(); sendEvent(sseEmitter, initialEvent); - sendStatusEvent(sseEmitter); + + SeatStreamStatus seatStreamStatus = seatStreamStatusStore.getCurrentStatus(); + SseEventBuilder initialSeatStreamStatusEvent = SseEventBuilderFactory.createInitialSeatStreamStatusEvent( + seatStreamStatus); + sendEvent(sseEmitter, initialSeatStreamStatusEvent); + return sseEmitter; } @@ -45,14 +51,6 @@ public void propagate(String token, String eventName, Object data) { }); } - public void updateStatus(SseStatus newStatus) { - if (Objects.equals(this.currentStatus, newStatus)) { - return; - } - this.currentStatus = newStatus; - propagateStatus(); - } - private void sendEvent(SseEmitter sseEmitter, SseEventBuilder eventBuilder) { try { sseEmitter.send(eventBuilder); @@ -62,24 +60,6 @@ private void sendEvent(SseEmitter sseEmitter, SseEventBuilder eventBuilder) { } } - private void sendStatusEvent(SseEmitter sseEmitter) { - SseStatusResponse sseStatusResponse = SseStatusResponse.of(currentStatus.name().toLowerCase(), - currentStatus.getMessage()); - - SseEventBuilder eventBuilder = SseEventBuilderFactory.create("status", sseStatusResponse); - sendEvent(sseEmitter, eventBuilder); - } - - private void propagateStatus() { - SseStatusResponse statusResponse = SseStatusResponse.of(currentStatus.name().toLowerCase(), - currentStatus.getMessage()); - - sseEmitterStorage.getEmitters().forEach(emitter -> { - SseEventBuilder eventBuilder = SseEventBuilderFactory.create("status", statusResponse); - sendEvent(emitter, eventBuilder); - }); - } - public List getConnectedTokens() { return sseEmitterStorage.getUserTokens().stream().toList(); } From bff74733fc199ab884cb54db9bda8223a0293d91 Mon Sep 17 00:00:00 2001 From: goldm0ng Date: Mon, 22 Sep 2025 20:41:21 +0900 Subject: [PATCH 12/16] =?UTF-8?q?refactor:=20SeatStream=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20=EB=A1=9C=EC=A7=81=20=ED=8C=A8=ED=82=A4=EC=A7=80=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC=EC=97=90=20=EB=94=B0=EB=A5=B8=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/preseat/AdminPreSeatService.java | 10 +++++----- .../backend/admin/seat/AdminSeatService.java | 18 ++++++++---------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/src/main/java/kr/allcll/backend/admin/preseat/AdminPreSeatService.java b/src/main/java/kr/allcll/backend/admin/preseat/AdminPreSeatService.java index adf59391..7ef3429f 100644 --- a/src/main/java/kr/allcll/backend/admin/preseat/AdminPreSeatService.java +++ b/src/main/java/kr/allcll/backend/admin/preseat/AdminPreSeatService.java @@ -3,8 +3,8 @@ import java.time.LocalDate; import java.util.List; import kr.allcll.backend.admin.preseat.dto.PreSeatResponse; -import kr.allcll.backend.support.sse.SseService; -import kr.allcll.backend.support.sse.SseStatus; +import kr.allcll.backend.admin.seat.SeatStreamStatus; +import kr.allcll.backend.admin.seat.SeatStreamStatusService; import kr.allcll.crawler.client.SeatClient; import kr.allcll.crawler.client.model.SeatResponse; import kr.allcll.crawler.client.payload.SeatPayload; @@ -24,14 +24,14 @@ @RequiredArgsConstructor public class AdminPreSeatService { - private final SseService sseService; private final SeatClient seatClient; private final Credentials credentials; private final AllPreSeatBuffer allPreSeatBuffer; + private final SeatStreamStatusService seatStreamStatusService; private final CrawlerSubjectRepository crawlerSubjectRepository; public void getAllPreSeat(String userId) { - sseService.updateStatus(SseStatus.PRESEAT); + seatStreamStatusService.updateStatus(SeatStreamStatus.PRESEAT); Credential credential = credentials.findByUserId(userId); List crawlerSubjects = crawlerSubjectRepository.findAllBySemesterAt(CrawlerSemester.now()); for (CrawlerSubject crawlerSubject : crawlerSubjects) { @@ -55,7 +55,7 @@ private void sendExternalPreSeatsRequest(CrawlerSubject crawlerSubject, Credenti } catch (CrawlerAllcllException e) { log.error( "[여석] 외부 API 호출에 실패했습니다. PreSeat: " + crawlerSubject.getCuriNo() + "-" + crawlerSubject.getClassName()); - sseService.updateStatus(SseStatus.ERROR); + seatStreamStatusService.updateStatus(SeatStreamStatus.ERROR); } } diff --git a/src/main/java/kr/allcll/backend/admin/seat/AdminSeatService.java b/src/main/java/kr/allcll/backend/admin/seat/AdminSeatService.java index d5736950..a8028dab 100644 --- a/src/main/java/kr/allcll/backend/admin/seat/AdminSeatService.java +++ b/src/main/java/kr/allcll/backend/admin/seat/AdminSeatService.java @@ -6,8 +6,6 @@ import java.util.concurrent.atomic.AtomicLong; import kr.allcll.backend.admin.seat.dto.ChangeSubjectsResponse; import kr.allcll.backend.admin.seat.dto.SeatStatusResponse; -import kr.allcll.backend.support.sse.SseService; -import kr.allcll.backend.support.sse.SseStatus; import kr.allcll.crawler.client.SeatClient; import kr.allcll.crawler.client.model.SeatResponse; import kr.allcll.crawler.client.payload.SeatPayload; @@ -32,23 +30,23 @@ public class AdminSeatService { private final SeatClient seatClient; private final Credentials credentials; + private final AllSeatBuffer allSeatBuffer; + private final ChangeDetector changeDetector; + private final SjptProperties sjptProperties; private final TargetSubjectStorage targetSubjectStorage; private final CrawlerScheduledTaskHandler seatScheduler; private final SeatPersistenceService seatPersistenceService; - private final SjptProperties sjptProperties; - private final ChangeDetector changeDetector; - private final AllSeatBuffer allSeatBuffer; - private final SseService sseService; + private final SeatStreamStatusService seatStreamStatusService; public void getAllSeatPeriodically(String userId) { - sseService.updateStatus(SseStatus.LIVE); + seatStreamStatusService.updateStatus(SeatStreamStatus.LIVE); Credential credential = credentials.findByUserId(userId); fetchPinSeat(credential); fetchGeneralSeat(credential); } public void getSeasonSeatPeriodically(String userId) { - sseService.updateStatus(SseStatus.LIVE); + seatStreamStatusService.updateStatus(SeatStreamStatus.LIVE); Credential credential = credentials.findByUserId(userId); fetchPinSeat(credential); fetchGeneralSeat(credential); @@ -56,7 +54,7 @@ public void getSeasonSeatPeriodically(String userId) { public void cancelSeatScheduling() { seatScheduler.cancelAll(); - sseService.updateStatus(SseStatus.IDLE); + seatStreamStatusService.updateStatus(SeatStreamStatus.IDLE); } public SeatStatusResponse getSeatCrawlerStatus() { @@ -132,7 +130,7 @@ private void sendExternalRequestWithOutDetect(CrawlerSubject crawlerSubject, Cre } catch (CrawlerAllcllException e) { log.error( "[여석] 외부 API 호출에 실패했습니다. 과목: " + crawlerSubject.getCuriNo() + "-" + crawlerSubject.getClassName()); - sseService.updateStatus(SseStatus.ERROR); + seatStreamStatusService.updateStatus(SeatStreamStatus.ERROR); } } From bd3b4a7f8cb527771e9bc0d8ba279c7e351f4784 Mon Sep 17 00:00:00 2001 From: goldm0ng Date: Mon, 22 Sep 2025 20:42:15 +0900 Subject: [PATCH 13/16] =?UTF-8?q?refactor:=20=EC=A0=81=ED=95=A9=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EC=9D=80=20=EB=84=A4=EC=9D=B4=EB=B0=8D?= =?UTF-8?q?=EC=9D=84=20=EA=B0=80=EC=A7=84=20=EA=B8=B0=EC=A1=B4=20DTO=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backend/support/sse/dto/SseStatusResponse.java | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 src/main/java/kr/allcll/backend/support/sse/dto/SseStatusResponse.java diff --git a/src/main/java/kr/allcll/backend/support/sse/dto/SseStatusResponse.java b/src/main/java/kr/allcll/backend/support/sse/dto/SseStatusResponse.java deleted file mode 100644 index 787fda58..00000000 --- a/src/main/java/kr/allcll/backend/support/sse/dto/SseStatusResponse.java +++ /dev/null @@ -1,11 +0,0 @@ -package kr.allcll.backend.support.sse.dto; - -public record SseStatusResponse( - String status, - String message -) { - - public static SseStatusResponse of(String status, String message) { - return new SseStatusResponse(status, message); - } -} From 92f831b56e23c6be9835ae768eb56f64cf1fc042 Mon Sep 17 00:00:00 2001 From: goldm0ng Date: Mon, 22 Sep 2025 20:50:10 +0900 Subject: [PATCH 14/16] =?UTF-8?q?test:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EA=B9=A8=EC=A7=80=EB=8A=94=20=EB=AC=B8=EC=A0=9C=20=ED=95=B4?= =?UTF-8?q?=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/kr/allcll/backend/support/sse/SseServiceTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/kr/allcll/backend/support/sse/SseServiceTest.java b/src/test/java/kr/allcll/backend/support/sse/SseServiceTest.java index 085bed0e..b8c56c4c 100644 --- a/src/test/java/kr/allcll/backend/support/sse/SseServiceTest.java +++ b/src/test/java/kr/allcll/backend/support/sse/SseServiceTest.java @@ -88,7 +88,7 @@ void ssePropagationTest() { + "\n" + "retry:1000\n" + "event:status\n" - + "data:{\"status\":\"idle\",\"message\":\"실시간 여석 제공 전이에요. 서비스가 시작되면 알림을 드릴게요.\"}\n" + + "data:{\"status\":\"idle\",\"message\":\"과목 실시간 여석 제공 전이에요. 서비스가 시작되면 알림을 드릴게요.\"}\n" + "\n" + "retry:1000\n" + "event:message\n" From 91083e27f2a5e903b99f1bf8453ceea67490988b Mon Sep 17 00:00:00 2001 From: goldm0ng Date: Mon, 22 Sep 2025 20:58:13 +0900 Subject: [PATCH 15/16] =?UTF-8?q?refactor:=20=EB=8D=94=20=EC=A7=81?= =?UTF-8?q?=EA=B4=80=EC=A0=81=EC=9D=B8=20=EB=A9=94=EC=84=9C=EB=93=9C?= =?UTF-8?q?=EB=AA=85=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../allcll/backend/admin/preseat/AdminPreSeatService.java | 4 ++-- .../kr/allcll/backend/admin/seat/AdminSeatService.java | 8 ++++---- .../backend/admin/seat/SeatStreamStatusService.java | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/kr/allcll/backend/admin/preseat/AdminPreSeatService.java b/src/main/java/kr/allcll/backend/admin/preseat/AdminPreSeatService.java index 7ef3429f..7f03d62b 100644 --- a/src/main/java/kr/allcll/backend/admin/preseat/AdminPreSeatService.java +++ b/src/main/java/kr/allcll/backend/admin/preseat/AdminPreSeatService.java @@ -31,7 +31,7 @@ public class AdminPreSeatService { private final CrawlerSubjectRepository crawlerSubjectRepository; public void getAllPreSeat(String userId) { - seatStreamStatusService.updateStatus(SeatStreamStatus.PRESEAT); + seatStreamStatusService.updateSeatStreamStatus(SeatStreamStatus.PRESEAT); Credential credential = credentials.findByUserId(userId); List crawlerSubjects = crawlerSubjectRepository.findAllBySemesterAt(CrawlerSemester.now()); for (CrawlerSubject crawlerSubject : crawlerSubjects) { @@ -55,7 +55,7 @@ private void sendExternalPreSeatsRequest(CrawlerSubject crawlerSubject, Credenti } catch (CrawlerAllcllException e) { log.error( "[여석] 외부 API 호출에 실패했습니다. PreSeat: " + crawlerSubject.getCuriNo() + "-" + crawlerSubject.getClassName()); - seatStreamStatusService.updateStatus(SeatStreamStatus.ERROR); + seatStreamStatusService.updateSeatStreamStatus(SeatStreamStatus.ERROR); } } diff --git a/src/main/java/kr/allcll/backend/admin/seat/AdminSeatService.java b/src/main/java/kr/allcll/backend/admin/seat/AdminSeatService.java index a8028dab..55200abf 100644 --- a/src/main/java/kr/allcll/backend/admin/seat/AdminSeatService.java +++ b/src/main/java/kr/allcll/backend/admin/seat/AdminSeatService.java @@ -39,14 +39,14 @@ public class AdminSeatService { private final SeatStreamStatusService seatStreamStatusService; public void getAllSeatPeriodically(String userId) { - seatStreamStatusService.updateStatus(SeatStreamStatus.LIVE); + seatStreamStatusService.updateSeatStreamStatus(SeatStreamStatus.LIVE); Credential credential = credentials.findByUserId(userId); fetchPinSeat(credential); fetchGeneralSeat(credential); } public void getSeasonSeatPeriodically(String userId) { - seatStreamStatusService.updateStatus(SeatStreamStatus.LIVE); + seatStreamStatusService.updateSeatStreamStatus(SeatStreamStatus.LIVE); Credential credential = credentials.findByUserId(userId); fetchPinSeat(credential); fetchGeneralSeat(credential); @@ -54,7 +54,7 @@ public void getSeasonSeatPeriodically(String userId) { public void cancelSeatScheduling() { seatScheduler.cancelAll(); - seatStreamStatusService.updateStatus(SeatStreamStatus.IDLE); + seatStreamStatusService.updateSeatStreamStatus(SeatStreamStatus.IDLE); } public SeatStatusResponse getSeatCrawlerStatus() { @@ -130,7 +130,7 @@ private void sendExternalRequestWithOutDetect(CrawlerSubject crawlerSubject, Cre } catch (CrawlerAllcllException e) { log.error( "[여석] 외부 API 호출에 실패했습니다. 과목: " + crawlerSubject.getCuriNo() + "-" + crawlerSubject.getClassName()); - seatStreamStatusService.updateStatus(SeatStreamStatus.ERROR); + seatStreamStatusService.updateSeatStreamStatus(SeatStreamStatus.ERROR); } } diff --git a/src/main/java/kr/allcll/backend/admin/seat/SeatStreamStatusService.java b/src/main/java/kr/allcll/backend/admin/seat/SeatStreamStatusService.java index 919bba5d..448b1110 100644 --- a/src/main/java/kr/allcll/backend/admin/seat/SeatStreamStatusService.java +++ b/src/main/java/kr/allcll/backend/admin/seat/SeatStreamStatusService.java @@ -14,7 +14,7 @@ public class SeatStreamStatusService { private final SseService sseService; public final SeatStreamStatusStore seatStreamStatusStore; - public void updateStatus(SeatStreamStatus newStatus) { + public void updateSeatStreamStatus(SeatStreamStatus newStatus) { SeatStreamStatus currentStatus = seatStreamStatusStore.getCurrentStatus(); if (Objects.equals(currentStatus, newStatus)) { return; From 4bb883c4c1fbb8e6a3ad37af3c08873f4a22bcc6 Mon Sep 17 00:00:00 2001 From: goldm0ng Date: Mon, 22 Sep 2025 21:25:01 +0900 Subject: [PATCH 16/16] =?UTF-8?q?refactor:=20=EC=97=AC=EC=84=9D=20?= =?UTF-8?q?=ED=81=AC=EB=A1=A4=EB=A7=81=20=EC=83=81=ED=83=9C=20=ED=8C=90?= =?UTF-8?q?=EB=B3=84=ED=95=98=EB=8A=94=20=EA=B8=B0=EC=A1=B4=20DTO=20?= =?UTF-8?q?=EB=84=A4=EC=9D=B4=EB=B0=8D=20=EB=8D=94=20=EC=A7=81=EA=B4=80?= =?UTF-8?q?=EC=A0=81=EC=9C=BC=EB=A1=9C=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kr/allcll/backend/admin/seat/AdminSeatApi.java | 8 ++++---- .../kr/allcll/backend/admin/seat/AdminSeatService.java | 6 +++--- .../admin/seat/dto/SeatCrawlingStatusResponse.java | 10 ++++++++++ .../backend/admin/seat/dto/SeatStatusResponse.java | 10 ---------- 4 files changed, 17 insertions(+), 17 deletions(-) create mode 100644 src/main/java/kr/allcll/backend/admin/seat/dto/SeatCrawlingStatusResponse.java delete mode 100644 src/main/java/kr/allcll/backend/admin/seat/dto/SeatStatusResponse.java diff --git a/src/main/java/kr/allcll/backend/admin/seat/AdminSeatApi.java b/src/main/java/kr/allcll/backend/admin/seat/AdminSeatApi.java index 504d3182..59e149e3 100644 --- a/src/main/java/kr/allcll/backend/admin/seat/AdminSeatApi.java +++ b/src/main/java/kr/allcll/backend/admin/seat/AdminSeatApi.java @@ -2,7 +2,7 @@ import jakarta.servlet.http.HttpServletRequest; import kr.allcll.backend.admin.AdminRequestValidator; -import kr.allcll.backend.admin.seat.dto.SeatStatusResponse; +import kr.allcll.backend.admin.seat.dto.SeatCrawlingStatusResponse; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; @@ -41,12 +41,12 @@ public ResponseEntity seasonSeatStart(HttpServletRequest request, } @GetMapping("/api/admin/seat/check") - public ResponseEntity getSeatStatus(HttpServletRequest request) { + public ResponseEntity getSeatStatus(HttpServletRequest request) { if (validator.isRateLimited(request) || validator.isUnauthorized(request)) { return ResponseEntity.status(401).build(); } - SeatStatusResponse seatStatusResponse = adminSeatService.getSeatCrawlerStatus(); - return ResponseEntity.ok(seatStatusResponse); + SeatCrawlingStatusResponse seatCrawlingStatusResponse = adminSeatService.getSeatCrawlingStatus(); + return ResponseEntity.ok(seatCrawlingStatusResponse); } @PostMapping("/api/admin/seat/cancel") diff --git a/src/main/java/kr/allcll/backend/admin/seat/AdminSeatService.java b/src/main/java/kr/allcll/backend/admin/seat/AdminSeatService.java index 55200abf..bb7cbb10 100644 --- a/src/main/java/kr/allcll/backend/admin/seat/AdminSeatService.java +++ b/src/main/java/kr/allcll/backend/admin/seat/AdminSeatService.java @@ -5,7 +5,7 @@ import java.time.LocalDateTime; import java.util.concurrent.atomic.AtomicLong; import kr.allcll.backend.admin.seat.dto.ChangeSubjectsResponse; -import kr.allcll.backend.admin.seat.dto.SeatStatusResponse; +import kr.allcll.backend.admin.seat.dto.SeatCrawlingStatusResponse; import kr.allcll.crawler.client.SeatClient; import kr.allcll.crawler.client.model.SeatResponse; import kr.allcll.crawler.client.payload.SeatPayload; @@ -57,7 +57,7 @@ public void cancelSeatScheduling() { seatStreamStatusService.updateSeatStreamStatus(SeatStreamStatus.IDLE); } - public SeatStatusResponse getSeatCrawlerStatus() { + public SeatCrawlingStatusResponse getSeatCrawlingStatus() { int seatSchedulerTaskCount = seatScheduler.getTaskCount(); boolean validSeatSchedulerCount = seatSchedulerTaskCount == sjptProperties.getRequestPerSecondCount(); boolean validRecentCrawlingSuccess = @@ -65,7 +65,7 @@ public SeatStatusResponse getSeatCrawlerStatus() { boolean isActive = validSeatSchedulerCount && validRecentCrawlingSuccess; - return SeatStatusResponse.of(isActive); + return SeatCrawlingStatusResponse.of(isActive); } private void fetchPinSeat(Credential credential) { diff --git a/src/main/java/kr/allcll/backend/admin/seat/dto/SeatCrawlingStatusResponse.java b/src/main/java/kr/allcll/backend/admin/seat/dto/SeatCrawlingStatusResponse.java new file mode 100644 index 00000000..ffe71183 --- /dev/null +++ b/src/main/java/kr/allcll/backend/admin/seat/dto/SeatCrawlingStatusResponse.java @@ -0,0 +1,10 @@ +package kr.allcll.backend.admin.seat.dto; + +public record SeatCrawlingStatusResponse( + boolean isActive +) { + + public static SeatCrawlingStatusResponse of(boolean isActive) { + return new SeatCrawlingStatusResponse(isActive); + } +} diff --git a/src/main/java/kr/allcll/backend/admin/seat/dto/SeatStatusResponse.java b/src/main/java/kr/allcll/backend/admin/seat/dto/SeatStatusResponse.java deleted file mode 100644 index d172a7e9..00000000 --- a/src/main/java/kr/allcll/backend/admin/seat/dto/SeatStatusResponse.java +++ /dev/null @@ -1,10 +0,0 @@ -package kr.allcll.backend.admin.seat.dto; - -public record SeatStatusResponse( - boolean isActive -) { - - public static SeatStatusResponse of(boolean isActive) { - return new SeatStatusResponse(isActive); - } -}