|
11 | 11 | import java.util.List; |
12 | 12 | import java.util.Map; |
13 | 13 | import java.util.concurrent.ExecutorService; |
| 14 | +import java.util.concurrent.Executors; |
| 15 | +import java.util.concurrent.ScheduledExecutorService; |
14 | 16 | import java.util.concurrent.ScheduledThreadPoolExecutor; |
15 | 17 | import java.util.concurrent.ThreadPoolExecutor; |
| 18 | +import java.util.concurrent.TimeUnit; |
16 | 19 | import java.util.concurrent.locks.ReentrantLock; |
17 | 20 |
|
18 | 21 | import io.split.android.android_client.BuildConfig; |
@@ -276,37 +279,41 @@ private SplitFactoryImpl(@NonNull String apiToken, @NonNull Key key, @NonNull Sp |
276 | 279 | mDestroyer = new Runnable() { |
277 | 280 | public void run() { |
278 | 281 | mInitLock.lock(); |
279 | | - Logger.w("Shutdown called for split"); |
280 | 282 | try { |
281 | | - mStorageContainer.getTelemetryStorage().recordSessionLength(System.currentTimeMillis() - initializationStartTime); |
282 | | - telemetrySynchronizer.flush(); |
283 | | - telemetrySynchronizer.destroy(); |
284 | | - Logger.d("Successful shutdown of telemetry"); |
285 | | - impressionsLoggingTaskExecutor.shutdown(); |
286 | | - impressionsObserverExecutor.shutdown(); |
287 | | - Logger.d("Successful shutdown of impressions logging executor"); |
288 | | - mSyncManager.stop(); |
289 | | - Logger.d("Flushing impressions and events"); |
290 | | - mLifecycleManager.destroy(); |
291 | | - Logger.d("Successful shutdown of lifecycle manager"); |
292 | | - mFactoryMonitor.remove(mApiKey); |
293 | | - Logger.d("Successful shutdown of segment fetchers"); |
294 | | - customerImpressionListener.close(); |
295 | | - Logger.d("Successful shutdown of ImpressionListener"); |
296 | | - defaultHttpClient.close(); |
297 | | - Logger.d("Successful shutdown of httpclient"); |
298 | | - mManager.destroy(); |
299 | | - Logger.d("Successful shutdown of manager"); |
300 | | - splitTaskExecutor.stop(); |
301 | | - splitSingleThreadTaskExecutor.stop(); |
302 | | - Logger.d("Successful shutdown of task executor"); |
303 | | - mStorageContainer.getAttributesStorageContainer().destroy(); |
304 | | - Logger.d("Successful shutdown of attributes storage"); |
| 283 | + if (mClientContainer.getAll().isEmpty()) { |
| 284 | + Logger.w("Shutdown called for split"); |
| 285 | + mStorageContainer.getTelemetryStorage().recordSessionLength(System.currentTimeMillis() - initializationStartTime); |
| 286 | + telemetrySynchronizer.flush(); |
| 287 | + telemetrySynchronizer.destroy(); |
| 288 | + Logger.d("Successful shutdown of telemetry"); |
| 289 | + impressionsLoggingTaskExecutor.shutdown(); |
| 290 | + impressionsObserverExecutor.shutdown(); |
| 291 | + Logger.d("Successful shutdown of impressions logging executor"); |
| 292 | + mSyncManager.stop(); |
| 293 | + Logger.d("Flushing impressions and events"); |
| 294 | + mLifecycleManager.destroy(); |
| 295 | + Logger.d("Successful shutdown of lifecycle manager"); |
| 296 | + mFactoryMonitor.remove(mApiKey); |
| 297 | + Logger.d("Successful shutdown of segment fetchers"); |
| 298 | + customerImpressionListener.close(); |
| 299 | + Logger.d("Successful shutdown of ImpressionListener"); |
| 300 | + defaultHttpClient.close(); |
| 301 | + Logger.d("Successful shutdown of httpclient"); |
| 302 | + mManager.destroy(); |
| 303 | + Logger.d("Successful shutdown of manager"); |
| 304 | + splitTaskExecutor.stop(); |
| 305 | + splitSingleThreadTaskExecutor.stop(); |
| 306 | + Logger.d("Successful shutdown of task executor"); |
| 307 | + mStorageContainer.getAttributesStorageContainer().destroy(); |
| 308 | + Logger.d("Successful shutdown of attributes storage"); |
| 309 | + mIsTerminated = true; |
| 310 | + Logger.d("SplitFactory has been destroyed"); |
| 311 | + } else { |
| 312 | + Logger.d("Avoiding shutdown of factory due to active clients"); |
| 313 | + } |
305 | 314 | } catch (Exception e) { |
306 | 315 | Logger.e(e, "We could not shutdown split"); |
307 | 316 | } finally { |
308 | | - mIsTerminated = true; |
309 | | - Logger.d("SplitFactory has been destroyed"); |
310 | 317 | mInitLock.unlock(); |
311 | 318 | } |
312 | 319 | } |
@@ -388,7 +395,22 @@ public SplitManager manager() { |
388 | 395 | public void destroy() { |
389 | 396 | synchronized (SplitFactoryImpl.class) { |
390 | 397 | if (!mIsTerminated) { |
391 | | - new Thread(mDestroyer).start(); |
| 398 | + ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); |
| 399 | + executor.schedule(mDestroyer, 100, TimeUnit.MILLISECONDS); |
| 400 | + executor.schedule(new Runnable() { |
| 401 | + @Override |
| 402 | + public void run() { |
| 403 | + executor.shutdown(); |
| 404 | + try { |
| 405 | + if (!executor.awaitTermination(5, TimeUnit.SECONDS)) { |
| 406 | + executor.shutdownNow(); |
| 407 | + } |
| 408 | + } catch (InterruptedException e) { |
| 409 | + executor.shutdownNow(); |
| 410 | + Thread.currentThread().interrupt(); |
| 411 | + } |
| 412 | + } |
| 413 | + }, 500, TimeUnit.MILLISECONDS); |
392 | 414 | } |
393 | 415 | } |
394 | 416 | } |
|
0 commit comments