kdcllc / CometD.NetCore

CometD for use with Salesforce Platform Events
MIT License
28 stars 16 forks source link

How to re-subscribe to a channel with a different replay id? #5

Closed simonness closed 4 years ago

simonness commented 5 years ago

In this scenario we see a message on the meta/connect channel along the lines: 400::The replayId you provided was invalid..

When trying to resubscribe with a different replay id, the method GetChannel in AbstractClientSession always gets the originally created channel with the invalid replay id (code).

public IClientSessionChannel GetChannel(string channelId, long replayId)
{
        Channels.TryGetValue(channelId, out var channel);

What's the best way to recover from this error? We're subscribing to various channels so would prefer not to create a whole new client. Is there anyway to dispose of the original channel and get a new one?

simonness commented 5 years ago

This is more of general issue around re-subscribing to a channel with a different replay id.

We persist the replay id and use this when re-subscribing to avoid missing events or consuming the same event twice as our downstream services can not treat the events as idempotent.

As recommend by cometd.org we do channel subscription on a "meta/Handshake" callback. Resubscription often has to occur after a 403::unknown client error (see issue).

Some logging from our code:

20 Jun 2019 05:57:53.121 channel '/meta/connect' subscription '', message: {"advice":{"interval":0,"reconnect":"handshake"},"channel":"/meta/connect","id":"2938","error":"403::Unknown client","successful":false}
20 Jun 2019 05:57:54.340 channel '/meta/handshake' subscription '', message: {"ext":{"replay":true,"payload.format":true},"minimumVersion":"1.0","clientId":"blah","supportedConnectionTypes":["long-polling"],"channel":"/meta/handshake","id":"2939","version":"1.0","successful":true}
20 Jun 2019 05:57:54.341 Detected handshake, subscribing to all push topics.
20 Jun 2019 05:57:54.430 Subscribing topic 'MyTopicName'. Will use last ReplayId '28759' from storage
20 Jun 2019 05:57:54.431 SubcribeMeta 'MyTopicName' done, channel has properties: id '/topic/MyTopicName', replay id '27554'

We're attempting to re-subscribe with the new later replay id of 28759 but the channel still has the replay id 27554. Further in our downstream logs we can see events from 27554 onward being received and processed for a 2nd time.

kdcllc commented 5 years ago

@simonness I am not sure if you saw the library that utilizes this one https://github.com/kdcllc/CometD.NetCore.Salesforce. If it is not helpful to solve your issue can you please provide with sample project?