All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.internal.FormManagerEventsBus.kt Maven / Gradle / Ivy

There is a newer version: 0.23.0
Show newest version
package io.kform.internal

import io.kform.*
import io.kform.collections.MutablePathMultimap
import io.kform.collections.PathMultimapEntryId
import io.kform.collections.mutablePathMultimapOf
import io.kform.collections.set
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock

/** Number of events to process before allowing the browser to "breathe". */
private const val BREATHING_COUNT = 10_000

/** Bus used to emit events to the user. */
internal class FormManagerEventsBus {
    private val subscriptionsMutex = Mutex()
    private val subscriptions: MutablePathMultimap = mutablePathMultimapOf()

    private var delayCounter = 0

    suspend fun emit(event: FormManagerEvent<*>) {
        // Allow browser to "breathe" every [BREATHING_COUNT] events
        if (++delayCounter % BREATHING_COUNT == 0) delayImmediate()

        subscriptionsMutex.withLock {
            FormManager.logger.trace {
                val subscriptionPaths = subscriptions.entries(event.path).map { it.path }.toList()
                "Emitting event to subscriptions $subscriptionPaths: $event"
            }
            for (handler in subscriptions[event.path]) {
                handler(event)
            }
        }
    }

    suspend fun subscribe(
        path: AbsolutePath,
        onSubscription: OnSubscription? = null,
        eventsHandler: EventHandler
    ): Unsubscribe =
        subscriptionsMutex.withLock {
            val id = subscriptions.set(path, eventsHandler)
            FormManager.logger.trace {
                "Subscribed to '$path' (total subscriptions: ${subscriptions.size})"
            }
            onSubscription?.invoke()
            return@withLock { unsubscribe(id, path) }
        }

    private suspend fun unsubscribe(id: PathMultimapEntryId, path: AbsolutePath) =
        subscriptionsMutex.withLock {
            subscriptions.removeEntry(id)
            FormManager.logger.trace {
                "Unsubscribed from '$path' (total subscriptions: ${subscriptions.size})"
            }
        }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy