Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,25 @@ import com.segment.analytics.kotlin.core.Analytics
import com.segment.analytics.kotlin.core.BaseEvent
import com.segment.analytics.kotlin.core.platform.plugins.logger.LogFilterKind
import com.segment.analytics.kotlin.core.platform.plugins.logger.segmentLog
import java.util.concurrent.CopyOnWriteArrayList
import kotlin.reflect.KClass

// Platform abstraction for managing plugins' execution (of a specific type)
// All operations are thread safe via the `synchronized` function
internal class Mediator(internal val plugins: MutableList<Plugin>) {
// All operations are thread safe via the CopyOnWriteArrayList. Which allows multiple
// threads to read the list but when a modification is made the modifier is given a new copy of
// list and that becomes the new version of the list.
// More info: https://developer.android.com/reference/kotlin/java/util/concurrent/CopyOnWriteArrayList
internal class Mediator(internal val plugins: CopyOnWriteArrayList<Plugin>) {

fun add(plugin: Plugin) = synchronized(plugins) {
fun add(plugin: Plugin) {
plugins.add(plugin)
}

fun remove(plugin: Plugin) = synchronized(plugins) {
fun remove(plugin: Plugin) {
plugins.removeAll { it === plugin } // remove only if reference is the same
}

fun execute(event: BaseEvent): BaseEvent? = synchronized(plugins) {
fun execute(event: BaseEvent): BaseEvent? {
var result: BaseEvent? = event

plugins.forEach { plugin ->
Expand All @@ -42,13 +46,13 @@ internal class Mediator(internal val plugins: MutableList<Plugin>) {
return result
}

fun applyClosure(closure: (Plugin) -> Unit) = synchronized(plugins) {
fun applyClosure(closure: (Plugin) -> Unit) {
plugins.forEach {
closure(it)
}
}

fun <T : Plugin> find(pluginClass: KClass<T>): T? = synchronized(plugins) {
fun <T : Plugin> find(pluginClass: KClass<T>): T? {
plugins.forEach {
if (pluginClass.isInstance(it)) {
return it as T
Expand All @@ -57,7 +61,7 @@ internal class Mediator(internal val plugins: MutableList<Plugin>) {
return null
}

fun <T : Plugin> findAll(pluginClass: KClass<T>): List<T> = synchronized(plugins) {
fun <T : Plugin> findAll(pluginClass: KClass<T>): List<T> {
return plugins.filter { pluginClass.isInstance(it) } as List<T>
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,19 @@ import com.segment.analytics.kotlin.core.Analytics
import com.segment.analytics.kotlin.core.BaseEvent
import com.segment.analytics.kotlin.core.System
import kotlinx.coroutines.launch
import java.util.concurrent.CopyOnWriteArrayList
import kotlin.reflect.KClass

// Platform abstraction for managing all plugins and their execution
// Currently the execution follows
// Before -> Enrichment -> Destination -> After
internal class Timeline {
internal val plugins: Map<Plugin.Type, Mediator> = mapOf(
Plugin.Type.Before to Mediator(mutableListOf()),
Plugin.Type.Enrichment to Mediator(mutableListOf()),
Plugin.Type.Destination to Mediator(mutableListOf()),
Plugin.Type.After to Mediator(mutableListOf()),
Plugin.Type.Utility to Mediator(mutableListOf())
Plugin.Type.Before to Mediator(CopyOnWriteArrayList()),
Plugin.Type.Enrichment to Mediator(CopyOnWriteArrayList()),
Plugin.Type.Destination to Mediator(CopyOnWriteArrayList()),
Plugin.Type.After to Mediator(CopyOnWriteArrayList()),
Plugin.Type.Utility to Mediator(CopyOnWriteArrayList())
)
lateinit var analytics: Analytics

Expand Down