Working with updates in MTProto
Apart from the basic operations required to work with MTProto update sequences, implementations also have to take care to postpone updates received via the socket while filling gaps in the event and Update sequences, as well as avoid filling gaps in the same sequence.
An interesting and easy way this can be implemented, instead of using various locks, is by running background loops, like in MadelineProto.
- A background feeder loop for each sequence, associated to a FIFO queue is initialized and then paused (event sequence FeedLoop, common sequence SeqLoop).
- Another set of updater loops is started: one for the common sequence, one for each channel sequence (UpdateLoop).
When a getDifference is requested, a signal resumes the updater loop, which starts fetching difference until the gap is filled, then it pauses itself again.
When a new Updates constructor or event is received, it is added to the FIFO queue of the correspondent feeder loop, and a signal is sent to said loop. The signal wakes up the loop, which starts parsing the queued events: as per update handling, duplicates are eliminated, correct events are accepted and the state is updated. When a gap is encountered, the updater loop is resumed: the feeder loop waits until the updater loop is paused again. Finally, the manually fetched difference is prepended to the feeder FIFO queue, to parse it before any additional update that was fetched from the socket while fetching the difference.
The simplicity of this approach is in its sequentiality:
- Each loop can only execute one action at a time.
- Each event is fetched one by one from the FIFO queue
- Loops cannot start handling a new event received from the socket while fetching the difference, or while still handling the previous one
- Only one part of the application at a time can trigger a getDifference, to avoid re-fetching and re-saving the same difference twice.