Skip to content

Commit

Permalink
wip discontinuities
Browse files Browse the repository at this point in the history
TODO test
TODO test figure out internal interface
TODO see if there are any spec points to do

TODO if Umair merges reactions before this, we need to incorporate here.

Resolves #47.
  • Loading branch information
lawrence-forooghian committed Nov 12, 2024
1 parent 8daa191 commit de44af8
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 8 deletions.
15 changes: 10 additions & 5 deletions Sources/AblyChat/DefaultMessages.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,16 @@ private struct MessageSubscriptionWrapper {
@MainActor
internal final class DefaultMessages: Messages, EmitsDiscontinuities {
private let roomID: String
public nonisolated let channel: RealtimeChannelProtocol
public nonisolated let featureChannel: FeatureChannel
private let chatAPI: ChatAPI
private let clientID: String

// TODO: https://github.com/ably-labs/ably-chat-swift/issues/36 - Handle unsubscribing in line with CHA-M4b
// UUID acts as a unique identifier for each listener/subscription. MessageSubscriptionWrapper houses the subscription and the timeserial of when it was attached or resumed.
private var subscriptionPoints: [UUID: MessageSubscriptionWrapper] = [:]

internal nonisolated init(channel: RealtimeChannelProtocol, chatAPI: ChatAPI, roomID: String, clientID: String) async {
self.channel = channel
internal nonisolated init(featureChannel: FeatureChannel, chatAPI: ChatAPI, roomID: String, clientID: String) async {
self.featureChannel = featureChannel
self.chatAPI = chatAPI
self.roomID = roomID
self.clientID = clientID
Expand All @@ -32,6 +32,10 @@ internal final class DefaultMessages: Messages, EmitsDiscontinuities {
await handleChannelEvents(roomId: roomID)
}

internal nonisolated var channel: any RealtimeChannelProtocol {
featureChannel.channel
}

// (CHA-M4) Messages can be received via a subscription in realtime.
internal func subscribe(bufferingPolicy: BufferingPolicy) async throws -> MessageSubscription {
let uuid = UUID()
Expand Down Expand Up @@ -100,8 +104,9 @@ internal final class DefaultMessages: Messages, EmitsDiscontinuities {
}

// TODO: (CHA-M7) Users may subscribe to discontinuity events to know when there’s been a break in messages that they need to resolve. Their listener will be called when a discontinuity event is triggered from the room lifecycle. - https://github.com/ably-labs/ably-chat-swift/issues/47
internal nonisolated func subscribeToDiscontinuities() -> Subscription<ARTErrorInfo> {
fatalError("not implemented")
internal func subscribeToDiscontinuities() async -> Subscription<ARTErrorInfo> {
// TODO: test
await featureChannel.subscribeToDiscontinuities()
}

private func getBeforeSubscriptionStart(_ uuid: UUID, params: QueryOptions) async throws -> any PaginatedResult<Message> {
Expand Down
16 changes: 13 additions & 3 deletions Sources/AblyChat/DefaultRoomLifecycleContributor.swift
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import Ably

internal actor DefaultRoomLifecycleContributor: RoomLifecycleContributor {
internal actor DefaultRoomLifecycleContributor: RoomLifecycleContributor, EmitsDiscontinuities {
internal let channel: DefaultRoomLifecycleContributorChannel
internal let feature: RoomFeature
private var discontinuitySubscriptions: [Subscription<ARTErrorInfo>] = []

internal init(channel: DefaultRoomLifecycleContributorChannel, feature: RoomFeature) {
self.channel = channel
Expand All @@ -11,8 +12,17 @@ internal actor DefaultRoomLifecycleContributor: RoomLifecycleContributor {

// MARK: - Discontinuities

internal func emitDiscontinuity(_: ARTErrorInfo) {
// TODO: https://github.com/ably-labs/ably-chat-swift/issues/47
internal func emitDiscontinuity(_ error: ARTErrorInfo) {
for subscription in discontinuitySubscriptions {
subscription.emit(error)
}
}

internal func subscribeToDiscontinuities() -> Subscription<ARTErrorInfo> {
let subscription = Subscription<ARTErrorInfo>(bufferingPolicy: .unbounded)
// TODO: clean up old subscriptions (https://github.com/ably-labs/ably-chat-swift/issues/36)
discontinuitySubscriptions.append(subscription)
return subscription
}
}

Expand Down
16 changes: 16 additions & 0 deletions Sources/AblyChat/RoomFeature.swift
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import Ably

/// The features offered by a chat room.
internal enum RoomFeature {
case messages
Expand All @@ -21,3 +23,17 @@ internal enum RoomFeature {
}
}
}

// TODO: what's this?
internal protocol FeatureChannel: Sendable, EmitsDiscontinuities {
var channel: RealtimeChannelProtocol { get }
}

internal struct DefaultFeatureChannel: FeatureChannel {
internal var channel: RealtimeChannelProtocol
internal var contributor: DefaultRoomLifecycleContributor

internal func subscribeToDiscontinuities() async -> Subscription<ARTErrorInfo> {
await contributor.subscribeToDiscontinuities()
}
}
14 changes: 14 additions & 0 deletions Tests/AblyChatTests/Mocks/MockFeatureChannel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import Ably
@testable import AblyChat

final class MockFeatureChannel: FeatureChannel {
let channel: RealtimeChannelProtocol

init(channel: RealtimeChannelProtocol) {
self.channel = channel
}

func subscribeToDiscontinuities() async -> Subscription<ARTErrorInfo> {
fatalError("TODO")
}
}

0 comments on commit de44af8

Please sign in to comment.