/debounce

Limit the rate at which a command can fire

Primary LanguageGoApache License 2.0Apache-2.0

debounce

debounce logo

Introduction

debounce is a simple utility to limit the rate at which a command can fire.

The command format is:

debounce <integer> <unit> <command>

Available units are:

  • seconds (s)
  • minutes (m)
  • hours (h)
  • days (d)

The following are equivalent:

debounce 1 s some-command
debounce 1 second some-command
debounce 1 seconds some-command
debounce 1 m some-command
debounce 1 minute some-command
debounce 1 minutes some-command
debounce 1 h some-command
debounce 1 hour some-command
debounce 1 hours some-command
debounce 1 d some-command
debounce 1 day some-command
debounce 1 days some-command

Note that day is shorthand for 24 hours. Daylight Saving Time is not taken into account.

Installation

Choose from the following options to install debounce.

Go Install

go install github.com/oalders/debounce@latest

or for a specific version:

go install github.com/oalders/debounce@v0.4.0

Using Ubi

You can use ubi to install debounce.

#!/usr/bin/env bash

set -eux -o pipefail

# Choose a directory in your $PATH
dir="$HOME/local/bin"

if [ ! "$(command -v ubi)" ]; then
    curl --silent --location \
        https://raw.githubusercontent.com/houseabsolute/ubi/master/bootstrap/bootstrap-ubi.sh |
        TARGET=$dir sh
fi

ubi --project oalders/debounce --in "$dir"

Download a Release

You can download the latest release directly from here.

Examples

A command without arguments

This runs the command without any parameters but prevents repeated execution within the set time window.

$ debounce 2 seconds date
Mon Aug  5 23:09:09 EDT 2024
$ debounce 2 seconds date
🚥 will not run date more than once every 2 seconds

A command with arguments

This example uses ubi to install is into the current directory. The command won't be executed more than once every 8 hours.

$ debounce 8 hours ubi --verbose --project oalders/is --in .
[ubi::installer][INFO] Installed binary into ./is
$ debounce 8 hours ubi --verbose --project oalders/is --in .
🚥 will not run "ubi --verbose --project oalders/is --in ." more than once every 8 hours

Using Shell Variables

Remember to single quote variables which shouldn't be expanded until the command is run.

debounce 10 s zsh -c 'echo $PWD'

More Complex Commands

You can use && and || in your commands. You'll want to quote your command to ensure that the entire command is passed to debounce.

debounce 2 s bash -c 'sleep 2 && date'

Available Flags

It's important to add debounce flags before other command arguments to avoid confusion between debounce flags and flags meant for your command.

Good: ✅

debounce --debug 90 s curl https://www.olafalders.com

Bad: 💥

$ debounce 90 s curl https://www.prettygoodping.com --debug
🚀 Running command: curl https://www.prettygoodping.com --debug
curl: option --debug: is unknown

You could be explicit about this by using -- as a visual indicator that flag parsing has ended.

debounce --debug 90 s -- curl https://www.prettygoodping.com

--cache-dir

Specify an alternate cache directory to use. The directory must already exist.

debounce --cache-dir /tmp 30 s date

--status

Print debounce status information for a command.

debounce --status 30 s date
📁 cache location: /Users/olaf/.cache/debounce/0e87632cd46bd4907c516317eb6d81fe0f921a23c7643018f21292894b470681
🚧 cache last modified: Thu, 19 Sep 2024 08:28:20 EDT
⏲️ debounce interval: 00:00:30
🕰️ cache age: 00:00:12
⏳ time remaining: 00:00:17

Resetting the Cache

Since the cache is just a file, you can rm the cache location file whenever you'd like to start fresh.

rm /Users/olaf/.cache/debounce/0e87632cd46bd4907c516317eb6d81fe0f921a23c7643018f21292894b470681

--version

Prints current version.

debounce --version
0.4.0

--help

Displays usage instructions.

debounce --help
Usage: debounce <quantity> <unit> <command> ... [flags]

limit the rate at which a command can fire

Arguments:
  <quantity>       Quantity of time
  <unit>           s,second,seconds,m,minute,minutes,h,hour,hours,d,day,days
  <command> ...    Command to run

Flags:
  -h, --help                Show context-sensitive help.
      --debug               Print debugging info to screen
      --version             Print version to screen
      --status              Print cache information for a command without running it
      --cache-dir=STRING    Override the default cache directory

Caveats

Under the hood, debounce creates or updates a cache file to track when a command was run successfully. This means that, under the right conditions, it's entirely possible to kick off two long-running tasks in parallel without debounce knowing about it.

Additionally, if a command fails, the cache file will not be created or updated.

I've created this tool in a way that meets my needs. I will consider pull requests for additional functionality to address issues like these. Please get in touch with me first to discuss your feature if you'd like to add something.