Rate Limiting in Modelica
Here’s the translation of the Go rate limiting example to Modelica, formatted in Markdown suitable for Hugo:
Rate limiting is an important mechanism for controlling resource utilization and maintaining quality of service. Modelica can support rate limiting using timers and events.
model RateLimiting
import Modelica.Utilities.Streams.*;
import Modelica.SIunits.Time;
constant Integer numRequests = 5;
discrete Integer[numRequests] requests;
discrete Real[numRequests] requestTimes;
discrete Integer burstyRequests[numRequests];
discrete Real burstyRequestTimes[numRequests];
parameter Time limitInterval = 0.2;
discrete Time nextAllowedTime;
discrete Integer burstyLimiterCount(start=3);
parameter Integer burstyLimiterMax = 3;
initial equation
for i in 1:numRequests loop
requests[i] = i;
burstyRequests[i] = i;
end for;
nextAllowedTime = time;
algorithm
when time >= pre(nextAllowedTime) and time >= 0 and time < 1 then
for i in 1:numRequests loop
requestTimes[i] := time;
nextAllowedTime := time + limitInterval;
printString("request " + String(requests[i]) + " at time " + String(time) + "\n");
end for;
end when;
when time >= 1 and time < 2 then
if pre(burstyLimiterCount) > 0 then
burstyLimiterCount := pre(burstyLimiterCount) - 1;
for i in 1:min(pre(burstyLimiterCount), numRequests) loop
burstyRequestTimes[i] := time;
printString("bursty request " + String(burstyRequests[i]) + " at time " + String(time) + "\n");
end for;
end if;
end when;
when sample(1, limitInterval) then
if pre(burstyLimiterCount) < burstyLimiterMax then
burstyLimiterCount := pre(burstyLimiterCount) + 1;
end if;
if pre(burstyLimiterCount) <= numRequests then
burstyRequestTimes[pre(burstyLimiterCount)] := time;
printString("bursty request " + String(burstyRequests[pre(burstyLimiterCount)]) + " at time " + String(time) + "\n");
end if;
end when;
end RateLimiting;
In this Modelica implementation:
We define arrays to represent the requests and their timestamps.
The
nextAllowedTime
variable acts as our rate limiter, ensuring requests are processed at the specified interval.For basic rate limiting, we use a
when
clause that triggers everylimitInterval
(200 ms in this case), processing one request at a time.For bursty rate limiting, we implement a token bucket-like system using
burstyLimiterCount
. It starts with 3 tokens and refills every 200 ms.The bursty requests are processed immediately if tokens are available, otherwise they wait for the next token to become available.
Running this model would produce output similar to the following:
request 1 at time 0
request 2 at time 0.2
request 3 at time 0.4
request 4 at time 0.6
request 5 at time 0.8
bursty request 1 at time 1
bursty request 2 at time 1
bursty request 3 at time 1
bursty request 4 at time 1.2
bursty request 5 at time 1.4
This output demonstrates both the regular rate limiting (every 200 ms) and the bursty rate limiting (allowing up to 3 requests immediately, then reverting to the regular rate).
Note that Modelica, being primarily used for physical system modeling, doesn’t have built-in constructs for some concepts like channels or goroutines. This implementation uses Modelica’s event-based system to simulate similar behavior.