mautrix / meta

A Matrix-Facebook Messenger and Instagram DM puppeting bridge.
GNU Affero General Public License v3.0
155 stars 11 forks source link

Improve sending messages while reconnecting #63

Closed javiercr closed 3 months ago

javiercr commented 3 months ago

Context

Now that #58 has been merged, the connection will be refreshed (reconnected) periodically. The challenge now is to ensure that messages sent by the user during the reconnection are not lost but are properly delivered to the recipient.

To better illustrate the problem here are are some diagrams:

image image

Colored in red are the changes we want to make to the current implementation.

Description

This PR adds a CanSendMessages boolean flag to the Client struct, accompanied by a SendMessagesCond (sync.Cond).

Once the initial bootstrapping after a new connection is established is completed, we receive an Event_Ready. There we set the new CanSendMessages flag, and notify the change using SendMessagesCond.Signal().

Before we send any new message to Meta, in handleMatrixMessage, we make sure to wait for the flag to be true using SendMessagesCond.Wait(). This way, handleMatrixMessage will be blocked while the reconnection is happening, effectively resuming once we're ready to send the messages.

Finally, note that setting CanSendMessages to false when disconnecting is not needed because the Client object is already disposed (set to nil) on unlockedDisconnect.

This approach seemed simpler than adding a message queue or a more sophisticated retry mechanism for failed sent messages.