Skip to content

Commit

Permalink
Initial run
Browse files Browse the repository at this point in the history
  • Loading branch information
jguz-pubnub committed Mar 28, 2024
1 parent 34bcc9f commit 59d01bd
Show file tree
Hide file tree
Showing 58 changed files with 428 additions and 466 deletions.
3 changes: 0 additions & 3 deletions Examples/Sources/ConfigDetailTableViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@ import UIKit
import PubNub

class ConfigDetailTableViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
}

let configCellID = "PubNubConfigDetailCell"

Expand Down
4 changes: 0 additions & 4 deletions Examples/Sources/MasterDetailTableViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -366,10 +366,6 @@ class MasterDetailTableViewController: UITableViewController {
}
}

override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
}

override func numberOfSections(in tableView: UITableView) -> Int {
super.numberOfSections(in: tableView)

Expand Down
22 changes: 11 additions & 11 deletions Sources/PubNub/EventEngine/Core/Dispatcher.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ protocol Dispatcher<Invocation, Event, Dependencies> {
associatedtype Invocation: AnyEffectInvocation
associatedtype Event
associatedtype Dependencies

func dispatch(
invocations: [EffectInvocation<Invocation>],
with dependencies: EventEngineDependencies<Dependencies>,
Expand All @@ -35,15 +35,15 @@ protocol Dispatcher<Invocation, Event, Dependencies> {
class EffectDispatcher<Invocation: AnyEffectInvocation, Event, Dependencies>: Dispatcher {
private let factory: any EffectHandlerFactory<Invocation, Event, Dependencies>
private let effectsCache = EffectsCache<Event>()

init(factory: some EffectHandlerFactory<Invocation, Event, Dependencies>) {
self.factory = factory
}

func hasPendingInvocation(_ invocation: Invocation) -> Bool {
effectsCache.hasPendingEffect(with: invocation.id)
}

func dispatch(
invocations: [EffectInvocation<Invocation>],
with dependencies: EventEngineDependencies<Dependencies>,
Expand All @@ -69,7 +69,7 @@ class EffectDispatcher<Invocation: AnyEffectInvocation, Event, Dependencies>: Di
}
}
}

private func executeEffect(
effect: some EffectHandler<Event>,
storageId id: String,
Expand All @@ -85,29 +85,29 @@ class EffectDispatcher<Invocation: AnyEffectInvocation, Event, Dependencies>: Di

// MARK: - EffectsCache

fileprivate class EffectsCache<Event> {
private class EffectsCache<Event> {
private var managedEffects: Atomic<[String: EffectWrapper<Event>]> = Atomic([:])

func hasPendingEffect(with id: String) -> Bool {
managedEffects.lockedRead { $0[id] } != nil
}

func put(effect: some EffectHandler<Event>, with id: String) {
managedEffects.lockedWrite { $0[id] = EffectWrapper<Event>(id: id, effect: effect) }
}

func getEffect(with id: String) -> (any EffectHandler<Event>)? {
managedEffects.lockedRead() { $0[id] }?.effect
managedEffects.lockedRead { $0[id] }?.effect
}

func removeEffect(id: String) {
managedEffects.lockedWrite { $0[id] = nil }
}
}

// MARK: - EffectWrapper

fileprivate struct EffectWrapper<Action> {
private struct EffectWrapper<Action> {
let id: String
let effect: any EffectHandler<Action>
}
14 changes: 7 additions & 7 deletions Sources/PubNub/EventEngine/Core/EffectHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ protocol EffectHandlerFactory<Invocation, Event, Dependencies> {
associatedtype Invocation
associatedtype Event
associatedtype Dependencies

func effect(
for invocation: Invocation,
with dependencies: EventEngineDependencies<Dependencies>
Expand All @@ -26,7 +26,7 @@ protocol EffectHandlerFactory<Invocation, Event, Dependencies> {

protocol EffectHandler<Event> {
associatedtype Event

func performTask(completionBlock: @escaping ([Event]) -> Void)
func cancelTask()
}
Expand All @@ -39,7 +39,7 @@ extension EffectHandler {

protocol DelayedEffectHandler: AnyObject, EffectHandler {
var workItem: DispatchWorkItem? { get set }

func delayInterval() -> TimeInterval?
func onEmptyInterval(notify completionBlock: @escaping ([Event]) -> Void)
func onDelayExpired(notify completionBlock: @escaping ([Event]) -> Void)
Expand All @@ -50,17 +50,17 @@ protocol DelayedEffectHandler: AnyObject, EffectHandler {
class TimerEffect: EffectHandler {
private let interval: TimeInterval
private var workItem: DispatchWorkItem?

init?(interval: TimeInterval?) {
if let interval = interval {
self.interval = interval
} else {
return nil
}
}

func performTask(completionBlock: @escaping ([Void]) -> Void) {
let workItem = DispatchWorkItem() {
let workItem = DispatchWorkItem {
completionBlock([])
}
DispatchQueue.global(qos: .default).asyncAfter(
Expand All @@ -69,7 +69,7 @@ class TimerEffect: EffectHandler {
)
self.workItem = workItem
}

func cancelTask() {
workItem?.cancel()
}
Expand Down
14 changes: 7 additions & 7 deletions Sources/PubNub/EventEngine/Core/EventEngine.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ class EventEngine<State, Event, Invocation: AnyEffectInvocation, Input> {
private let transition: any TransitionProtocol<State, Event, Invocation>
private let dispatcher: any Dispatcher<Invocation, Event, Input>
private(set) var state: State

var dependencies: EventEngineDependencies<Input>
var onStateUpdated: ((State) -> Void)?

init(
state: State,
transition: some TransitionProtocol<State, Event, Invocation>,
Expand All @@ -35,10 +35,10 @@ class EventEngine<State, Event, Invocation: AnyEffectInvocation, Input> {
self.dispatcher = dispatcher
self.dependencies = dependencies
}

func send(event: Event) {
objc_sync_enter(self)

defer {
objc_sync_exit(self)
}
Expand All @@ -48,13 +48,13 @@ class EventEngine<State, Event, Invocation: AnyEffectInvocation, Input> {
) else {
return
}

let transitionResult = transition.transition(from: state, event: event)
let invocations = transitionResult.invocations

state = transitionResult.state
onStateUpdated?(state)

let listener = DispatcherListener<Event>(
onAnyInvocationCompleted: { [weak self] results in
results.forEach {
Expand Down
6 changes: 3 additions & 3 deletions Sources/PubNub/EventEngine/Core/TransitionProtocol.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ protocol AnyIdentifiableInvocation {
}

protocol AnyCancellableInvocation: AnyIdentifiableInvocation {

}

protocol AnyEffectInvocation: AnyIdentifiableInvocation {
Expand All @@ -25,7 +25,7 @@ protocol AnyEffectInvocation: AnyIdentifiableInvocation {
struct TransitionResult<State, Invocation: AnyEffectInvocation> {
let state: State
let invocations: [EffectInvocation<Invocation>]

init(state: State, invocations: [EffectInvocation<Invocation>] = []) {
self.state = state
self.invocations = invocations
Expand All @@ -42,7 +42,7 @@ protocol TransitionProtocol<State, Event, Invocation> {
associatedtype State
associatedtype Event
associatedtype Invocation: AnyEffectInvocation

func canTransition(from state: State, dueTo event: Event) -> Bool
func transition(from state: State, event: Event) -> TransitionResult<State, Invocation>
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class DelayedHeartbeatEffect: EffectHandler {
private let request: PresenceHeartbeatRequest
private let reason: PubNubError
private let timerEffect: TimerEffect?

init(
request: PresenceHeartbeatRequest,
retryAttempt: Int,
Expand All @@ -24,28 +24,28 @@ class DelayedHeartbeatEffect: EffectHandler {
self.reason = reason
self.timerEffect = TimerEffect(interval: request.reconnectionDelay(dueTo: reason, retryAttempt: retryAttempt))
}

func performTask(completionBlock: @escaping ([Presence.Event]) -> Void) {
guard let timerEffect = timerEffect else {
completionBlock([.heartbeatGiveUp(error: reason)]); return
}
timerEffect.performTask { [weak self] _ in
self?.request.execute() { result in
self?.request.execute { result in
switch result {
case .success(_):
case .success:
completionBlock([.heartbeatSuccess])
case .failure(let error):
completionBlock([.heartbeatFailed(error: error)])
}
}
}
}

func cancelTask() {
timerEffect?.cancelTask()
request.cancel()
}

deinit {
cancelTask()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,22 @@ import Foundation

class HeartbeatEffect: EffectHandler {
private let request: PresenceHeartbeatRequest

init(request: PresenceHeartbeatRequest) {
self.request = request
}

func performTask(completionBlock: @escaping ([Presence.Event]) -> Void) {
request.execute() { result in
request.execute { result in
switch result {
case .success(_):
case .success:
completionBlock([.heartbeatSuccess])
case .failure(let error):
completionBlock([.heartbeatFailed(error: error)])
}
}
}

deinit {
request.cancel()
}
Expand Down
12 changes: 6 additions & 6 deletions Sources/PubNub/EventEngine/Presence/Effects/LeaveEffect.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,22 @@ import Foundation

class LeaveEffect: EffectHandler {
private let request: PresenceLeaveRequest

init(request: PresenceLeaveRequest) {
self.request = request
}

func performTask(completionBlock: @escaping ([Presence.Event]) -> Void) {
request.execute() { result in
request.execute { result in
switch result {
case .success(_):
case .success:
completionBlock([])
case .failure(_):
case .failure:
completionBlock([])
}
}
}

deinit {
request.cancel()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class PresenceEffectFactory: EffectHandlerFactory {
private let session: SessionReplaceable
private let sessionResponseQueue: DispatchQueue
private let presenceStateContainer: PubNubPresenceStateContainer

init(
session: SessionReplaceable,
sessionResponseQueue: DispatchQueue = .main,
Expand All @@ -24,7 +24,7 @@ class PresenceEffectFactory: EffectHandlerFactory {
self.sessionResponseQueue = sessionResponseQueue
self.presenceStateContainer = presenceStateContainer
}

func effect(
for invocation: Presence.Invocation,
with dependencies: EventEngineDependencies<Presence.Dependencies>
Expand Down Expand Up @@ -68,7 +68,7 @@ class PresenceEffectFactory: EffectHandlerFactory {
return WaitEffect(configuration: dependencies.value.configuration)
}
}

deinit {
session.invalidateAndCancel()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ class PresenceHeartbeatRequest {
let channels: [String]
let groups: [String]
let configuration: PubNubConfiguration

private let session: SessionReplaceable
private let sessionResponseQueue: DispatchQueue
private let channelStates: [String: JSONCodable]
private var request: RequestReplaceable?

init(
channels: [String],
groups: [String],
Expand All @@ -35,7 +35,7 @@ class PresenceHeartbeatRequest {
self.session = session
self.sessionResponseQueue = sessionResponseQueue
}

func execute(completionBlock: @escaping (Result<Void, PubNubError>) -> Void) {
let endpoint = PresenceRouter.Endpoint.heartbeat(
channels: channels,
Expand All @@ -56,11 +56,11 @@ class PresenceHeartbeatRequest {
}
}
}

func cancel() {
request?.cancel(PubNubError(.clientCancelled))
}

func reconnectionDelay(dueTo error: PubNubError, retryAttempt: Int) -> TimeInterval? {
guard let automaticRetry = configuration.automaticRetry else {
return nil
Expand All @@ -82,7 +82,7 @@ class PresenceHeartbeatRequest {
response: urlResponse,
error: underlyingError
)

return shouldRetry ? automaticRetry.policy.delay(for: retryAttempt) : nil
}
}
Loading

0 comments on commit 59d01bd

Please sign in to comment.