Skip to content

Instantly share code, notes, and snippets.

@colrichie
Last active December 4, 2023 06:30
Show Gist options
  • Save colrichie/90d2e015136c705c78719b7921e624c4 to your computer and use it in GitHub Desktop.
Save colrichie/90d2e015136c705c78719b7921e624c4 to your computer and use it in GitHub Desktop.
Rate Limitter for Line Oriented Data
#!/usr/bin/awk -f
######################################################################
#
# linelim.awk : Rate Limitter for Line Oriented Data
#
# If many lines come over the rate limit specified by this command's
# arguments, the latter lines will be disposed of, and the situation
# will continue until the current speed falls below the limit.
#
# ATTENTION: This program is NOT compliant with POSIX about the following
# two points.
# 1. The "date" command cannot be used to know a more precise
# time than one second in the case of POSIX.
# 2. The "length" function cannot be used to know the number
# of members of array values in the case of POSIX.
#
#
# Written by @colrichie on 2023-12-04
#
######################################################################
BEGIN{
if (ARGC!=3 ) {print_usage();}
if (! match(ARGV[1],/^[0-9]+$/ )) {print_usage();}
if (! match(ARGV[2],/^[0-9]+(\.[0-9]+)?$/)) {print_usage();}
max=ARGV[1]+0; delete ARGV[1];
dur=ARGV[2]+0; delete ARGV[2];
cmd="date +%s.%3N";
split("",tl);
}
{
# 1) Get the current time
cmd | getline now; close(cmd);
# 2) Unregister the stale timestamps
for (ts in tl) {if (now-ts >= dur) {delete tl[ts];}}
# 3) Register the timestamp of the latest line
tl[now]=1;
# 4) Pass through the line only when under the limit
if (length(tl) <= max) {print;next}
delete tl[now];
#print "Calm down!" > "/dev/stderr";
next;
}
function print_usage() {
printf("linelim.awk: <maxtimes> <duration_(sec)>\n",ARGV[0]) > "/dev/stderr";
exit 1;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment