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

Idempotence for method calls #126

Closed
KnorpelSenf opened this issue Apr 27, 2021 · 2 comments
Closed

Idempotence for method calls #126

KnorpelSenf opened this issue Apr 27, 2021 · 2 comments

Comments

@KnorpelSenf
Copy link
Contributor

It is hard to build a bot that is very reliable. Suppose I want to send two messages for an incoming update. I have no way to guarantee that my bot works correctly all the time, e.g. when my bot crashes between sending the first and the second message. This is orthogonal to using long polling vs. webhooks.

If I repeat processing the update, I might send one message again that I sent before (duplication), and if I don't, then I send one message too few (data loss). Either way, I have to decide between at-least once processing or at-most once processing of the updates.

Am I right that the Telegram Bot API server dedupes updates from the Telegram side before sending them further to the bot?

If so, would it be possible to also dedupe incoming method calls from bots? This way, a crashing bot instance can recover, process all incompletely handled updates again, and can be sure that no duplicate messages are delivered to the user. All that bots have to do for this is to process messages deterministically, and generate stable event identifiers, e.g. in the format<incoming update_id>-<operation counter>.

Instead of adding a new field to the payloads of every single method, this could perhaps we achieved via an optional HTTP header? I do not see a way to solve this problem only on the bot's side without idempotence on Telegram's side. If I am overlooking something, or if there is a better way do what I'm trying, please let me know.

@levlam
Copy link
Contributor

levlam commented Apr 28, 2021

Am I right that the Telegram Bot API server dedupes updates from the Telegram side before sending them further to the bot?

Bot API guarantees that an update about the same event will be received with a fixed update_id until its delivery isn't confirmed. A very complex update handling system is used in Bot API to achieve this and it is unlikely that all bot developers will be able to do something similar. In fact, most developers ignore even update_id, which allows to deduplicate updates,

If so, would it be possible to also dedupe incoming method calls from bots?

No, this isn't possible, because these calls can consist from a lot of other calls, which use a lot of other calls, any of which may fail. Telegram clients are able to deduplicate only message sending itself, but incorrect use of this feature can lead to much worse consequences than a very-very rare message duplication.

Either way, I have to decide between at-least once processing or at-most once processing of the updates.

If the bot doesn't crash while waiting response for a request to the Bot API, it can store state of the update handling to avoid both issues. Bots usually have reliable network connections and reliable hardware, so they have no obstacles to achieve this.

@KnorpelSenf
Copy link
Contributor Author

with a fixed update_id until its delivery isn't confirmed

You mean until its delivery is confirmed, correct? I agree with the rest, that makes sense.

No, this isn't possible

I see …

Bots usually have reliable network connections

That is true, we're talking about extremely rare cases. In practise, it has not been an issue yet. I was considering what's possible from a rather theoretical point of view, and to know what guarantees my software can give. This is especially interesting with regards to the recent release of version 5.2 as it will make payments in bots much more common.

Thank you for the thorough explanation :)

I don't think it makes much sense to put in any more effort into this. I know now about the limitations and then I can just document things accordingly, that'll do.

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

No branches or pull requests

2 participants