All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.pubnub.internal.presence.Presence.kt Maven / Gradle / Ivy
package com.pubnub.internal.presence
import com.pubnub.api.enums.PNHeartbeatNotificationOptions
import com.pubnub.internal.eventengine.EffectDispatcher
import com.pubnub.internal.eventengine.EventEngineConf
import com.pubnub.internal.managers.ListenerManager
import com.pubnub.internal.managers.PresenceEventEngineManager
import com.pubnub.internal.presence.eventengine.PresenceEventEngine
import com.pubnub.internal.presence.eventengine.data.PresenceData
import com.pubnub.internal.presence.eventengine.effect.PresenceEffectFactory
import com.pubnub.internal.presence.eventengine.effect.PresenceEffectInvocation
import com.pubnub.internal.presence.eventengine.effect.effectprovider.HeartbeatProvider
import com.pubnub.internal.presence.eventengine.effect.effectprovider.LeaveProvider
import com.pubnub.internal.presence.eventengine.event.PresenceEvent
import org.slf4j.LoggerFactory
import java.util.concurrent.ScheduledExecutorService
import kotlin.time.Duration
internal interface Presence {
companion object {
internal fun create(
heartbeatProvider: HeartbeatProvider,
leaveProvider: LeaveProvider,
heartbeatInterval: Duration,
suppressLeaveEvents: Boolean,
heartbeatNotificationOptions: PNHeartbeatNotificationOptions,
listenerManager: ListenerManager,
eventEngineConf: EventEngineConf,
presenceData: PresenceData = PresenceData(),
sendStateWithHeartbeat: Boolean,
executorService: ScheduledExecutorService,
): Presence {
if (heartbeatInterval <= Duration.ZERO) {
return PresenceNoOp(suppressLeaveEvents, leaveProvider)
}
val effectFactory =
PresenceEffectFactory(
heartbeatProvider = heartbeatProvider,
leaveProvider = leaveProvider,
presenceEventSink = eventEngineConf.eventSink,
executorService = executorService,
heartbeatInterval = heartbeatInterval,
suppressLeaveEvents = suppressLeaveEvents,
heartbeatNotificationOptions = heartbeatNotificationOptions,
statusConsumer = listenerManager,
presenceData = presenceData,
sendStateWithHeartbeat = sendStateWithHeartbeat,
)
val eventEngineManager =
PresenceEventEngineManager(
eventEngine =
PresenceEventEngine(
effectSink = eventEngineConf.effectSink,
eventSource = eventEngineConf.eventSource,
),
eventSink = eventEngineConf.eventSink,
effectDispatcher =
EffectDispatcher(
effectFactory = effectFactory,
effectSource = eventEngineConf.effectSource,
),
).also { it.start() }
return EnabledPresence(eventEngineManager)
}
}
fun joined(
channels: Set = emptySet(),
channelGroups: Set = emptySet(),
)
fun left(
channels: Set = emptySet(),
channelGroups: Set = emptySet(),
)
fun leftAll()
fun presence(
channels: Set = emptySet(),
channelGroups: Set = emptySet(),
connected: Boolean = false,
) {
if (connected) {
joined(channels, channelGroups)
} else {
left(channels, channelGroups)
}
}
fun reconnect()
fun disconnect()
fun destroy()
}
internal class PresenceNoOp(
private val suppressLeaveEvents: Boolean = false,
private val leaveProvider: LeaveProvider,
) : Presence {
private val log = LoggerFactory.getLogger(PresenceNoOp::class.java)
private val channels = mutableSetOf()
private val channelGroups = mutableSetOf()
@Synchronized
override fun joined(
channels: Set,
channelGroups: Set,
) {
this.channels.addAll(channels)
this.channelGroups.addAll(channelGroups)
}
@Synchronized
override fun left(
channels: Set,
channelGroups: Set,
) {
if (!suppressLeaveEvents && (channels.isNotEmpty() || channelGroups.isNotEmpty())) {
leaveProvider.getLeaveRemoteAction(channels, channelGroups).async { result ->
result.onFailure {
log.error("LeaveEffect failed", it)
}
}
}
this.channels.removeAll(channels)
this.channelGroups.removeAll(channelGroups)
}
@Synchronized
override fun leftAll() {
if (!suppressLeaveEvents && (channels.isNotEmpty() || channelGroups.isNotEmpty())) {
leaveProvider.getLeaveRemoteAction(channels, channelGroups).async { result ->
result.onFailure {
log.error("LeaveEffect failed", it)
}
}
}
channels.clear()
channelGroups.clear()
}
override fun reconnect() = noAction()
override fun disconnect() = noAction()
override fun destroy() = noAction()
private fun noAction() {
// Presence Event Engine is not initialized so no action here
}
}
internal class EnabledPresence(
private val presenceEventEngineManager: PresenceEventEngineManager,
) : Presence {
override fun joined(
channels: Set,
channelGroups: Set,
) {
presenceEventEngineManager.addEventToQueue(PresenceEvent.Joined(channels, channelGroups))
}
override fun left(
channels: Set,
channelGroups: Set,
) {
presenceEventEngineManager.addEventToQueue(PresenceEvent.Left(channels, channelGroups))
}
override fun leftAll() {
presenceEventEngineManager.addEventToQueue(PresenceEvent.LeftAll)
}
override fun reconnect() {
presenceEventEngineManager.addEventToQueue(PresenceEvent.Reconnect)
}
override fun disconnect() {
presenceEventEngineManager.addEventToQueue(PresenceEvent.Disconnect)
}
override fun destroy() {
disconnect()
presenceEventEngineManager.stop()
}
}