Skip to content

Commit

Permalink
[feat] 수정, 삭제 분산락 적용 (#152)
Browse files Browse the repository at this point in the history
* [feat] 분산락 셋팅 #9

* [feat] 분산락 테스트 완료 #9

* [feat] archiving 분산락 적용 #9

* [feat] archiving 분산락 적용 #9

* [feat] update, delete usecase lock 도입 #9
  • Loading branch information
wjdtkdgns authored Aug 29, 2023
1 parent 4c9699e commit c721fdf
Show file tree
Hide file tree
Showing 42 changed files with 457 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import allchive.server.api.archiving.model.dto.response.ArchivingsResponse;
import allchive.server.api.archiving.service.*;
import allchive.server.api.common.slice.SliceResponse;
import allchive.server.api.config.security.SecurityUtil;
import allchive.server.domain.domains.archiving.domain.enums.Category;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
Expand Down Expand Up @@ -118,13 +119,15 @@ public ArchivingContentsResponse getArchivingContents(
@PatchMapping(value = "/{archivingId}/scrap")
public void updateArchivingScrap(
@RequestParam("cancel") Boolean cancel, @PathVariable("archivingId") Long archivingId) {
updateArchivingScrapUseCase.execute(archivingId, cancel);
Long userId = SecurityUtil.getCurrentUserId();
updateArchivingScrapUseCase.execute(archivingId, cancel, userId);
}

@Operation(summary = "아카이빙을 고정합니다.", description = "고정 취소면 cancel에 true 값 보내주세요")
@PatchMapping(value = "/{archivingId}/pin")
public void updateArchivingPin(
@RequestParam("cancel") Boolean cancel, @PathVariable("archivingId") Long archivingId) {
updateArchivingPinUseCase.execute(archivingId, cancel);
Long userId = SecurityUtil.getCurrentUserId();
updateArchivingPinUseCase.execute(archivingId, cancel, userId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import allchive.server.api.config.security.SecurityUtil;
import allchive.server.api.recycle.model.mapper.RecycleMapper;
import allchive.server.core.annotation.UseCase;
import allchive.server.domain.common.aop.distributedLock.DistributedLock;
import allchive.server.domain.common.enums.DistributedLockType;
import allchive.server.domain.domains.archiving.service.ArchivingDomainService;
import allchive.server.domain.domains.archiving.validator.ArchivingValidator;
import allchive.server.domain.domains.recycle.domain.Recycle;
Expand All @@ -20,6 +22,7 @@ public class DeleteArchivingUseCase {
private final RecycleDomainService recycleDomainService;

@Transactional
@DistributedLock(lockType = DistributedLockType.ARCHIVING, identifier ={"archivingId"})
public void execute(Long archivingId) {
Long userId = SecurityUtil.getCurrentUserId();
validateExecution(archivingId, userId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

import allchive.server.api.config.security.SecurityUtil;
import allchive.server.core.annotation.UseCase;
import allchive.server.domain.common.aop.distributedLock.DistributedLock;
import allchive.server.domain.common.enums.DistributedLockType;
import allchive.server.domain.domains.archiving.service.ArchivingDomainService;
import allchive.server.domain.domains.archiving.validator.ArchivingValidator;
import lombok.RequiredArgsConstructor;
Expand All @@ -15,8 +17,8 @@ public class UpdateArchivingPinUseCase {
private final ArchivingDomainService archivingDomainService;

@Transactional
public void execute(Long archivingId, Boolean cancel) {
Long userId = SecurityUtil.getCurrentUserId();
@DistributedLock(lockType = DistributedLockType.ARCHIVING_PIN, identifier ={"archivingId", "userId"})
public void execute(Long archivingId, Boolean cancel, Long userId) {
validateExecution(archivingId, userId, cancel);
archivingDomainService.updatePin(archivingId, userId, !cancel);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

import allchive.server.api.config.security.SecurityUtil;
import allchive.server.core.annotation.UseCase;
import allchive.server.domain.common.aop.distributedLock.DistributedLock;
import allchive.server.domain.common.enums.DistributedLockType;
import allchive.server.domain.domains.archiving.service.ArchivingDomainService;
import allchive.server.domain.domains.archiving.validator.ArchivingValidator;
import allchive.server.domain.domains.user.adaptor.UserAdaptor;
Expand All @@ -25,8 +27,8 @@ public class UpdateArchivingScrapUseCase {
private final ScrapValidator scrapValidator;

@Transactional
public void execute(Long archivingId, Boolean cancel) {
Long userId = SecurityUtil.getCurrentUserId();
@DistributedLock(lockType = DistributedLockType.ARCHIVING_SCRAP, identifier ={"archivingId", "userId"})
public void execute(Long archivingId, Boolean cancel, Long userId) {
validateExecution(archivingId, userId, cancel);
User user = userAdaptor.findById(userId);
if (cancel) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import allchive.server.api.common.util.UrlUtil;
import allchive.server.api.config.security.SecurityUtil;
import allchive.server.core.annotation.UseCase;
import allchive.server.domain.common.aop.distributedLock.DistributedLock;
import allchive.server.domain.common.enums.DistributedLockType;
import allchive.server.core.event.Event;
import allchive.server.core.event.events.s3.S3ImageDeleteEvent;
import allchive.server.domain.domains.archiving.adaptor.ArchivingAdaptor;
Expand All @@ -22,9 +24,9 @@ public class UpdateArchivingUseCase {
private final ArchivingDomainService archivingDomainService;
private final ArchivingAdaptor archivingAdaptor;
private final ArchivingValidator archivingValidator;
private final S3DeleteObjectService s3DeleteObjectService;

@Transactional
@DistributedLock(lockType = DistributedLockType.ARCHIVING, identifier ={"archivingId"})
public void execute(Long archivingId, UpdateArchivingRequest request) {
validateExecution(archivingId);
Archiving archiving = archivingAdaptor.findById(archivingId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import allchive.server.api.auth.service.LogOutUserUseCase;
import allchive.server.api.auth.service.TokenRefreshUseCase;
import allchive.server.api.auth.service.WithdrawUserUseCase;
import allchive.server.api.config.security.SecurityUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
Expand All @@ -26,7 +27,8 @@ public class AuthController {
public void withDrawUser(
@RequestParam(required = false, name = "appleCode", value = "") String appleCode,
@RequestHeader(value = "referer", required = false) String referer) {
withdrawUserUseCase.execute(appleCode, referer);
Long userId = SecurityUtil.getCurrentUserId();
withdrawUserUseCase.execute(appleCode, referer, userId);
}

@Operation(summary = "회원탈퇴를 합니다. (개발용)", deprecated = true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import allchive.server.api.config.security.SecurityUtil;
import allchive.server.core.annotation.UseCase;
import allchive.server.core.error.exception.InvalidOauthProviderException;
import allchive.server.domain.common.aop.distributedLock.DistributedLock;
import allchive.server.domain.common.enums.DistributedLockType;
import allchive.server.domain.domains.archiving.adaptor.ArchivingAdaptor;
import allchive.server.domain.domains.archiving.domain.Archiving;
import allchive.server.domain.domains.archiving.service.ArchivingDomainService;
Expand Down Expand Up @@ -47,8 +49,8 @@ public class WithdrawUserUseCase {
private final ArchivingDomainService archivingDomainService;

@Transactional
public void execute(String appleAccessToken, String referer) {
Long userId = SecurityUtil.getCurrentUserId();
@DistributedLock(lockType = DistributedLockType.USER, identifier ={"userId"})
public void execute(String appleAccessToken, String referer, Long userId) {
User user = userAdaptor.findById(userId);
// oauth쪽 탈퇴
withdrawOauth(user.getOauthInfo().getProvider(), appleAccessToken, user, referer);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import allchive.server.api.block.service.CreateBlockUseCase;
import allchive.server.api.block.service.DeleteBlockUseCase;
import allchive.server.api.block.service.GetBlockUseCase;
import allchive.server.api.config.security.SecurityUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
Expand All @@ -32,7 +33,8 @@ public BlockResponse createBlock(@RequestBody BlockRequest blockRequest) {
@Operation(summary = "유저 차단을 해제합니다.")
@DeleteMapping()
public BlockResponse deleteBlock(@RequestBody BlockRequest blockRequest) {
return deleteBlockUseCase.execute(blockRequest);
Long userId = SecurityUtil.getCurrentUserId();
return deleteBlockUseCase.execute(blockRequest, userId, blockRequest.getUserId());
}

@Operation(summary = "차단한 유저 정보를 가져옵니다.")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import allchive.server.api.block.model.dto.response.BlockResponse;
import allchive.server.api.config.security.SecurityUtil;
import allchive.server.core.annotation.UseCase;
import allchive.server.domain.common.aop.distributedLock.DistributedLock;
import allchive.server.domain.common.enums.DistributedLockType;
import allchive.server.domain.domains.block.service.BlockDomainService;
import allchive.server.domain.domains.block.validator.BlockValidator;
import allchive.server.domain.domains.user.adaptor.UserAdaptor;
Expand All @@ -21,7 +23,8 @@ public class DeleteBlockUseCase {
private final UserAdaptor userAdaptor;

@Transactional
public BlockResponse execute(BlockRequest request) {
@DistributedLock(lockType = DistributedLockType.BLOCK, identifier ={"fromUserId, toUserId"})
public BlockResponse execute(BlockRequest request, Long fromUserId, Long toUserId) {
Long userId = SecurityUtil.getCurrentUserId();
validateExecution(userId, request);
blockDomainService.deleteByBlockFromAndBlockUser(userId, request.getUserId());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import allchive.server.api.config.security.SecurityUtil;
import allchive.server.api.recycle.model.mapper.RecycleMapper;
import allchive.server.core.annotation.UseCase;
import allchive.server.domain.common.aop.distributedLock.DistributedLock;
import allchive.server.domain.common.enums.DistributedLockType;
import allchive.server.domain.domains.archiving.service.ArchivingAsyncDomainService;
import allchive.server.domain.domains.content.adaptor.ContentAdaptor;
import allchive.server.domain.domains.content.domain.Content;
Expand All @@ -27,6 +29,7 @@ public class DeleteContentUseCase {
private final ArchivingAsyncDomainService archivingAsyncDomainService;

@Transactional
@DistributedLock(lockType = DistributedLockType.CONTENT, identifier ={"contentId"})
public void execute(Long contentId) {
Long userId = SecurityUtil.getCurrentUserId();
validateExecution(contentId, userId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
import allchive.server.core.annotation.UseCase;
import allchive.server.core.event.Event;
import allchive.server.core.event.events.s3.S3ImageDeleteEvent;
import allchive.server.domain.common.aop.distributedLock.DistributedLock;
import allchive.server.domain.common.enums.DistributedLockType;
import allchive.server.domain.domains.archiving.service.ArchivingAsyncDomainService;
import allchive.server.domain.domains.content.adaptor.ContentAdaptor;
import allchive.server.domain.domains.content.adaptor.ContentTagGroupAdaptor;
Expand Down Expand Up @@ -42,6 +44,7 @@ public class UpdateContentUseCase {
private final ArchivingAsyncDomainService archivingAsyncDomainService;

@Transactional
@DistributedLock(lockType = DistributedLockType.CONTENT, identifier ={"contentId"})
public void execute(Long contentId, UpdateContentRequest request) {
validateExecution(contentId, request);
regenerateContentTagGroup(contentId, request.getTagIds());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package allchive.server.api.recycle.controller;


import allchive.server.api.config.security.SecurityUtil;
import allchive.server.api.recycle.model.dto.request.ClearDeletedObjectRequest;
import allchive.server.api.recycle.model.dto.request.RestoreDeletedObjectRequest;
import allchive.server.api.recycle.model.dto.response.DeletedObjectResponse;
Expand All @@ -13,6 +14,9 @@
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/recycles")
@RequiredArgsConstructor
Expand All @@ -26,7 +30,8 @@ public class RecycleController {
@Operation(summary = "삭제된 아카이빙, 컨텐츠를 복구합니다.")
@PatchMapping()
public void restoreDeletedObject(@RequestBody RestoreDeletedObjectRequest request) {
restoreDeletedObjectUseCase.execute(request);
Long userId = SecurityUtil.getCurrentUserId();
restoreDeletedObjectUseCase.execute(request, userId);
}

@Operation(summary = "삭제된 아카이빙, 컨텐츠를 가져옵니다.")
Expand All @@ -38,6 +43,7 @@ public DeletedObjectResponse getDeletedObject() {
@Operation(summary = "삭제된 아카이빙, 컨텐츠를 영구적으로 삭제합니다.")
@DeleteMapping()
public void clearDeletedObject(@RequestBody ClearDeletedObjectRequest request) {
clearDeletedObjectUseCase.execute(request);
Long userId = SecurityUtil.getCurrentUserId();
clearDeletedObjectUseCase.execute(request, userId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import allchive.server.core.annotation.UseCase;
import allchive.server.core.event.Event;
import allchive.server.core.event.events.s3.S3ImageDeleteEvent;
import allchive.server.domain.common.aop.distributedLock.DistributedLock;
import allchive.server.domain.common.enums.DistributedLockType;
import allchive.server.domain.domains.archiving.adaptor.ArchivingAdaptor;
import allchive.server.domain.domains.archiving.domain.Archiving;
import allchive.server.domain.domains.archiving.service.ArchivingDomainService;
Expand Down Expand Up @@ -44,8 +46,8 @@ public class ClearDeletedObjectUseCase {
private final ArchivingAdaptor archivingAdaptor;

@Transactional
public void execute(ClearDeletedObjectRequest request) {
Long userId = SecurityUtil.getCurrentUserId();
@DistributedLock(lockType = DistributedLockType.RECYCLE, identifier ={"userId"})
public void execute(ClearDeletedObjectRequest request, Long userId) {
validateExecution(userId, request);
List<Content> contents = contentAdaptor.findAllByArchivingIds(request.getArchivingIds());
List<Long> contentsId = getContentsId(contents, request);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import allchive.server.api.config.security.SecurityUtil;
import allchive.server.api.recycle.model.dto.request.RestoreDeletedObjectRequest;
import allchive.server.core.annotation.UseCase;
import allchive.server.domain.common.aop.distributedLock.DistributedLock;
import allchive.server.domain.common.enums.DistributedLockType;
import allchive.server.domain.domains.archiving.service.ArchivingDomainService;
import allchive.server.domain.domains.archiving.validator.ArchivingValidator;
import allchive.server.domain.domains.content.adaptor.ContentAdaptor;
Expand All @@ -28,8 +30,8 @@ public class RestoreDeletedObjectUseCase {
private final ContentAdaptor contentAdaptor;

@Transactional
public void execute(RestoreDeletedObjectRequest request) {
Long userId = SecurityUtil.getCurrentUserId();
@DistributedLock(lockType = DistributedLockType.RECYCLE, identifier ={"userId"})
public void execute(RestoreDeletedObjectRequest request, Long userId) {
validateExecution(request, userId);
archivingDomainService.restoreByIdIn(request.getArchivingIds());
contentDomainService.restoreByIdIn(request.getContentIds());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

import allchive.server.api.config.security.SecurityUtil;
import allchive.server.core.annotation.UseCase;
import allchive.server.domain.common.aop.distributedLock.DistributedLock;
import allchive.server.domain.common.enums.DistributedLockType;
import allchive.server.domain.domains.content.adaptor.TagAdaptor;
import allchive.server.domain.domains.content.domain.Tag;
import allchive.server.domain.domains.content.service.ContentTagGroupDomainService;
Expand All @@ -20,6 +22,7 @@ public class DeleteTagUseCase {
private final TagDomainService tagDomainService;

@Transactional
@DistributedLock(lockType = DistributedLockType.TAG, identifier ={"tagId"})
public void execute(Long tagId) {
validateExecution(tagId);
Tag tag = tagAdaptor.findById(tagId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import allchive.server.api.config.security.SecurityUtil;
import allchive.server.api.tag.model.dto.request.UpdateTagRequest;
import allchive.server.core.annotation.UseCase;
import allchive.server.domain.common.aop.distributedLock.DistributedLock;
import allchive.server.domain.common.enums.DistributedLockType;
import allchive.server.domain.domains.content.service.TagDomainService;
import allchive.server.domain.domains.content.validator.TagValidator;
import lombok.RequiredArgsConstructor;
Expand All @@ -16,6 +18,7 @@ public class UpdateTagUseCase {
private final TagDomainService tagDomainService;

@Transactional
@DistributedLock(lockType = DistributedLockType.TAG, identifier ={"tagId"})
public void execute(Long tagId, UpdateTagRequest request) {
validateExecution(tagId);
tagDomainService.updateTag(tagId, request.getName());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package allchive.server.api.user.controller;


import allchive.server.api.config.security.SecurityUtil;
import allchive.server.api.user.model.dto.request.CheckUserNicknameRequest;
import allchive.server.api.user.model.dto.request.UpdateUserInfoRequest;
import allchive.server.api.user.model.dto.response.GetUserInfoResponse;
Expand Down Expand Up @@ -41,7 +42,8 @@ public GetUserInfoResponse getUserInfo() {
@Operation(summary = "내 정보를 수정합니다.")
@PostMapping(value = "/info")
public void getUserInfo(@RequestBody UpdateUserInfoRequest updateUserInfoRequest) {
updateUserInfoUseCase.execute(updateUserInfoRequest);
Long userId = SecurityUtil.getCurrentUserId();
updateUserInfoUseCase.execute(updateUserInfoRequest, userId);
}

@Operation(summary = "닉네임 중복체크합니다.")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import allchive.server.core.annotation.UseCase;
import allchive.server.core.event.Event;
import allchive.server.core.event.events.s3.S3ImageDeleteEvent;
import allchive.server.domain.common.aop.distributedLock.DistributedLock;
import allchive.server.domain.common.enums.DistributedLockType;
import allchive.server.domain.domains.user.adaptor.UserAdaptor;
import allchive.server.domain.domains.user.domain.User;
import allchive.server.domain.domains.user.service.UserDomainService;
Expand All @@ -25,8 +27,8 @@ public class UpdateUserInfoUseCase {
private final S3DeleteObjectService s3DeleteObjectService;

@Transactional
public void execute(UpdateUserInfoRequest request) {
Long userId = SecurityUtil.getCurrentUserId();
@DistributedLock(lockType = DistributedLockType.USER, identifier ={"userId"})
public void execute(UpdateUserInfoRequest request, Long userId) {
validateExecution(userId);
eliminateOldImage(userId, request.getImgUrl());
userDomainService.updateUserInfo(
Expand Down
7 changes: 7 additions & 0 deletions Core/src/main/java/allchive/server/core/CoreApplication.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package allchive.server.core;

import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class CoreApplication {
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ public class AllchiveConst {
public static final String REFRESH_TOKEN = "REFRESH_TOKEN";

public static final String KID = "kid";
public static final String KR_YES = "예";
public static final String KR_NO = "아니요";

public static final String PROD = "prod";
public static final String DEV = "dev";
Expand Down Expand Up @@ -47,6 +45,10 @@ public class AllchiveConst {
public static final int MINUS_ONE = -1;
public static final int ZERO = 0;

public static final Long LOCK_WAIT_TIME = 5L;
public static final Long LOCK_LEASE_TIME = 3L;
public static final String REDISSON_LOCK_PREFIX = "LOCK:";

public static final int CORE_POOL_SIZE = 1;
public static final int MAX_POOL_SIZE = 30;
public static final int QUEUE_CAPACITY = 500;
Expand Down
Loading

0 comments on commit c721fdf

Please sign in to comment.