25
25
import java .util .Iterator ;
26
26
import java .util .Map ;
27
27
import java .util .concurrent .ConcurrentHashMap ;
28
- import java .util .concurrent .Executors ;
29
28
import java .util .concurrent .ScheduledExecutorService ;
30
29
import java .util .concurrent .TimeUnit ;
31
30
@@ -34,7 +33,6 @@ public class IdleWindowScaner implements AutoCloseable {
34
33
private static final Logger logger = LoggerFactory .getLogger (IdleWindowScaner .class .getName ());
35
34
36
35
private final Integer maxIdleTime ;
37
- private long sessionTimeOut = 0 ;
38
36
private final ScheduledExecutorService executor ;
39
37
40
38
private final ConcurrentHashMap <WindowKey , TimeType > lastUpdateTime2WindowKey = new ConcurrentHashMap <>(16 );
@@ -59,65 +57,66 @@ public IdleWindowScaner(Integer maxIdleTime, ScheduledExecutorService executor)
59
57
}, 0 , 1000 , TimeUnit .MILLISECONDS );
60
58
}
61
59
62
- public void initSessionTimeOut (long sessionTimeOut ) {
63
- this .sessionTimeOut = sessionTimeOut ;
64
- }
65
-
66
- public void putAccumulatorWindowCallback (WindowKey windowKey , AccumulatorWindowFire <?, ?, ?, ?> function ) {
60
+ public void putAccumulatorWindowCallback (WindowKey windowKey , long watermark , AccumulatorWindowFire <?, ?, ?, ?> function ) {
67
61
this .fireWindowCallBack .putIfAbsent (windowKey , function );
68
62
this .lastUpdateTime2WindowKey .compute (windowKey , (key , timeType ) -> {
69
63
if (timeType == null ) {
70
- timeType = new TimeType (Type .AccumulatorWindow , System .currentTimeMillis ());
64
+ timeType = new TimeType (Type .AccumulatorWindow , System .currentTimeMillis (), watermark );
71
65
} else {
72
66
timeType .setUpdateTime (System .currentTimeMillis ());
67
+ timeType .setWatermark (watermark );
73
68
}
74
69
return timeType ;
75
70
});
76
71
}
77
72
78
- public void putAccumulatorSessionWindowCallback (WindowKey windowKey , AccumulatorSessionWindowFire <?, ?, ?, ?> function ) {
73
+ public void putAccumulatorSessionWindowCallback (WindowKey windowKey , long watermark , AccumulatorSessionWindowFire <?, ?, ?, ?> function ) {
79
74
this .fireSessionWindowCallback .putIfAbsent (windowKey , function );
80
75
this .lastUpdateTime2WindowKey .compute (windowKey , (key , timeType ) -> {
81
76
if (timeType == null ) {
82
- timeType = new TimeType (Type .AccumulatorSessionWindow , System .currentTimeMillis ());
77
+ timeType = new TimeType (Type .AccumulatorSessionWindow , System .currentTimeMillis (), watermark );
83
78
} else {
84
79
timeType .setUpdateTime (System .currentTimeMillis ());
80
+ timeType .setWatermark (watermark );
85
81
}
86
82
return timeType ;
87
83
});
88
84
}
89
85
90
- public void putAggregateWindowCallback (WindowKey windowKey , AggregateWindowFire <?, ?, ?> function ) {
86
+ public void putAggregateWindowCallback (WindowKey windowKey , long watermark , AggregateWindowFire <?, ?, ?> function ) {
91
87
this .windowKeyAggregate .putIfAbsent (windowKey , function );
92
88
this .lastUpdateTime2WindowKey .compute (windowKey , (key , timeType ) -> {
93
89
if (timeType == null ) {
94
- timeType = new TimeType (Type .AggregateWindow , System .currentTimeMillis ());
90
+ timeType = new TimeType (Type .AggregateWindow , System .currentTimeMillis (), watermark );
95
91
} else {
96
92
timeType .setUpdateTime (System .currentTimeMillis ());
93
+ timeType .setWatermark (watermark );
97
94
}
98
95
return timeType ;
99
96
});
100
97
}
101
98
102
- public void putAggregateSessionWindowCallback (WindowKey windowKey , AggregateSessionWindowFire <?, ?, ?> function ) {
99
+ public void putAggregateSessionWindowCallback (WindowKey windowKey , long watermark , AggregateSessionWindowFire <?, ?, ?> function ) {
103
100
this .windowKeyAggregateSession .putIfAbsent (windowKey , function );
104
101
this .lastUpdateTime2WindowKey .compute (windowKey , (key , timeType ) -> {
105
102
if (timeType == null ) {
106
- timeType = new TimeType (Type .AggregateSessionWindow , System .currentTimeMillis ());
103
+ timeType = new TimeType (Type .AggregateSessionWindow , System .currentTimeMillis (), watermark );
107
104
} else {
108
105
timeType .setUpdateTime (System .currentTimeMillis ());
106
+ timeType .setWatermark (watermark );
109
107
}
110
108
return timeType ;
111
109
});
112
110
}
113
111
114
- public void putJoinWindowCallback (WindowKey windowKey , JoinWindowFire <?, ?, ?, ?> function ) {
112
+ public void putJoinWindowCallback (WindowKey windowKey , long watermark , JoinWindowFire <?, ?, ?, ?> function ) {
115
113
this .fireJoinWindowCallback .putIfAbsent (windowKey , function );
116
114
this .lastUpdateTime2WindowKey .compute (windowKey , (key , timeType ) -> {
117
115
if (timeType == null ) {
118
- timeType = new TimeType (Type .JoinWindow , System .currentTimeMillis ());
116
+ timeType = new TimeType (Type .JoinWindow , System .currentTimeMillis (), watermark );
119
117
} else {
120
118
timeType .setUpdateTime (System .currentTimeMillis ());
119
+ timeType .setWatermark (watermark );
121
120
}
122
121
return timeType ;
123
122
});
@@ -169,9 +168,10 @@ private void scanAndFireWindow() throws Throwable {
169
168
switch (type ) {
170
169
case AggregateSessionWindow :
171
170
case AccumulatorSessionWindow : {
172
- if (idleTime >= sessionTimeOut ) {
171
+ long watermark = timeType .getWatermark () + idleTime ;
172
+ if (watermark > windowKey .getWindowEnd ()) {
173
173
try {
174
- doFire (windowKey , type );
174
+ doFire (windowKey , type , watermark );
175
175
} finally {
176
176
iterator .remove ();
177
177
}
@@ -181,10 +181,10 @@ private void scanAndFireWindow() throws Throwable {
181
181
case AccumulatorWindow :
182
182
case JoinWindow :
183
183
case AggregateWindow : {
184
- long windowSize = windowKey . getWindowEnd () - windowKey . getWindowStart () ;
185
- if (idleTime > this .maxIdleTime && idleTime > windowSize ) {
184
+ long watermark = timeType . getWatermark () + idleTime ;
185
+ if (idleTime > this .maxIdleTime && watermark > windowKey . getWindowEnd () ) {
186
186
try {
187
- doFire (windowKey , type );
187
+ doFire (windowKey , type , watermark );
188
188
} finally {
189
189
iterator .remove ();
190
190
}
@@ -197,8 +197,7 @@ private void scanAndFireWindow() throws Throwable {
197
197
}
198
198
}
199
199
200
- private void doFire (WindowKey windowKey , Type type ) throws Throwable {
201
- long watermark = windowKey .getWindowEnd () + 1 ;
200
+ private void doFire (WindowKey windowKey , Type type , long watermark ) throws Throwable {
202
201
String operatorName = windowKey .getOperatorName ();
203
202
204
203
switch (type ) {
@@ -258,10 +257,12 @@ public void close() throws Exception {
258
257
static class TimeType {
259
258
private Type type ;
260
259
private long updateTime ;
260
+ private long watermark ;
261
261
262
- public TimeType (Type type , long updateTime ) {
262
+ public TimeType (Type type , long updateTime , long watermark ) {
263
263
this .type = type ;
264
264
this .updateTime = updateTime ;
265
+ this .watermark = watermark ;
265
266
}
266
267
267
268
public Type getType () {
@@ -279,6 +280,14 @@ public long getUpdateTime() {
279
280
public void setUpdateTime (long updateTime ) {
280
281
this .updateTime = updateTime ;
281
282
}
283
+
284
+ public long getWatermark () {
285
+ return watermark ;
286
+ }
287
+
288
+ public void setWatermark (long watermark ) {
289
+ this .watermark = watermark ;
290
+ }
282
291
}
283
292
284
293
enum Type {
0 commit comments