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

Refactor realtime presence spec #166

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

sacOO7
Copy link
Collaborator

@sacOO7 sacOO7 commented Sep 7, 2023

@sacOO7 sacOO7 changed the title Refactored spec definition for new sync proto message sent by server Refactor spec definition for new sync proto message sent by server Sep 7, 2023
@@ -723,7 +723,7 @@ h3(#realtime-presence). RealtimePresence
** @(RTP2f)@ If a @SYNC@ is in progress, then when a presence message with an action of @LEAVE@ arrives, it should be stored in the presence map with the action set to @ABSENT@. When the @SYNC@ completes, any @ABSENT@ members should be deleted from the presence map. (This is because in a @SYNC@, we might receive a @LEAVE@ before the corresponding @ENTER@).
** @(RTP2g)@ Any incoming presence message that passes the newness check should be emitted on the @RealtimePresence@ object, with an event name set to its original action. Note: this action may not be the same one that it will have when stored in the presence map. For example: an incoming presence message with an @ENTER@ action will be emitted as an @enter@ event, and the emitted presence message will have its action set to @ENTER@. However, it will be stored in the presence map with a @PRESENT@ action.
* @(RTP18)@ The realtime system reserves the right to initiate a sync of the presence members at any point once a channel is attached. A server initiated sync provides Ably with a means to send a complete list of members present on the channel at any point
** @(RTP18a)@ The client library determines that a new sync has started whenever a @SYNC@ @ProtocolMessage@ is received with a @channel@ attribute and a new sync sequence identifier in the @channelSerial@ attribute. The @channelSerial@ is used as the sync cursor and is a two-part identifier @<sync sequence id>:<cursor value>@. If a new sequence identifier is sent from Ably, then the client library must consider that to be the start of a new sync sequence and any previous in-flight sync should be discarded
** @(RTP18a)@ The client library determines that a sync has started whenever a @SYNC @ProtocolMessage@ is received with a @non-empty@ @channelSerial@ attribute. The @channelSerial@ is a two-part identifier @<sync sequence id>:<cursor value>@. If there is an ongoing sync with different @sync sequence id@, it should be ended while discarding related changes and a new sync should be started.
** @(RTP18b)@ The sync operation for that sequence identifier has completed once the cursor is empty; that is, when the @channelSerial@ looks like @<sync sequence id>:@
** @(RTP18c)@ a @SYNC@ may also be sent with no @channelSerial@ attribute. In this case, the sync data is entirely contained within that @ProtocolMessage@
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@SimonWoolf I have not encountered this particular case [RTP18c] yet. Is this still valid or do we need to remove it?
As of now, I mostly get channelSerial in the format sdfsdf: with all presence data. So, first two cases RTP18a and RTP18b are covered. But third one is not covered : (

Copy link
Member

Choose a reason for hiding this comment

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

sure feel free to remove RTP18c

Copy link
Collaborator Author

@sacOO7 sacOO7 Sep 15, 2023

Choose a reason for hiding this comment

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

Are we sure about it? This means we have to remove check at
https://github.com/ably/ably-dotnet/blob/b359101412f57844c09b8ae276d49008a7adfbd9/src/IO.Ably.Shared/Realtime/Presence.cs#L609
So instead of

if (syncChannelSerial == null || syncCursor.Length <= 1)

it will become

if (syncCursor.IsEmpty())

Copy link
Collaborator Author

@sacOO7 sacOO7 Sep 15, 2023

Choose a reason for hiding this comment

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

Okay, this shouldn't break, since I will be doing this change across dotnet, go and java codebase : )

@sacOO7 sacOO7 changed the title Refactor spec definition for new sync proto message sent by server Refactor realtime presence spec Sep 7, 2023
@@ -743,9 +743,9 @@ h3(#realtime-presence). RealtimePresence
* @(RTP5)@ RealtimeChannel state change side effects:
** @(RTP5a)@ If the channel enters the @DETACHED@ or @FAILED@ state then all queued presence messages will fail immediately, and the @PresenceMap@ and "internal PresenceMap (see RTP17)":#RTP17 is cleared. The latter ensures members are not automatically re-entered if the @RealtimeChannel@ later becomes attached. Since channels in the @DETACHED@ and @FAILED@ states will not receive any presence updates from Ably, presence events (specifically @LEAVE@) should not be emitted when the @PresenceMap@ is cleared as each presence member's state is unknown
*** @(RTP5a1)@ A channel entering the @DETACHED@, @SUSPENDED@, or @FAILED@ state should also clear any @channelSerial@ it has stored per @RTL15b@.
** @(RTP5f)@ If the channel enters the @SUSPENDED@ state then all queued presence messages will fail immediately, and the @PresenceMap@ is maintained. This ensures that if the channel later becomes @ATTACHED@, it will only emit presence events for the changes in the @PresenceMap@ that have occurred whilst the client was disconnected. A test should exist for a channel that is in the @SUSPENDED@ state containing presence members to transition to the @ATTACHED@ state, and following the @SYNC@ process after attaching, any members present before and after the sync should not emit presence events, all other changes should be reflected in the @PresenceMap@ and should emit presence events on the channel
** @(RTP5f)@ If the channel enters the @SUSPENDED@ state then all queued presence messages will fail immediately, and the @PresenceMap@ and "internal PresenceMap (see RTP17)":#RTP17 is maintained. This ensures that if the channel later becomes @ATTACHED@, it will only emit presence events for the changes in the @PresenceMap@ that have occurred (during sync) whilst the channel was @SUSPENDED@. A test should exist for a channel that is in the @SUSPENDED@ state containing presence members to transition to the @ATTACHED@ state, and following the @SYNC@ process after attaching, any members present before and after the sync should not emit presence events, all other changes should be reflected in the @PresenceMap@ and should emit presence events on the channel
Copy link
Collaborator Author

@sacOO7 sacOO7 Sep 7, 2023

Choose a reason for hiding this comment

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

[RTP5f] Do we also need to add a test that says, it should enter internal presence map members to the channel after attached?
I think it probably should get covered as a part of RTP17f

Copy link
Member

Choose a reason for hiding this comment

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

the changes in the @PresenceMap@ that have occurred (during sync)

This addition I think makes it more confusing. The sdk finds out about the changes during the sync, but they might have happened at any point while the channel was suspended

Copy link
Member

Choose a reason for hiding this comment

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

Do we also need to add a test that says, it should enter internal presence map members to the channel after attached? I think it probably should get covered as a part of RTP17f

Just my opinion, but personally, I don't like the "A test should exist that..." spec items. All the spec items specify behaviour, most behaviour should be tested as normal practice. The spec shouldn't need to explicitly require that.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

the changes in the @PresenceMap@ that have occurred (during sync)

This addition I think makes it more confusing. The sdk finds out about the changes during the sync, but they might have happened at any point while the channel was suspended

yeah it's confusing either way, because you have to consider server presencemap and not local presencemap while referring to the statement : (

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I was confused at first, because for all spec statements, presencemap refers to the local one, except this statement.

@sacOO7 sacOO7 marked this pull request as ready for review September 7, 2023 17:55
@sacOO7 sacOO7 requested a review from SimonWoolf September 7, 2023 17:56
@@ -723,7 +723,7 @@ h3(#realtime-presence). RealtimePresence
** @(RTP2f)@ If a @SYNC@ is in progress, then when a presence message with an action of @LEAVE@ arrives, it should be stored in the presence map with the action set to @ABSENT@. When the @SYNC@ completes, any @ABSENT@ members should be deleted from the presence map. (This is because in a @SYNC@, we might receive a @LEAVE@ before the corresponding @ENTER@).
** @(RTP2g)@ Any incoming presence message that passes the newness check should be emitted on the @RealtimePresence@ object, with an event name set to its original action. Note: this action may not be the same one that it will have when stored in the presence map. For example: an incoming presence message with an @ENTER@ action will be emitted as an @enter@ event, and the emitted presence message will have its action set to @ENTER@. However, it will be stored in the presence map with a @PRESENT@ action.
* @(RTP18)@ The realtime system reserves the right to initiate a sync of the presence members at any point once a channel is attached. A server initiated sync provides Ably with a means to send a complete list of members present on the channel at any point
** @(RTP18a)@ The client library determines that a new sync has started whenever a @SYNC@ @ProtocolMessage@ is received with a @channel@ attribute and a new sync sequence identifier in the @channelSerial@ attribute. The @channelSerial@ is used as the sync cursor and is a two-part identifier @<sync sequence id>:<cursor value>@. If a new sequence identifier is sent from Ably, then the client library must consider that to be the start of a new sync sequence and any previous in-flight sync should be discarded
** @(RTP18a)@ The client library determines that a sync has started whenever a @SYNC@ @ProtocolMessage@ is received with a @non-empty@ @channelSerial@ attribute. The @channelSerial@ is a two-part identifier @<sync sequence id>:<cursor value>@. If there is an ongoing sync with different @sync sequence id@, it should be ended while discarding related changes and a new sync should be started.
Copy link
Member

Choose a reason for hiding this comment

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

discarding related changes

This makes it sound like the sdk needs to remember what the presence set was like before the previous sync and revert back to it, which is not necessary

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

So, what is supposed to be done instead? That's the only thing I can think of, reverting presencemap state to previous sync state

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Or do we need to wait for current sync to complete and apply the next immediate sync 🤔

Copy link
Member

Choose a reason for hiding this comment

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

So, what is supposed to be done instead? That's the only thing I can think of, reverting presencemap state to previous sync state

eg clearing the state that needs to be tracked for RTP19, removing any members that you don't see in the sync.

@@ -723,7 +723,7 @@ h3(#realtime-presence). RealtimePresence
** @(RTP2f)@ If a @SYNC@ is in progress, then when a presence message with an action of @LEAVE@ arrives, it should be stored in the presence map with the action set to @ABSENT@. When the @SYNC@ completes, any @ABSENT@ members should be deleted from the presence map. (This is because in a @SYNC@, we might receive a @LEAVE@ before the corresponding @ENTER@).
** @(RTP2g)@ Any incoming presence message that passes the newness check should be emitted on the @RealtimePresence@ object, with an event name set to its original action. Note: this action may not be the same one that it will have when stored in the presence map. For example: an incoming presence message with an @ENTER@ action will be emitted as an @enter@ event, and the emitted presence message will have its action set to @ENTER@. However, it will be stored in the presence map with a @PRESENT@ action.
* @(RTP18)@ The realtime system reserves the right to initiate a sync of the presence members at any point once a channel is attached. A server initiated sync provides Ably with a means to send a complete list of members present on the channel at any point
** @(RTP18a)@ The client library determines that a new sync has started whenever a @SYNC@ @ProtocolMessage@ is received with a @channel@ attribute and a new sync sequence identifier in the @channelSerial@ attribute. The @channelSerial@ is used as the sync cursor and is a two-part identifier @<sync sequence id>:<cursor value>@. If a new sequence identifier is sent from Ably, then the client library must consider that to be the start of a new sync sequence and any previous in-flight sync should be discarded
** @(RTP18a)@ The client library determines that a sync has started whenever a @SYNC @ProtocolMessage@ is received with a @non-empty@ @channelSerial@ attribute. The @channelSerial@ is a two-part identifier @<sync sequence id>:<cursor value>@. If there is an ongoing sync with different @sync sequence id@, it should be ended while discarding related changes and a new sync should be started.
** @(RTP18b)@ The sync operation for that sequence identifier has completed once the cursor is empty; that is, when the @channelSerial@ looks like @<sync sequence id>:@
** @(RTP18c)@ a @SYNC@ may also be sent with no @channelSerial@ attribute. In this case, the sync data is entirely contained within that @ProtocolMessage@
Copy link
Member

Choose a reason for hiding this comment

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

sure feel free to remove RTP18c

@@ -743,9 +743,9 @@ h3(#realtime-presence). RealtimePresence
* @(RTP5)@ RealtimeChannel state change side effects:
** @(RTP5a)@ If the channel enters the @DETACHED@ or @FAILED@ state then all queued presence messages will fail immediately, and the @PresenceMap@ and "internal PresenceMap (see RTP17)":#RTP17 is cleared. The latter ensures members are not automatically re-entered if the @RealtimeChannel@ later becomes attached. Since channels in the @DETACHED@ and @FAILED@ states will not receive any presence updates from Ably, presence events (specifically @LEAVE@) should not be emitted when the @PresenceMap@ is cleared as each presence member's state is unknown
*** @(RTP5a1)@ A channel entering the @DETACHED@, @SUSPENDED@, or @FAILED@ state should also clear any @channelSerial@ it has stored per @RTL15b@.
** @(RTP5f)@ If the channel enters the @SUSPENDED@ state then all queued presence messages will fail immediately, and the @PresenceMap@ is maintained. This ensures that if the channel later becomes @ATTACHED@, it will only emit presence events for the changes in the @PresenceMap@ that have occurred whilst the client was disconnected. A test should exist for a channel that is in the @SUSPENDED@ state containing presence members to transition to the @ATTACHED@ state, and following the @SYNC@ process after attaching, any members present before and after the sync should not emit presence events, all other changes should be reflected in the @PresenceMap@ and should emit presence events on the channel
** @(RTP5f)@ If the channel enters the @SUSPENDED@ state then all queued presence messages will fail immediately, and the @PresenceMap@ and "internal PresenceMap (see RTP17)":#RTP17 is maintained. This ensures that if the channel later becomes @ATTACHED@, it will only emit presence events for the changes in the @PresenceMap@ that have occurred (during sync) whilst the channel was @SUSPENDED@. A test should exist for a channel that is in the @SUSPENDED@ state containing presence members to transition to the @ATTACHED@ state, and following the @SYNC@ process after attaching, any members present before and after the sync should not emit presence events, all other changes should be reflected in the @PresenceMap@ and should emit presence events on the channel
Copy link
Member

Choose a reason for hiding this comment

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

the changes in the @PresenceMap@ that have occurred (during sync)

This addition I think makes it more confusing. The sdk finds out about the changes during the sync, but they might have happened at any point while the channel was suspended

** @(RTP5b)@ If a channel enters the @ATTACHED@ state then all queued presence messages will be sent immediately. A presence @SYNC@ may be initiated per "@RTP1@":#RTP1
* @(RTP16)@ Connection state conditions:
* @(RTP16)@ Channel/Connection state conditions side effects while "enter, update and leave presence message (see RTP8, RTP9, RTP10 and RTP14)":#RTP8
Copy link
Member

Choose a reason for hiding this comment

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

this addition is quite unclear. "conditions side effects", "while enter presence message"

Copy link
Collaborator Author

@sacOO7 sacOO7 Sep 8, 2023

Choose a reason for hiding this comment

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

I mean it's related to enter, update and leave presence message. Problem is, all specs mentioned right above RTP16 are supposed to be applied while processing presence message. This one is while sending the message, and it's not explicitly mentioned. I had to refer to the code to truly understand the context.

Copy link
Member

Choose a reason for hiding this comment

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

In that case I think we can do even better -- after all "enter, update, and leave presence messages" doesn't really clarify, those can all be received too.

How about @(RTP16)@ Effect of channel state on enter(), update(), and leave() methods?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

yeah, this makes more sense

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants