Changes RestClient to allow for concurrent requests
Created by: RedworkDE
Details
- Changed Buckets from HashSet to ConcurrentDictionary (currently this can and will throw ocasionally)
- Removed the RequestSemaphore that serialized all requests
- To preserve the preemptive ratelimiting the following changes were made:
- Decrement the remaining number of requests before the reqest is made, to allow this to happen atomically the Remaining property was changed to have a explicit backing field
- Responses only update their ratelimit bucket when the response is for a newer interval than what the bucket currently points at. Otherwise this would push that remaining number of requests in that bucket back up when a response is received while other requests for that bucket are still pending
- A ManualResetEvent has been added to signal that the global ratelimit has been hit and further requests should be delayed temporarily
- A HttpClientFactory has been added to allow for custom HttpClient implementation similar to how custom WebSocketClients and UdpClients are realized.
Notes
- This should propably use a async implementation of the ManualResetEvent, but that would require additional dependencies and is only relevant in the case that the global ratelimit has been hit so I just used the framework implementation
- the one big issue this could cause is that when spamming requests a deadlock could occour where all Threads from the TaskPool are blocked by the Wait, so that there are none left to set the event. A similar issue can occour now when a Exception is thrown while performing the request so that the Semaphore is never released
- This change will propably expose a couple of issues similar to #219 (closed) where the library assumes to be single-threaded while Tasks are in fact multi-threaded