My task is to process asynchronously balance deltas for multiple clients and provide aggregated balance amounts.
I have a REST service which accepts requests from N clients
C₁…Cₙ, each of them has its own financial balance value which changes throughout time. These clients send their positive/negative balance updates to the REST service, it accumulates and aggregates them. For instance, C₁ has initial balance amount of
100 and sends this sequence:
[+20, -15, +5], so the resulting balance should be
Amount of requests is quite a big and my current solution is the following. Each request is being stored as a separate record in DB table specifying client ID and a delta value. The pool of background worker threads sums deltas for those clients which are assigned to a certain thread. For instance, only
Thread₁ and no other will process, say,
C₁, C₁₀, C₂₀ and C₃₀. The assignment is performed on insertion of a new record with delta value.
This approach has one drawback. For example, if several clients (say,
C₁₀, C₂₀) which produce heavy traffic are assigned on the same worker thread (say,
Thread₁), all other threads will be idling most of the time as opposed to this
Thread₁. Reassignment of
Thread₂ would make the system more performant, but it is not possible in this design. It requires dynamic reassignment which requires some kind of "stop-accepting-requests" action followed by clients weight recalculation and reassignment. (UPD: Or calculating each client weight in the background and stopping accepting requests at least from those clients which should be reassigned.)
Letting workers process arbitrary records will lead to wrong balance values since it is not allowed for the balance to be less than zero.
Are there any ideas on how to improve this solution?