Skip to content

Commit 9ba163d

Browse files
committed
[rfc] Reference level explanation
1 parent 68c35b7 commit 9ba163d

1 file changed

Lines changed: 62 additions & 9 deletions

File tree

rfcs/0000-limitador-multithread-inmemory.md

Lines changed: 62 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -125,21 +125,74 @@ be the difference between the expected value of the counter and the value that t
125125
stored value is **lower** than the expected one. Usually, this would happen when trying to revert a wrongly updated counter
126126
twice in a row, for example, when trying to revert the _overshoot_ from the previous example.
127127

128-
These scenarios will be explained in detail in the [Reference-level explanation](#reference-level-explanation) section.
129-
130-
131128

132129
# Reference-level explanation
133130
[reference-level-explanation]: #reference-level-explanation
134131

135-
This is the technical portion of the RFC. Explain the design in sufficient detail that:
132+
Enhancing the Limitador service to process requests in parallel and being capable of operating in the previously described
133+
modes, entails considering various implications.
134+
135+
Firstly, ensuring consistency in storing counter values across multiple threads is paramount to maintinging the integrity
136+
of rate limiting operations. This involves implementing robust concurrency control mechanisms to prevent race conditions
137+
and data corruption when accessing and updating shared counter data.
138+
139+
Additionally, choosing the data structure that will store the counter values must prioritize efficiency and thread safety
140+
to handle concurrect access effectively.
141+
142+
Finally, considering that initially we will implement the setup of the mode at the service initialization time, balancing
143+
the need for strict adherence to defined limits with the desire to maximize throughput presents a trade-off that we could
144+
give the user the ability to manage.
145+
146+
147+
## Implementation guidelines
148+
149+
### Data structures
150+
151+
Limitador already possess a data structure to store the limit counters that also stores the expiration time of the counter,
152+
the type is named `AtomicExpiringCounter`. This data structure is a thread-safe counter that can be incremented and
153+
decremented atomically, and it also has a methods to check the value at a certain time and update the counter.
154+
155+
The collection of these counters should be consistent across threads and also being able to quickly sort and retrieve the
156+
counters associated to a certain namespace and limits definitions. Currently, the data structure can't provide this
157+
much desired functionality, so we need to introduce a new data structure that can provide this.
158+
159+
### Request handling and concurrency control
160+
161+
When a request comes in, Limitador needs to determine the appropriate Counter object(s) based on the request's namespace
162+
and limit definitions. Taking into account the collection will be in ascending order by expiration time, iterating over the
163+
counter objects associated with those premises and performing the following steps:
164+
165+
1. Retrieve the Counter object from the collection.
166+
2. Compare the current timestamp with the expiration time of the counter to determine if the request falls within the
167+
sliding window
168+
3. If the request falls within the window, increment the hit count of the Counter.
169+
4. If the hit count exceeds the limit defined for the Counter, deny the request.
170+
5. If the request passes all limit checks, allow it to proceed.
171+
172+
To ensure that these operations are performed atomically and consistently across threads, we need to use fine-grained
173+
locking or atomic operations when accessing and updating the counter data in the collection. Using synchronization
174+
primitives such as mutexes or atomic types will help to protect the integrity of the counter data from concurrent modifications.
175+
176+
### Configuration and mode selection
177+
178+
The configuration of the service will be done at the initialization time, and it will be done through the command line as
179+
described in the [Guide-level explanation](#guide-level-explanation) section.
180+
181+
#### Accuracy mode
182+
183+
* In Accuracy mode, we need to strictly adhere to the defined limits by denying requests that exeed the limits for each
184+
Counter Object.
185+
* Check and update Counter values atomically to maintin consistency and prevent race conditions.
186+
* Enforce rate limits accurately by comparing the number of hits within the sliding window to the defined limit.
187+
188+
#### Throughput mode
136189

137-
- Its interaction with other features is clear.
138-
- It is reasonably clear how the feature would be implemented.
139-
- How error would be reported to the users.
140-
- Corner cases are dissected by example.
190+
* In Throughput mode, we need to prioritize maximizing the number of requests that can be processed concurrently over
191+
strict adherence to defined limits.
192+
* Allowing request to proceed even if they temproarly exceed the defined limits, favouring higher request rates.
193+
* We should use appropriate concurrency mechanisms and CAS oeprations to handle request efficiently while maintaining
194+
consistency in the counter data. We might not need to use locks, but we need to be careful with the CAS operations nonetheless.
141195

142-
The section should return to the examples given in the previous section, and explain more fully how the detailed proposal makes those examples work.
143196

144197
# Drawbacks
145198
[drawbacks]: #drawbacks

0 commit comments

Comments
 (0)