Skip to content

Commit

Permalink
Merge pull request #855 from ably/publisher-presence-at-subscriber
Browse files Browse the repository at this point in the history
Present Publisher as offline to Subscribers on loss of connectivity on the Subscriber's side
  • Loading branch information
QuintinWillison authored Dec 22, 2022
2 parents a75fa17 + 88067b8 commit 17a8a26
Show file tree
Hide file tree
Showing 24 changed files with 339 additions and 336 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ fun io.ably.lib.types.PresenceMessage.toTracking(gson: Gson): PresenceMessage? =
PresenceMessage(
this.action.toTracking(),
presenceData,
this.clientId
this.memberKey(),
)
}

Expand Down
14 changes: 13 additions & 1 deletion common/src/main/java/com/ably/tracking/common/AblyModels.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,19 @@ package com.ably.tracking.common

import com.ably.tracking.Resolution

data class PresenceMessage(val action: PresenceAction, val data: PresenceData, val clientId: String)
/**
* Encapsulates the properties of an Ably presence message which are needed by asset tracking SDKs.
*/
data class PresenceMessage(
val action: PresenceAction,
val data: PresenceData,

/**
* Combination of Ably `clientId` and `connectionId`.
* See: https://sdk.ably.com/builds/ably/specification/main/features/#TP3h
*/
val memberKey: String,
)

enum class PresenceAction {
PRESENT_OR_ENTER, LEAVE_OR_ABSENT, UPDATE;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ data class Trackable(
override fun hashCode(): Int = id.hashCode()
}

data class Subscriber(val id: String, val trackable: Trackable)
data class Subscriber(val memberKey: String, val trackable: Trackable)

sealed class Proximity

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,17 @@ internal interface CorePublisher {
val routingProfile: RoutingProfile
val trackableStateFlows: Map<String, StateFlow<TrackableState>>

fun addSubscriber(id: String, trackable: Trackable, data: PresenceData, properties: PublisherProperties)
fun addSubscriber(memberKey: String, trackable: Trackable, data: PresenceData, properties: PublisherProperties)
fun updateSubscriber(
id: String,
memberKey: String,
trackable: Trackable,
data: PresenceData,
properties: PublisherProperties
)

fun removeSubscriber(id: String, trackable: Trackable, properties: PublisherProperties)
fun removeSubscriber(memberKey: String, trackable: Trackable, properties: PublisherProperties)
fun removeAllSubscribers(trackable: Trackable, properties: PublisherProperties)

fun setDestination(destination: Destination, properties: PublisherProperties)
fun removeCurrentDestination(properties: PublisherProperties)
fun startLocationUpdates(properties: PublisherProperties)
Expand Down Expand Up @@ -492,8 +493,13 @@ constructor(
}
}

override fun addSubscriber(id: String, trackable: Trackable, data: PresenceData, properties: PublisherProperties) {
val subscriber = Subscriber(id, trackable)
override fun addSubscriber(
memberKey: String,
trackable: Trackable,
data: PresenceData,
properties: PublisherProperties
) {
val subscriber = Subscriber(memberKey, trackable)
if (properties.subscribers[trackable.id] == null) {
properties.subscribers[trackable.id] = mutableSetOf()
}
Expand All @@ -504,13 +510,13 @@ constructor(
}

override fun updateSubscriber(
id: String,
memberKey: String,
trackable: Trackable,
data: PresenceData,
properties: PublisherProperties
) {
properties.subscribers[trackable.id]?.let { subscribers ->
subscribers.find { it.id == id }?.let { subscriber ->
subscribers.find { it.memberKey == memberKey }?.let { subscriber ->
data.resolution.let { resolution ->
saveOrRemoveResolutionRequest(resolution, trackable, subscriber, properties)
resolveResolution(trackable, properties)
Expand All @@ -519,9 +525,9 @@ constructor(
}
}

override fun removeSubscriber(id: String, trackable: Trackable, properties: PublisherProperties) {
override fun removeSubscriber(memberKey: String, trackable: Trackable, properties: PublisherProperties) {
properties.subscribers[trackable.id]?.let { subscribers ->
subscribers.find { it.id == id }?.let { subscriber ->
subscribers.find { it.memberKey == memberKey }?.let { subscriber ->
subscribers.remove(subscriber)
properties.requests[trackable.id]?.remove(subscriber)
hooks.subscribers?.onSubscriberRemoved(subscriber)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ internal class PresenceMessageWorker(
PresenceAction.PRESENT_OR_ENTER -> {
if (presenceMessage.data.type == ClientTypes.SUBSCRIBER) {
corePublisher.addSubscriber(
presenceMessage.clientId,
presenceMessage.memberKey,
trackable,
presenceMessage.data,
properties
Expand All @@ -28,13 +28,13 @@ internal class PresenceMessageWorker(
}
PresenceAction.LEAVE_OR_ABSENT -> {
if (presenceMessage.data.type == ClientTypes.SUBSCRIBER) {
corePublisher.removeSubscriber(presenceMessage.clientId, trackable, properties)
corePublisher.removeSubscriber(presenceMessage.memberKey, trackable, properties)
}
}
PresenceAction.UPDATE -> {
if (presenceMessage.data.type == ClientTypes.SUBSCRIBER) {
corePublisher.updateSubscriber(
presenceMessage.clientId,
presenceMessage.memberKey,
trackable,
presenceMessage.data,
properties
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ class PresenceMessageWorkerTest {
PresenceMessage(
action,
PresenceData(if (isSubscriber) ClientTypes.SUBSCRIBER else ClientTypes.PUBLISHER),
"test-client-id"
"test-member-key"
),
corePublisher
)
Expand Down
Loading

0 comments on commit 17a8a26

Please sign in to comment.