diff --git a/build.gradle b/build.gradle index 7945a4a..828451c 100644 --- a/build.gradle +++ b/build.gradle @@ -63,6 +63,7 @@ dependencies { // caffeine implementation 'com.github.ben-manes.caffeine:caffeine' + implementation 'org.springframework.retry:spring-retry:2.0.12' } tasks.named('test') { diff --git a/src/main/java/com/oronaminc/join/global/config/RestTemplateConfig.java b/src/main/java/com/oronaminc/join/global/config/RestTemplateConfig.java new file mode 100644 index 0000000..1e98591 --- /dev/null +++ b/src/main/java/com/oronaminc/join/global/config/RestTemplateConfig.java @@ -0,0 +1,38 @@ +package com.oronaminc.join.global.config; + +import java.time.Duration; + +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.client.ClientHttpRequestInterceptor; +import org.springframework.retry.policy.SimpleRetryPolicy; +import org.springframework.retry.support.RetryTemplate; +import org.springframework.web.client.RestTemplate; + +@Configuration +class RestTemplateConfig { + + @Bean + public RestTemplate restTemplate() { + return new RestTemplateBuilder() + .connectTimeout(Duration.ofSeconds(5)) + .readTimeout(Duration.ofSeconds(5)) + .additionalInterceptors(clientHttpRequestInterceptor()) + .build(); + } + + // 3번 재시도 + public ClientHttpRequestInterceptor clientHttpRequestInterceptor() { + return (request, body, execution) -> { + RetryTemplate retryTemplate = new RetryTemplate(); + retryTemplate.setRetryPolicy(new SimpleRetryPolicy(3)); + try { + return retryTemplate.execute(context -> execution.execute(request, body)); + } catch (Throwable throwable) { + throw new RuntimeException(throwable); + } + }; + } + +} diff --git a/src/main/java/com/oronaminc/join/room/api/RoomController.java b/src/main/java/com/oronaminc/join/room/api/RoomController.java index ff58993..d64cc68 100644 --- a/src/main/java/com/oronaminc/join/room/api/RoomController.java +++ b/src/main/java/com/oronaminc/join/room/api/RoomController.java @@ -63,7 +63,7 @@ public CreateRoomResponse createRoom( description = "비밀코드를 통해 해당 발표방에 참가자로 등록합니다. 시작 전 상태이면 참가할 수 없습니다.", security = @SecurityRequirement(name = "sessionAuth") ) - @GetMapping("/code") + @PostMapping("/code") @ResponseStatus(HttpStatus.OK) public JoinRoomResponse joinRoom( @RequestBody JoinRoomRequest joinRoomRequest, diff --git a/src/main/java/com/oronaminc/join/websocket/session/CurrentParticipantManager.java b/src/main/java/com/oronaminc/join/websocket/session/CurrentParticipantManager.java index 3716745..d976c9c 100644 --- a/src/main/java/com/oronaminc/join/websocket/session/CurrentParticipantManager.java +++ b/src/main/java/com/oronaminc/join/websocket/session/CurrentParticipantManager.java @@ -23,17 +23,36 @@ public void createRoom(Long roomId) { roomParticipants.computeIfAbsent(roomId, k -> ConcurrentHashMap.newKeySet()); } + // public void addParticipant(Long roomId, Long memberId, int limit) { + // Set participants = getRoomParticipants(roomId); + // + // if (participants.contains(memberId)) return; + // + // synchronized (participants) { + // if (participants.size() >= limit) { + // throw new ErrorException(UNAUTHORIZED_LIMIT_PARTICIPANT); + // } + // participants.add(memberId); + // } + // } + public void addParticipant(Long roomId, Long memberId, int limit) { - Set participants = getRoomParticipants(roomId); + roomParticipants.compute(roomId, (id, participants) -> { + participants = getRoomParticipants(roomId); - if (participants.contains(memberId)) return; + // 중복 참가자일 경우 그대로 반환 (변화 없음) + if (participants.contains(memberId)) { + return participants; + } - synchronized (participants) { + // 인원 초과 시 예외 발생 if (participants.size() >= limit) { throw new ErrorException(UNAUTHORIZED_LIMIT_PARTICIPANT); } + participants.add(memberId); - } + return participants; + }); } public void removeParticipant(Long memberId, Long roomId) {