Let the messages do the work themselves

First of all, we haven’t really looked at what the task-queue does internally.

At a high-level, the task-queue will sort incoming messages per task-source, make “normal” priority ones immediately available for the event-loop to drain and handle, while counting the tasks that are handled, and holding back “low-priority” tasks once a “high-watermark” of handled tasks has been reached for a given iteration of the event-loop.

At the next iteration of the event-loop, the ‘business counter’ is reset, and priority tasks are made available for the event-loop to handle. Any previously throttled non-priority task could be handled as well, since it’s a new iteration of the event-loop, but once the “high-watermark” is reached once more, such tasks will be held-back for a subsequent “less-busy” iteration of the event-loop.

Internally, the task-queue stores tasks in their most basic format, represented by a QueuedTask

So basically, in order to “sort tasks per task-source”, store them, and later make them available to the event-loop in less-busy times, the task-queue is going to have to go from the various message type to a QueuedTask , and then back.

Since the messages themselves are intimately familiar with their own structure, an “easy” way to do the above, is by letting the messages do it themselves. This can be achieved through a trait:

Here is an example of an implementation:

Essentially, it’s the message itself that will unwrap and re-construct itself. So the task-queue can simply do something like: