diff --git a/README.md b/README.md index c607b0563..31be7d04a 100644 --- a/README.md +++ b/README.md @@ -98,6 +98,7 @@ COMMANDS onion service onion address cert service tls cert compose docker compose passthrough + pgboss control pgboss jobs ``` ### Modifying services diff --git a/scripts/control-pgboss b/scripts/control-pgboss new file mode 100755 index 000000000..99740b161 --- /dev/null +++ b/scripts/control-pgboss @@ -0,0 +1,294 @@ +#!/usr/bin/env bash +# Script to handle pgboss jobs + +# prep +set -e + +# general usage +usage() { + cat < [flags] [data] Add a job + edit [flags] [data] Edit a job + remove Remove a job + remove-all Remove all jobs of a given name + details Show details of a job + list List jobs + +FLAGS + -h Show this help message + +FLAGS: add/edit + -s Start the job after given SECONDS + -r Set the number of retries on thrown errors + -d Set the delay between retries in SECONDS + -b Enable pgboss exponential backoff between retries + -k Keep the job until a given date in SECONDS + +EXAMPLES + $ sndev pgboss add jobname -s 10 "{\"id\": \"test\"}" + $ sndev pgboss edit jobId -s 10 "{\"id\": \"test\"}" + $ sndev pgboss remove jobId + $ sndev pgboss remove-all jobname + $ sndev pgboss list jobname +EOF +exit 0 +} + +if [ "$1" = "-h" ]; then + usage + exit 0 +fi + +INTENT=$1 # add, edit, remove, remove-all, list +if [ -z "$INTENT" ]; then + echo "At least a command is required" + usage + exit 1 +fi +shift + +JOB=$1 # job name or jobId +if [ -z "$JOB" ]; then + echo "At least a job name or job ID is required" + usage + exit 1 +fi +shift + +# flags +STARTAFTER= +RETRYLIMIT= +RETRYDELAY= +RETRYBACKOFF= +KEEPUNTIL= + +# handle flags with optargs +if [[ "$INTENT" == "add" ]] || [[ "$INTENT" == "edit" ]]; then + while getopts "s:r:d:k:bh" opt; do + case "$opt" in + s) + STARTAFTER=$(date -d "$OPTARG seconds" +"%Y-%m-%d %H:%M:%S.%N") + ;; + r) + RETRYLIMIT=$OPTARG + ;; + d) + RETRYDELAY=$OPTARG + ;; + b) + RETRYBACKOFF=true + ;; + k) + KEEPUNTIL=$(date -d "$OPTARG seconds" +"%Y-%m-%d %H:%M:%S.%N") + ;; + h) + usage + exit 0 + ;; + ?) + echo "Invalid option: -$OPTARG" + usage + exit 1 + esac + done + # shift after flags to get data + shift $((OPTIND-1)) +fi + +DATA=$1 # data + +# query/values builder for pgboss +# with support for multiple flags +# TODO: more elegant, see edit_job +build_opts() { + query=$1 + values=$2 + if [ ! -z "$DATA" ]; then + query="$query, data" + values="$values, '$DATA'" + fi + if [ ! -z "$STARTAFTER" ]; then + query="$query, startafter" + values="$values, '$STARTAFTER'" + fi + if [ ! -z "$RETRYLIMIT" ]; then + query="$query, retrylimit" + values="$values, '$RETRYLIMIT'" + fi + if [ ! -z "$RETRYDELAY" ]; then + query="$query, retrydelay" + values="$values, '$RETRYDELAY'" + fi + if [ ! -z "$RETRYBACKOFF" ]; then + query="$query, retrybackoff" + values="$values, '$RETRYBACKOFF'" + fi + if [ ! -z "$KEEPUNTIL" ]; then + query="$query, keepuntil" + values="$values, '$KEEPUNTIL'" + fi + echo "$query) $values)" +} + +docker__exec() { + if [ ! -x "$(command -v docker)" ]; then + echo "docker is not installed" + echo "installation instructions are here: https://docs.docker.com/desktop/" + exit 0 + fi + + DOCKER_CLI_HINTS=false command docker exec -i "$@" +} + +# add a job +add_job() { + if [ -z "$JOB" ]; then + echo "At least a job name is required" + usage + exit 1 + fi + + query="INSERT INTO pgboss.job (name" + values="VALUES ('$JOB'" + query=$(build_opts "$query" "$values") + query="$query RETURNING id;" + + job_id=$(docker__exec db psql -U sn -d stackernews -t -q <