How to locally loadbalance threadsafe [Answered]
Hola,
I got an instance of a class that holds a list of end-points.
The class performs and awaits an http request to one of the end-points in the list.
The same instance of the class will be accessed async from multiple threads (about 300 times a second)
I need to round-robin load-balance the endpoints in the list.
Initially I thought of using a concurrentQueue and to dequeue/enqueue before and after every request. but the locking will hurt my performance as I have no need to wait for each request to finish before using the same end-point again..
I want that eventually within the 1 second, the 300 requests will be balanced between all the endpoints without delaying them.
I thought of using counter field as an index accessor, that I keep adjusting its value in a circle according to the end-points length.
what do you think? is there a better approach?
Simplified example -
9 Replies
I would take a similar approach to what you suggested with index incrementing, but use
Interlocked.Increment
and then modulo to get the index of endpoint to use
so something like
(I switched the counter from int to ulong to avoid overflow issues)Ok so instead of reseting the indexCounter you modulo it with the length of the array. makes sense, not really worried about overflow each instance won't be surpassing the 1-2 million.
Using
Interlocked.Increment
means that a lock is in place on every update so it makes the indexCounter
incremental thread-safe, correct?
It shouldn't affect performance as such a basic operation won't hold the lock?
That being said, I can abandon the index counter and use concurrent queue to manage that for me if I dequeue and enqueue before awating the request?
Something like -
What do you think? @XymanekUsing Interlocked.Increment means that a lock is in place on every updateno
Interlocked.xyz
methods are atomic
I suggested it precisely since there is no locking❯ : System.Threading.Interlocked.Increment(Int32)
Increments a specified variable and stores the result, as an atomic operation.
❯ : System.Threading.Interlocked.Increment(Int64)
Increments a specified variable and stores the result, as an atomic operation.
❯ : System.Threading.Interlocked.Increment(UInt32)
Increments a specified variable and stores the result, as an atomic operation.
3/4 results shown ~ Click Here for more results
React with ❌ to remove this embed.
as an atomic operationany queue approach will definitely be more expensive than increment with modulo
Ok so queue is out.
I'm not sure what atomic operation actually is, not sure how it achieves that without a lock.
I'll be googling for a few minutes and come back afterwards 😅
Saying that an atomic operation is having a lock on the hardware level is a correct statement?
ehhhh
in terms of the effect - yes, your statement is correct
in terms of how it works - not correct
Got it. ok makes sense now.
Thanks mate! I'll close this topic
✅ This post has been marked as answered!