Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

State transitions for presence event engine #203

Merged
merged 32 commits into from
Feb 19, 2024
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
b4bcc30
add events
Xavrax Jan 23, 2024
c405b51
proper formatting
Xavrax Jan 23, 2024
135c876
all states declared
Xavrax Jan 23, 2024
0ac1aba
fields declared
Xavrax Jan 23, 2024
2ffd098
joined event
Xavrax Jan 23, 2024
f61a79a
Left event
Xavrax Jan 23, 2024
3798d8b
left all
Xavrax Jan 23, 2024
13b22a8
fix function param
Xavrax Jan 23, 2024
edc602a
hb fail + transition fix
Xavrax Jan 23, 2024
3f4ce72
give up
Xavrax Jan 23, 2024
3881560
reconnect
Xavrax Jan 23, 2024
d0a12d3
disconnect
Xavrax Jan 23, 2024
d4c7a1e
timeup
Xavrax Jan 23, 2024
384ef5d
missing enumerable
Xavrax Jan 23, 2024
e371d59
building should work
Xavrax Jan 23, 2024
c6bcba0
enumerable instead of list
Xavrax Jan 23, 2024
9cb95a5
add UT
Xavrax Jan 23, 2024
3427cbc
fix/build: missing reference links for effect handlers
mohitpubnub Jan 24, 2024
2581fa9
attempt to fix UWP project build errors
mohitpubnub Jan 24, 2024
56ebedd
fix CSC : error CS1617: error for language version
mohitpubnub Jan 24, 2024
19eb3f3
updating language version to 9 suppoerted by VS2019
mohitpubnub Jan 25, 2024
9b26375
updated LangVersion to `preview`
mohitpubnub Jan 25, 2024
dc61a26
take-4/fix language version. `default`
mohitpubnub Jan 25, 2024
abd4327
take-5: reverting LangVersion to `latest`
mohitpubnub Jan 25, 2024
491d5c9
removed `<LangVersion>` overrides
mohitpubnub Jan 28, 2024
3fff0d1
reverted 491d5c9
mohitpubnub Jan 28, 2024
c6b03c6
Update run-tests.yml
mohitpubnub Feb 1, 2024
39d45f1
take-2
mohitpubnub Feb 1, 2024
eae3301
take-3
mohitpubnub Feb 1, 2024
e03a01f
fix state switches
Xavrax Feb 5, 2024
b223349
wip for ci
Xavrax Feb 5, 2024
8db5621
leave this branch as is - new branch for testing
Xavrax Feb 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions src/Api/PubnubApi/EventEngine/Presence/Common/PresenceInput.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System.Collections.Generic;
using System.Linq;

namespace PubnubApi.EventEngine.Presence.Common
{
public class PresenceInput
{
public IEnumerable<string> Channels { get; set; }
public IEnumerable<string> ChannelGroups { get; set; }

public static PresenceInput operator +(PresenceInput a, PresenceInput b)
{
return new PresenceInput
{
Channels = a.Channels?.Union(b.Channels ?? new string[0]),
ChannelGroups = a.ChannelGroups?.Union(b.ChannelGroups ?? new string[0]),
};
}

public static PresenceInput operator -(PresenceInput a, PresenceInput b)
{
return new PresenceInput
{
Channels = a.Channels?.Except(b.Channels ?? new string[0]),
ChannelGroups = a.ChannelGroups?.Except(b.ChannelGroups ?? new string[0]),
};
}

public bool IsEmpty()
{
return (Channels == null && ChannelGroups == null)
|| ((Channels != null && Channels.Count() == 0)
&& (ChannelGroups != null && ChannelGroups.Count() == 0));
}
}
}
35 changes: 35 additions & 0 deletions src/Api/PubnubApi/EventEngine/Presence/Events/PresenceEvents.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System.Collections.Generic;
using PubnubApi;
using PubnubApi.EventEngine.Presence.Common;

namespace PubnubApi.EventEngine.Presence.Events {
public class JoinedEvent : Core.IEvent
{
public PresenceInput Input { get; set; }
}

public class LeftEvent : Core.IEvent
{
public PresenceInput Input { get; set; }
}

public class LeftAllEvent : Core.IEvent {}

public class HeartbeatSuccessEvent : Core.IEvent {}

public class HeartbeatFailureEvent : Core.IEvent
{
public PNStatus Status { get; set; }
}

public class HeartbeatGiveUpEvent : Core.IEvent
{
public PNStatus Status { get; set; }
}

public class ReconnectEvent : Core.IEvent {}

public class DisconnectEvent : Core.IEvent {}

public class TimesUpEvent : Core.IEvent {}
}
4 changes: 4 additions & 0 deletions src/Api/PubnubApi/EventEngine/Presence/Invocations/Dummy.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// TODO: Dummy Invocation until we have real ones
namespace PubnubApi.EventEngine.Presence.Invocations {
public class DummyInvocation : Core.IEffectInvocation {}
}
27 changes: 27 additions & 0 deletions src/Api/PubnubApi/EventEngine/Presence/States/APresenceState.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using PubnubApi.EventEngine.Core;
using PubnubApi.EventEngine.Presence.Common;

namespace PubnubApi.EventEngine.Presence.States
{
public abstract class APresenceState : Core.State
{
public PresenceInput Input { get; set; }

public bool IsEmpty()
{
return Input.IsEmpty();
}

protected TransitionResult HandleLeftEvent(Events.LeftEvent e)
{
var newInput = this.Input - e.Input;

return newInput.IsEmpty()
? (TransitionResult)new InactiveState()
: (TransitionResult)new HeartbeatingState()
{
Input = newInput,
};
}
}
}
42 changes: 42 additions & 0 deletions src/Api/PubnubApi/EventEngine/Presence/States/CooldownState.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using PubnubApi;
using PubnubApi.EventEngine.Presence.Invocations;
using PubnubApi.EventEngine.Core;
using System.Collections.Generic;
using System;

namespace PubnubApi.EventEngine.Presence.States
{
public class CooldownState : APresenceState
{
// TODO: Dummy Invocation until we have real ones
public override IEnumerable<IEffectInvocation> OnEntry => new DummyInvocation().AsArray();
public override IEnumerable<IEffectInvocation> OnExit => new DummyInvocation().AsArray();

// TODO: transitions
public override TransitionResult Transition(IEvent ev)
{
return ev switch
{
Events.JoinedEvent e => new HeartbeatingState()
{
Input = e.Input != this.Input ? this.Input + e.Input : this.Input,
},
Events.LeftEvent e => HandleLeftEvent(e),
Events.LeftAllEvent e => new InactiveState(),
Events.HeartbeatSuccessEvent e => new CooldownState()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to handle HeratbeatSuccess when we are on Cooldown state ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. Probably I've added that in favour of Heartbeating and Reconnecting! I will change that after the compiling fix.

{
Input = this.Input,
},
Events.DisconnectEvent e => new StoppedState()
{
Input = this.Input,
},
Events.TimesUpEvent e => new HeartbeatingState()
{
Input = this.Input,
},
_ => null,
};
}
}
}
40 changes: 40 additions & 0 deletions src/Api/PubnubApi/EventEngine/Presence/States/FailedState.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using PubnubApi.EventEngine.Presence.Invocations;
using PubnubApi.EventEngine.Core;
using System.Collections.Generic;
using System;

namespace PubnubApi.EventEngine.Presence.States
{
public class FailedState : APresenceState
{
public PNStatus Reason { get; set; }

// TODO: Dummy Invocation until we have real ones
public override IEnumerable<IEffectInvocation> OnEntry => new DummyInvocation().AsArray();
public override IEnumerable<IEffectInvocation> OnExit => new DummyInvocation().AsArray();

// TODO: transitions
public override TransitionResult Transition(IEvent ev)
{
return ev switch
{
Events.JoinedEvent e => new HeartbeatingState()
{
Input = e.Input != this.Input ? this.Input + e.Input : this.Input,
},
Events.LeftEvent e => HandleLeftEvent(e),
Events.LeftAllEvent e => new InactiveState(),
Events.ReconnectEvent e => new HeartbeatingState()
{
Input = this.Input,
},
Events.DisconnectEvent e => new StoppedState()
{
Input = this.Input,
},
_ => null,
};
}
}

}
47 changes: 47 additions & 0 deletions src/Api/PubnubApi/EventEngine/Presence/States/HeartBeatingState.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using PubnubApi.EventEngine.Presence.Invocations;
using PubnubApi.EventEngine.Core;
using System.Collections.Generic;
using System;

namespace PubnubApi.EventEngine.Presence.States
{
public class HeartbeatingState : APresenceState
{
// TODO: Dummy Invocation until we have real ones
public override IEnumerable<IEffectInvocation> OnEntry => new DummyInvocation().AsArray();
public override IEnumerable<IEffectInvocation> OnExit => new DummyInvocation().AsArray();

// TODO: transitions
public override TransitionResult Transition(IEvent ev)
{
return ev switch
{
Events.JoinedEvent e => new HeartbeatingState()
{
Input = e.Input != this.Input ? this.Input + e.Input : this.Input,
},
Events.LeftEvent e => HandleLeftEvent(e),
Events.LeftAllEvent e => new InactiveState(),
Events.HeartbeatFailureEvent e => HandleHeartbeatFailureEvent(e),
Events.DisconnectEvent e => new StoppedState()
{
Input = this.Input,
},
_ => null,
};
}

private TransitionResult HandleHeartbeatFailureEvent(Events.HeartbeatFailureEvent e)
{
return e.Status.Category == PNStatusCategory.PNCancelledCategory
? (TransitionResult)null
: (TransitionResult)new ReconnectingState()
{
Input = this.Input,
RetryCount = 1,
Reason = e.Status,
};
}
}

}
33 changes: 33 additions & 0 deletions src/Api/PubnubApi/EventEngine/Presence/States/InactiveState.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using PubnubApi.EventEngine.Presence.Invocations;
using PubnubApi.EventEngine.Core;
using System.Collections.Generic;
using System;

namespace PubnubApi.EventEngine.Presence.States
{
public class InactiveState : APresenceState
{
public InactiveState()
{
Input = null;
}

// TODO: Dummy Invocation until we have real ones
public override IEnumerable<IEffectInvocation> OnEntry => new DummyInvocation().AsArray();
public override IEnumerable<IEffectInvocation> OnExit => new DummyInvocation().AsArray();

// TODO: transitions
public override TransitionResult Transition(IEvent ev)
{
return ev switch
{
Events.JoinedEvent e => new HeartbeatingState()
{
Input = e.Input,
},
_ => null,
};
}
}

}
59 changes: 59 additions & 0 deletions src/Api/PubnubApi/EventEngine/Presence/States/ReconnectingState.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using PubnubApi.EventEngine.Presence.Invocations;
using PubnubApi.EventEngine.Core;
using System.Collections.Generic;
using System;

namespace PubnubApi.EventEngine.Presence.States
{
public class ReconnectingState : APresenceState
{
public int RetryCount { get; set; }
public PNStatus Reason { get; set; }

// TODO: Dummy Invocation until we have real ones
public override IEnumerable<IEffectInvocation> OnEntry => new DummyInvocation().AsArray();
public override IEnumerable<IEffectInvocation> OnExit => new DummyInvocation().AsArray();

// TODO: transitions
public override TransitionResult Transition(IEvent ev)
{
return ev switch
{
Events.JoinedEvent e => new HeartbeatingState()
{
Input = e.Input != this.Input ? this.Input + e.Input : this.Input,
},
Events.LeftEvent e => HandleLeftEvent(e),
Events.LeftAllEvent e => new InactiveState(),
Events.HeartbeatSuccessEvent e => new CooldownState()
{
Input = this.Input,
},
Events.HeartbeatFailureEvent e => HandleHeartbeatFailureEvent(e),
Events.HeartbeatGiveUpEvent e => new FailedState()
{
Input = this.Input,
Reason = this.Reason,
},
Events.DisconnectEvent e => new StoppedState()
{
Input = this.Input,
},
_ => null,
};
}

private TransitionResult HandleHeartbeatFailureEvent(Events.HeartbeatFailureEvent e)
{
return e.Status.Category == PNStatusCategory.PNCancelledCategory
? (TransitionResult)null
: (TransitionResult)new ReconnectingState()
{
Input = this.Input,
RetryCount = this.RetryCount + 1,
Reason = e.Status,
};
}
}

}
46 changes: 46 additions & 0 deletions src/Api/PubnubApi/EventEngine/Presence/States/StoppedState.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using PubnubApi.EventEngine.Presence.Invocations;
using PubnubApi.EventEngine.Core;
using System.Collections.Generic;
using System;

namespace PubnubApi.EventEngine.Presence.States
{
public class StoppedState : APresenceState
{
// TODO: Dummy Invocation until we have real ones
public override IEnumerable<IEffectInvocation> OnEntry => new DummyInvocation().AsArray();
public override IEnumerable<IEffectInvocation> OnExit => new DummyInvocation().AsArray();

// TODO: transitions
public override TransitionResult Transition(IEvent ev)
{
return ev switch
{
Events.JoinedEvent e => new StoppedState()
{
Input = e.Input != this.Input ? this.Input + e.Input : this.Input,
},
Events.LeftEvent e => HandleLeftEvent(e),
Events.LeftAllEvent e => new InactiveState(),
Events.ReconnectEvent e => new HeartbeatingState()
{
Input = this.Input,
},
_ => null,
};
}

protected TransitionResult HandleLeftEvent(Events.LeftEvent e)
{
var newInput = this.Input - e.Input;

return newInput.IsEmpty()
? (TransitionResult)new InactiveState()
: (TransitionResult)new StoppedState()
{
Input = newInput,
};
}
}

}
Loading
Loading