Rate Limiting in Fortran

program rate_limiting
    use, intrinsic :: iso_fortran_env
    implicit none
    
    integer :: i, req
    integer, parameter :: num_requests = 5
    real :: start_time, current_time
    
    ! First we'll look at basic rate limiting. Suppose
    ! we want to limit our handling of incoming requests.
    ! We'll simulate these requests with a simple loop.
    
    call cpu_time(start_time)
    
    do i = 1, num_requests
        ! This call_sleep subroutine will be our rate limiter,
        ! ensuring we process no more than 1 request every 200 milliseconds.
        call call_sleep(0.2)
        
        call cpu_time(current_time)
        print '(A,I0,A,F6.3,A)', "request ", i, " at ", current_time - start_time, " seconds"
    end do
    
    ! Now we'll implement a bursty rate limiter.
    ! This will allow short bursts of requests while preserving the overall rate limit.
    
    print *, ""
    print *, "Bursty Rate Limiting:"
    
    call cpu_time(start_time)
    
    ! Simulate a burst of 3 requests
    do i = 1, 3
        call cpu_time(current_time)
        print '(A,I0,A,F6.3,A)', "request ", i, " at ", current_time - start_time, " seconds"
    end do
    
    ! The remaining requests will be rate limited
    do i = 4, num_requests
        call call_sleep(0.2)
        
        call cpu_time(current_time)
        print '(A,I0,A,F6.3,A)', "request ", i, " at ", current_time - start_time, " seconds"
    end do
    
contains

    subroutine call_sleep(seconds)
        real, intent(in) :: seconds
        integer :: i, j
        
        ! Simple busy-wait to simulate sleep
        do i = 1, int(seconds * 1000000)
            j = i * 2
        end do
    end subroutine call_sleep

end program rate_limiting

This Fortran program demonstrates rate limiting, which is an important mechanism for controlling resource utilization and maintaining quality of service. While Fortran doesn’t have built-in support for concurrent programming like channels or goroutines, we can still illustrate the concept of rate limiting.

In this example, we implement two types of rate limiting:

  1. Basic rate limiting: We process requests at a fixed rate of one request every 200 milliseconds.

  2. Bursty rate limiting: We allow a burst of requests (in this case, 3) to be processed immediately, and then revert to the fixed rate for subsequent requests.

The program uses the cpu_time intrinsic function to measure elapsed time, and a simple busy-wait call_sleep subroutine to simulate delays between requests.

To run the program, save it as rate_limiting.f90 and compile it using a Fortran compiler:

$ gfortran rate_limiting.f90 -o rate_limiting
$ ./rate_limiting

The output will show the timing of each request, demonstrating the effect of rate limiting:

request 1 at 0.200 seconds
request 2 at 0.400 seconds
request 3 at 0.600 seconds
request 4 at 0.800 seconds
request 5 at 1.000 seconds

Bursty Rate Limiting:
request 1 at 1.000 seconds
request 2 at 1.000 seconds
request 3 at 1.000 seconds
request 4 at 1.200 seconds
request 5 at 1.400 seconds

In the basic rate limiting example, you can see that each request is processed approximately 200 milliseconds apart. In the bursty rate limiting example, the first three requests are processed immediately, while the remaining requests are again spaced out by about 200 milliseconds.

This example demonstrates how rate limiting can be implemented in Fortran, even without native support for concurrency primitives like channels or goroutines.