40
40
41
41
public final class DelayedCachedOutputStreamCleaner implements CachedOutputStreamCleaner , BusLifeCycleListener {
42
42
private static final Logger LOG = LogUtils .getL7dLogger (DelayedCachedOutputStreamCleaner .class );
43
+ private static final long MIN_DELAY = 2000 ; /* 2 seconds */
44
+ private static final DelayedCleaner NOOP_CLEANER = new DelayedCleaner () {
45
+ // NOOP
46
+ };
43
47
44
- private long delay ; /* default is 30 minutes, in milliseconds */
45
- private final DelayQueue <DelayedCloseable > queue = new DelayQueue <>();
46
- private Timer timer ;
48
+ private DelayedCleaner cleaner = NOOP_CLEANER ;
49
+
50
+ private interface DelayedCleaner extends CachedOutputStreamCleaner , Closeable {
51
+ @ Override
52
+ default void register (Closeable closeable ) {
53
+ }
54
+
55
+ @ Override
56
+ default void unregister (Closeable closeable ) {
57
+ }
58
+
59
+ @ Override
60
+ default void close () {
61
+ }
62
+
63
+ @ Override
64
+ default void clean () {
65
+ }
66
+
67
+ default void forceClean () {
68
+ }
69
+ }
70
+
71
+ private static final class DelayedCleanerImpl implements DelayedCleaner {
72
+ private final long delay ; /* default is 30 minutes, in milliseconds */
73
+ private final DelayQueue <DelayedCloseable > queue = new DelayQueue <>();
74
+ private final Timer timer ;
75
+
76
+ DelayedCleanerImpl (final long delay ) {
77
+ this .delay = delay ;
78
+ this .timer = new Timer ("DelayedCachedOutputStreamCleaner" , true );
79
+ this .timer .scheduleAtFixedRate (new TimerTask () {
80
+ @ Override
81
+ public void run () {
82
+ clean ();
83
+ }
84
+ }, 0 , Math .max (MIN_DELAY , delay >> 1 ));
85
+ }
86
+
87
+ @ Override
88
+ public void register (Closeable closeable ) {
89
+ queue .put (new DelayedCloseable (closeable , delay ));
90
+ }
91
+
92
+ @ Override
93
+ public void unregister (Closeable closeable ) {
94
+ queue .remove (new DelayedCloseable (closeable , delay ));
95
+ }
96
+
97
+ @ Override
98
+ public void clean () {
99
+ final Collection <DelayedCloseable > closeables = new ArrayList <>();
100
+ queue .drainTo (closeables );
101
+ clean (closeables );
102
+ }
103
+
104
+ @ Override
105
+ public void forceClean () {
106
+ clean (queue );
107
+ }
108
+
109
+ @ Override
110
+ public void close () {
111
+ timer .cancel ();
112
+ queue .clear ();
113
+ }
114
+
115
+ private void clean (Collection <DelayedCloseable > closeables ) {
116
+ final Iterator <DelayedCloseable > iterator = closeables .iterator ();
117
+ while (iterator .hasNext ()) {
118
+ final DelayedCloseable next = iterator .next ();
119
+ try {
120
+ iterator .remove ();
121
+ LOG .warning ("Unclosed (leaked?) stream detected: " + next .closeable );
122
+ next .closeable .close ();
123
+ } catch (final IOException | RuntimeException ex ) {
124
+ LOG .warning ("Unable to close (leaked?) stream: " + ex .getMessage ());
125
+ }
126
+ }
127
+ }
128
+ }
47
129
48
130
private static final class DelayedCloseable implements Delayed {
49
131
private final Closeable closeable ;
@@ -97,52 +179,45 @@ public void setBus(Bus bus) {
97
179
delayValue = (Number ) bus .getProperty (CachedConstants .CLEANER_DELAY_BUS_PROP );
98
180
busLifeCycleManager = bus .getExtension (BusLifeCycleManager .class );
99
181
}
100
-
182
+
183
+ if (cleaner != null ) {
184
+ cleaner .close ();
185
+ }
186
+
101
187
if (delayValue == null ) {
102
- delay = TimeUnit .MILLISECONDS .convert (30 , TimeUnit .MINUTES );
188
+ // Default delay is set to 30 mins
189
+ cleaner = new DelayedCleanerImpl (TimeUnit .MILLISECONDS .convert (30 , TimeUnit .MINUTES ));
103
190
} else {
104
191
final long value = delayValue .longValue ();
105
- if (value > 0 ) {
106
- delay = value ; /* already in milliseconds */
192
+ if (value > 0 && value >= MIN_DELAY ) {
193
+ cleaner = new DelayedCleanerImpl (value ); /* already in milliseconds */
194
+ } else {
195
+ cleaner = NOOP_CLEANER ;
196
+ if (value < 0 ) {
197
+ LOG .warning ("The value of " + CachedConstants .CLEANER_DELAY_BUS_PROP + " property is invalid: "
198
+ + value + " (should be >= " + MIN_DELAY + ", 0 to deactivate)" );
199
+ }
107
200
}
108
201
}
109
202
110
203
if (busLifeCycleManager != null ) {
111
204
busLifeCycleManager .registerLifeCycleListener (this );
112
205
}
113
-
114
- if (timer != null ) {
115
- timer .cancel ();
116
- timer = null ;
117
- }
118
-
119
- if (delay > 0 ) {
120
- timer = new Timer ("DelayedCachedOutputStreamCleaner" , true );
121
- timer .scheduleAtFixedRate (new TimerTask () {
122
- @ Override
123
- public void run () {
124
- clean ();
125
- }
126
- }, 0 , Math .max (1 , delay >> 1 ));
127
- }
128
-
129
206
}
130
-
207
+
131
208
@ Override
132
209
public void register (Closeable closeable ) {
133
- queue . put ( new DelayedCloseable ( closeable , delay ) );
210
+ cleaner . register ( closeable );
134
211
}
135
212
136
213
@ Override
137
214
public void unregister (Closeable closeable ) {
138
- queue . remove ( new DelayedCloseable ( closeable , delay ) );
215
+ cleaner . unregister ( closeable );
139
216
}
140
217
141
218
@ Override
142
219
public void clean () {
143
- final Collection <DelayedCloseable > closeables = new ArrayList <>();
144
- queue .drainTo (closeables );
145
- clean (closeables );
220
+ cleaner .clean ();
146
221
}
147
222
148
223
@ Override
@@ -155,26 +230,10 @@ public void postShutdown() {
155
230
156
231
@ Override
157
232
public void preShutdown () {
158
- if (timer != null ) {
159
- timer .cancel ();
160
- }
233
+ cleaner .close ();
161
234
}
162
235
163
236
public void forceClean () {
164
- clean (queue );
165
- }
166
-
167
- private void clean (Collection <DelayedCloseable > closeables ) {
168
- final Iterator <DelayedCloseable > iterator = closeables .iterator ();
169
- while (iterator .hasNext ()) {
170
- final DelayedCloseable next = iterator .next ();
171
- try {
172
- iterator .remove ();
173
- LOG .warning ("Unclosed (leaked?) stream detected: " + next .closeable );
174
- next .closeable .close ();
175
- } catch (final IOException | RuntimeException ex ) {
176
- LOG .warning ("Unable to close (leaked?) stream: " + ex .getMessage ());
177
- }
178
- }
237
+ cleaner .forceClean ();
179
238
}
180
239
}
0 commit comments