Skip to content

Commit a66e3be

Browse files
committed
Improve resource cleanup on shutdown
1 parent 347333c commit a66e3be

File tree

4 files changed

+29
-34
lines changed

4 files changed

+29
-34
lines changed

core/src/main/java/com/segment/analytics/kotlin/core/Analytics.kt

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import com.segment.analytics.kotlin.core.platform.plugins.StartupQueue
1111
import com.segment.analytics.kotlin.core.platform.plugins.UserInfoPlugin
1212
import com.segment.analytics.kotlin.core.platform.plugins.logger.*
1313
import com.segment.analytics.kotlin.core.utilities.JsonAnySerializer
14+
import com.segment.analytics.kotlin.core.utilities.StorageImpl
15+
import com.segment.analytics.kotlin.core.utilities.FileEventStream
1416
import kotlinx.coroutines.*
1517
import kotlinx.serialization.*
1618
import kotlinx.serialization.json.Json
@@ -598,14 +600,38 @@ open class Analytics protected constructor(
598600
* Should only be called in containerized environments where you need to free resources like
599601
* CoroutineDispatchers and ExecutorService instances so they allow the container to shutdown
600602
* properly.
603+
*
604+
* @param waitForTasks if true, waits for all analyticsScope coroutines to complete before shutdown
601605
*/
606+
@JvmOverloads
602607
@OptIn(ExperimentalCoroutinesApi::class)
603-
fun shutdown() {
608+
fun shutdown(waitForTasks: Boolean = false) {
609+
timeline.applyClosure {
610+
if (it is com.segment.analytics.kotlin.core.platform.EventPipeline) {
611+
it.stop()
612+
}
613+
}
614+
615+
val job = analyticsScope.coroutineContext[Job]
616+
job?.cancel()
617+
if (waitForTasks) {
618+
runBlocking {
619+
job?.join()
620+
}
621+
}
622+
604623
(analyticsDispatcher as CloseableCoroutineDispatcher).close()
605624
(networkIODispatcher as CloseableCoroutineDispatcher).close()
606625
(fileIODispatcher as CloseableCoroutineDispatcher).close()
607626

608-
store.shutdown();
627+
store.shutdown()
628+
629+
if (storage is StorageImpl) {
630+
val s = storage as StorageImpl
631+
if (s.eventStream is FileEventStream) {
632+
(s.eventStream as FileEventStream).close()
633+
}
634+
}
609635
}
610636

611637
/**
@@ -773,4 +799,4 @@ internal fun isAndroid(): Boolean {
773799
} catch (ignored: ClassNotFoundException) {
774800
false
775801
}
776-
}
802+
}

core/src/main/java/com/segment/analytics/kotlin/core/platform/EventPipeline.kt

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,6 @@ open class EventPipeline(
5353

5454
writeChannel = Channel(UNLIMITED)
5555
uploadChannel = Channel(UNLIMITED)
56-
57-
registerShutdownHook()
5856
}
5957

6058
fun put(event: BaseEvent) {
@@ -202,13 +200,4 @@ open class EventPipeline(
202200

203201
return shouldCleanup
204202
}
205-
206-
private fun registerShutdownHook() {
207-
// close the stream if the app shuts down
208-
Runtime.getRuntime().addShutdownHook(object : Thread() {
209-
override fun run() {
210-
this@EventPipeline.stop()
211-
}
212-
})
213-
}
214203
}

core/src/main/java/com/segment/analytics/kotlin/core/utilities/EventStream.kt

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,6 @@ open class FileEventStream(
160160

161161
init {
162162
createDirectory(directory)
163-
registerShutdownHook()
164163
}
165164

166165
protected open var fs: FileOutputStream? = null
@@ -239,13 +238,4 @@ open class FileEventStream(
239238
val file = File(source)
240239
return if (file.exists()) FileInputStream(file) else null
241240
}
242-
243-
private fun registerShutdownHook() {
244-
// close the stream if the app shuts down
245-
Runtime.getRuntime().addShutdownHook(object : Thread() {
246-
override fun run() {
247-
fs?.close()
248-
}
249-
})
250-
}
251241
}

core/src/main/java/com/segment/analytics/kotlin/core/utilities/EventsFileManager.kt

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ class EventsFileManager(
4141

4242
init {
4343
createDirectory(directory)
44-
registerShutdownHook()
4544
}
4645

4746
private val fileIndexKey = if(subject == null) "segment.events.file.index.$writeKey" else "segment.events.file.index.$writeKey.$subject"
@@ -170,15 +169,6 @@ class EventsFileManager(
170169
curFile = null
171170
}
172171

173-
private fun registerShutdownHook() {
174-
// close the stream if the app shuts down
175-
Runtime.getRuntime().addShutdownHook(object : Thread() {
176-
override fun run() {
177-
os?.close()
178-
}
179-
})
180-
}
181-
182172
private suspend fun withLock(block: () -> Unit) {
183173
semaphore.acquire()
184174
block()

0 commit comments

Comments
 (0)