LaKraven / LKSL

LaKraven Studios Standard Library
http://otapi.com
Other
51 stars 15 forks source link

Event Engine - Impose Event Queue/Stack Limits #117

Closed LaKraven closed 6 years ago

LaKraven commented 9 years ago

At present, it is possible for a suitably-fast processor (particularly if using multiple Threads) to dispatch so many Events so quickly that it floods the Event Engine, subsequently crashing the system.

This is particularly true on Win32 binaries, as it is possible to allocate more than 2GB of memory to Events that have yet to be processed.

Simple solution (most logical, even) is to provide a globally-modifiable Variable LKSL_EVENTENGINE_EVENTLIMIT (name may change) (with a "rational" default value) to dictate an absolute limit to the Event Engine.

When a Thread dispatches an Event to the Event Engine after the Queue/Stack hits the defined limit, the dispatching Thread will be made to wait until there is room for the new Event.

Important: Don't freeze the entire dispatching Thread while waiting for room, because this might create a deadlock with the Event Engine trying to pass the Event along to said Thread. Easily avoided with a little careful implementation.

LaKraven commented 9 years ago

It may actually be better to make the limits a "per-thread" affair. This would provide maximum flexibility, particularly if you know one or more threads will process their Events much more quickly than others.

This would mean the "global variable" would define only the maximum limit for the Event Engine's internal Threads (Queue/Stack) only as the central dispatch.

Possible downside of this approach would be that the central Event Engine could be stalled out waiting for an Event Thread to complete its work in order to free a slot in its Queue/Stack.

This warrants more thought!

LaKraven commented 9 years ago

Yeah, I'm going to implement a new member FMaxEventCount in TLKEventContainer and this limit will be applied collectively between the Queue and the Stack (which means the total potential dispatched Events in a given Thread will be FMaxEventCount regardless of whether they are in the Queue or the Stack)

If set to 0, there will be no limit (but this is to be discouraged for the reasons stated in the OP)

It may be necessary to revoke any ability to set this by the implementing developer, and instead "automagically" balance the limit between all registered TLKEventContainer descendant instances. This will be determined during further development.

LaKraven commented 9 years ago

Weirdly, it would also be fairly easy to dictate the Event Limit using the "Events Per Second" calculation, so that the limit is dynamically calculated based on the raw Event Processing Performance of each Event Thread.

This could be made an option reasonably easily, and might even be preferable for most applications!

LaKraven commented 9 years ago

Okay, through trial and error, as well as some fairly straight-forward deductive reasoning, I've determined that two separate limits are required.

A Per-Thread limit: Default to 0 (Unlimited), but allow the implementing developer to impose a maximum Queue/Stack limit for each Event Thread type.

A Global limit: Provided with a rational default value (which is higher on 64bit than 32bit for obvious reasons), as a global variable in the Event Engine's main unit, defining an absolute, system-wide, limit on the number of Events Queued/Stacked at any given moment. I have to decide whether I should increment the global counter when a TLKEvent descendant instance is created, or only when it is dispatched. This is a fairly critical consideration, and at present I'm leaning toward the former.