@@ -33,54 +33,51 @@ public Mono<SlidingWindowCounterProfileResponse> createSlidingWindowCounter() {
33
33
// 현재 윈도우의 시작 시간 계산
34
34
double startTimeCurrentWindow = calculateTimeRange (currentTimestamp );
35
35
36
- // 이전 윈도우의 시작 시간 계산
37
- double startTimePreviousWindow = calculateTimeRange (currentTimestamp - SLIDING_WINDOW_COUNTER_DURATION * 1000 );
38
-
39
36
//식별자 - 현재의 타임 스탬프와 UUID 조합
40
37
String uniqueRequestIdentifier = String .valueOf (currentTimestamp ) + ":" + UUID .randomUUID ().toString ();
41
38
42
39
return reactiveRedisTemplate .opsForZSet ()
43
- .add (redisKey , uniqueRequestIdentifier , currentTimestamp )
44
- .flatMap ( success -> {
45
- if (! success ) {
46
- return Mono . empty ();
47
- }
48
-
49
- // 이전 윈도우의 요청 수를 가져옴
50
- Mono < Long > currentCountValue = reactiveRedisTemplate . opsForZSet ()
51
- . count ( redisKey , Range . closed ( startTimeCurrentWindow , ( double ) currentTimestamp ))
52
- . defaultIfEmpty ( 0L );
53
-
54
- return currentCountValue . flatMap ( previousCount -> {
55
- double overlapRate = calculateOverlapRate ( currentTimestamp ) ;
56
-
57
- // 현재 요청을 포함한 최종 요청 수 계산
58
- long totalCount = Math . round ( 1 + ( previousCount * overlapRate ) );
59
- log . info ( "Adjusted Sliding Window Counter count: {}" , totalCount );
60
-
61
- log .info ("Sliding Window Counter count: {}" , totalCount );
62
- log . debug ( "previousCountValue Sliding Window Counter count: {}" , currentCountValue );
63
- log . debug ( "overlapRate Window Counter count: {}" , overlapRate );
64
- if ( totalCount >= SLIDING_WINDOW_COUNTER_MAX_REQUEST ) {
65
- log . error ( "Rate limit exceeded. key: {}" , redisKey );
66
- return Mono .< SlidingWindowCounterProfileResponse > error (
67
- new RateLimitExceededException ( RateExceptionCode . COMMON_TOO_MANY_REQUESTS , totalCount )
68
- );
69
- } else {
70
- return Mono . just (
71
- SlidingWindowCounterProfileResponse . from (
72
- List . of ( SlidingWindowCounterResponse . from (redisKey , totalCount ))
73
- )
74
- );
75
- }
76
- });
77
- } )
40
+ .count (redisKey , Range . closed ( startTimeCurrentWindow , ( double ) currentTimestamp ) )
41
+ .defaultIfEmpty ( 0L )
42
+ . flatMap ( previousCount -> reactiveRedisTemplate . opsForZSet ()
43
+ . add ( redisKey , uniqueRequestIdentifier , currentTimestamp )
44
+ . flatMap ( success -> {
45
+ if (! success ) {
46
+ return Mono . empty ();
47
+ }
48
+
49
+ double overlapRate = calculateOverlapRate ( currentTimestamp );
50
+
51
+ // 현재 요청을 포함한 최종 요청 수 계산
52
+ long totalCount ;
53
+ if ( previousCount == 0 ) {
54
+ totalCount = 1 ;
55
+ log . info ( "Init Sliding Window Counter count: {}" , totalCount );
56
+ } else {
57
+ totalCount = Math . round ( 1 + ( previousCount * overlapRate ));
58
+ log .info ("Adjusted Sliding Window Counter count: {}" , totalCount );
59
+ }
60
+
61
+ log . info ( "Sliding Window Counter count: {}" , totalCount );
62
+ if ( totalCount >= SLIDING_WINDOW_COUNTER_MAX_REQUEST ) {
63
+ log . error ("Rate limit exceeded. key: {}" , redisKey );
64
+ return Mono . error (
65
+ new RateLimitExceededException ( RateExceptionCode . COMMON_TOO_MANY_REQUESTS , totalCount )
66
+ );
67
+ } else {
68
+ return Mono . just (
69
+ SlidingWindowCounterProfileResponse . from (
70
+ List . of ( SlidingWindowCounterResponse . from ( redisKey , totalCount ) )
71
+ )
72
+ );
73
+ }
74
+ }) )
78
75
// 에러 로깅
79
76
.doOnError (error -> {
80
77
log .error ("An error occurred: {}" , error .getMessage ());
81
78
})
82
79
.onErrorResume (error -> {
83
- // 에러가 발생했을 때 에러 처리
80
+ // 에러가 발생하면 RateLimitExceededException을 반환
84
81
return Mono .error (new RateLimitExceededException (RateExceptionCode .COMMON_TOO_MANY_REQUESTS , 0L ));
85
82
});
86
83
}
@@ -91,8 +88,7 @@ public Flux<SlidingWindowCounterResponse> findAllSlidingWindowCounter() {
91
88
log .info ("Sliding Window Counter find all. key: {}" , redisKey );
92
89
93
90
return reactiveRedisTemplate .opsForZSet ().rangeByScore (redisKey ,
94
- Range .closed (Double .MIN_VALUE , (double ) currentTimestamp ))
95
- //Range.closed(calculateTimeRange(currentTimestamp), (double) currentTimestamp))
91
+ Range .closed (calculateTimeRange (currentTimestamp ), (double ) currentTimestamp ))
96
92
.map (value -> {
97
93
String [] parts = value .toString ().split (":" );
98
94
long timestamp = Long .parseLong (parts [0 ]);
@@ -112,7 +108,7 @@ private double calculateOverlapRate(long currentTimestamp) {
112
108
// 겹치는 시간의 길이를 계산
113
109
double overlapDuration = (startTimeCurrentWindow - startTimePreviousWindow ) / 1000.0 ;
114
110
115
- // 겹치는 시간 비율을 계산 (윈도우 지속 시간으로 나눔)
111
+ // 겹치는 시간 비율을 계산
116
112
double overlapRate = overlapDuration / SLIDING_WINDOW_COUNTER_DURATION ;
117
113
118
114
return overlapRate ;
0 commit comments