From 6051d31506365fa6bd07024a2dbe0cbe7553169e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Dobrza=C5=84ski?= Date: Thu, 6 Jul 2023 15:10:03 +0200 Subject: [PATCH 01/27] feat: simplified abstraction --- src/Api/PubnubApi/EventEngine/Core/Engine.cs | 10 ++-- .../EventEngine/Core/EventEngineInterfaces.cs | 19 +++++-- src/Api/PubnubApi/EventEngine/Core/Utils.cs | 49 +++++++++++++++++-- .../Subscribe/States/HandshakeFailedState.cs | 13 ++--- .../States/HandshakeReconnectingState.cs | 14 +++--- .../Subscribe/States/HandshakeStoppedState.cs | 15 +++--- .../Subscribe/States/HandshakingState.cs | 12 ++--- .../Subscribe/States/ReceiveFailedState.cs | 10 ++-- .../States/ReceiveReconnectingState.cs | 12 ++--- .../Subscribe/States/ReceiveStoppedState.cs | 14 ++---- .../Subscribe/States/ReceivingState.cs | 14 +++--- .../Subscribe/States/UnsubscribedState.cs | 11 ++--- 12 files changed, 115 insertions(+), 78 deletions(-) diff --git a/src/Api/PubnubApi/EventEngine/Core/Engine.cs b/src/Api/PubnubApi/EventEngine/Core/Engine.cs index 4cc1e6ef4..f0315ac13 100644 --- a/src/Api/PubnubApi/EventEngine/Core/Engine.cs +++ b/src/Api/PubnubApi/EventEngine/Core/Engine.cs @@ -6,7 +6,7 @@ internal abstract class Engine { public EventQueue eventQueue = new EventQueue(); protected EffectDispatcher dispatcher = new EffectDispatcher(); - protected IState currentState; + protected State currentState; private Task currentTransitionLoop = Utils.EmptyTask; @@ -26,22 +26,22 @@ private async void OnEvent(EventQueue q) currentTransitionLoop = eventQueue.Loop(async e => currentState = await Transition(e)); } - private async Task Transition(IEvent e) { + private async Task Transition(IEvent e) { var stateInvocationPair = currentState.Transition(e); if (stateInvocationPair is null) { return currentState; } - await ExecuteStateChange(currentState, stateInvocationPair.Item1, stateInvocationPair.Item2); + await ExecuteStateChange(currentState, stateInvocationPair.State, stateInvocationPair.Invocations); - return stateInvocationPair.Item1; + return stateInvocationPair.State; } /// /// Launch the invocations associated with transitioning between states /// - private async Task ExecuteStateChange(IState sourceState, IState targetState, IEnumerable invocations) { + private async Task ExecuteStateChange(State sourceState, State targetState, IEnumerable invocations) { foreach (var effectInvocation in sourceState.OnExit ?? emptyInvocationList) { await dispatcher.Dispatch(effectInvocation); } diff --git a/src/Api/PubnubApi/EventEngine/Core/EventEngineInterfaces.cs b/src/Api/PubnubApi/EventEngine/Core/EventEngineInterfaces.cs index 85bc64f9f..4dbc203b9 100644 --- a/src/Api/PubnubApi/EventEngine/Core/EventEngineInterfaces.cs +++ b/src/Api/PubnubApi/EventEngine/Core/EventEngineInterfaces.cs @@ -31,15 +31,26 @@ internal interface IEffectCancelInvocation : IEffectInvocation { } internal interface IEvent { }; - internal interface IState { - public IEnumerable OnEntry { get; } - public IEnumerable OnExit { get; } + internal abstract class State + { + public virtual IEnumerable OnEntry { get; } = null; + public virtual IEnumerable OnExit { get; } = null; /// /// The EE transition pure function. /// /// Input event /// Target state and invocation list, or null for no-transition - public System.Tuple> Transition(IEvent e); + public abstract TransitionResult Transition(IEvent e); + + public TransitionResult With(params IEffectInvocation[] invocations) + { + return new TransitionResult(this, invocations); + } + + public static implicit operator TransitionResult(State s) + { + return new TransitionResult(s); + } } } \ No newline at end of file diff --git a/src/Api/PubnubApi/EventEngine/Core/Utils.cs b/src/Api/PubnubApi/EventEngine/Core/Utils.cs index 83b0159d2..f3edacb10 100644 --- a/src/Api/PubnubApi/EventEngine/Core/Utils.cs +++ b/src/Api/PubnubApi/EventEngine/Core/Utils.cs @@ -11,16 +11,55 @@ static Utils() EmptyTask.Start(); } - internal static Task EmptyTask { get; } = new Task(() => null); + internal static Task EmptyTask { get; } = new Task(() => null); + + internal static IEffectInvocation[] AsArray(this IEffectInvocation invocation) + { + return new IEffectInvocation[] { invocation }; + } + } + + internal class TransitionResult + { + public State State => tuple.Item1; + public IEnumerable Invocations => tuple.Item2; - internal static Tuple> With(this IState state, params IEffectInvocation[] invocations) + private readonly Tuple> tuple; + + /// + /// Create a state-invocation pair with empty invocations + /// + public TransitionResult(State state) { - return new Tuple>(state, invocations); + this.tuple = new Tuple>(state, new IEffectInvocation[0]); } - internal static IEffectInvocation[] AsArray(this IEffectInvocation invocation) + /// + /// Create a state-invocation pair + /// + public TransitionResult(State state, IEnumerable invocations) { - return new IEffectInvocation[] { invocation }; + this.tuple = new Tuple>(state, invocations); + } + + /// + /// Create a state-invocation pair + /// + public TransitionResult(State state, params IEffectInvocation[] invocations) : this(state, invocations as IEnumerable) { } + + public static implicit operator Tuple>(TransitionResult t) + { + return t.tuple; + } + + public static implicit operator TransitionResult(Tuple> t) + { + return new TransitionResult(t.Item1, t.Item2); + } + + public override int GetHashCode() + { + return tuple.GetHashCode(); } } } \ No newline at end of file diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeFailedState.cs b/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeFailedState.cs index b21ca1c8b..a62e27b18 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeFailedState.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeFailedState.cs @@ -5,34 +5,31 @@ namespace PubnubApi.PubnubEventEngine.Subscribe.States { - internal class HandshakeFailedState : Core.IState + internal class HandshakeFailedState : Core.State { public IEnumerable Channels; public IEnumerable ChannelGroups; - public IEnumerable OnEntry { get; } - public IEnumerable OnExit { get; } - - public Tuple> Transition(IEvent e) + public override TransitionResult Transition(IEvent e) { return e switch { Events.SubscriptionChangedEvent subscriptionChanged => new HandshakingState() { Channels = subscriptionChanged.Channels, ChannelGroups = subscriptionChanged.ChannelGroups, - }.With(), + }, Events.ReconnectEvent reconnect => new HandshakingState() { Channels = reconnect.Channels, ChannelGroups = reconnect.ChannelGroups, - }.With(), + }, Events.SubscriptionRestoredEvent subscriptionRestored => new ReceivingState() { Channels = subscriptionRestored.Channels, ChannelGroups = subscriptionRestored.ChannelGroups, Cursor = subscriptionRestored.Cursor - }.With(), + }, _ => null }; diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeReconnectingState.cs b/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeReconnectingState.cs index 89d8092f6..ae8fd3524 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeReconnectingState.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeReconnectingState.cs @@ -5,28 +5,28 @@ namespace PubnubApi.PubnubEventEngine.Subscribe.States { - internal class HandshakeReconnectingState : Core.IState + internal class HandshakeReconnectingState : Core.State { public IEnumerable Channels; public IEnumerable ChannelGroups; - public IEnumerable OnEntry => new HandshakeReconnectInvocation() + public override IEnumerable OnEntry => new HandshakeReconnectInvocation() { Channels = this.Channels, ChannelGroups = this.ChannelGroups }.AsArray(); - public IEnumerable OnExit { get; } = new CancelHandshakeReconnectInvocation().AsArray(); + public override IEnumerable OnExit { get; } = new CancelHandshakeReconnectInvocation().AsArray(); - public Tuple> Transition(IEvent e) + public override TransitionResult Transition(IEvent e) { return e switch { Events.SubscriptionChangedEvent subscriptionChanged => new HandshakingState() { Channels = subscriptionChanged.Channels, ChannelGroups = subscriptionChanged.ChannelGroups, - }.With(), + }, Events.DisconnectEvent disconnect => new HandshakeStoppedState() { Channels = disconnect.Channels, ChannelGroups = disconnect.ChannelGroups - }.With(), + }, Events.HandshakeReconnectGiveUpEvent handshakeReconnectGiveUp => new HandshakeFailedState() { @@ -48,7 +48,7 @@ internal class HandshakeReconnectingState : Core.IState Channels = subscriptionRestored.Channels, ChannelGroups = subscriptionRestored.ChannelGroups, Cursor = subscriptionRestored.Cursor - }.With(), + }, _ => null }; diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeStoppedState.cs b/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeStoppedState.cs index 91df0fca8..f58100818 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeStoppedState.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeStoppedState.cs @@ -5,34 +5,31 @@ namespace PubnubApi.PubnubEventEngine.Subscribe.States { - internal class HandshakeStoppedState : Core.IState + internal class HandshakeStoppedState : Core.State { public IEnumerable Channels; public IEnumerable ChannelGroups; - - public IEnumerable OnEntry { get; } - public IEnumerable OnExit { get; } - - public Tuple> Transition(IEvent e) + + public override TransitionResult Transition(IEvent e) { return e switch { Events.SubscriptionChangedEvent subscriptionChanged => new HandshakingState() { Channels = subscriptionChanged.Channels, ChannelGroups = subscriptionChanged.ChannelGroups, - }.With(), + }, Events.ReconnectEvent reconnect => new HandshakingState() { Channels = reconnect.Channels, ChannelGroups = reconnect.ChannelGroups, - }.With(), + }, Events.SubscriptionRestoredEvent subscriptionRestored => new ReceivingState() { Channels = subscriptionRestored.Channels, ChannelGroups = subscriptionRestored.ChannelGroups, Cursor = subscriptionRestored.Cursor - }.With(), + }, _ => null }; diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakingState.cs b/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakingState.cs index 154282a13..7b2584c52 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakingState.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakingState.cs @@ -5,31 +5,31 @@ namespace PubnubApi.PubnubEventEngine.Subscribe.States { - internal class HandshakingState : Core.IState + internal class HandshakingState : Core.State { public IEnumerable Channels; public IEnumerable ChannelGroups; - public IEnumerable OnEntry => new HandshakeInvocation() + public override IEnumerable OnEntry => new HandshakeInvocation() { Channels = this.Channels, ChannelGroups = this.ChannelGroups }.AsArray(); - public IEnumerable OnExit { get; } = new CancelHandshakeInvocation().AsArray(); + public override IEnumerable OnExit { get; } = new CancelHandshakeInvocation().AsArray(); - public Tuple> Transition(IEvent e) + public override TransitionResult Transition(IEvent e) { return e switch { Events.SubscriptionChangedEvent subscriptionChanged => new States.HandshakingState() { Channels = subscriptionChanged.Channels, ChannelGroups = subscriptionChanged.ChannelGroups - }.With(), + }, Events.SubscriptionRestoredEvent subscriptionRestored => new States.ReceivingState() { Channels = subscriptionRestored.Channels, ChannelGroups = subscriptionRestored.ChannelGroups, Cursor = subscriptionRestored.Cursor - }.With(), + }, Events.HandshakeFailureEvent handshakeFailure => new States.HandshakeFailedState() { diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveFailedState.cs b/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveFailedState.cs index 3bb0c7c3a..6c7e4632c 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveFailedState.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveFailedState.cs @@ -5,7 +5,7 @@ namespace PubnubApi.PubnubEventEngine.Subscribe.States { - internal class ReceiveFailedState : Core.IState + internal class ReceiveFailedState : Core.State { public IEnumerable Channels; public IEnumerable ChannelGroups; @@ -14,7 +14,7 @@ internal class ReceiveFailedState : Core.IState public IEnumerable OnEntry { get; } public IEnumerable OnExit { get; } - public Tuple> Transition(IEvent e) + public override TransitionResult Transition(IEvent e) { return e switch { @@ -23,21 +23,21 @@ internal class ReceiveFailedState : Core.IState Channels = subscriptionChanged.Channels, ChannelGroups = subscriptionChanged.ChannelGroups, Cursor = this.Cursor - }.With(), + }, Events.ReconnectEvent reconnect => new ReceivingState() { Channels = reconnect.Channels, ChannelGroups = reconnect.ChannelGroups, Cursor = reconnect.Cursor - }.With(), + }, Events.SubscriptionRestoredEvent subscriptionRestored => new ReceivingState() { Channels = subscriptionRestored.Channels, ChannelGroups = subscriptionRestored.ChannelGroups, Cursor = subscriptionRestored.Cursor - }.With(), + }, _ => null }; diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveReconnectingState.cs b/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveReconnectingState.cs index 159d229cc..7d9bbaf9d 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveReconnectingState.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveReconnectingState.cs @@ -5,19 +5,19 @@ namespace PubnubApi.PubnubEventEngine.Subscribe.States { - internal class ReceiveReconnectingState : Core.IState + internal class ReceiveReconnectingState : Core.State { public IEnumerable Channels; public IEnumerable ChannelGroups; public SubscriptionCursor Cursor; - public IEnumerable OnEntry => new ReceiveReconnectInvocation() + public override IEnumerable OnEntry => new ReceiveReconnectInvocation() { Channels = this.Channels, ChannelGroups = this.ChannelGroups, Cursor = this.Cursor }.AsArray(); - public IEnumerable OnExit { get; } = + public override IEnumerable OnExit { get; } = new CancelReceiveReconnectInvocation().AsArray(); - public Tuple> Transition(IEvent e) + public override TransitionResult Transition(IEvent e) { return e switch { @@ -26,7 +26,7 @@ internal class ReceiveReconnectingState : Core.IState Channels = subscriptionChanged.Channels, ChannelGroups = subscriptionChanged.ChannelGroups, Cursor = this.Cursor - }.With(), + }, Events.DisconnectEvent disconnect => new ReceiveStoppedState() { @@ -40,7 +40,7 @@ internal class ReceiveReconnectingState : Core.IState Channels = subscriptionRestored.Channels, ChannelGroups = subscriptionRestored.ChannelGroups, Cursor = subscriptionRestored.Cursor - }.With(), + }, Events.ReceiveReconnectSuccessEvent receiveReconnectSuccess => new ReceivingState() { diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveStoppedState.cs b/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveStoppedState.cs index 9684a0ad0..06c6daded 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveStoppedState.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveStoppedState.cs @@ -5,17 +5,13 @@ namespace PubnubApi.PubnubEventEngine.Subscribe.States { - internal class ReceiveStoppedState : Core.IState + internal class ReceiveStoppedState : Core.State { public IEnumerable Channels; public IEnumerable ChannelGroups; public SubscriptionCursor Cursor; - - public IEnumerable OnEntry { get; } - public IEnumerable OnExit { get; } - - public Tuple> Transition(IEvent e) + public override TransitionResult Transition(IEvent e) { return e switch { @@ -24,21 +20,21 @@ internal class ReceiveStoppedState : Core.IState Channels = subscriptionChanged.Channels, ChannelGroups = subscriptionChanged.ChannelGroups, Cursor = this.Cursor, - }.With(), + }, Events.ReconnectEvent reconnect => new ReceivingState() { Channels = reconnect.Channels, ChannelGroups = reconnect.ChannelGroups, Cursor = reconnect.Cursor - }.With(), + }, Events.SubscriptionRestoredEvent subscriptionRestored => new ReceivingState() { Channels = subscriptionRestored.Channels, ChannelGroups = subscriptionRestored.ChannelGroups, Cursor = subscriptionRestored.Cursor - }.With(), + }, _ => null }; diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceivingState.cs b/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceivingState.cs index 882eb3987..428507ddb 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceivingState.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceivingState.cs @@ -5,18 +5,18 @@ namespace PubnubApi.PubnubEventEngine.Subscribe.States { - internal class ReceivingState : Core.IState + internal class ReceivingState : Core.State { public IEnumerable Channels; public IEnumerable ChannelGroups; public SubscriptionCursor Cursor; - public IEnumerable OnEntry => new ReceiveMessagesInvocation() + public override IEnumerable OnEntry => new ReceiveMessagesInvocation() { Channels = this.Channels, ChannelGroups = this.ChannelGroups, Cursor = this.Cursor }.AsArray(); - public IEnumerable OnExit { get; } = new CancelReceiveMessagesInvocation().AsArray(); + public override IEnumerable OnExit { get; } = new CancelReceiveMessagesInvocation().AsArray(); - public Tuple> Transition(IEvent e) + public override TransitionResult Transition(IEvent e) { return e switch { @@ -35,14 +35,14 @@ internal class ReceivingState : Core.IState Channels = subscriptionChanged.Channels, ChannelGroups = subscriptionChanged.ChannelGroups, Cursor = this.Cursor - }.With(), + }, Events.SubscriptionRestoredEvent subscriptionRestored => new ReceivingState() { Channels = subscriptionRestored.Channels, ChannelGroups = subscriptionRestored.ChannelGroups, Cursor = subscriptionRestored.Cursor - }.With(), + }, Events.DisconnectEvent disconnect => new ReceiveStoppedState() { @@ -56,7 +56,7 @@ internal class ReceivingState : Core.IState Channels = this.Channels, ChannelGroups = this.ChannelGroups, Cursor = this.Cursor - }.With(), + }, _ => null }; diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/States/UnsubscribedState.cs b/src/Api/PubnubApi/EventEngine/Subscribe/States/UnsubscribedState.cs index 757ce04ce..2a5affc92 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/States/UnsubscribedState.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/States/UnsubscribedState.cs @@ -5,26 +5,23 @@ namespace PubnubApi.PubnubEventEngine.Subscribe.States { - internal class UnsubscribedState : Core.IState + internal class UnsubscribedState : Core.State { - public IEnumerable OnEntry { get; } - public IEnumerable OnExit { get; } - - public Tuple> Transition(Core.IEvent e) + public override TransitionResult Transition(Core.IEvent e) { return e switch { Events.SubscriptionChangedEvent subscriptionChanged => new HandshakingState() { Channels = subscriptionChanged.Channels, ChannelGroups = subscriptionChanged.ChannelGroups, - }.With(), + }, Events.SubscriptionRestoredEvent subscriptionRestored => new States.ReceivingState() { Channels = subscriptionRestored.Channels, ChannelGroups = subscriptionRestored.ChannelGroups, Cursor = subscriptionRestored.Cursor - }.With(), + }, _ => null }; From 44674ced2a2236806e5ba3e8ea60c9665cae68d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Dobrza=C5=84ski?= Date: Mon, 10 Jul 2023 13:34:46 +0200 Subject: [PATCH 02/27] feat: handshake effect handler --- .../Effects/HandshakeEffectHandler.cs | 100 +++++++++++------- src/Api/PubnubApi/Model/Consumer/PNStatus.cs | 10 ++ 2 files changed, 71 insertions(+), 39 deletions(-) diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/Effects/HandshakeEffectHandler.cs b/src/Api/PubnubApi/EventEngine/Subscribe/Effects/HandshakeEffectHandler.cs index 72a15f8ce..7d0f30461 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/Effects/HandshakeEffectHandler.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/Effects/HandshakeEffectHandler.cs @@ -6,43 +6,65 @@ using PubnubApi.PubnubEventEngine.Core; using PubnubApi.PubnubEventEngine.Subscribe.Invocations; -namespace PubnubApi.PubnubEventEngine.Subscribe.Effects { - internal class HandshakeEffectHandler : Core.IEffectHandler { - private SubscribeManager2 manager; - private EventQueue eventQueue; - - public HandshakeEffectHandler(SubscribeManager2 manager, EventQueue eventQueue) { - this.manager = manager; - this.eventQueue = eventQueue; - } - - public async Task Run(HandshakeInvocation invocation) { - // TODO fix this, probably wrong :) - var resp = await manager.HandshakeRequest( - PNOperationType.PNSubscribeOperation, - invocation.Channels.ToArray(), - invocation.ChannelGroups.ToArray(), - null, - null, - invocation.InitialSubscribeQueryParams, - invocation.ExternalQueryParams - ); - - if (!resp.Item2.Error) { - // TODO move deserialization outside - // TODO does this need more error checking? - var handshakeResponse = JsonConvert.DeserializeObject(resp.Item1); - var c = new SubscriptionCursor() { - Region = handshakeResponse.Timetoken.Region, - Timetoken = handshakeResponse.Timetoken.Timestamp - }; - - eventQueue.Enqueue(new Events.HandshakeSuccessEvent() {Cursor = c}); - } - } - - public async Task Cancel() { - manager.HandshakeRequestCancellation(); - } - } +namespace PubnubApi.PubnubEventEngine.Subscribe.Effects +{ + internal class HandshakeEffectHandler : Core.IEffectHandler + { + private SubscribeManager2 manager; + private EventQueue eventQueue; + + public HandshakeEffectHandler(SubscribeManager2 manager, EventQueue eventQueue) + { + this.manager = manager; + this.eventQueue = eventQueue; + } + + public async Task Run(HandshakeInvocation invocation) + { + var resp = await manager.HandshakeRequest( + PNOperationType.PNSubscribeOperation, + invocation.Channels.ToArray(), + invocation.ChannelGroups.ToArray(), + null, + null, + invocation.InitialSubscribeQueryParams, + invocation.ExternalQueryParams + ); + + if (resp.Item2 is null || resp.Item2.Error) + { + eventQueue.Enqueue(new Events.HandshakeFailureEvent() { Status = resp.Item2 }); + return; + } + + HandshakeResponse handshakeResponse = null; + + try + { + // TODO move deserialization outside + handshakeResponse = JsonConvert.DeserializeObject(resp.Item1); + var c = new SubscriptionCursor() + { + Region = handshakeResponse.Timetoken.Region, + Timetoken = handshakeResponse.Timetoken.Timestamp + }; + + eventQueue.Enqueue(new Events.HandshakeSuccessEvent() { Cursor = c }); + } + catch (System.Exception e) + { + eventQueue.Enqueue(new Events.HandshakeFailureEvent() + { + Status = new PNStatus(e, PNOperationType.PNSubscribeOperation, + PNStatusCategory.PNUnknownCategory, invocation.Channels, invocation.ChannelGroups) + } + ); + } + } + + public async Task Cancel() + { + manager.HandshakeRequestCancellation(); + } + } } \ No newline at end of file diff --git a/src/Api/PubnubApi/Model/Consumer/PNStatus.cs b/src/Api/PubnubApi/Model/Consumer/PNStatus.cs index 5abb9de27..4e3e3a5ff 100644 --- a/src/Api/PubnubApi/Model/Consumer/PNStatus.cs +++ b/src/Api/PubnubApi/Model/Consumer/PNStatus.cs @@ -14,6 +14,16 @@ public class PNStatus public PNStatus() { } + public PNStatus(Exception e, PNOperationType operationType, PNStatusCategory category, IEnumerable affectedChannels = null, IEnumerable affectedChannelGroups = null) + { + this.Error = true; + this.Operation = operationType; + this.ErrorData = new PNErrorData(e.Message, e); + this.AffectedChannels = affectedChannels?.ToList(); + this.AffectedChannelGroups = affectedChannelGroups?.ToList(); + this.Category = category; + } + internal PNStatus(object endpointOperation) { this.savedEndpointOperation = endpointOperation; From cc4b87c2a2c5ca74069feb1e4ed52c1d51ef124d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Dobrza=C5=84ski?= Date: Tue, 18 Jul 2023 15:10:56 +0200 Subject: [PATCH 03/27] fix: initial retry implementation --- .../Effects/HandshakeEffectHandler.cs | 67 ++++++++++++------- .../Subscribe/Events/SubscriptionEvents.cs | 1 + .../Invocations/SubscriptionInvocations.cs | 7 +- .../States/HandshakeReconnectingState.cs | 5 +- .../Subscribe/States/HandshakingState.cs | 5 +- 5 files changed, 52 insertions(+), 33 deletions(-) diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/Effects/HandshakeEffectHandler.cs b/src/Api/PubnubApi/EventEngine/Subscribe/Effects/HandshakeEffectHandler.cs index 7d0f30461..f5fca7d33 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/Effects/HandshakeEffectHandler.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/Effects/HandshakeEffectHandler.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Newtonsoft.Json; @@ -8,7 +9,9 @@ namespace PubnubApi.PubnubEventEngine.Subscribe.Effects { - internal class HandshakeEffectHandler : Core.IEffectHandler + internal class HandshakeEffectHandler : + Core.IEffectHandler, + Core.IEffectHandler { private SubscribeManager2 manager; private EventQueue eventQueue; @@ -19,7 +22,39 @@ public HandshakeEffectHandler(SubscribeManager2 manager, EventQueue eventQueue) this.eventQueue = eventQueue; } + public async Task Run(HandshakeReconnectInvocation invocation) + { + await this.Run((HandshakeInvocation)invocation); + } + public async Task Run(HandshakeInvocation invocation) + { + var response = await MakeHandshakeRequest(invocation); + + switch (invocation) + { + case Invocations.HandshakeReconnectInvocation reconnectInvocation when response.Item2.Error: + eventQueue.Enqueue(new Events.HandshakeReconnectFailureEvent() {RemainingRetries = reconnectInvocation.RemainingRetries - 1, Status = response.Item2}); + break; + case Invocations.HandshakeReconnectInvocation reconnectInvocation: + eventQueue.Enqueue(new Events.HandshakeReconnectSuccessEvent() { Cursor = response.Item1, Status = response.Item2 }); + break; + case { } when response.Item2.Error: + eventQueue.Enqueue(new Events.HandshakeFailureEvent() { Status = response.Item2}); + break; + case { }: + eventQueue.Enqueue(new Events.HandshakeSuccessEvent() { Cursor = response.Item1, Status = response.Item2 }); + break; + + } + } + + public async Task Cancel() + { + manager.HandshakeRequestCancellation(); + } + + private async Task> MakeHandshakeRequest(HandshakeInvocation invocation) { var resp = await manager.HandshakeRequest( PNOperationType.PNSubscribeOperation, @@ -31,40 +66,20 @@ public async Task Run(HandshakeInvocation invocation) invocation.ExternalQueryParams ); - if (resp.Item2 is null || resp.Item2.Error) - { - eventQueue.Enqueue(new Events.HandshakeFailureEvent() { Status = resp.Item2 }); - return; - } - - HandshakeResponse handshakeResponse = null; - try { - // TODO move deserialization outside - handshakeResponse = JsonConvert.DeserializeObject(resp.Item1); + var handshakeResponse = JsonConvert.DeserializeObject(resp.Item1); var c = new SubscriptionCursor() { Region = handshakeResponse.Timetoken.Region, Timetoken = handshakeResponse.Timetoken.Timestamp }; - - eventQueue.Enqueue(new Events.HandshakeSuccessEvent() { Cursor = c }); + return new System.Tuple(c, resp.Item2); } - catch (System.Exception e) + catch (Exception e) { - eventQueue.Enqueue(new Events.HandshakeFailureEvent() - { - Status = new PNStatus(e, PNOperationType.PNSubscribeOperation, - PNStatusCategory.PNUnknownCategory, invocation.Channels, invocation.ChannelGroups) - } - ); + return new Tuple(null, new PNStatus(e, PNOperationType.PNSubscribeOperation, PNStatusCategory.PNUnknownCategory, invocation.Channels, invocation.ChannelGroups)); } } - - public async Task Cancel() - { - manager.HandshakeRequestCancellation(); - } } } \ No newline at end of file diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/Events/SubscriptionEvents.cs b/src/Api/PubnubApi/EventEngine/Subscribe/Events/SubscriptionEvents.cs index 42739802d..46c062937 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/Events/SubscriptionEvents.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/Events/SubscriptionEvents.cs @@ -28,6 +28,7 @@ public class HandshakeReconnectSuccessEvent : HandshakeSuccessEvent { public class HandshakeReconnectFailureEvent : HandshakeFailureEvent { public PNStatus Status; + public int RemainingRetries; } public class HandshakeReconnectRetryEvent : Core.IEvent { diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/Invocations/SubscriptionInvocations.cs b/src/Api/PubnubApi/EventEngine/Subscribe/Invocations/SubscriptionInvocations.cs index 7fc22eceb..fa29acbdf 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/Invocations/SubscriptionInvocations.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/Invocations/SubscriptionInvocations.cs @@ -50,10 +50,9 @@ internal class CancelReceiveMessagesInvocation : ReceiveMessagesInvocation, Core internal class CancelHandshakeInvocation : HandshakeInvocation, Core.IEffectCancelInvocation { } - internal class HandshakeReconnectInvocation: Core.IEffectInvocation - { - public IEnumerable Channels; - public IEnumerable ChannelGroups; + internal class HandshakeReconnectInvocation: HandshakeInvocation + { + public int RemainingRetries; } internal class CancelHandshakeReconnectInvocation: HandshakeReconnectInvocation, Core.IEffectCancelInvocation { } diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeReconnectingState.cs b/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeReconnectingState.cs index ae8fd3524..1138a56c0 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeReconnectingState.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeReconnectingState.cs @@ -9,9 +9,12 @@ internal class HandshakeReconnectingState : Core.State { public IEnumerable Channels; public IEnumerable ChannelGroups; + + // TODO introduce policy provider + public int RetryCount = 3; public override IEnumerable OnEntry => new HandshakeReconnectInvocation() - { Channels = this.Channels, ChannelGroups = this.ChannelGroups }.AsArray(); + { Channels = this.Channels, ChannelGroups = this.ChannelGroups, RemainingRetries = this.RetryCount}.AsArray(); public override IEnumerable OnExit { get; } = new CancelHandshakeReconnectInvocation().AsArray(); public override TransitionResult Transition(IEvent e) diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakingState.cs b/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakingState.cs index 7b2584c52..6b33e070b 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakingState.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakingState.cs @@ -31,9 +31,10 @@ public override TransitionResult Transition(IEvent e) Cursor = subscriptionRestored.Cursor }, - Events.HandshakeFailureEvent handshakeFailure => new States.HandshakeFailedState() + Events.HandshakeFailureEvent handshakeFailure => new States.HandshakeReconnectingState() { - Channels = this.Channels, ChannelGroups = this.ChannelGroups + // TODO replace retryCount with value from policy + Channels = this.Channels, ChannelGroups = this.ChannelGroups, RetryCount = 3 }.With(new EmitStatusInvocation(handshakeFailure.Status)), Events.DisconnectEvent disconnect => new States.HandshakeStoppedState() From 7f41ebd8d816269cb50de99a863f70c894e36647 Mon Sep 17 00:00:00 2001 From: Mohit Tejani Date: Wed, 19 Jul 2023 14:39:34 +0530 Subject: [PATCH 04/27] handshake reconnect --- .../Context/ReconnectionDelayUtil.cs | 30 +++++++ .../HandshakeReconnectEffectHandler.cs | 85 +++++++++++++++++++ .../Subscribe/Events/SubscriptionEvents.cs | 2 + .../Invocations/SubscriptionInvocations.cs | 9 +- src/Api/PubnubApi/PubnubApi.csproj | 50 ++++------- .../Features/grant-token.feature.cs | 6 +- .../Features/revoke-token.feature.cs | 4 +- .../MockServerPubnubApi.csproj | 7 +- .../PubnubApi.Tests/PubnubApi.Tests.csproj | 11 +-- 9 files changed, 150 insertions(+), 54 deletions(-) create mode 100644 src/Api/PubnubApi/EventEngine/Subscribe/Context/ReconnectionDelayUtil.cs create mode 100644 src/Api/PubnubApi/EventEngine/Subscribe/Effects/HandshakeReconnectEffectHandler.cs diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/Context/ReconnectionDelayUtil.cs b/src/Api/PubnubApi/EventEngine/Subscribe/Context/ReconnectionDelayUtil.cs new file mode 100644 index 000000000..07749610c --- /dev/null +++ b/src/Api/PubnubApi/EventEngine/Subscribe/Context/ReconnectionDelayUtil.cs @@ -0,0 +1,30 @@ +using System; +namespace PubnubApi.EventEngine.Subscribe.Context +{ + public static class ReconnectionDelayUtil + { + public static int CalculateDelay(PNReconnectionPolicy policy, int attempts) + { + Random numGenerator = new Random(); + int delayValue = 0; + int backoff = 5; + switch (policy) { + case PNReconnectionPolicy.LINEAR: + delayValue = attempts * backoff + numGenerator.Next(1000); + break; + case PNReconnectionPolicy.EXPONENTIAL: + delayValue = (int)(Math.Pow(2, attempts - 1) * 1000 + numGenerator.Next(1000)); + break; + } + return delayValue; + + } + + public static bool shouldRetry(PNReconnectionPolicy policy, int attempts, int maxAttempts) + { + if (policy == PNReconnectionPolicy.NONE) return false; + return maxAttempts < attempts; + } + } +} + diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/Effects/HandshakeReconnectEffectHandler.cs b/src/Api/PubnubApi/EventEngine/Subscribe/Effects/HandshakeReconnectEffectHandler.cs new file mode 100644 index 000000000..17d8f2368 --- /dev/null +++ b/src/Api/PubnubApi/EventEngine/Subscribe/Effects/HandshakeReconnectEffectHandler.cs @@ -0,0 +1,85 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Newtonsoft.Json; +using PubnubApi.EndPoint; +using PubnubApi.PubnubEventEngine.Core; +using PubnubApi.PubnubEventEngine.Subscribe.Invocations; +using PubnubApi.PubnubEventEngine.Subscribe.Events; +using PubnubApi.PubnubEventEngine; +using System; +using PubnubApi.EventEngine.Subscribe.Context; + +namespace PubnubApi.EventEngine.Subscribe.Effects +{ + internal class HandshakeReconnectEffectHandler : IEffectHandler + { + private SubscribeManager2 manager; + private EventQueue eventQueue; + + public HandshakeReconnectEffectHandler(SubscribeManager2 manager, EventQueue eventQueue) + { + this.manager = manager; + this.eventQueue = eventQueue; + } + + public async Task Cancel() + { + manager.HandshakeRequestCancellation(); + } + + public async Task IEffectHandler.Run(HandshakeReconnectInvocation invocation) + { + if (!ReconnectionDelayUtil.shouldRetry(invocation.Policy, invocation.AttemptedRetries, invocation.MaxConnectionRetry)) + { + eventQueue.Enqueue(new HandshakeReconnectGiveUpEvent() { Status = PNStatus(PNStatusCategory.PNCancelledCategory) }); + } + else + { + // TODO: Check cancellation token whether this operation is cancelled already or not. + + // have a delay - blocking/ non-blocking thing + // TODO: Look for examples in PCL library + await Task.Delay(ReconnectionDelayUtil.CalculateDelay(invocation.Policy, invocation.AttemptedRetries)); + + // TODO: Check cancellation token whether this operation is cancelled or not. + // attempt handshake + var handshakeResponse = await attemptHandshake(invocation); + + if (handshakeResponse.Item2.Error) { + eventQueue.Enqueue(new HandshakeReconnectFailureEvent() { AttemptedRetries = invocation.AttemptedRetries + 1, Status = handshakeResponse.Item2 }); + } + + eventQueue.Enqueue(new HandshakeReconnectSuccessEvent() { Cursor = handshakeResponse.Item1, Status = handshakeResponse.Item2 }); + } + + } + + private async Task> attemptHandshake(HandshakeReconnectInvocation invocation) + { + var resp = await manager.HandshakeRequest( + PNOperationType.PNSubscribeOperation, + invocation.Channels.ToArray(), + invocation.ChannelGroups.ToArray(), + null, + null, + invocation.InitialSubscribeQueryParams, + invocation.ExternalQueryParams + ); + + try { + var handshakeResponse = JsonConvert.DeserializeObject(resp.Item1); + var c = new SubscriptionCursor() { + Region = handshakeResponse.Timetoken.Region, + Timetoken = handshakeResponse.Timetoken.Timestamp + }; + return new System.Tuple(c, resp.Item2); + } catch (Exception e) { + return new Tuple(null, new PNStatus(e, PNOperationType.PNSubscribeOperation, PNStatusCategory.PNUnknownCategory, invocation.Channels, invocation.ChannelGroups)); + } + } + } + +} + diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/Events/SubscriptionEvents.cs b/src/Api/PubnubApi/EventEngine/Subscribe/Events/SubscriptionEvents.cs index 42739802d..ae239ac0b 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/Events/SubscriptionEvents.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/Events/SubscriptionEvents.cs @@ -28,8 +28,10 @@ public class HandshakeReconnectSuccessEvent : HandshakeSuccessEvent { public class HandshakeReconnectFailureEvent : HandshakeFailureEvent { public PNStatus Status; + public int AttemptedRetries; } + // Do we have this in system description ? public class HandshakeReconnectRetryEvent : Core.IEvent { } diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/Invocations/SubscriptionInvocations.cs b/src/Api/PubnubApi/EventEngine/Subscribe/Invocations/SubscriptionInvocations.cs index 7fc22eceb..aa23bb07d 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/Invocations/SubscriptionInvocations.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/Invocations/SubscriptionInvocations.cs @@ -50,10 +50,11 @@ internal class CancelReceiveMessagesInvocation : ReceiveMessagesInvocation, Core internal class CancelHandshakeInvocation : HandshakeInvocation, Core.IEffectCancelInvocation { } - internal class HandshakeReconnectInvocation: Core.IEffectInvocation - { - public IEnumerable Channels; - public IEnumerable ChannelGroups; + internal class HandshakeReconnectInvocation: HandshakeInvocation + { + public int AttemptedRetries; + public int MaxConnectionRetry; + public PNReconnectionPolicy Policy; } internal class CancelHandshakeReconnectInvocation: HandshakeReconnectInvocation, Core.IEffectCancelInvocation { } diff --git a/src/Api/PubnubApi/PubnubApi.csproj b/src/Api/PubnubApi/PubnubApi.csproj index b82ecba0f..857cf5412 100644 --- a/src/Api/PubnubApi/PubnubApi.csproj +++ b/src/Api/PubnubApi/PubnubApi.csproj @@ -1,11 +1,10 @@  - net35;net40;net45;net461;net48 + net40 8.0 True pubnub.snk - False False PubNub C# .NET - Web Data Push API Pubnub @@ -31,22 +30,10 @@ Addressed threading issue on reading ConcurrentDictionary keys.false - - $(DefineConstants);NET35 - C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v3.5\Profile\Client - $(DefineConstants);NET40 - - $(DefineConstants);NET45 - - - $(DefineConstants);NET461 - - - $(DefineConstants);NET48 - + 1701;1702;0436; @@ -59,6 +46,9 @@ Addressed threading issue on reading ConcurrentDictionary keys. 0436; + + + @@ -71,16 +61,13 @@ Addressed threading issue on reading ConcurrentDictionary keys. - - 0.3.1 + None - - 1.0.2856 + None - - 1.0.2856 + None @@ -90,8 +77,7 @@ Addressed threading issue on reading ConcurrentDictionary keys. - - 0.3.1 + None @@ -107,40 +93,38 @@ Addressed threading issue on reading ConcurrentDictionary keys. None - - 4.3.0 + None - - 4.3.0 + None - - 4.3.0 + None - - 4.3.0 + None - - 4.3.0 + None + + + diff --git a/src/UnitTests/AcceptanceTests/Features/grant-token.feature.cs b/src/UnitTests/AcceptanceTests/Features/grant-token.feature.cs index a1aaaf549..c8bb56301 100644 --- a/src/UnitTests/AcceptanceTests/Features/grant-token.feature.cs +++ b/src/UnitTests/AcceptanceTests/Features/grant-token.feature.cs @@ -37,9 +37,9 @@ public partial class GrantAnAccessTokenFeature public virtual void FeatureSetup() { testRunner = TechTalk.SpecFlow.TestRunnerManager.GetTestRunner(); - TechTalk.SpecFlow.FeatureInfo featureInfo = new TechTalk.SpecFlow.FeatureInfo(new System.Globalization.CultureInfo("en-US"), "Features", "Grant an access token", " As a PubNub customer I want to restrict and allow access to\r\n specific PubNub " + - "resources (channels, channel groups, uuids)\r\n by my user base (both people and " + - "devices) which are each\r\n identified by a unique UUID.", ProgrammingLanguage.CSharp, featureTags); + TechTalk.SpecFlow.FeatureInfo featureInfo = new TechTalk.SpecFlow.FeatureInfo(new System.Globalization.CultureInfo("en-US"), "Features", "Grant an access token", " As a PubNub customer I want to restrict and allow access to\n specific PubNub r" + + "esources (channels, channel groups, uuids)\n by my user base (both people and de" + + "vices) which are each\n identified by a unique UUID.", ProgrammingLanguage.CSharp, featureTags); testRunner.OnFeatureStart(featureInfo); } diff --git a/src/UnitTests/AcceptanceTests/Features/revoke-token.feature.cs b/src/UnitTests/AcceptanceTests/Features/revoke-token.feature.cs index d5a85c045..f98f833b4 100644 --- a/src/UnitTests/AcceptanceTests/Features/revoke-token.feature.cs +++ b/src/UnitTests/AcceptanceTests/Features/revoke-token.feature.cs @@ -39,8 +39,8 @@ public partial class RevokeAnAccessTokenFeature public virtual void FeatureSetup() { testRunner = TechTalk.SpecFlow.TestRunnerManager.GetTestRunner(); - TechTalk.SpecFlow.FeatureInfo featureInfo = new TechTalk.SpecFlow.FeatureInfo(new System.Globalization.CultureInfo("en-US"), "Features", "Revoke an access token", " As a PubNub customer I want to withdraw existing permission for\r\n specific Pub" + - "Nub resources by revoking corresponding tokens.", ProgrammingLanguage.CSharp, featureTags); + TechTalk.SpecFlow.FeatureInfo featureInfo = new TechTalk.SpecFlow.FeatureInfo(new System.Globalization.CultureInfo("en-US"), "Features", "Revoke an access token", " As a PubNub customer I want to withdraw existing permission for\n specific PubN" + + "ub resources by revoking corresponding tokens.", ProgrammingLanguage.CSharp, featureTags); testRunner.OnFeatureStart(featureInfo); } diff --git a/src/UnitTests/MockServerPubnubApi/MockServerPubnubApi.csproj b/src/UnitTests/MockServerPubnubApi/MockServerPubnubApi.csproj index 41e331582..a1b8d8e74 100644 --- a/src/UnitTests/MockServerPubnubApi/MockServerPubnubApi.csproj +++ b/src/UnitTests/MockServerPubnubApi/MockServerPubnubApi.csproj @@ -1,7 +1,7 @@  - net35;net40;net45;net461;net48 + net40 False false PubNub C# .NET - MockServerPubnubApi @@ -16,10 +16,7 @@ true--> - - $(DefineConstants);NET35 - C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v3.5\Profile\Client - + $(DefineConstants);NET40 diff --git a/src/UnitTests/PubnubApi.Tests/PubnubApi.Tests.csproj b/src/UnitTests/PubnubApi.Tests/PubnubApi.Tests.csproj index ae358d01b..901745923 100644 --- a/src/UnitTests/PubnubApi.Tests/PubnubApi.Tests.csproj +++ b/src/UnitTests/PubnubApi.Tests/PubnubApi.Tests.csproj @@ -1,7 +1,7 @@  - net35;net40;net45;net461;net48 + net40 false Debug AnyCPU @@ -13,10 +13,7 @@ 512 true - - $(DefineConstants);NET35 - C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v3.5\Profile\Client - + $(DefineConstants);NET40 @@ -91,7 +88,7 @@ - - + From 6d2001d4f1fe10422ca490e6b23c5d130a6ba8d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Dobrza=C5=84ski?= Date: Wed, 19 Jul 2023 15:31:59 +0200 Subject: [PATCH 05/27] fix: handshake handler --- src/Api/PubnubApi/EventEngine/Common/Delay.cs | 57 +++++++++++++ .../EventEngine/Core/EffectDispatcher.cs | 2 +- src/Api/PubnubApi/EventEngine/Core/Engine.cs | 2 +- .../EventEngine/Core/EventEngineInterfaces.cs | 2 +- .../PubnubApi/EventEngine/Core/EventQueue.cs | 2 +- src/Api/PubnubApi/EventEngine/Core/Utils.cs | 2 +- .../Subscribe/Common/CommonSubscribeTypes.cs | 37 ++++++++ .../Effects/HandshakeEffectHandler.cs | 51 ++++++++--- .../HandshakeReconnectEffectHandler.cs | 85 ------------------- .../Subscribe/Events/SubscriptionEvents.cs | 6 +- .../Invocations/SubscriptionInvocations.cs | 5 +- .../Subscribe/States/HandshakeFailedState.cs | 6 +- .../States/HandshakeReconnectingState.cs | 11 +-- .../Subscribe/States/HandshakeStoppedState.cs | 6 +- .../Subscribe/States/HandshakingState.cs | 9 +- .../Subscribe/States/ReceiveFailedState.cs | 7 +- .../States/ReceiveReconnectingState.cs | 7 +- .../Subscribe/States/ReceiveStoppedState.cs | 7 +- .../Subscribe/States/ReceivingState.cs | 7 +- .../Subscribe/States/UnsubscribedState.cs | 6 +- .../Subscribe/SubscribeEventEngine.cs | 11 +-- 21 files changed, 183 insertions(+), 145 deletions(-) create mode 100644 src/Api/PubnubApi/EventEngine/Common/Delay.cs create mode 100644 src/Api/PubnubApi/EventEngine/Subscribe/Common/CommonSubscribeTypes.cs delete mode 100644 src/Api/PubnubApi/EventEngine/Subscribe/Effects/HandshakeReconnectEffectHandler.cs diff --git a/src/Api/PubnubApi/EventEngine/Common/Delay.cs b/src/Api/PubnubApi/EventEngine/Common/Delay.cs new file mode 100644 index 000000000..22f9536ba --- /dev/null +++ b/src/Api/PubnubApi/EventEngine/Common/Delay.cs @@ -0,0 +1,57 @@ +using System.Threading; +using System.Threading.Tasks; + +namespace PubnubApi.EventEngine.Common +{ + public class Delay + { + public bool Cancelled { get; private set; } = false; + private readonly Thread awaiterThread; + private readonly TaskCompletionSource taskCompletionSource = new TaskCompletionSource(); + private readonly object monitor = new object(); + private readonly int milliseconds; + + public Delay(int milliseconds) + { + this.milliseconds = milliseconds; + awaiterThread = new Thread(AwaiterLoop); + } + + public Task Start() + { + awaiterThread.Start(); + return taskCompletionSource.Task; + } + + public void Cancel() + { + lock (monitor) + { + Cancelled = true; + Monitor.Pulse(monitor); + } + } + + private void AwaiterLoop() + { + while(true) + { + lock (monitor) + { + if (Cancelled) + { + taskCompletionSource.SetCanceled(); + break; + } + Monitor.Wait(monitor, milliseconds); + if (Cancelled) + { + taskCompletionSource.SetCanceled(); + break; + } + taskCompletionSource.SetResult(null); + } + } + } + } +} \ No newline at end of file diff --git a/src/Api/PubnubApi/EventEngine/Core/EffectDispatcher.cs b/src/Api/PubnubApi/EventEngine/Core/EffectDispatcher.cs index babde75de..673ef726f 100644 --- a/src/Api/PubnubApi/EventEngine/Core/EffectDispatcher.cs +++ b/src/Api/PubnubApi/EventEngine/Core/EffectDispatcher.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Threading.Tasks; -namespace PubnubApi.PubnubEventEngine.Core { +namespace PubnubApi.EventEngine.Core { internal class EffectDispatcher { // assumes 1 instance of handler - capable of managing itself private readonly Dictionary effectInvocationHandlerMap = diff --git a/src/Api/PubnubApi/EventEngine/Core/Engine.cs b/src/Api/PubnubApi/EventEngine/Core/Engine.cs index f0315ac13..11b176c16 100644 --- a/src/Api/PubnubApi/EventEngine/Core/Engine.cs +++ b/src/Api/PubnubApi/EventEngine/Core/Engine.cs @@ -1,7 +1,7 @@ using System.Threading.Tasks; using System.Collections.Generic; -namespace PubnubApi.PubnubEventEngine.Core { +namespace PubnubApi.EventEngine.Core { internal abstract class Engine { public EventQueue eventQueue = new EventQueue(); diff --git a/src/Api/PubnubApi/EventEngine/Core/EventEngineInterfaces.cs b/src/Api/PubnubApi/EventEngine/Core/EventEngineInterfaces.cs index 4dbc203b9..698055e27 100644 --- a/src/Api/PubnubApi/EventEngine/Core/EventEngineInterfaces.cs +++ b/src/Api/PubnubApi/EventEngine/Core/EventEngineInterfaces.cs @@ -2,7 +2,7 @@ using System.Threading.Tasks; using System.Collections.Generic; -namespace PubnubApi.PubnubEventEngine.Core { +namespace PubnubApi.EventEngine.Core { /// /// Generic effect handler. diff --git a/src/Api/PubnubApi/EventEngine/Core/EventQueue.cs b/src/Api/PubnubApi/EventEngine/Core/EventQueue.cs index a0eb2fe64..a23e30d39 100644 --- a/src/Api/PubnubApi/EventEngine/Core/EventQueue.cs +++ b/src/Api/PubnubApi/EventEngine/Core/EventQueue.cs @@ -2,7 +2,7 @@ using System.Linq; using System.Threading.Tasks; -namespace PubnubApi.PubnubEventEngine.Core +namespace PubnubApi.EventEngine.Core { internal class EventQueue { diff --git a/src/Api/PubnubApi/EventEngine/Core/Utils.cs b/src/Api/PubnubApi/EventEngine/Core/Utils.cs index f3edacb10..c7c4cbe04 100644 --- a/src/Api/PubnubApi/EventEngine/Core/Utils.cs +++ b/src/Api/PubnubApi/EventEngine/Core/Utils.cs @@ -2,7 +2,7 @@ using System.Threading.Tasks; using System.Collections.Generic; -namespace PubnubApi.PubnubEventEngine.Core +namespace PubnubApi.EventEngine.Core { internal static class Utils { diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/Common/CommonSubscribeTypes.cs b/src/Api/PubnubApi/EventEngine/Subscribe/Common/CommonSubscribeTypes.cs new file mode 100644 index 000000000..1579e6521 --- /dev/null +++ b/src/Api/PubnubApi/EventEngine/Subscribe/Common/CommonSubscribeTypes.cs @@ -0,0 +1,37 @@ +using Newtonsoft.Json; + +namespace PubnubApi.EventEngine.Subscribe.Common +{ + public class SubscriptionCursor + { + public long? Timetoken { get; set; } + public int? Region { get; set; } + } + + public class HandshakeResponse + { + [JsonProperty("t")] + public Timetoken Timetoken { get; set; } + + [JsonProperty("m")] + public object[] Messages { get; set; } + } + public class HandshakeError + { + [JsonProperty("status")] + public int Status { get; set; } + + [JsonProperty("error")] + public string ErrorMessage { get; set; } + } + + public class Timetoken + { + [JsonProperty("t")] + public long? Timestamp { get; set; } + + [JsonProperty("r")] + public int? Region { get; set; } + + } +} \ No newline at end of file diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/Effects/HandshakeEffectHandler.cs b/src/Api/PubnubApi/EventEngine/Subscribe/Effects/HandshakeEffectHandler.cs index f5fca7d33..f9782d993 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/Effects/HandshakeEffectHandler.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/Effects/HandshakeEffectHandler.cs @@ -1,13 +1,18 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; using Newtonsoft.Json; using PubnubApi.EndPoint; -using PubnubApi.PubnubEventEngine.Core; -using PubnubApi.PubnubEventEngine.Subscribe.Invocations; +using PubnubApi.EventEngine.Common; +using PubnubApi.EventEngine.Core; +using PubnubApi.EventEngine.Subscribe.Context; +using PubnubApi.EventEngine.Subscribe.Events; +using PubnubApi.EventEngine.Subscribe.Invocations; +using PubnubApi.EventEngine.Subscribe.Common; -namespace PubnubApi.PubnubEventEngine.Subscribe.Effects +namespace PubnubApi.EventEngine.Subscribe.Effects { internal class HandshakeEffectHandler : Core.IEffectHandler, @@ -15,6 +20,8 @@ internal class HandshakeEffectHandler : { private SubscribeManager2 manager; private EventQueue eventQueue; + + private Delay retryDelay = new Delay(0); public HandshakeEffectHandler(SubscribeManager2 manager, EventQueue eventQueue) { @@ -22,9 +29,20 @@ public HandshakeEffectHandler(SubscribeManager2 manager, EventQueue eventQueue) this.eventQueue = eventQueue; } - public async Task Run(HandshakeReconnectInvocation invocation) + public Task Run(HandshakeReconnectInvocation invocation) { - await this.Run((HandshakeInvocation)invocation); + if (!ReconnectionDelayUtil.shouldRetry(invocation.Policy, invocation.AttemptedRetries, invocation.MaxConnectionRetry)) + { + eventQueue.Enqueue(new HandshakeReconnectGiveUpEvent() { Status = new PNStatus(PNStatusCategory.PNCancelledCategory) }); + } + else + { + retryDelay = new Delay(ReconnectionDelayUtil.CalculateDelay(invocation.Policy, invocation.AttemptedRetries)); + // Run in the background + retryDelay.Start().ContinueWith((_) => this.Run((HandshakeInvocation)invocation)); + } + + return Utils.EmptyTask; } public async Task Run(HandshakeInvocation invocation) @@ -34,7 +52,7 @@ public async Task Run(HandshakeInvocation invocation) switch (invocation) { case Invocations.HandshakeReconnectInvocation reconnectInvocation when response.Item2.Error: - eventQueue.Enqueue(new Events.HandshakeReconnectFailureEvent() {RemainingRetries = reconnectInvocation.RemainingRetries - 1, Status = response.Item2}); + eventQueue.Enqueue(new Events.HandshakeReconnectFailureEvent() { AttemptedRetries = reconnectInvocation.AttemptedRetries + 1, Status = response.Item2}); break; case Invocations.HandshakeReconnectInvocation reconnectInvocation: eventQueue.Enqueue(new Events.HandshakeReconnectSuccessEvent() { Cursor = response.Item1, Status = response.Item2 }); @@ -48,12 +66,8 @@ public async Task Run(HandshakeInvocation invocation) } } - - public async Task Cancel() - { - manager.HandshakeRequestCancellation(); - } - + + private async Task> MakeHandshakeRequest(HandshakeInvocation invocation) { var resp = await manager.HandshakeRequest( @@ -81,5 +95,18 @@ public async Task Cancel() return new Tuple(null, new PNStatus(e, PNOperationType.PNSubscribeOperation, PNStatusCategory.PNUnknownCategory, invocation.Channels, invocation.ChannelGroups)); } } + + public async Task Cancel() + { + if (!retryDelay.Cancelled) + { + retryDelay.Cancel(); + } + else + { + manager.HandshakeRequestCancellation(); + } + } + } } \ No newline at end of file diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/Effects/HandshakeReconnectEffectHandler.cs b/src/Api/PubnubApi/EventEngine/Subscribe/Effects/HandshakeReconnectEffectHandler.cs deleted file mode 100644 index 17d8f2368..000000000 --- a/src/Api/PubnubApi/EventEngine/Subscribe/Effects/HandshakeReconnectEffectHandler.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using Newtonsoft.Json; -using PubnubApi.EndPoint; -using PubnubApi.PubnubEventEngine.Core; -using PubnubApi.PubnubEventEngine.Subscribe.Invocations; -using PubnubApi.PubnubEventEngine.Subscribe.Events; -using PubnubApi.PubnubEventEngine; -using System; -using PubnubApi.EventEngine.Subscribe.Context; - -namespace PubnubApi.EventEngine.Subscribe.Effects -{ - internal class HandshakeReconnectEffectHandler : IEffectHandler - { - private SubscribeManager2 manager; - private EventQueue eventQueue; - - public HandshakeReconnectEffectHandler(SubscribeManager2 manager, EventQueue eventQueue) - { - this.manager = manager; - this.eventQueue = eventQueue; - } - - public async Task Cancel() - { - manager.HandshakeRequestCancellation(); - } - - public async Task IEffectHandler.Run(HandshakeReconnectInvocation invocation) - { - if (!ReconnectionDelayUtil.shouldRetry(invocation.Policy, invocation.AttemptedRetries, invocation.MaxConnectionRetry)) - { - eventQueue.Enqueue(new HandshakeReconnectGiveUpEvent() { Status = PNStatus(PNStatusCategory.PNCancelledCategory) }); - } - else - { - // TODO: Check cancellation token whether this operation is cancelled already or not. - - // have a delay - blocking/ non-blocking thing - // TODO: Look for examples in PCL library - await Task.Delay(ReconnectionDelayUtil.CalculateDelay(invocation.Policy, invocation.AttemptedRetries)); - - // TODO: Check cancellation token whether this operation is cancelled or not. - // attempt handshake - var handshakeResponse = await attemptHandshake(invocation); - - if (handshakeResponse.Item2.Error) { - eventQueue.Enqueue(new HandshakeReconnectFailureEvent() { AttemptedRetries = invocation.AttemptedRetries + 1, Status = handshakeResponse.Item2 }); - } - - eventQueue.Enqueue(new HandshakeReconnectSuccessEvent() { Cursor = handshakeResponse.Item1, Status = handshakeResponse.Item2 }); - } - - } - - private async Task> attemptHandshake(HandshakeReconnectInvocation invocation) - { - var resp = await manager.HandshakeRequest( - PNOperationType.PNSubscribeOperation, - invocation.Channels.ToArray(), - invocation.ChannelGroups.ToArray(), - null, - null, - invocation.InitialSubscribeQueryParams, - invocation.ExternalQueryParams - ); - - try { - var handshakeResponse = JsonConvert.DeserializeObject(resp.Item1); - var c = new SubscriptionCursor() { - Region = handshakeResponse.Timetoken.Region, - Timetoken = handshakeResponse.Timetoken.Timestamp - }; - return new System.Tuple(c, resp.Item2); - } catch (Exception e) { - return new Tuple(null, new PNStatus(e, PNOperationType.PNSubscribeOperation, PNStatusCategory.PNUnknownCategory, invocation.Channels, invocation.ChannelGroups)); - } - } - } - -} - diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/Events/SubscriptionEvents.cs b/src/Api/PubnubApi/EventEngine/Subscribe/Events/SubscriptionEvents.cs index ae239ac0b..21af146d5 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/Events/SubscriptionEvents.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/Events/SubscriptionEvents.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; +using PubnubApi.EventEngine.Subscribe.Common; -namespace PubnubApi.PubnubEventEngine.Subscribe.Events { +namespace PubnubApi.EventEngine.Subscribe.Events { public class SubscriptionChangedEvent : Core.IEvent { public IEnumerable Channels; public IEnumerable ChannelGroups; @@ -19,6 +20,7 @@ public class HandshakeSuccessEvent : Core.IEvent { public class HandshakeFailureEvent : Core.IEvent { public PNStatus Status; + public int AttemptedRetries; } public class HandshakeReconnectSuccessEvent : HandshakeSuccessEvent { @@ -27,8 +29,6 @@ public class HandshakeReconnectSuccessEvent : HandshakeSuccessEvent { public class HandshakeReconnectFailureEvent : HandshakeFailureEvent { - public PNStatus Status; - public int AttemptedRetries; } // Do we have this in system description ? diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/Invocations/SubscriptionInvocations.cs b/src/Api/PubnubApi/EventEngine/Subscribe/Invocations/SubscriptionInvocations.cs index aa23bb07d..8edd9ee7c 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/Invocations/SubscriptionInvocations.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/Invocations/SubscriptionInvocations.cs @@ -1,7 +1,8 @@ using System.Collections.Generic; -using PubnubApi.PubnubEventEngine.Core; +using PubnubApi.EventEngine.Core; +using PubnubApi.EventEngine.Subscribe.Common; -namespace PubnubApi.PubnubEventEngine.Subscribe.Invocations { +namespace PubnubApi.EventEngine.Subscribe.Invocations { internal class EmitMessagesInvocation : Core.IEffectInvocation { public IEnumerable> Messages; diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeFailedState.cs b/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeFailedState.cs index a62e27b18..694e49d30 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeFailedState.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeFailedState.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; -using PubnubApi.PubnubEventEngine.Core; -using PubnubApi.PubnubEventEngine.Subscribe.Invocations; +using PubnubApi.EventEngine.Core; +using PubnubApi.EventEngine.Subscribe.Invocations; -namespace PubnubApi.PubnubEventEngine.Subscribe.States +namespace PubnubApi.EventEngine.Subscribe.States { internal class HandshakeFailedState : Core.State { diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeReconnectingState.cs b/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeReconnectingState.cs index 1138a56c0..6e260d9dd 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeReconnectingState.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeReconnectingState.cs @@ -1,20 +1,17 @@ using System; using System.Collections.Generic; -using PubnubApi.PubnubEventEngine.Core; -using PubnubApi.PubnubEventEngine.Subscribe.Invocations; +using PubnubApi.EventEngine.Core; +using PubnubApi.EventEngine.Subscribe.Invocations; -namespace PubnubApi.PubnubEventEngine.Subscribe.States +namespace PubnubApi.EventEngine.Subscribe.States { internal class HandshakeReconnectingState : Core.State { public IEnumerable Channels; public IEnumerable ChannelGroups; - - // TODO introduce policy provider - public int RetryCount = 3; public override IEnumerable OnEntry => new HandshakeReconnectInvocation() - { Channels = this.Channels, ChannelGroups = this.ChannelGroups, RemainingRetries = this.RetryCount}.AsArray(); + { Channels = this.Channels, ChannelGroups = this.ChannelGroups }.AsArray(); public override IEnumerable OnExit { get; } = new CancelHandshakeReconnectInvocation().AsArray(); public override TransitionResult Transition(IEvent e) diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeStoppedState.cs b/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeStoppedState.cs index f58100818..152c3ca0a 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeStoppedState.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeStoppedState.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; -using PubnubApi.PubnubEventEngine.Core; -using PubnubApi.PubnubEventEngine.Subscribe.Invocations; +using PubnubApi.EventEngine.Core; +using PubnubApi.EventEngine.Subscribe.Invocations; -namespace PubnubApi.PubnubEventEngine.Subscribe.States +namespace PubnubApi.EventEngine.Subscribe.States { internal class HandshakeStoppedState : Core.State { diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakingState.cs b/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakingState.cs index 6b33e070b..9fde00f99 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakingState.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakingState.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; -using PubnubApi.PubnubEventEngine.Core; -using PubnubApi.PubnubEventEngine.Subscribe.Invocations; +using PubnubApi.EventEngine.Core; +using PubnubApi.EventEngine.Subscribe.Invocations; -namespace PubnubApi.PubnubEventEngine.Subscribe.States +namespace PubnubApi.EventEngine.Subscribe.States { internal class HandshakingState : Core.State { @@ -33,8 +33,7 @@ public override TransitionResult Transition(IEvent e) Events.HandshakeFailureEvent handshakeFailure => new States.HandshakeReconnectingState() { - // TODO replace retryCount with value from policy - Channels = this.Channels, ChannelGroups = this.ChannelGroups, RetryCount = 3 + Channels = this.Channels, ChannelGroups = this.ChannelGroups }.With(new EmitStatusInvocation(handshakeFailure.Status)), Events.DisconnectEvent disconnect => new States.HandshakeStoppedState() diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveFailedState.cs b/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveFailedState.cs index 6c7e4632c..d78dd819a 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveFailedState.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveFailedState.cs @@ -1,9 +1,10 @@ using System; using System.Collections.Generic; -using PubnubApi.PubnubEventEngine.Core; -using PubnubApi.PubnubEventEngine.Subscribe.Invocations; +using PubnubApi.EventEngine.Core; +using PubnubApi.EventEngine.Subscribe.Invocations; +using PubnubApi.EventEngine.Subscribe.Common; -namespace PubnubApi.PubnubEventEngine.Subscribe.States +namespace PubnubApi.EventEngine.Subscribe.States { internal class ReceiveFailedState : Core.State { diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveReconnectingState.cs b/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveReconnectingState.cs index 7d9bbaf9d..ded0cec4b 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveReconnectingState.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveReconnectingState.cs @@ -1,9 +1,10 @@ using System; using System.Collections.Generic; -using PubnubApi.PubnubEventEngine.Core; -using PubnubApi.PubnubEventEngine.Subscribe.Invocations; +using PubnubApi.EventEngine.Core; +using PubnubApi.EventEngine.Subscribe.Invocations; +using PubnubApi.EventEngine.Subscribe.Common; -namespace PubnubApi.PubnubEventEngine.Subscribe.States +namespace PubnubApi.EventEngine.Subscribe.States { internal class ReceiveReconnectingState : Core.State { diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveStoppedState.cs b/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveStoppedState.cs index 06c6daded..7be7a1462 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveStoppedState.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveStoppedState.cs @@ -1,9 +1,10 @@ using System; using System.Collections.Generic; -using PubnubApi.PubnubEventEngine.Core; -using PubnubApi.PubnubEventEngine.Subscribe.Invocations; +using PubnubApi.EventEngine.Core; +using PubnubApi.EventEngine.Subscribe.Invocations; +using PubnubApi.EventEngine.Subscribe.Common; -namespace PubnubApi.PubnubEventEngine.Subscribe.States +namespace PubnubApi.EventEngine.Subscribe.States { internal class ReceiveStoppedState : Core.State { diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceivingState.cs b/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceivingState.cs index 428507ddb..e7f52c857 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceivingState.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceivingState.cs @@ -1,9 +1,10 @@ using System; using System.Collections.Generic; -using PubnubApi.PubnubEventEngine.Core; -using PubnubApi.PubnubEventEngine.Subscribe.Invocations; +using PubnubApi.EventEngine.Core; +using PubnubApi.EventEngine.Subscribe.Invocations; +using PubnubApi.EventEngine.Subscribe.Common; -namespace PubnubApi.PubnubEventEngine.Subscribe.States +namespace PubnubApi.EventEngine.Subscribe.States { internal class ReceivingState : Core.State { diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/States/UnsubscribedState.cs b/src/Api/PubnubApi/EventEngine/Subscribe/States/UnsubscribedState.cs index 2a5affc92..f1e9fc683 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/States/UnsubscribedState.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/States/UnsubscribedState.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; -using PubnubApi.PubnubEventEngine.Core; -using PubnubApi.PubnubEventEngine.Subscribe.Invocations; +using PubnubApi.EventEngine.Core; +using PubnubApi.EventEngine.Subscribe.Invocations; -namespace PubnubApi.PubnubEventEngine.Subscribe.States +namespace PubnubApi.EventEngine.Subscribe.States { internal class UnsubscribedState : Core.State { diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/SubscribeEventEngine.cs b/src/Api/PubnubApi/EventEngine/Subscribe/SubscribeEventEngine.cs index f71bd366f..3815d704a 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/SubscribeEventEngine.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/SubscribeEventEngine.cs @@ -1,10 +1,11 @@ using PubnubApi.EndPoint; -using PubnubApi.PubnubEventEngine.Subscribe.Effects; -using PubnubApi.PubnubEventEngine.Subscribe.Invocations; -using PubnubApi.PubnubEventEngine.Subscribe.States; +using PubnubApi.EventEngine.Core; +using PubnubApi.EventEngine.Subscribe.States; +using PubnubApi.EventEngine.Subscribe.Effects; +using PubnubApi.EventEngine.Subscribe.Invocations; -namespace PubnubApi.PubnubEventEngine.Subscribe { - internal class SubscribeEventEngine : PubnubEventEngine.Core.Engine { +namespace PubnubApi.EventEngine.Subscribe { + internal class SubscribeEventEngine : Engine { private SubscribeManager2 subscribeManager; public SubscribeEventEngine(SubscribeManager2 subscribeManager) { From 28952011d54ce38f04b2fdb3c8cdd1a2d50cd2c1 Mon Sep 17 00:00:00 2001 From: Mohit Tejani Date: Wed, 19 Jul 2023 19:48:41 +0530 Subject: [PATCH 06/27] revert *.csproj changes --- src/Api/PubnubApi/PubnubApi.csproj | 55 ++++++++++++------- .../MockServerPubnubApi.csproj | 7 ++- .../PubnubApi.Tests/PubnubApi.Tests.csproj | 11 ++-- 3 files changed, 47 insertions(+), 26 deletions(-) diff --git a/src/Api/PubnubApi/PubnubApi.csproj b/src/Api/PubnubApi/PubnubApi.csproj index 857cf5412..b1ebf5097 100644 --- a/src/Api/PubnubApi/PubnubApi.csproj +++ b/src/Api/PubnubApi/PubnubApi.csproj @@ -1,10 +1,11 @@  - net40 + net35;net40;net45;net461;net48 8.0 True pubnub.snk + False False PubNub C# .NET - Web Data Push API Pubnub @@ -13,7 +14,7 @@ Pubnub - 6.16.0.0 + 6.17.0.0 PubNub C# .NET - Web Data Push API Pandu Masabathula PubNub @@ -21,8 +22,7 @@ http://pubnub.s3.amazonaws.com/2011/powered-by-pubnub/pubnub-icon-600x600.png true https://github.com/pubnub/c-sharp/ - Replaced ConcurrentDictionary class file with System.Collections.Concurrent package for all target frameworks except .net 3.5/4.0. -Addressed threading issue on reading ConcurrentDictionary keys. + Validate json string before deserialization. Web Data Push Real-time Notifications ESB Message Broadcasting Distributed Computing PubNub is a Massively Scalable Web Push Service for Web and Mobile Games. This is a cloud-based service for broadcasting messages to thousands of web and mobile clients simultaneously @@ -30,10 +30,22 @@ Addressed threading issue on reading ConcurrentDictionary keys.false + + $(DefineConstants);NET35 + C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v3.5\Profile\Client + $(DefineConstants);NET40 - + + $(DefineConstants);NET45 + + + $(DefineConstants);NET461 + + + $(DefineConstants);NET48 + 1701;1702;0436; @@ -46,9 +58,6 @@ Addressed threading issue on reading ConcurrentDictionary keys. 0436; - - - @@ -61,13 +70,16 @@ Addressed threading issue on reading ConcurrentDictionary keys. - + + 0.3.1 None - + + 1.0.2856 None - + + 1.0.2856 None @@ -77,7 +89,8 @@ Addressed threading issue on reading ConcurrentDictionary keys. - + + 0.3.1 None @@ -93,38 +106,40 @@ Addressed threading issue on reading ConcurrentDictionary keys. None - + + 4.3.0 None - + + 4.3.0 None - + + 4.3.0 None - + + 4.3.0 None - + + 4.3.0 None - - - diff --git a/src/UnitTests/MockServerPubnubApi/MockServerPubnubApi.csproj b/src/UnitTests/MockServerPubnubApi/MockServerPubnubApi.csproj index a1b8d8e74..41e331582 100644 --- a/src/UnitTests/MockServerPubnubApi/MockServerPubnubApi.csproj +++ b/src/UnitTests/MockServerPubnubApi/MockServerPubnubApi.csproj @@ -1,7 +1,7 @@  - net40 + net35;net40;net45;net461;net48 False false PubNub C# .NET - MockServerPubnubApi @@ -16,7 +16,10 @@ true--> - + + $(DefineConstants);NET35 + C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v3.5\Profile\Client + $(DefineConstants);NET40 diff --git a/src/UnitTests/PubnubApi.Tests/PubnubApi.Tests.csproj b/src/UnitTests/PubnubApi.Tests/PubnubApi.Tests.csproj index 901745923..ae358d01b 100644 --- a/src/UnitTests/PubnubApi.Tests/PubnubApi.Tests.csproj +++ b/src/UnitTests/PubnubApi.Tests/PubnubApi.Tests.csproj @@ -1,7 +1,7 @@  - net40 + net35;net40;net45;net461;net48 false Debug AnyCPU @@ -13,7 +13,10 @@ 512 true - + + $(DefineConstants);NET35 + C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v3.5\Profile\Client + $(DefineConstants);NET40 @@ -88,7 +91,7 @@ - + + From 7748a477a70cbdb0fc7309f6698ade88920ce06f Mon Sep 17 00:00:00 2001 From: Mohit Tejani Date: Thu, 20 Jul 2023 12:28:56 +0530 Subject: [PATCH 07/27] added required info in handshake reconnect invocation. --- .../Subscribe/States/HandshakeReconnectingState.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeReconnectingState.cs b/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeReconnectingState.cs index 6e260d9dd..843380e34 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeReconnectingState.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeReconnectingState.cs @@ -9,9 +9,13 @@ internal class HandshakeReconnectingState : Core.State { public IEnumerable Channels; public IEnumerable ChannelGroups; + public PNReconnectionPolicy RetryPolicy; + public int MaxConnectionRetry; + public int AttemptedRetries; + public override IEnumerable OnEntry => new HandshakeReconnectInvocation() - { Channels = this.Channels, ChannelGroups = this.ChannelGroups }.AsArray(); + { Channels = this.Channels, ChannelGroups = this.ChannelGroups, Policy = this.RetryPolicy, MaxConnectionRetry = this.MaxConnectionRetry, AttemptedRetries = this.AttemptedRetries }.AsArray(); public override IEnumerable OnExit { get; } = new CancelHandshakeReconnectInvocation().AsArray(); public override TransitionResult Transition(IEvent e) From 4bff839fbc4f1515f21f3b277ebe291eaa50fd3b Mon Sep 17 00:00:00 2001 From: Pandu Masabathula Date: Thu, 20 Jul 2023 14:46:00 +0530 Subject: [PATCH 08/27] receive handler (#180) * receive handler --- .../EndPoint/PubSub/SubscribeOperation2.cs | 26 ++-- src/Api/PubnubApi/EventEngine/Common/Delay.cs | 11 +- .../Subscribe/Common/CommonSubscribeTypes.cs | 45 +++++++ .../Effects/ReceivingEffectHandler.cs | 113 ++++++++++++++++++ .../Subscribe/Events/SubscriptionEvents.cs | 2 + .../Invocations/SubscriptionInvocations.cs | 10 +- src/Api/PubnubApiPCL/PubnubApiPCL.csproj | 6 + src/Api/PubnubApiUWP/PubnubApiUWP.csproj | 6 + 8 files changed, 198 insertions(+), 21 deletions(-) create mode 100644 src/Api/PubnubApi/EventEngine/Subscribe/Effects/ReceivingEffectHandler.cs diff --git a/src/Api/PubnubApi/EndPoint/PubSub/SubscribeOperation2.cs b/src/Api/PubnubApi/EndPoint/PubSub/SubscribeOperation2.cs index 7e9511bf7..61b9d5c26 100644 --- a/src/Api/PubnubApi/EndPoint/PubSub/SubscribeOperation2.cs +++ b/src/Api/PubnubApi/EndPoint/PubSub/SubscribeOperation2.cs @@ -26,7 +26,7 @@ public class SubscribeOperation2: ISubscribeOperation private bool presenceSubscribeEnabled; private SubscribeManager2 manager; private Dictionary queryParam; - private EventEngine pnEventEngine; + private PubnubEventEngine.EventEngine pnEventEngine; private Pubnub PubnubInstance; public List SubscribeListenerList { @@ -104,18 +104,18 @@ public SubscribeOperation2(PNConfiguration pubnubConfig, IJsonPluggableLibrary j effectDispatcher.Register(EventType.ReceiveReconnectSuccess, receiveReconnectEffectHandler); effectDispatcher.Register(EventType.ReceiveReconnectGiveUp, receiveReconnectEffectHandler); - pnEventEngine = new EventEngine(effectDispatcher, eventEmitter); - pnEventEngine.PubnubUnitTest = unit; - pnEventEngine.Setup(config); - - if (pnEventEngine.PubnubUnitTest != null) - { - pnEventEngine.PubnubUnitTest.EventTypeList = new List>(); - } - else - { - pnEventEngine.InitialState(new State(StateType.Unsubscribed) { EventType = EventType.SubscriptionChanged }); - } + // pnEventEngine = new EventEngine(effectDispatcher, eventEmitter); + // pnEventEngine.PubnubUnitTest = unit; + // pnEventEngine.Setup(config); + + // if (pnEventEngine.PubnubUnitTest != null) + // { + // pnEventEngine.PubnubUnitTest.EventTypeList = new List>(); + // } + // else + // { + //pnEventEngine.InitialState(new State(StateType.Unsubscribed) { EventType = EventType.SubscriptionChanged }); + // } } private void ReceivingEffect_ReceiveRequested(object sender, ReceiveRequestEventArgs e) diff --git a/src/Api/PubnubApi/EventEngine/Common/Delay.cs b/src/Api/PubnubApi/EventEngine/Common/Delay.cs index 22f9536ba..3afb9a4a6 100644 --- a/src/Api/PubnubApi/EventEngine/Common/Delay.cs +++ b/src/Api/PubnubApi/EventEngine/Common/Delay.cs @@ -6,7 +6,6 @@ namespace PubnubApi.EventEngine.Common public class Delay { public bool Cancelled { get; private set; } = false; - private readonly Thread awaiterThread; private readonly TaskCompletionSource taskCompletionSource = new TaskCompletionSource(); private readonly object monitor = new object(); private readonly int milliseconds; @@ -14,14 +13,18 @@ public class Delay public Delay(int milliseconds) { this.milliseconds = milliseconds; - awaiterThread = new Thread(AwaiterLoop); } public Task Start() { + #if NETFX_CORE || WINDOWS_UWP || UAP || NETSTANDARD10 || NETSTANDARD11 || NETSTANDARD12 + Task taskAwaiter = Task.Factory.StartNew(AwaiterLoop); + taskAwaiter.Wait(); + #else + Thread awaiterThread = new Thread(AwaiterLoop); awaiterThread.Start(); - return taskCompletionSource.Task; - } + #endif + return taskCompletionSource.Task; } public void Cancel() { diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/Common/CommonSubscribeTypes.cs b/src/Api/PubnubApi/EventEngine/Subscribe/Common/CommonSubscribeTypes.cs index 1579e6521..3dd44c938 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/Common/CommonSubscribeTypes.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/Common/CommonSubscribeTypes.cs @@ -34,4 +34,49 @@ public class Timetoken public int? Region { get; set; } } + + public class ReceivingResponse + { + [JsonProperty("t")] + public Timetoken Timetoken { get; set; } + + [JsonProperty("m")] + public Message[] Messages { get; set; } + } + + public class Message + { + [JsonProperty ("a")] + public string Shard { get; set;} + + [JsonProperty ("b")] + public string SubscriptionMatch { get; set;} + + [JsonProperty("c")] + public string Channel { get; set; } + + [JsonProperty("d")] + public T Payload { get; set; } + + [JsonProperty("e")] + public int MessageType { get; set; } + + [JsonProperty("f")] + public string Flags { get; set; } + + //[JsonProperty("i")] + //public string IssuingClientId { get; set; } + + [JsonProperty("k")] + public string SubscribeKey { get; set; } + + [JsonProperty("o")] + public object OriginatingTimetoken { get; set; } + + [JsonProperty("p")] + public object PublishMetadata { get; set; } + + [JsonProperty("s")] + public long SequenceNumber { get; set; } + } } \ No newline at end of file diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/Effects/ReceivingEffectHandler.cs b/src/Api/PubnubApi/EventEngine/Subscribe/Effects/ReceivingEffectHandler.cs new file mode 100644 index 000000000..48a5b27af --- /dev/null +++ b/src/Api/PubnubApi/EventEngine/Subscribe/Effects/ReceivingEffectHandler.cs @@ -0,0 +1,113 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Newtonsoft.Json; +using PubnubApi.EndPoint; +using PubnubApi.EventEngine.Common; +using PubnubApi.EventEngine.Core; +using PubnubApi.EventEngine.Subscribe.Context; +using PubnubApi.EventEngine.Subscribe.Events; +using PubnubApi.EventEngine.Subscribe.Invocations; +using PubnubApi.EventEngine.Subscribe.Common; + +namespace PubnubApi.EventEngine.Subscribe.Effects +{ + internal class ReceivingEffectHandler: + Core.IEffectHandler, + Core.IEffectHandler + { + private SubscribeManager2 manager; + private EventQueue eventQueue; + + private Delay retryDelay = new Delay(0); + + public ReceivingEffectHandler(SubscribeManager2 manager, EventQueue eventQueue) + { + this.manager = manager; + this.eventQueue = eventQueue; + } + + public Task Run(ReceiveReconnectInvocation invocation) + { + if (!ReconnectionDelayUtil.shouldRetry(invocation.Policy, invocation.AttemptedRetries, invocation.MaxConnectionRetry)) + { + eventQueue.Enqueue(new ReceiveReconnectGiveUpEvent() { Status = new PNStatus(PNStatusCategory.PNCancelledCategory) }); + } + else + { + retryDelay = new Delay(ReconnectionDelayUtil.CalculateDelay(invocation.Policy, invocation.AttemptedRetries)); + // Run in the background + retryDelay.Start().ContinueWith((_) => this.Run((ReceiveMessagesInvocation)invocation)); + } + + return Utils.EmptyTask; + } + + public async Task Run(ReceiveMessagesInvocation invocation) + { + var response = await MakeReceiveMessagesRequest(invocation); + + switch (invocation) + { + case Invocations.ReceiveReconnectInvocation reconnectInvocation when response.Item2.Error: + eventQueue.Enqueue(new Events.ReceiveReconnectFailureEvent() { AttemptedRetries = reconnectInvocation.AttemptedRetries + 1, Status = response.Item2}); + break; + case Invocations.ReceiveReconnectInvocation reconnectInvocation: + eventQueue.Enqueue(new Events.ReceiveReconnectSuccessEvent() { Cursor = response.Item1, Status = response.Item2 }); + break; + case { } when response.Item2.Error: + eventQueue.Enqueue(new Events.ReceiveFailureEvent() { Cursor = response.Item1, Status = response.Item2}); + break; + case { }: + //TODO: get messages + List> listOfMessages = null; + eventQueue.Enqueue(new Events.ReceiveSuccessEvent() { Cursor = response.Item1, Messages= listOfMessages, Status = response.Item2 }); + break; + + } + } + + private async Task> MakeReceiveMessagesRequest(ReceiveMessagesInvocation invocation) + { + var resp = await manager.ReceiveRequest( + PNOperationType.PNSubscribeOperation, + invocation.Channels.ToArray(), + invocation.ChannelGroups.ToArray(), + invocation.Cursor.Timetoken.Value, + invocation.Cursor.Region.Value, + invocation.InitialSubscribeQueryParams, + invocation.ExternalQueryParams + ); + + try + { + //TODO: get ReceivingResponse from manager.ReceiveRequest + var receiveResponse = JsonConvert.DeserializeObject>(resp.Item1); + var c = new SubscriptionCursor() + { + Region = receiveResponse.Timetoken.Region, + Timetoken = receiveResponse.Timetoken.Timestamp + }; + return new System.Tuple(c, resp.Item2); + } + catch (Exception e) + { + return new Tuple(null, new PNStatus(e, PNOperationType.PNSubscribeOperation, PNStatusCategory.PNUnknownCategory, invocation.Channels, invocation.ChannelGroups)); + } + } + + public async Task Cancel() + { + if (!retryDelay.Cancelled) + { + retryDelay.Cancel(); + } + else + { + manager.ReceiveRequestCancellation(); + } + } + } +} diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/Events/SubscriptionEvents.cs b/src/Api/PubnubApi/EventEngine/Subscribe/Events/SubscriptionEvents.cs index 21af146d5..5dfa789f0 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/Events/SubscriptionEvents.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/Events/SubscriptionEvents.cs @@ -49,6 +49,8 @@ public class ReceiveSuccessEvent : Core.IEvent { public class ReceiveFailureEvent : Core.IEvent { public PNStatus Status; + public int AttemptedRetries; + public SubscriptionCursor Cursor; } public class ReceiveReconnectRetry : Core.IEvent { diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/Invocations/SubscriptionInvocations.cs b/src/Api/PubnubApi/EventEngine/Subscribe/Invocations/SubscriptionInvocations.cs index 8edd9ee7c..bd6e771ea 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/Invocations/SubscriptionInvocations.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/Invocations/SubscriptionInvocations.cs @@ -45,6 +45,8 @@ internal class ReceiveMessagesInvocation : Core.IEffectInvocation public IEnumerable Channels; public IEnumerable ChannelGroups; public SubscriptionCursor Cursor; + public Dictionary InitialSubscribeQueryParams = new Dictionary(); + public Dictionary ExternalQueryParams = new Dictionary(); } internal class CancelReceiveMessagesInvocation : ReceiveMessagesInvocation, Core.IEffectCancelInvocation { } @@ -60,11 +62,11 @@ internal class HandshakeReconnectInvocation: HandshakeInvocation internal class CancelHandshakeReconnectInvocation: HandshakeReconnectInvocation, Core.IEffectCancelInvocation { } - internal class ReceiveReconnectInvocation: Core.IEffectInvocation + internal class ReceiveReconnectInvocation: ReceiveMessagesInvocation { - public IEnumerable Channels; - public IEnumerable ChannelGroups; - public SubscriptionCursor Cursor; + public int AttemptedRetries; + public int MaxConnectionRetry; + public PNReconnectionPolicy Policy; } internal class CancelReceiveReconnectInvocation: ReceiveReconnectInvocation, Core.IEffectCancelInvocation { } diff --git a/src/Api/PubnubApiPCL/PubnubApiPCL.csproj b/src/Api/PubnubApiPCL/PubnubApiPCL.csproj index 75f021e2e..46b2a3d0e 100644 --- a/src/Api/PubnubApiPCL/PubnubApiPCL.csproj +++ b/src/Api/PubnubApiPCL/PubnubApiPCL.csproj @@ -214,6 +214,7 @@ Addressed threading issue on reading ConcurrentDictionary keys. Enum\ResponseType.cs + @@ -229,6 +230,8 @@ Addressed threading issue on reading ConcurrentDictionary keys. + + @@ -918,9 +921,12 @@ Addressed threading issue on reading ConcurrentDictionary keys. + + + diff --git a/src/Api/PubnubApiUWP/PubnubApiUWP.csproj b/src/Api/PubnubApiUWP/PubnubApiUWP.csproj index 2b28b1763..652e2e30b 100644 --- a/src/Api/PubnubApiUWP/PubnubApiUWP.csproj +++ b/src/Api/PubnubApiUWP/PubnubApiUWP.csproj @@ -331,6 +331,7 @@ Addressed threading issue on reading ConcurrentDictionary keys. Enum\ResponseType.cs + @@ -346,6 +347,8 @@ Addressed threading issue on reading ConcurrentDictionary keys. + + @@ -727,9 +730,12 @@ Addressed threading issue on reading ConcurrentDictionary keys. + + + From b2fdbe391abbde59ff4d4af26586f76ba69362dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Dobrza=C5=84ski?= Date: Thu, 20 Jul 2023 14:08:06 +0200 Subject: [PATCH 09/27] fix: background handlers --- .../EventEngine/Core/EffectDispatcher.cs | 9 ++++++-- .../EventEngine/Core/EventEngineInterfaces.cs | 1 + .../Effects/HandshakeEffectHandler.cs | 21 +++++++++++++------ .../Effects/ReceivingEffectHandler.cs | 11 +++++++++- .../Subscribe/SubscribeEventEngine.cs | 1 + 5 files changed, 34 insertions(+), 9 deletions(-) diff --git a/src/Api/PubnubApi/EventEngine/Core/EffectDispatcher.cs b/src/Api/PubnubApi/EventEngine/Core/EffectDispatcher.cs index 673ef726f..334366490 100644 --- a/src/Api/PubnubApi/EventEngine/Core/EffectDispatcher.cs +++ b/src/Api/PubnubApi/EventEngine/Core/EffectDispatcher.cs @@ -18,8 +18,13 @@ public async Task Dispatch(T invocation) where T : IEffectInvocation { if (invocation is IEffectCancelInvocation) { await effectInvocationHandlerMap[invocation.GetType()].Cancel(); - } else { - await ((IEffectHandler)effectInvocationHandlerMap[invocation.GetType()]).Run(invocation); + } else + { + var handler = ((IEffectHandler)effectInvocationHandlerMap[invocation.GetType()]); + if (handler.IsBackground(invocation)) + handler.Run(invocation).Start(); + else + await handler.Run(invocation); } } diff --git a/src/Api/PubnubApi/EventEngine/Core/EventEngineInterfaces.cs b/src/Api/PubnubApi/EventEngine/Core/EventEngineInterfaces.cs index 698055e27..16717dc36 100644 --- a/src/Api/PubnubApi/EventEngine/Core/EventEngineInterfaces.cs +++ b/src/Api/PubnubApi/EventEngine/Core/EventEngineInterfaces.cs @@ -17,6 +17,7 @@ internal interface IEffectHandler { /// Associated invocation internal interface IEffectHandler : IEffectHandler where T : IEffectInvocation { Task Run(T invocation); + bool IsBackground(T invocation); } /// diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/Effects/HandshakeEffectHandler.cs b/src/Api/PubnubApi/EventEngine/Subscribe/Effects/HandshakeEffectHandler.cs index f9782d993..f85f995d0 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/Effects/HandshakeEffectHandler.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/Effects/HandshakeEffectHandler.cs @@ -29,7 +29,7 @@ public HandshakeEffectHandler(SubscribeManager2 manager, EventQueue eventQueue) this.eventQueue = eventQueue; } - public Task Run(HandshakeReconnectInvocation invocation) + public async Task Run(HandshakeReconnectInvocation invocation) { if (!ReconnectionDelayUtil.shouldRetry(invocation.Policy, invocation.AttemptedRetries, invocation.MaxConnectionRetry)) { @@ -38,11 +38,15 @@ public Task Run(HandshakeReconnectInvocation invocation) else { retryDelay = new Delay(ReconnectionDelayUtil.CalculateDelay(invocation.Policy, invocation.AttemptedRetries)); - // Run in the background - retryDelay.Start().ContinueWith((_) => this.Run((HandshakeInvocation)invocation)); + await retryDelay.Start(); + if (!retryDelay.Cancelled) + await Run((HandshakeInvocation)invocation); } + } - return Utils.EmptyTask; + public bool IsBackground(HandshakeReconnectInvocation invocation) + { + return true; } public async Task Run(HandshakeInvocation invocation) @@ -66,8 +70,13 @@ public async Task Run(HandshakeInvocation invocation) } } - - + + public bool IsBackground(HandshakeInvocation invocation) + { + return false; + } + + private async Task> MakeHandshakeRequest(HandshakeInvocation invocation) { var resp = await manager.HandshakeRequest( diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/Effects/ReceivingEffectHandler.cs b/src/Api/PubnubApi/EventEngine/Subscribe/Effects/ReceivingEffectHandler.cs index 48a5b27af..ce4c469eb 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/Effects/ReceivingEffectHandler.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/Effects/ReceivingEffectHandler.cs @@ -45,6 +45,11 @@ public Task Run(ReceiveReconnectInvocation invocation) return Utils.EmptyTask; } + public bool IsBackground(ReceiveReconnectInvocation invocation) + { + return true; + } + public async Task Run(ReceiveMessagesInvocation invocation) { var response = await MakeReceiveMessagesRequest(invocation); @@ -65,10 +70,14 @@ public async Task Run(ReceiveMessagesInvocation invocation) List> listOfMessages = null; eventQueue.Enqueue(new Events.ReceiveSuccessEvent() { Cursor = response.Item1, Messages= listOfMessages, Status = response.Item2 }); break; - } } + public bool IsBackground(ReceiveMessagesInvocation invocation) + { + return true; + } + private async Task> MakeReceiveMessagesRequest(ReceiveMessagesInvocation invocation) { var resp = await manager.ReceiveRequest( diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/SubscribeEventEngine.cs b/src/Api/PubnubApi/EventEngine/Subscribe/SubscribeEventEngine.cs index 3815d704a..bbe6f6bb2 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/SubscribeEventEngine.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/SubscribeEventEngine.cs @@ -14,6 +14,7 @@ public SubscribeEventEngine(SubscribeManager2 subscribeManager) { // initialize the handler, pass dependencies var handshakeHandler = new Effects.HandshakeEffectHandler(subscribeManager, eventQueue); dispatcher.Register(handshakeHandler); + dispatcher.Register(handshakeHandler); dispatcher.Register(handshakeHandler); currentState = new UnsubscribedState(); From 3cebc79be81b9d792c69a1b632bdafe1c0db91f6 Mon Sep 17 00:00:00 2001 From: Mohit Tejani Date: Thu, 20 Jul 2023 18:15:53 +0530 Subject: [PATCH 10/27] *reconnection configurations *refactor naming --- .../Invocations/SubscriptionInvocations.cs | 8 ++++---- .../Subscribe/States/HandshakeReconnectingState.cs | 6 +++--- .../Subscribe/States/HandshakingState.cs | 12 +++++++++--- .../Subscribe/States/ReceiveReconnectingState.cs | 14 ++++++++++++-- .../EventEngine/Subscribe/States/ReceivingState.cs | 9 +++++++-- 5 files changed, 35 insertions(+), 14 deletions(-) diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/Invocations/SubscriptionInvocations.cs b/src/Api/PubnubApi/EventEngine/Subscribe/Invocations/SubscriptionInvocations.cs index bd6e771ea..01ec91e66 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/Invocations/SubscriptionInvocations.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/Invocations/SubscriptionInvocations.cs @@ -56,8 +56,8 @@ internal class CancelHandshakeInvocation : HandshakeInvocation, Core.IEffectCanc internal class HandshakeReconnectInvocation: HandshakeInvocation { public int AttemptedRetries; - public int MaxConnectionRetry; - public PNReconnectionPolicy Policy; + public int MaximumReconnectionRetries; + public PNReconnectionPolicy ReconnectionPolicy; } internal class CancelHandshakeReconnectInvocation: HandshakeReconnectInvocation, Core.IEffectCancelInvocation { } @@ -65,8 +65,8 @@ internal class CancelHandshakeReconnectInvocation: HandshakeReconnectInvocation, internal class ReceiveReconnectInvocation: ReceiveMessagesInvocation { public int AttemptedRetries; - public int MaxConnectionRetry; - public PNReconnectionPolicy Policy; + public int MaximumReconnectionRetries; + public PNReconnectionPolicy ReconnectionPolicy; } internal class CancelReceiveReconnectInvocation: ReceiveReconnectInvocation, Core.IEffectCancelInvocation { } diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeReconnectingState.cs b/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeReconnectingState.cs index 843380e34..da93f12b3 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeReconnectingState.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeReconnectingState.cs @@ -9,13 +9,13 @@ internal class HandshakeReconnectingState : Core.State { public IEnumerable Channels; public IEnumerable ChannelGroups; - public PNReconnectionPolicy RetryPolicy; - public int MaxConnectionRetry; + public PNReconnectionPolicy ReconnectionPolicy; + public int MaximumReconnectionRetries; public int AttemptedRetries; public override IEnumerable OnEntry => new HandshakeReconnectInvocation() - { Channels = this.Channels, ChannelGroups = this.ChannelGroups, Policy = this.RetryPolicy, MaxConnectionRetry = this.MaxConnectionRetry, AttemptedRetries = this.AttemptedRetries }.AsArray(); + { Channels = this.Channels, ChannelGroups = this.ChannelGroups, ReconnectionPolicy = this.ReconnectionPolicy, MaximumReconnectionRetries = this.MaximumReconnectionRetries, AttemptedRetries = this.AttemptedRetries }.AsArray(); public override IEnumerable OnExit { get; } = new CancelHandshakeReconnectInvocation().AsArray(); public override TransitionResult Transition(IEvent e) diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakingState.cs b/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakingState.cs index 9fde00f99..b09b0bfe8 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakingState.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakingState.cs @@ -9,8 +9,10 @@ internal class HandshakingState : Core.State { public IEnumerable Channels; public IEnumerable ChannelGroups; + public PNReconnectionPolicy ReconnectionPolicy; + public int MaximumReconnectionRetries; - public override IEnumerable OnEntry => new HandshakeInvocation() + public override IEnumerable OnEntry => new HandshakeInvocation() { Channels = this.Channels, ChannelGroups = this.ChannelGroups }.AsArray(); public override IEnumerable OnExit { get; } = new CancelHandshakeInvocation().AsArray(); @@ -33,8 +35,12 @@ public override TransitionResult Transition(IEvent e) Events.HandshakeFailureEvent handshakeFailure => new States.HandshakeReconnectingState() { - Channels = this.Channels, ChannelGroups = this.ChannelGroups - }.With(new EmitStatusInvocation(handshakeFailure.Status)), + Channels = this.Channels, + ChannelGroups = this.ChannelGroups, + AttemptedRetries = 0, + MaximumReconnectionRetries = this.MaximumReconnectionRetries, + ReconnectionPolicy = this.ReconnectionPolicy + }.With(new EmitStatusInvocation(handshakeFailure.Status)), Events.DisconnectEvent disconnect => new States.HandshakeStoppedState() { diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveReconnectingState.cs b/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveReconnectingState.cs index ded0cec4b..96197fdac 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveReconnectingState.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveReconnectingState.cs @@ -10,10 +10,20 @@ internal class ReceiveReconnectingState : Core.State { public IEnumerable Channels; public IEnumerable ChannelGroups; - public SubscriptionCursor Cursor; + public PNReconnectionPolicy ReconnectionPolicy; + public int MaximumReconnectionRetries; + public int AttemptedRetries; + public SubscriptionCursor Cursor; public override IEnumerable OnEntry => new ReceiveReconnectInvocation() - { Channels = this.Channels, ChannelGroups = this.ChannelGroups, Cursor = this.Cursor }.AsArray(); + { + Channels = this.Channels, + ChannelGroups = this.ChannelGroups, + Cursor = this.Cursor, + ReconnectionPolicy = this.ReconnectionPolicy, + MaximumReconnectionRetries = this.MaximumReconnectionRetries, + AttemptedRetries = this.AttemptedRetries + }.AsArray(); public override IEnumerable OnExit { get; } = new CancelReceiveReconnectInvocation().AsArray(); diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceivingState.cs b/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceivingState.cs index e7f52c857..c4767909d 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceivingState.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceivingState.cs @@ -10,7 +10,9 @@ internal class ReceivingState : Core.State { public IEnumerable Channels; public IEnumerable ChannelGroups; - public SubscriptionCursor Cursor; + public PNReconnectionPolicy ReconnectionPolicy; + public int MaximumReconnectionRetries; + public SubscriptionCursor Cursor; public override IEnumerable OnEntry => new ReceiveMessagesInvocation() { Channels = this.Channels, ChannelGroups = this.ChannelGroups, Cursor = this.Cursor }.AsArray(); @@ -56,7 +58,10 @@ public override TransitionResult Transition(IEvent e) { Channels = this.Channels, ChannelGroups = this.ChannelGroups, - Cursor = this.Cursor + AttemptedRetries = 0, + MaximumReconnectionRetries = this.MaximumReconnectionRetries, + ReconnectionPolicy = this.ReconnectionPolicy, + Cursor = this.Cursor }, _ => null From c1a2629e8b359298e702455ccb18217bc9a5a53e Mon Sep 17 00:00:00 2001 From: Mohit Tejani Date: Thu, 20 Jul 2023 18:52:15 +0530 Subject: [PATCH 11/27] passing configuration for reconnection --- .../Subscribe/States/HandshakeFailedState.cs | 24 +++++++++++----- .../Subscribe/States/HandshakeStoppedState.cs | 24 +++++++++++----- .../Subscribe/States/HandshakingState.cs | 28 +++++++++++++------ .../Subscribe/States/ReceiveFailedState.cs | 22 ++++++++++----- .../Subscribe/States/ReceiveStoppedState.cs | 20 +++++++++---- .../Subscribe/States/UnsubscribedState.cs | 18 ++++++++---- .../Subscribe/SubscribeEventEngine.cs | 3 +- 7 files changed, 98 insertions(+), 41 deletions(-) diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeFailedState.cs b/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeFailedState.cs index 694e49d30..91d10cb9d 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeFailedState.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeFailedState.cs @@ -9,27 +9,37 @@ internal class HandshakeFailedState : Core.State { public IEnumerable Channels; public IEnumerable ChannelGroups; + public PNReconnectionPolicy ReconnectionPolicy; + public int MaximumReconnectionRetries; - public override TransitionResult Transition(IEvent e) + public override TransitionResult Transition(IEvent e) { return e switch { Events.SubscriptionChangedEvent subscriptionChanged => new HandshakingState() { - Channels = subscriptionChanged.Channels, ChannelGroups = subscriptionChanged.ChannelGroups, - }, + Channels = subscriptionChanged.Channels, + ChannelGroups = subscriptionChanged.ChannelGroups, + MaximumReconnectionRetries = this.MaximumReconnectionRetries, + ReconnectionPolicy = this.ReconnectionPolicy + }, Events.ReconnectEvent reconnect => new HandshakingState() { - Channels = reconnect.Channels, ChannelGroups = reconnect.ChannelGroups, - }, + Channels = reconnect.Channels, + ChannelGroups = reconnect.ChannelGroups, + MaximumReconnectionRetries = this.MaximumReconnectionRetries, + ReconnectionPolicy = this.ReconnectionPolicy + }, Events.SubscriptionRestoredEvent subscriptionRestored => new ReceivingState() { Channels = subscriptionRestored.Channels, ChannelGroups = subscriptionRestored.ChannelGroups, - Cursor = subscriptionRestored.Cursor - }, + Cursor = subscriptionRestored.Cursor, + MaximumReconnectionRetries = this.MaximumReconnectionRetries, + ReconnectionPolicy = this.ReconnectionPolicy + }, _ => null }; diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeStoppedState.cs b/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeStoppedState.cs index 152c3ca0a..a997af4ae 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeStoppedState.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeStoppedState.cs @@ -9,26 +9,36 @@ internal class HandshakeStoppedState : Core.State { public IEnumerable Channels; public IEnumerable ChannelGroups; - - public override TransitionResult Transition(IEvent e) + public PNReconnectionPolicy ReconnectionPolicy; + public int MaximumReconnectionRetries; + + public override TransitionResult Transition(IEvent e) { return e switch { Events.SubscriptionChangedEvent subscriptionChanged => new HandshakingState() { - Channels = subscriptionChanged.Channels, ChannelGroups = subscriptionChanged.ChannelGroups, - }, + Channels = subscriptionChanged.Channels, + ChannelGroups = subscriptionChanged.ChannelGroups, + MaximumReconnectionRetries = this.MaximumReconnectionRetries, + ReconnectionPolicy = this.ReconnectionPolicy + }, Events.ReconnectEvent reconnect => new HandshakingState() { - Channels = reconnect.Channels, ChannelGroups = reconnect.ChannelGroups, - }, + Channels = reconnect.Channels, + ChannelGroups = reconnect.ChannelGroups, + MaximumReconnectionRetries = this.MaximumReconnectionRetries, + ReconnectionPolicy = this.ReconnectionPolicy + }, Events.SubscriptionRestoredEvent subscriptionRestored => new ReceivingState() { Channels = subscriptionRestored.Channels, ChannelGroups = subscriptionRestored.ChannelGroups, - Cursor = subscriptionRestored.Cursor + MaximumReconnectionRetries = this.MaximumReconnectionRetries, + ReconnectionPolicy = this.ReconnectionPolicy, + Cursor = subscriptionRestored.Cursor }, _ => null diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakingState.cs b/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakingState.cs index b09b0bfe8..ace9c6df9 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakingState.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakingState.cs @@ -23,15 +23,20 @@ public override TransitionResult Transition(IEvent e) { Events.SubscriptionChangedEvent subscriptionChanged => new States.HandshakingState() { - Channels = subscriptionChanged.Channels, ChannelGroups = subscriptionChanged.ChannelGroups - }, + Channels = subscriptionChanged.Channels, + ChannelGroups = subscriptionChanged.ChannelGroups, + MaximumReconnectionRetries = this.MaximumReconnectionRetries, + ReconnectionPolicy = this.ReconnectionPolicy + }, Events.SubscriptionRestoredEvent subscriptionRestored => new States.ReceivingState() { Channels = subscriptionRestored.Channels, ChannelGroups = subscriptionRestored.ChannelGroups, - Cursor = subscriptionRestored.Cursor - }, + Cursor = subscriptionRestored.Cursor, + MaximumReconnectionRetries = this.MaximumReconnectionRetries, + ReconnectionPolicy = this.ReconnectionPolicy + }, Events.HandshakeFailureEvent handshakeFailure => new States.HandshakeReconnectingState() { @@ -44,13 +49,20 @@ public override TransitionResult Transition(IEvent e) Events.DisconnectEvent disconnect => new States.HandshakeStoppedState() { - Channels = disconnect.Channels, ChannelGroups = disconnect.ChannelGroups, - }.With(new EmitStatusInvocation(PNStatusCategory.PNDisconnectedCategory)), + Channels = disconnect.Channels, + ChannelGroups = disconnect.ChannelGroups, + MaximumReconnectionRetries = this.MaximumReconnectionRetries, + ReconnectionPolicy = this.ReconnectionPolicy + }.With(new EmitStatusInvocation(PNStatusCategory.PNDisconnectedCategory)), Events.HandshakeSuccessEvent success => new ReceivingState() { - Channels = this.Channels, ChannelGroups = this.ChannelGroups, Cursor = success.Cursor - }.With(new EmitStatusInvocation(success.Status)), + Channels = this.Channels, + ChannelGroups = this.ChannelGroups, + Cursor = success.Cursor, + MaximumReconnectionRetries = this.MaximumReconnectionRetries, + ReconnectionPolicy = this.ReconnectionPolicy + }.With(new EmitStatusInvocation(success.Status)), _ => null }; diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveFailedState.cs b/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveFailedState.cs index d78dd819a..54435b43c 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveFailedState.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveFailedState.cs @@ -11,8 +11,10 @@ internal class ReceiveFailedState : Core.State public IEnumerable Channels; public IEnumerable ChannelGroups; public SubscriptionCursor Cursor; + public PNReconnectionPolicy ReconnectionPolicy; + public int MaximumReconnectionRetries; - public IEnumerable OnEntry { get; } + public IEnumerable OnEntry { get; } public IEnumerable OnExit { get; } public override TransitionResult Transition(IEvent e) @@ -23,22 +25,28 @@ public override TransitionResult Transition(IEvent e) { Channels = subscriptionChanged.Channels, ChannelGroups = subscriptionChanged.ChannelGroups, - Cursor = this.Cursor - }, + Cursor = this.Cursor, + MaximumReconnectionRetries = this.MaximumReconnectionRetries, + ReconnectionPolicy = this.ReconnectionPolicy + }, Events.ReconnectEvent reconnect => new ReceivingState() { Channels = reconnect.Channels, ChannelGroups = reconnect.ChannelGroups, - Cursor = reconnect.Cursor - }, + Cursor = reconnect.Cursor, + MaximumReconnectionRetries = this.MaximumReconnectionRetries, + ReconnectionPolicy = this.ReconnectionPolicy + }, Events.SubscriptionRestoredEvent subscriptionRestored => new ReceivingState() { Channels = subscriptionRestored.Channels, ChannelGroups = subscriptionRestored.ChannelGroups, - Cursor = subscriptionRestored.Cursor - }, + Cursor = subscriptionRestored.Cursor, + MaximumReconnectionRetries = this.MaximumReconnectionRetries, + ReconnectionPolicy = this.ReconnectionPolicy + }, _ => null }; diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveStoppedState.cs b/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveStoppedState.cs index 7be7a1462..e374cc583 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveStoppedState.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveStoppedState.cs @@ -11,8 +11,10 @@ internal class ReceiveStoppedState : Core.State public IEnumerable Channels; public IEnumerable ChannelGroups; public SubscriptionCursor Cursor; + public PNReconnectionPolicy ReconnectionPolicy; + public int MaximumReconnectionRetries; - public override TransitionResult Transition(IEvent e) + public override TransitionResult Transition(IEvent e) { return e switch { @@ -21,21 +23,27 @@ public override TransitionResult Transition(IEvent e) Channels = subscriptionChanged.Channels, ChannelGroups = subscriptionChanged.ChannelGroups, Cursor = this.Cursor, - }, + MaximumReconnectionRetries = this.MaximumReconnectionRetries, + ReconnectionPolicy = this.ReconnectionPolicy + }, Events.ReconnectEvent reconnect => new ReceivingState() { Channels = reconnect.Channels, ChannelGroups = reconnect.ChannelGroups, - Cursor = reconnect.Cursor - }, + Cursor = reconnect.Cursor, + MaximumReconnectionRetries = this.MaximumReconnectionRetries, + ReconnectionPolicy = this.ReconnectionPolicy + }, Events.SubscriptionRestoredEvent subscriptionRestored => new ReceivingState() { Channels = subscriptionRestored.Channels, ChannelGroups = subscriptionRestored.ChannelGroups, - Cursor = subscriptionRestored.Cursor - }, + Cursor = subscriptionRestored.Cursor, + MaximumReconnectionRetries = this.MaximumReconnectionRetries, + ReconnectionPolicy = this.ReconnectionPolicy + }, _ => null }; diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/States/UnsubscribedState.cs b/src/Api/PubnubApi/EventEngine/Subscribe/States/UnsubscribedState.cs index f1e9fc683..0210d8f12 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/States/UnsubscribedState.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/States/UnsubscribedState.cs @@ -7,21 +7,29 @@ namespace PubnubApi.EventEngine.Subscribe.States { internal class UnsubscribedState : Core.State { - public override TransitionResult Transition(Core.IEvent e) + public PNReconnectionPolicy ReconnectionPolicy; + public int MaximumReconnectionRetries; + + public override TransitionResult Transition(Core.IEvent e) { return e switch { Events.SubscriptionChangedEvent subscriptionChanged => new HandshakingState() { - Channels = subscriptionChanged.Channels, ChannelGroups = subscriptionChanged.ChannelGroups, - }, + Channels = subscriptionChanged.Channels, + ChannelGroups = subscriptionChanged.ChannelGroups, + MaximumReconnectionRetries = this.MaximumReconnectionRetries, + ReconnectionPolicy = this.ReconnectionPolicy + }, Events.SubscriptionRestoredEvent subscriptionRestored => new States.ReceivingState() { Channels = subscriptionRestored.Channels, ChannelGroups = subscriptionRestored.ChannelGroups, - Cursor = subscriptionRestored.Cursor - }, + Cursor = subscriptionRestored.Cursor, + MaximumReconnectionRetries = this.MaximumReconnectionRetries, + ReconnectionPolicy = this.ReconnectionPolicy + }, _ => null }; diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/SubscribeEventEngine.cs b/src/Api/PubnubApi/EventEngine/Subscribe/SubscribeEventEngine.cs index bbe6f6bb2..c1022b0f9 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/SubscribeEventEngine.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/SubscribeEventEngine.cs @@ -7,7 +7,8 @@ namespace PubnubApi.EventEngine.Subscribe { internal class SubscribeEventEngine : Engine { private SubscribeManager2 subscribeManager; - + + // TODO: Initialise reconnection related info here in ctor public SubscribeEventEngine(SubscribeManager2 subscribeManager) { this.subscribeManager = subscribeManager; From f8d19ee6c62524649fdfec88527f820b08c3634e Mon Sep 17 00:00:00 2001 From: Mohit Tejani Date: Mon, 24 Jul 2023 12:18:03 +0530 Subject: [PATCH 12/27] fix: transition values from receive reconnect --- .../EventEngine/Subscribe/Effects/ReceivingEffectHandler.cs | 4 ++-- .../EventEngine/Subscribe/States/ReceiveReconnectingState.cs | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/Effects/ReceivingEffectHandler.cs b/src/Api/PubnubApi/EventEngine/Subscribe/Effects/ReceivingEffectHandler.cs index ce4c469eb..9348694e9 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/Effects/ReceivingEffectHandler.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/Effects/ReceivingEffectHandler.cs @@ -31,13 +31,13 @@ public ReceivingEffectHandler(SubscribeManager2 manager, EventQueue eventQueue) public Task Run(ReceiveReconnectInvocation invocation) { - if (!ReconnectionDelayUtil.shouldRetry(invocation.Policy, invocation.AttemptedRetries, invocation.MaxConnectionRetry)) + if (!ReconnectionDelayUtil.shouldRetry(invocation.ReconnectionPolicy, invocation.AttemptedRetries, invocation.MaximumReconnectionRetries)) { eventQueue.Enqueue(new ReceiveReconnectGiveUpEvent() { Status = new PNStatus(PNStatusCategory.PNCancelledCategory) }); } else { - retryDelay = new Delay(ReconnectionDelayUtil.CalculateDelay(invocation.Policy, invocation.AttemptedRetries)); + retryDelay = new Delay(ReconnectionDelayUtil.CalculateDelay(invocation.ReconnectionPolicy, invocation.AttemptedRetries)); // Run in the background retryDelay.Start().ContinueWith((_) => this.Run((ReceiveMessagesInvocation)invocation)); } diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveReconnectingState.cs b/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveReconnectingState.cs index 96197fdac..d55b719a7 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveReconnectingState.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveReconnectingState.cs @@ -64,7 +64,10 @@ public override TransitionResult Transition(IEvent e) { Channels = this.Channels, ChannelGroups = this.ChannelGroups, - Cursor = this.Cursor + Cursor = this.Cursor, + AttemptedRetries = this.AttemptedRetries, + MaximumReconnectionRetries = this.MaximumReconnectionRetries, + ReconnectionPolicy = this.ReconnectionPolicy }.With(new EmitStatusInvocation(receiveReconnectFailure.Status)), Events.ReceiveReconnectGiveUpEvent receiveReconnectGiveUp => new ReceiveFailedState() From 0da6c9a314f7dcfddf6edadb89d8f7d31f8490f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Dobrza=C5=84ski?= Date: Mon, 24 Jul 2023 12:09:14 +0200 Subject: [PATCH 13/27] wip: receive messages --- .../EventEngine/Subscribe/Effects/ReceivingEffectHandler.cs | 2 +- .../EventEngine/Subscribe/Events/SubscriptionEvents.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/Effects/ReceivingEffectHandler.cs b/src/Api/PubnubApi/EventEngine/Subscribe/Effects/ReceivingEffectHandler.cs index ce4c469eb..642dfd1ae 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/Effects/ReceivingEffectHandler.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/Effects/ReceivingEffectHandler.cs @@ -67,7 +67,7 @@ public async Task Run(ReceiveMessagesInvocation invocation) break; case { }: //TODO: get messages - List> listOfMessages = null; + ReceivingResponse listOfMessages = null; eventQueue.Enqueue(new Events.ReceiveSuccessEvent() { Cursor = response.Item1, Messages= listOfMessages, Status = response.Item2 }); break; } diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/Events/SubscriptionEvents.cs b/src/Api/PubnubApi/EventEngine/Subscribe/Events/SubscriptionEvents.cs index 5dfa789f0..c8cf2810e 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/Events/SubscriptionEvents.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/Events/SubscriptionEvents.cs @@ -42,7 +42,7 @@ public class HandshakeReconnectGiveUpEvent : Core.IEvent { public class ReceiveSuccessEvent : Core.IEvent { public IEnumerable Channels; public IEnumerable ChannelGroups; - public List> Messages; + public ReceivingResponse Messages; public SubscriptionCursor Cursor; public PNStatus Status; } From 535c093c7d1d74d66f59deb0743947762c0a3d2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Dobrza=C5=84ski?= Date: Mon, 24 Jul 2023 12:32:18 +0200 Subject: [PATCH 14/27] Revert "Merge remote-tracking branch 'origin/eventengine/handshake-handler' into eventengine/handshake-handler" This reverts commit be568f7a1b1127151de3e56960539e1019d92bbd, reversing changes made to 0da6c9a314f7dcfddf6edadb89d8f7d31f8490f1. --- .../Effects/ReceivingEffectHandler.cs | 4 +- .../Invocations/SubscriptionInvocations.cs | 8 ++-- .../Subscribe/States/HandshakeFailedState.cs | 24 ++++------- .../States/HandshakeReconnectingState.cs | 6 +-- .../Subscribe/States/HandshakeStoppedState.cs | 24 ++++------- .../Subscribe/States/HandshakingState.cs | 40 +++++-------------- .../Subscribe/States/ReceiveFailedState.cs | 22 ++++------ .../States/ReceiveReconnectingState.cs | 19 ++------- .../Subscribe/States/ReceiveStoppedState.cs | 20 +++------- .../Subscribe/States/ReceivingState.cs | 9 +---- .../Subscribe/States/UnsubscribedState.cs | 18 +++------ .../Subscribe/SubscribeEventEngine.cs | 3 +- 12 files changed, 58 insertions(+), 139 deletions(-) diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/Effects/ReceivingEffectHandler.cs b/src/Api/PubnubApi/EventEngine/Subscribe/Effects/ReceivingEffectHandler.cs index 45b3b1a92..642dfd1ae 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/Effects/ReceivingEffectHandler.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/Effects/ReceivingEffectHandler.cs @@ -31,13 +31,13 @@ public ReceivingEffectHandler(SubscribeManager2 manager, EventQueue eventQueue) public Task Run(ReceiveReconnectInvocation invocation) { - if (!ReconnectionDelayUtil.shouldRetry(invocation.ReconnectionPolicy, invocation.AttemptedRetries, invocation.MaximumReconnectionRetries)) + if (!ReconnectionDelayUtil.shouldRetry(invocation.Policy, invocation.AttemptedRetries, invocation.MaxConnectionRetry)) { eventQueue.Enqueue(new ReceiveReconnectGiveUpEvent() { Status = new PNStatus(PNStatusCategory.PNCancelledCategory) }); } else { - retryDelay = new Delay(ReconnectionDelayUtil.CalculateDelay(invocation.ReconnectionPolicy, invocation.AttemptedRetries)); + retryDelay = new Delay(ReconnectionDelayUtil.CalculateDelay(invocation.Policy, invocation.AttemptedRetries)); // Run in the background retryDelay.Start().ContinueWith((_) => this.Run((ReceiveMessagesInvocation)invocation)); } diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/Invocations/SubscriptionInvocations.cs b/src/Api/PubnubApi/EventEngine/Subscribe/Invocations/SubscriptionInvocations.cs index 01ec91e66..bd6e771ea 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/Invocations/SubscriptionInvocations.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/Invocations/SubscriptionInvocations.cs @@ -56,8 +56,8 @@ internal class CancelHandshakeInvocation : HandshakeInvocation, Core.IEffectCanc internal class HandshakeReconnectInvocation: HandshakeInvocation { public int AttemptedRetries; - public int MaximumReconnectionRetries; - public PNReconnectionPolicy ReconnectionPolicy; + public int MaxConnectionRetry; + public PNReconnectionPolicy Policy; } internal class CancelHandshakeReconnectInvocation: HandshakeReconnectInvocation, Core.IEffectCancelInvocation { } @@ -65,8 +65,8 @@ internal class CancelHandshakeReconnectInvocation: HandshakeReconnectInvocation, internal class ReceiveReconnectInvocation: ReceiveMessagesInvocation { public int AttemptedRetries; - public int MaximumReconnectionRetries; - public PNReconnectionPolicy ReconnectionPolicy; + public int MaxConnectionRetry; + public PNReconnectionPolicy Policy; } internal class CancelReceiveReconnectInvocation: ReceiveReconnectInvocation, Core.IEffectCancelInvocation { } diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeFailedState.cs b/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeFailedState.cs index 91d10cb9d..694e49d30 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeFailedState.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeFailedState.cs @@ -9,37 +9,27 @@ internal class HandshakeFailedState : Core.State { public IEnumerable Channels; public IEnumerable ChannelGroups; - public PNReconnectionPolicy ReconnectionPolicy; - public int MaximumReconnectionRetries; - public override TransitionResult Transition(IEvent e) + public override TransitionResult Transition(IEvent e) { return e switch { Events.SubscriptionChangedEvent subscriptionChanged => new HandshakingState() { - Channels = subscriptionChanged.Channels, - ChannelGroups = subscriptionChanged.ChannelGroups, - MaximumReconnectionRetries = this.MaximumReconnectionRetries, - ReconnectionPolicy = this.ReconnectionPolicy - }, + Channels = subscriptionChanged.Channels, ChannelGroups = subscriptionChanged.ChannelGroups, + }, Events.ReconnectEvent reconnect => new HandshakingState() { - Channels = reconnect.Channels, - ChannelGroups = reconnect.ChannelGroups, - MaximumReconnectionRetries = this.MaximumReconnectionRetries, - ReconnectionPolicy = this.ReconnectionPolicy - }, + Channels = reconnect.Channels, ChannelGroups = reconnect.ChannelGroups, + }, Events.SubscriptionRestoredEvent subscriptionRestored => new ReceivingState() { Channels = subscriptionRestored.Channels, ChannelGroups = subscriptionRestored.ChannelGroups, - Cursor = subscriptionRestored.Cursor, - MaximumReconnectionRetries = this.MaximumReconnectionRetries, - ReconnectionPolicy = this.ReconnectionPolicy - }, + Cursor = subscriptionRestored.Cursor + }, _ => null }; diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeReconnectingState.cs b/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeReconnectingState.cs index da93f12b3..843380e34 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeReconnectingState.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeReconnectingState.cs @@ -9,13 +9,13 @@ internal class HandshakeReconnectingState : Core.State { public IEnumerable Channels; public IEnumerable ChannelGroups; - public PNReconnectionPolicy ReconnectionPolicy; - public int MaximumReconnectionRetries; + public PNReconnectionPolicy RetryPolicy; + public int MaxConnectionRetry; public int AttemptedRetries; public override IEnumerable OnEntry => new HandshakeReconnectInvocation() - { Channels = this.Channels, ChannelGroups = this.ChannelGroups, ReconnectionPolicy = this.ReconnectionPolicy, MaximumReconnectionRetries = this.MaximumReconnectionRetries, AttemptedRetries = this.AttemptedRetries }.AsArray(); + { Channels = this.Channels, ChannelGroups = this.ChannelGroups, Policy = this.RetryPolicy, MaxConnectionRetry = this.MaxConnectionRetry, AttemptedRetries = this.AttemptedRetries }.AsArray(); public override IEnumerable OnExit { get; } = new CancelHandshakeReconnectInvocation().AsArray(); public override TransitionResult Transition(IEvent e) diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeStoppedState.cs b/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeStoppedState.cs index a997af4ae..152c3ca0a 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeStoppedState.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakeStoppedState.cs @@ -9,36 +9,26 @@ internal class HandshakeStoppedState : Core.State { public IEnumerable Channels; public IEnumerable ChannelGroups; - public PNReconnectionPolicy ReconnectionPolicy; - public int MaximumReconnectionRetries; - - public override TransitionResult Transition(IEvent e) + + public override TransitionResult Transition(IEvent e) { return e switch { Events.SubscriptionChangedEvent subscriptionChanged => new HandshakingState() { - Channels = subscriptionChanged.Channels, - ChannelGroups = subscriptionChanged.ChannelGroups, - MaximumReconnectionRetries = this.MaximumReconnectionRetries, - ReconnectionPolicy = this.ReconnectionPolicy - }, + Channels = subscriptionChanged.Channels, ChannelGroups = subscriptionChanged.ChannelGroups, + }, Events.ReconnectEvent reconnect => new HandshakingState() { - Channels = reconnect.Channels, - ChannelGroups = reconnect.ChannelGroups, - MaximumReconnectionRetries = this.MaximumReconnectionRetries, - ReconnectionPolicy = this.ReconnectionPolicy - }, + Channels = reconnect.Channels, ChannelGroups = reconnect.ChannelGroups, + }, Events.SubscriptionRestoredEvent subscriptionRestored => new ReceivingState() { Channels = subscriptionRestored.Channels, ChannelGroups = subscriptionRestored.ChannelGroups, - MaximumReconnectionRetries = this.MaximumReconnectionRetries, - ReconnectionPolicy = this.ReconnectionPolicy, - Cursor = subscriptionRestored.Cursor + Cursor = subscriptionRestored.Cursor }, _ => null diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakingState.cs b/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakingState.cs index ace9c6df9..9fde00f99 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakingState.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/States/HandshakingState.cs @@ -9,10 +9,8 @@ internal class HandshakingState : Core.State { public IEnumerable Channels; public IEnumerable ChannelGroups; - public PNReconnectionPolicy ReconnectionPolicy; - public int MaximumReconnectionRetries; - public override IEnumerable OnEntry => new HandshakeInvocation() + public override IEnumerable OnEntry => new HandshakeInvocation() { Channels = this.Channels, ChannelGroups = this.ChannelGroups }.AsArray(); public override IEnumerable OnExit { get; } = new CancelHandshakeInvocation().AsArray(); @@ -23,46 +21,30 @@ public override TransitionResult Transition(IEvent e) { Events.SubscriptionChangedEvent subscriptionChanged => new States.HandshakingState() { - Channels = subscriptionChanged.Channels, - ChannelGroups = subscriptionChanged.ChannelGroups, - MaximumReconnectionRetries = this.MaximumReconnectionRetries, - ReconnectionPolicy = this.ReconnectionPolicy - }, + Channels = subscriptionChanged.Channels, ChannelGroups = subscriptionChanged.ChannelGroups + }, Events.SubscriptionRestoredEvent subscriptionRestored => new States.ReceivingState() { Channels = subscriptionRestored.Channels, ChannelGroups = subscriptionRestored.ChannelGroups, - Cursor = subscriptionRestored.Cursor, - MaximumReconnectionRetries = this.MaximumReconnectionRetries, - ReconnectionPolicy = this.ReconnectionPolicy - }, + Cursor = subscriptionRestored.Cursor + }, Events.HandshakeFailureEvent handshakeFailure => new States.HandshakeReconnectingState() { - Channels = this.Channels, - ChannelGroups = this.ChannelGroups, - AttemptedRetries = 0, - MaximumReconnectionRetries = this.MaximumReconnectionRetries, - ReconnectionPolicy = this.ReconnectionPolicy - }.With(new EmitStatusInvocation(handshakeFailure.Status)), + Channels = this.Channels, ChannelGroups = this.ChannelGroups + }.With(new EmitStatusInvocation(handshakeFailure.Status)), Events.DisconnectEvent disconnect => new States.HandshakeStoppedState() { - Channels = disconnect.Channels, - ChannelGroups = disconnect.ChannelGroups, - MaximumReconnectionRetries = this.MaximumReconnectionRetries, - ReconnectionPolicy = this.ReconnectionPolicy - }.With(new EmitStatusInvocation(PNStatusCategory.PNDisconnectedCategory)), + Channels = disconnect.Channels, ChannelGroups = disconnect.ChannelGroups, + }.With(new EmitStatusInvocation(PNStatusCategory.PNDisconnectedCategory)), Events.HandshakeSuccessEvent success => new ReceivingState() { - Channels = this.Channels, - ChannelGroups = this.ChannelGroups, - Cursor = success.Cursor, - MaximumReconnectionRetries = this.MaximumReconnectionRetries, - ReconnectionPolicy = this.ReconnectionPolicy - }.With(new EmitStatusInvocation(success.Status)), + Channels = this.Channels, ChannelGroups = this.ChannelGroups, Cursor = success.Cursor + }.With(new EmitStatusInvocation(success.Status)), _ => null }; diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveFailedState.cs b/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveFailedState.cs index 54435b43c..d78dd819a 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveFailedState.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveFailedState.cs @@ -11,10 +11,8 @@ internal class ReceiveFailedState : Core.State public IEnumerable Channels; public IEnumerable ChannelGroups; public SubscriptionCursor Cursor; - public PNReconnectionPolicy ReconnectionPolicy; - public int MaximumReconnectionRetries; - public IEnumerable OnEntry { get; } + public IEnumerable OnEntry { get; } public IEnumerable OnExit { get; } public override TransitionResult Transition(IEvent e) @@ -25,28 +23,22 @@ public override TransitionResult Transition(IEvent e) { Channels = subscriptionChanged.Channels, ChannelGroups = subscriptionChanged.ChannelGroups, - Cursor = this.Cursor, - MaximumReconnectionRetries = this.MaximumReconnectionRetries, - ReconnectionPolicy = this.ReconnectionPolicy - }, + Cursor = this.Cursor + }, Events.ReconnectEvent reconnect => new ReceivingState() { Channels = reconnect.Channels, ChannelGroups = reconnect.ChannelGroups, - Cursor = reconnect.Cursor, - MaximumReconnectionRetries = this.MaximumReconnectionRetries, - ReconnectionPolicy = this.ReconnectionPolicy - }, + Cursor = reconnect.Cursor + }, Events.SubscriptionRestoredEvent subscriptionRestored => new ReceivingState() { Channels = subscriptionRestored.Channels, ChannelGroups = subscriptionRestored.ChannelGroups, - Cursor = subscriptionRestored.Cursor, - MaximumReconnectionRetries = this.MaximumReconnectionRetries, - ReconnectionPolicy = this.ReconnectionPolicy - }, + Cursor = subscriptionRestored.Cursor + }, _ => null }; diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveReconnectingState.cs b/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveReconnectingState.cs index d55b719a7..ded0cec4b 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveReconnectingState.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveReconnectingState.cs @@ -10,20 +10,10 @@ internal class ReceiveReconnectingState : Core.State { public IEnumerable Channels; public IEnumerable ChannelGroups; - public PNReconnectionPolicy ReconnectionPolicy; - public int MaximumReconnectionRetries; - public int AttemptedRetries; - public SubscriptionCursor Cursor; + public SubscriptionCursor Cursor; public override IEnumerable OnEntry => new ReceiveReconnectInvocation() - { - Channels = this.Channels, - ChannelGroups = this.ChannelGroups, - Cursor = this.Cursor, - ReconnectionPolicy = this.ReconnectionPolicy, - MaximumReconnectionRetries = this.MaximumReconnectionRetries, - AttemptedRetries = this.AttemptedRetries - }.AsArray(); + { Channels = this.Channels, ChannelGroups = this.ChannelGroups, Cursor = this.Cursor }.AsArray(); public override IEnumerable OnExit { get; } = new CancelReceiveReconnectInvocation().AsArray(); @@ -64,10 +54,7 @@ public override TransitionResult Transition(IEvent e) { Channels = this.Channels, ChannelGroups = this.ChannelGroups, - Cursor = this.Cursor, - AttemptedRetries = this.AttemptedRetries, - MaximumReconnectionRetries = this.MaximumReconnectionRetries, - ReconnectionPolicy = this.ReconnectionPolicy + Cursor = this.Cursor }.With(new EmitStatusInvocation(receiveReconnectFailure.Status)), Events.ReceiveReconnectGiveUpEvent receiveReconnectGiveUp => new ReceiveFailedState() diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveStoppedState.cs b/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveStoppedState.cs index e374cc583..7be7a1462 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveStoppedState.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceiveStoppedState.cs @@ -11,10 +11,8 @@ internal class ReceiveStoppedState : Core.State public IEnumerable Channels; public IEnumerable ChannelGroups; public SubscriptionCursor Cursor; - public PNReconnectionPolicy ReconnectionPolicy; - public int MaximumReconnectionRetries; - public override TransitionResult Transition(IEvent e) + public override TransitionResult Transition(IEvent e) { return e switch { @@ -23,27 +21,21 @@ public override TransitionResult Transition(IEvent e) Channels = subscriptionChanged.Channels, ChannelGroups = subscriptionChanged.ChannelGroups, Cursor = this.Cursor, - MaximumReconnectionRetries = this.MaximumReconnectionRetries, - ReconnectionPolicy = this.ReconnectionPolicy - }, + }, Events.ReconnectEvent reconnect => new ReceivingState() { Channels = reconnect.Channels, ChannelGroups = reconnect.ChannelGroups, - Cursor = reconnect.Cursor, - MaximumReconnectionRetries = this.MaximumReconnectionRetries, - ReconnectionPolicy = this.ReconnectionPolicy - }, + Cursor = reconnect.Cursor + }, Events.SubscriptionRestoredEvent subscriptionRestored => new ReceivingState() { Channels = subscriptionRestored.Channels, ChannelGroups = subscriptionRestored.ChannelGroups, - Cursor = subscriptionRestored.Cursor, - MaximumReconnectionRetries = this.MaximumReconnectionRetries, - ReconnectionPolicy = this.ReconnectionPolicy - }, + Cursor = subscriptionRestored.Cursor + }, _ => null }; diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceivingState.cs b/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceivingState.cs index c4767909d..e7f52c857 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceivingState.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/States/ReceivingState.cs @@ -10,9 +10,7 @@ internal class ReceivingState : Core.State { public IEnumerable Channels; public IEnumerable ChannelGroups; - public PNReconnectionPolicy ReconnectionPolicy; - public int MaximumReconnectionRetries; - public SubscriptionCursor Cursor; + public SubscriptionCursor Cursor; public override IEnumerable OnEntry => new ReceiveMessagesInvocation() { Channels = this.Channels, ChannelGroups = this.ChannelGroups, Cursor = this.Cursor }.AsArray(); @@ -58,10 +56,7 @@ public override TransitionResult Transition(IEvent e) { Channels = this.Channels, ChannelGroups = this.ChannelGroups, - AttemptedRetries = 0, - MaximumReconnectionRetries = this.MaximumReconnectionRetries, - ReconnectionPolicy = this.ReconnectionPolicy, - Cursor = this.Cursor + Cursor = this.Cursor }, _ => null diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/States/UnsubscribedState.cs b/src/Api/PubnubApi/EventEngine/Subscribe/States/UnsubscribedState.cs index 0210d8f12..f1e9fc683 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/States/UnsubscribedState.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/States/UnsubscribedState.cs @@ -7,29 +7,21 @@ namespace PubnubApi.EventEngine.Subscribe.States { internal class UnsubscribedState : Core.State { - public PNReconnectionPolicy ReconnectionPolicy; - public int MaximumReconnectionRetries; - - public override TransitionResult Transition(Core.IEvent e) + public override TransitionResult Transition(Core.IEvent e) { return e switch { Events.SubscriptionChangedEvent subscriptionChanged => new HandshakingState() { - Channels = subscriptionChanged.Channels, - ChannelGroups = subscriptionChanged.ChannelGroups, - MaximumReconnectionRetries = this.MaximumReconnectionRetries, - ReconnectionPolicy = this.ReconnectionPolicy - }, + Channels = subscriptionChanged.Channels, ChannelGroups = subscriptionChanged.ChannelGroups, + }, Events.SubscriptionRestoredEvent subscriptionRestored => new States.ReceivingState() { Channels = subscriptionRestored.Channels, ChannelGroups = subscriptionRestored.ChannelGroups, - Cursor = subscriptionRestored.Cursor, - MaximumReconnectionRetries = this.MaximumReconnectionRetries, - ReconnectionPolicy = this.ReconnectionPolicy - }, + Cursor = subscriptionRestored.Cursor + }, _ => null }; diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/SubscribeEventEngine.cs b/src/Api/PubnubApi/EventEngine/Subscribe/SubscribeEventEngine.cs index c1022b0f9..bbe6f6bb2 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/SubscribeEventEngine.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/SubscribeEventEngine.cs @@ -7,8 +7,7 @@ namespace PubnubApi.EventEngine.Subscribe { internal class SubscribeEventEngine : Engine { private SubscribeManager2 subscribeManager; - - // TODO: Initialise reconnection related info here in ctor + public SubscribeEventEngine(SubscribeManager2 subscribeManager) { this.subscribeManager = subscribeManager; From 5aae31581054c750592e77df252edfd3c8968a17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Dobrza=C5=84ski?= Date: Mon, 24 Jul 2023 12:38:50 +0200 Subject: [PATCH 15/27] fix --- .../Subscribe/Invocations/SubscriptionInvocations.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/Invocations/SubscriptionInvocations.cs b/src/Api/PubnubApi/EventEngine/Subscribe/Invocations/SubscriptionInvocations.cs index bd6e771ea..d585580f9 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/Invocations/SubscriptionInvocations.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/Invocations/SubscriptionInvocations.cs @@ -4,9 +4,9 @@ namespace PubnubApi.EventEngine.Subscribe.Invocations { internal class EmitMessagesInvocation : Core.IEffectInvocation { - public IEnumerable> Messages; + public ReceivingResponse Messages; - public EmitMessagesInvocation(IEnumerable> messages) + public EmitMessagesInvocation(ReceivingResponse messages) { this.Messages = messages; } From fca3791e95bdecfc2dedebd1120270eff84ad98a Mon Sep 17 00:00:00 2001 From: Pandu Masabathula Date: Mon, 24 Jul 2023 16:30:01 +0530 Subject: [PATCH 16/27] ReceivingEffectHandler - ReceivingResponse --- .../Effects/ReceivingEffectHandler.cs | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/Effects/ReceivingEffectHandler.cs b/src/Api/PubnubApi/EventEngine/Subscribe/Effects/ReceivingEffectHandler.cs index 642dfd1ae..1b091fbb1 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/Effects/ReceivingEffectHandler.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/Effects/ReceivingEffectHandler.cs @@ -53,6 +53,11 @@ public bool IsBackground(ReceiveReconnectInvocation invocation) public async Task Run(ReceiveMessagesInvocation invocation) { var response = await MakeReceiveMessagesRequest(invocation); + var cursor = new SubscriptionCursor() + { + Region = response.Item1.Timetoken.Region, + Timetoken = response.Item1.Timetoken.Timestamp + }; switch (invocation) { @@ -60,15 +65,13 @@ public async Task Run(ReceiveMessagesInvocation invocation) eventQueue.Enqueue(new Events.ReceiveReconnectFailureEvent() { AttemptedRetries = reconnectInvocation.AttemptedRetries + 1, Status = response.Item2}); break; case Invocations.ReceiveReconnectInvocation reconnectInvocation: - eventQueue.Enqueue(new Events.ReceiveReconnectSuccessEvent() { Cursor = response.Item1, Status = response.Item2 }); + eventQueue.Enqueue(new Events.ReceiveReconnectSuccessEvent() { Cursor = cursor, Status = response.Item2 }); break; case { } when response.Item2.Error: - eventQueue.Enqueue(new Events.ReceiveFailureEvent() { Cursor = response.Item1, Status = response.Item2}); + eventQueue.Enqueue(new Events.ReceiveFailureEvent() { Cursor = cursor, Status = response.Item2}); break; case { }: - //TODO: get messages - ReceivingResponse listOfMessages = null; - eventQueue.Enqueue(new Events.ReceiveSuccessEvent() { Cursor = response.Item1, Messages= listOfMessages, Status = response.Item2 }); + eventQueue.Enqueue(new Events.ReceiveSuccessEvent() { Cursor = cursor, Messages= response.Item1, Status = response.Item2 }); break; } } @@ -78,7 +81,7 @@ public bool IsBackground(ReceiveMessagesInvocation invocation) return true; } - private async Task> MakeReceiveMessagesRequest(ReceiveMessagesInvocation invocation) + private async Task, PNStatus>> MakeReceiveMessagesRequest(ReceiveMessagesInvocation invocation) { var resp = await manager.ReceiveRequest( PNOperationType.PNSubscribeOperation, @@ -94,16 +97,11 @@ public bool IsBackground(ReceiveMessagesInvocation invocation) { //TODO: get ReceivingResponse from manager.ReceiveRequest var receiveResponse = JsonConvert.DeserializeObject>(resp.Item1); - var c = new SubscriptionCursor() - { - Region = receiveResponse.Timetoken.Region, - Timetoken = receiveResponse.Timetoken.Timestamp - }; - return new System.Tuple(c, resp.Item2); + return new System.Tuple, PNStatus>(receiveResponse, resp.Item2); } catch (Exception e) { - return new Tuple(null, new PNStatus(e, PNOperationType.PNSubscribeOperation, PNStatusCategory.PNUnknownCategory, invocation.Channels, invocation.ChannelGroups)); + return new Tuple, PNStatus>(null, new PNStatus(e, PNOperationType.PNSubscribeOperation, PNStatusCategory.PNUnknownCategory, invocation.Channels, invocation.ChannelGroups)); } } From c36afc1599e0f0b3bdb44afb1ab236be46cfde23 Mon Sep 17 00:00:00 2001 From: Pandu Masabathula Date: Mon, 24 Jul 2023 16:35:51 +0530 Subject: [PATCH 17/27] null check --- .../EventEngine/Subscribe/Effects/ReceivingEffectHandler.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/Effects/ReceivingEffectHandler.cs b/src/Api/PubnubApi/EventEngine/Subscribe/Effects/ReceivingEffectHandler.cs index 1b091fbb1..d80cf0b3a 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/Effects/ReceivingEffectHandler.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/Effects/ReceivingEffectHandler.cs @@ -55,8 +55,8 @@ public async Task Run(ReceiveMessagesInvocation invocation) var response = await MakeReceiveMessagesRequest(invocation); var cursor = new SubscriptionCursor() { - Region = response.Item1.Timetoken.Region, - Timetoken = response.Item1.Timetoken.Timestamp + Region = response.Item1?.Timetoken.Region, + Timetoken = response.Item1?.Timetoken.Timestamp }; switch (invocation) From 74fea9343420281e0ad57ca5a5cea27d389fa760 Mon Sep 17 00:00:00 2001 From: Pandu Masabathula Date: Mon, 24 Jul 2023 18:58:28 +0530 Subject: [PATCH 18/27] SubscribeEventEngine - receiveHandler --- .../PubnubApi/EventEngine/Subscribe/SubscribeEventEngine.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/SubscribeEventEngine.cs b/src/Api/PubnubApi/EventEngine/Subscribe/SubscribeEventEngine.cs index bbe6f6bb2..862fb5819 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/SubscribeEventEngine.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/SubscribeEventEngine.cs @@ -17,6 +17,11 @@ public SubscribeEventEngine(SubscribeManager2 subscribeManager) { dispatcher.Register(handshakeHandler); dispatcher.Register(handshakeHandler); + var receiveHandler = new Effects.ReceivingEffectHandler(subscribeManager, eventQueue); + dispatcher.Register(receiveHandler); + dispatcher.Register(receiveHandler); + dispatcher.Register(receiveHandler); + currentState = new UnsubscribedState(); } } From ff2b976361bed6848b84d5b97303a85ed3ad1290 Mon Sep 17 00:00:00 2001 From: Pandu Masabathula Date: Mon, 24 Jul 2023 19:00:14 +0530 Subject: [PATCH 19/27] *csproj file for RReceivingEffectHandler --- src/Api/PubnubApiPCL/PubnubApiPCL.csproj | 1 + src/Api/PubnubApiUWP/PubnubApiUWP.csproj | 1 + 2 files changed, 2 insertions(+) diff --git a/src/Api/PubnubApiPCL/PubnubApiPCL.csproj b/src/Api/PubnubApiPCL/PubnubApiPCL.csproj index f54f1d88b..356a8f73b 100644 --- a/src/Api/PubnubApiPCL/PubnubApiPCL.csproj +++ b/src/Api/PubnubApiPCL/PubnubApiPCL.csproj @@ -232,6 +232,7 @@ + diff --git a/src/Api/PubnubApiUWP/PubnubApiUWP.csproj b/src/Api/PubnubApiUWP/PubnubApiUWP.csproj index 950e317ee..00800be1c 100644 --- a/src/Api/PubnubApiUWP/PubnubApiUWP.csproj +++ b/src/Api/PubnubApiUWP/PubnubApiUWP.csproj @@ -349,6 +349,7 @@ + From e5367b60dc2bc95b0e6879dc0e93aface0bcda94 Mon Sep 17 00:00:00 2001 From: Mohit Tejani Date: Tue, 25 Jul 2023 12:57:02 +0530 Subject: [PATCH 20/27] EmitStatus effect handler - take1 --- .../Effects/EmitStatusEffectHandler.cs | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 src/Api/PubnubApi/EventEngine/Subscribe/Effects/EmitStatusEffectHandler.cs diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/Effects/EmitStatusEffectHandler.cs b/src/Api/PubnubApi/EventEngine/Subscribe/Effects/EmitStatusEffectHandler.cs new file mode 100644 index 000000000..cea3df435 --- /dev/null +++ b/src/Api/PubnubApi/EventEngine/Subscribe/Effects/EmitStatusEffectHandler.cs @@ -0,0 +1,39 @@ +using System; +using System.Threading.Tasks; +using PubnubApi.EventEngine.Core; +using PubnubApi.EventEngine.Subscribe.Invocations; + +namespace PubnubApi.EventEngine.Subscribe.Effects +{ + public class EmitStatusEffectHandler: Core.IEffectHandler + { + public delegate void EmitStatusFunction(Pubnub PnReference, PNStatus status); + + public EmitStatusFunction StatusEmitter; + + public Pubnub PnReference; + + public EmitStatusEffectHandler(Pubnub pn, Action statusAction) + { + this.StatusEmitter = new EmitStatusFunction(statusAction); + this.PnReference = pn; + } + + public Task Cancel() + { + return Task.FromResult(0); + } + + bool IEffectHandler.IsBackground(EmitStatusInvocation invocation) + { + return false; + } + + Task IEffectHandler.Run(EmitStatusInvocation invocation) + { + this.StatusEmitter(this.PnReference, invocation.Status); + return Task.FromResult(0); + } + } +} + From aa873c45ffc78301916b15847a62619ad201de0a Mon Sep 17 00:00:00 2001 From: Mohit Tejani Date: Tue, 25 Jul 2023 13:08:53 +0530 Subject: [PATCH 21/27] empty task --- .../EventEngine/Subscribe/Effects/EmitStatusEffectHandler.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/Effects/EmitStatusEffectHandler.cs b/src/Api/PubnubApi/EventEngine/Subscribe/Effects/EmitStatusEffectHandler.cs index cea3df435..15161e64f 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/Effects/EmitStatusEffectHandler.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/Effects/EmitStatusEffectHandler.cs @@ -21,7 +21,7 @@ public EmitStatusEffectHandler(Pubnub pn, Action statusAction) public Task Cancel() { - return Task.FromResult(0); + return Utils.EmptyTask; } bool IEffectHandler.IsBackground(EmitStatusInvocation invocation) @@ -32,7 +32,7 @@ bool IEffectHandler.IsBackground(EmitStatusInvocation invo Task IEffectHandler.Run(EmitStatusInvocation invocation) { this.StatusEmitter(this.PnReference, invocation.Status); - return Task.FromResult(0); + return Utils.EmptyTask; } } } From 73abf600553e8fe4a1907d8518fc729de410dfda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Dobrza=C5=84ski?= Date: Tue, 25 Jul 2023 10:00:44 +0200 Subject: [PATCH 22/27] wip emit messages --- .../Subscribe/Common/CommonSubscribeTypes.cs | 7 ++- .../Subscribe/Effects/EmitMessagesHandler.cs | 56 +++++++++++++++++++ 2 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 src/Api/PubnubApi/EventEngine/Subscribe/Effects/EmitMessagesHandler.cs diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/Common/CommonSubscribeTypes.cs b/src/Api/PubnubApi/EventEngine/Subscribe/Common/CommonSubscribeTypes.cs index 3dd44c938..e8d0338ec 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/Common/CommonSubscribeTypes.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/Common/CommonSubscribeTypes.cs @@ -28,10 +28,10 @@ public class HandshakeError public class Timetoken { [JsonProperty("t")] - public long? Timestamp { get; set; } + public long Timestamp { get; set; } [JsonProperty("r")] - public int? Region { get; set; } + public int Region { get; set; } } @@ -78,5 +78,8 @@ public class Message [JsonProperty("s")] public long SequenceNumber { get; set; } + + [JsonProperty("p")] + public Timetoken Timetoken { get; set; } } } \ No newline at end of file diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/Effects/EmitMessagesHandler.cs b/src/Api/PubnubApi/EventEngine/Subscribe/Effects/EmitMessagesHandler.cs new file mode 100644 index 000000000..c4a4c8968 --- /dev/null +++ b/src/Api/PubnubApi/EventEngine/Subscribe/Effects/EmitMessagesHandler.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Newtonsoft.Json; +using PubnubApi.EndPoint; +using PubnubApi.EventEngine.Common; +using PubnubApi.EventEngine.Core; +using PubnubApi.EventEngine.Subscribe.Context; +using PubnubApi.EventEngine.Subscribe.Events; +using PubnubApi.EventEngine.Subscribe.Invocations; +using PubnubApi.EventEngine.Subscribe.Common; + +namespace PubnubApi.EventEngine.Subscribe.Effects +{ + internal class EmitMessagesHandler : IEffectHandler + { + private System.Action> messageEmitterFunction; + private Pubnub pubnubInstance; + + //Message(Pubnub pubnub, PNMessageResult message) + public EmitMessagesHandler(Pubnub pubnubInstance, + System.Action> messageEmitterFunction) + { + this.messageEmitterFunction = messageEmitterFunction; + this.pubnubInstance = pubnubInstance; + } + + public async Task Run(EmitMessagesInvocation invocation) + { + var processedMessages = invocation.Messages.Messages.Select(m => new PNMessageResult() + { + // TODO is this ok? :) + Channel = m.Channel, + Message = JsonConvert.DeserializeObject(m.Payload), + Subscription = m.SubscriptionMatch, // ?? + Timetoken = m.Timetoken.Timestamp, + UserMetadata = m.PublishMetadata, + // Publisher = ?? + }); + + foreach (var message in processedMessages) + { + messageEmitterFunction(pubnubInstance, message); + } + } + + public bool IsBackground(EmitMessagesInvocation invocation) => false; + + public Task Cancel() + { + throw new NotImplementedException(); + } + } +} \ No newline at end of file From ac49b569968a5a81581c2b852b89564e22b125a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Dobrza=C5=84ski?= Date: Tue, 25 Jul 2023 10:11:48 +0200 Subject: [PATCH 23/27] wip emit messages --- .../Subscribe/Effects/EmitMessagesHandler.cs | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/Effects/EmitMessagesHandler.cs b/src/Api/PubnubApi/EventEngine/Subscribe/Effects/EmitMessagesHandler.cs index c4a4c8968..72cfbac7c 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/Effects/EmitMessagesHandler.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/Effects/EmitMessagesHandler.cs @@ -1,25 +1,17 @@ using System; -using System.Collections.Generic; using System.Linq; -using System.Threading; using System.Threading.Tasks; using Newtonsoft.Json; -using PubnubApi.EndPoint; -using PubnubApi.EventEngine.Common; using PubnubApi.EventEngine.Core; -using PubnubApi.EventEngine.Subscribe.Context; -using PubnubApi.EventEngine.Subscribe.Events; using PubnubApi.EventEngine.Subscribe.Invocations; -using PubnubApi.EventEngine.Subscribe.Common; namespace PubnubApi.EventEngine.Subscribe.Effects { internal class EmitMessagesHandler : IEffectHandler { - private System.Action> messageEmitterFunction; - private Pubnub pubnubInstance; - - //Message(Pubnub pubnub, PNMessageResult message) + private readonly System.Action> messageEmitterFunction; + private readonly Pubnub pubnubInstance; + public EmitMessagesHandler(Pubnub pubnubInstance, System.Action> messageEmitterFunction) { From b7475ac304261b90c9f90704e2bc78b02dd32e25 Mon Sep 17 00:00:00 2001 From: Mohit Tejani Date: Tue, 25 Jul 2023 13:49:38 +0530 Subject: [PATCH 24/27] cleanup and unify convention for *emitters --- .../Effects/EmitStatusEffectHandler.cs | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/Effects/EmitStatusEffectHandler.cs b/src/Api/PubnubApi/EventEngine/Subscribe/Effects/EmitStatusEffectHandler.cs index 15161e64f..d3fc32f91 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/Effects/EmitStatusEffectHandler.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/Effects/EmitStatusEffectHandler.cs @@ -7,31 +7,24 @@ namespace PubnubApi.EventEngine.Subscribe.Effects { public class EmitStatusEffectHandler: Core.IEffectHandler { - public delegate void EmitStatusFunction(Pubnub PnReference, PNStatus status); - - public EmitStatusFunction StatusEmitter; + private readonly Action statusEmitterFunction; + private readonly Pubnub pubnubInstance; public Pubnub PnReference; - public EmitStatusEffectHandler(Pubnub pn, Action statusAction) + public EmitStatusEffectHandler(Pubnub pn, Action statusEmitter) { - this.StatusEmitter = new EmitStatusFunction(statusAction); + this.statusEmitterFunction = statusEmitter; this.PnReference = pn; } - public Task Cancel() - { - return Utils.EmptyTask; - } + public Task Cancel() => Utils.EmptyTask; - bool IEffectHandler.IsBackground(EmitStatusInvocation invocation) - { - return false; - } + bool IEffectHandler.IsBackground(EmitStatusInvocation invocation) => false; Task IEffectHandler.Run(EmitStatusInvocation invocation) { - this.StatusEmitter(this.PnReference, invocation.Status); + this.statusEmitterFunction(this.PnReference, invocation.Status); return Utils.EmptyTask; } } From 724ef741f05f8177fa305762713f12699184c6c1 Mon Sep 17 00:00:00 2001 From: Mohit Tejani Date: Tue, 25 Jul 2023 14:02:39 +0530 Subject: [PATCH 25/27] missing changes emitmessage --- .../Subscribe/Effects/EmitStatusEffectHandler.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/Effects/EmitStatusEffectHandler.cs b/src/Api/PubnubApi/EventEngine/Subscribe/Effects/EmitStatusEffectHandler.cs index d3fc32f91..e52ecae06 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/Effects/EmitStatusEffectHandler.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/Effects/EmitStatusEffectHandler.cs @@ -10,12 +10,10 @@ public class EmitStatusEffectHandler: Core.IEffectHandler private readonly Action statusEmitterFunction; private readonly Pubnub pubnubInstance; - public Pubnub PnReference; - public EmitStatusEffectHandler(Pubnub pn, Action statusEmitter) { this.statusEmitterFunction = statusEmitter; - this.PnReference = pn; + this.pubnubInstance = pn; } public Task Cancel() => Utils.EmptyTask; @@ -24,7 +22,7 @@ public EmitStatusEffectHandler(Pubnub pn, Action statusEmitter Task IEffectHandler.Run(EmitStatusInvocation invocation) { - this.statusEmitterFunction(this.PnReference, invocation.Status); + this.statusEmitterFunction(this.pubnubInstance, invocation.Status); return Utils.EmptyTask; } } From 63982f390c9d2df65812ecd0af15030f45cf87b4 Mon Sep 17 00:00:00 2001 From: Pandu Masabathula Date: Tue, 25 Jul 2023 14:57:56 +0530 Subject: [PATCH 26/27] Added publisher --- .../EventEngine/Subscribe/Common/CommonSubscribeTypes.cs | 4 ++-- .../EventEngine/Subscribe/Effects/EmitMessagesHandler.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/Common/CommonSubscribeTypes.cs b/src/Api/PubnubApi/EventEngine/Subscribe/Common/CommonSubscribeTypes.cs index e8d0338ec..19157d716 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/Common/CommonSubscribeTypes.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/Common/CommonSubscribeTypes.cs @@ -64,8 +64,8 @@ public class Message [JsonProperty("f")] public string Flags { get; set; } - //[JsonProperty("i")] - //public string IssuingClientId { get; set; } + [JsonProperty("i")] + public string IssuingClientId { get; set; } [JsonProperty("k")] public string SubscribeKey { get; set; } diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/Effects/EmitMessagesHandler.cs b/src/Api/PubnubApi/EventEngine/Subscribe/Effects/EmitMessagesHandler.cs index 72cfbac7c..c52b6dc66 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/Effects/EmitMessagesHandler.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/Effects/EmitMessagesHandler.cs @@ -26,10 +26,10 @@ public async Task Run(EmitMessagesInvocation invocation) // TODO is this ok? :) Channel = m.Channel, Message = JsonConvert.DeserializeObject(m.Payload), - Subscription = m.SubscriptionMatch, // ?? + Subscription = m.SubscriptionMatch, // This is channel group Timetoken = m.Timetoken.Timestamp, UserMetadata = m.PublishMetadata, - // Publisher = ?? + Publisher = m.IssuingClientId }); foreach (var message in processedMessages) From 345400861ccb3b24bbc046431442e74e55e5a762 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Dobrza=C5=84ski?= Date: Tue, 25 Jul 2023 11:36:19 +0200 Subject: [PATCH 27/27] emitmessages --- .../EventEngine/Subscribe/Effects/EmitMessagesHandler.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Api/PubnubApi/EventEngine/Subscribe/Effects/EmitMessagesHandler.cs b/src/Api/PubnubApi/EventEngine/Subscribe/Effects/EmitMessagesHandler.cs index c52b6dc66..77c7e1eb8 100644 --- a/src/Api/PubnubApi/EventEngine/Subscribe/Effects/EmitMessagesHandler.cs +++ b/src/Api/PubnubApi/EventEngine/Subscribe/Effects/EmitMessagesHandler.cs @@ -23,10 +23,9 @@ public async Task Run(EmitMessagesInvocation invocation) { var processedMessages = invocation.Messages.Messages.Select(m => new PNMessageResult() { - // TODO is this ok? :) Channel = m.Channel, Message = JsonConvert.DeserializeObject(m.Payload), - Subscription = m.SubscriptionMatch, // This is channel group + Subscription = m.SubscriptionMatch, Timetoken = m.Timetoken.Timestamp, UserMetadata = m.PublishMetadata, Publisher = m.IssuingClientId