MajMcCloud / TelegramBotFramework

This is a context based application framework for the C# TelegramBot library.
https://www.t.me/tgbotbase
MIT License
151 stars 43 forks source link

Bot Form Lifecycle #68

Open sashok2k opened 4 days ago

sashok2k commented 4 days ago

Hi

I'm building a bot which should work with other services of my applicaiton(i.e database). Right now I'm not sure that is't correct to inject database context(or any other services) into forms. Reason I think so is that forms are newer disposed.

To justify my conserns, i would like to know lifecycle of Form component. So I will have understanding at which moment injected services will be released.

MajMcCloud commented 4 days ago

Hi,

there are ways to DI, but it has some limitations. But you can do it. Forms should get disposed, when the garbage collector kicks in. And as far as I know, this will happen when there are no more "active" references to the form.

Did you have any issues with disposal of forms ? You can check out the lifecycle on your own in one of the message loops. Like the default one: https://github.com/MajMcCloud/TelegramBotFramework/blob/master/TelegramBotBase/MessageLoops/FormBaseMessageLoop.cs

Cheers!

sashok2k commented 4 days ago

Am i right to assume that when new session started, session saved into SessionManager.SessionList, once user send message/command, session saved there, and also instanse of Form attached to session?

In code i found only one line where Session is removed from SessionList https://github.com/MajMcCloud/TelegramBotFramework/blob/master/TelegramBotBase/SessionManager.cs#L235

Since Sessions never ended, and sesions always reference Form, it mean that form will never be disposed.

There's another place where Remove called, but that method is not called from anywhere https://github.com/MajMcCloud/TelegramBotFramework/blob/master/TelegramBotBase/SessionManager.cs#L81

MajMcCloud commented 3 days ago

Yes basically thats correct. If you do not use session storage, then its only until a restart.

You can remove it at any time, but if you do so, the hole point of the project gets almost lost. via BotInstance.Sessions.EndSession(SessionId) you should be able to remove the session at any time.

Sessions itself will not end, but forms you navigated from to another will get disposed. So you should only keep the latest one in the cache/memory.

May I ask, how many users do have on your bot (or could become users on your bot approx.), so this could become an issue ?

sashok2k commented 3 days ago

We are planning to create a bot for 20-30k monthly users. They may use bot quite frequently. I'm evaluting different bot builing solutions.

I like idea of forms and how form automate interraction with user, but I think current state management and integration with DI is not suitable for our needs. Our app shouldn't call EndSession, as it's not our domain.

I beleave state should be saved/restored(best is Redis) on every message received by bot, that will allow to not keep forms in memory. On every new message a new Scope should be created, so it will be possible to use existing DI container. After message processed, scope is ended, form disposed

MajMcCloud commented 3 days ago

Ok got it. So with the current system I would say it would work fine.

But anyway, you can extend at least the Session serialization to use Redis on your own if you wish.

I thought already about an automatic mechanism which will keep a session for x minutes of time (5 should probably fine enough) to cleanup a session then. For that I have to rebuild the SessionManager, where time is missing right now for.

When you got more time and can contribute something here, would be really helpful. At least the Redis Session serialiation.

Cheers and good success!