xiongzhu 3 ani în urmă
părinte
comite
fbc06013ff

+ 28 - 3
src/main/java/com/izouma/nineth/aspect/AssetSaveAspect.java

@@ -7,15 +7,31 @@ import lombok.extern.slf4j.Slf4j;
 import org.aspectj.lang.JoinPoint;
 import org.aspectj.lang.annotation.After;
 import org.aspectj.lang.annotation.Aspect;
+import org.springframework.scheduling.TaskScheduler;
 import org.springframework.stereotype.Component;
 
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
 @Aspect
 @Component
 @Slf4j
-@AllArgsConstructor
 public class AssetSaveAspect {
 
-    private UserAssetSummaryService userAssetSummaryService;
+    private final UserAssetSummaryService  userAssetSummaryService;
+    private final ScheduledExecutorService executorService;
+    private final Map<Long, Future>        futureMap;
+
+    public AssetSaveAspect(UserAssetSummaryService userAssetSummaryService, ScheduledExecutorService executorService) {
+        this.userAssetSummaryService = userAssetSummaryService;
+        this.executorService = executorService;
+        this.futureMap = new HashMap<>();
+    }
 
     @After("execution(* com.izouma.nineth.repo.AssetRepo.save(..)) || execution(* com.izouma.nineth.repo.AssetRepo.saveAndFlush(..))")
     public void redisLock(JoinPoint joinPoint) {
@@ -23,7 +39,16 @@ public class AssetSaveAspect {
         try {
             Asset asset = (Asset) joinPoint.getArgs()[0];
             log.info("recalculate user asset summary {}", asset.getUserId());
-            userAssetSummaryService.calculateNum(asset.getUserId());
+            synchronized (AssetSaveAspect.class) {
+                Optional.ofNullable(futureMap.get(asset.getUserId()))
+                        .ifPresent(f -> {
+                            log.info("debouncing previous task {}", asset.getUserId());
+                            f.cancel(false);
+                        });
+                futureMap.put(asset.getUserId(), executorService.schedule(() -> {
+                    userAssetSummaryService.calculateNum(asset.getUserId());
+                }, 500, TimeUnit.MILLISECONDS));
+            }
         } catch (Exception e) {
             log.error("AssetSaveAspect error", e);
         }

+ 8 - 0
src/main/java/com/izouma/nineth/config/SchedulingConfig.java

@@ -5,6 +5,9 @@ import org.springframework.context.annotation.Configuration;
 import org.springframework.scheduling.TaskScheduler;
 import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
 
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+
 @Configuration
 public class SchedulingConfig {
     @Bean
@@ -16,4 +19,9 @@ public class SchedulingConfig {
         taskScheduler.setThreadNamePrefix("Scheduler-");
         return taskScheduler;
     }
+
+    @Bean
+    public ScheduledExecutorService ScheduledExecutorService() {
+        return Executors.newScheduledThreadPool(10);
+    }
 }

+ 3 - 3
src/main/java/com/izouma/nineth/service/AirDropService.java

@@ -82,10 +82,10 @@ public class AirDropService {
             List<User> users = userRepo.findByIdInAndDelFalse(record.getTargets().stream()
                     .map(DropTarget::getUserId).collect(Collectors.toList()));
 
-            for (DropTarget target : record.getTargets()) {
+            record.getTargets().parallelStream().forEach(target -> {
                 User user = users.stream().filter(u -> u.getId().equals(target.getUserId()))
                         .findFirst().orElse(null);
-                if (user == null) continue;
+                if (user == null) return;
                 try {
                     for (int i = 0; i < target.getNum(); i++) {
                         if (collection.getType() == CollectionType.BLIND_BOX) {
@@ -152,7 +152,7 @@ public class AirDropService {
                     e.printStackTrace();
                     log.error("空投出错", e);
                 }
-            }
+            });
         }
         return airDropRepo.save(record);
     }

+ 1 - 1
src/main/java/com/izouma/nineth/service/CollectionService.java

@@ -434,7 +434,7 @@ public class CollectionService {
                 .build());
     }
 
-    public synchronized BlindBoxItem draw(Long userId, Long collectionId) {
+    public BlindBoxItem draw(Long userId, Long collectionId) {
         log.info("blindBoxDraw, userId={}, collectionId={}", userId, collectionId);
         List<BlindBoxItem> items = blindBoxItemRepo.findByBlindBoxId(collectionId);
         BoundHashOperations<String, Object, Object> operations = redisTemplate.boundHashOps(RedisKeys.DRAW_BLIND_BOX + collectionId);