zetadin / LogistiX

A browser game about supplying an active front.
Other
0 stars 0 forks source link

Separate processes to handle the map simulations #9

Open zetadin opened 1 month ago

zetadin commented 1 month ago

Every ~30 seconds need to evaluate how the battles on the map are going and update the amount of equipment each unit has.

Using a Django Background Task for this is not optimal, as repeating tasks there only start their timers after the last task is done. This can be circumvented by removing the processing time from the expected delay interval and scheduling the next task within the current one.

The more complicated method is to manually write an implementation with multiprocessing, but if not implemented carefully this will lead to balooning RAM use under load (eg. with separate process for each active map). With Background Task can use built in queues to schedule everything.

So let's try doing this with Background Tasks with async workers.

Step 1: hook up the Background Tasks app and send periodic updates to the client.

zetadin commented 1 month ago

A more robust solution would be Django Q. It can run without a broker (Redis) relying instead on Django's ORM. When scaling up will be needed, can switch to Redis much easier than rewriting the infrastructure from Background Tasks. Besides, Background Tasks was not maintained for most of 4 years and someone took over its maintenance only a few months ago.

zetadin commented 1 month ago

Django Q only supports task schedules with a minimum of 1 minute intervals because of heart beat to Redis and other brokers. https://github.com/Koed00/django-q/issues/179

A workaround is scheduling 2 simulation steps at once with a sleep between them.

zetadin commented 1 month ago

Huey also has the same issue where scheduler only has a 1 minute resolution.

zetadin commented 3 weeks ago

With a custom queue-driven implementation I can now schedule tasks that repeat every 10 seconds with a start time <5ms after the scheduled one.

zetadin commented 2 weeks ago

To know when simulation is needed:

During each turn of the simulation: