From 7f8e7d2a93d6bd322655859244610d1944514593 Mon Sep 17 00:00:00 2001 From: Soxasora Date: Mon, 19 May 2025 13:51:37 -0500 Subject: [PATCH 1/3] control pgboss jobs via sndev cli --- README.md | 1 + scripts/control-pgboss | 262 +++++++++++++++++++++++++++++++++++++++++ sndev | 10 ++ 3 files changed, 273 insertions(+) create mode 100755 scripts/control-pgboss 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..a13b5f5b0 --- /dev/null +++ b/scripts/control-pgboss @@ -0,0 +1,262 @@ +#!/bin/bash +# Script to handle pgboss jobs + +# prep +INTENT=$1 # add, edit, remove, remove-all, list +JOB=$2 # job name or jobId +shift 2 + +# flags +STARTAFTER= +RETRYLIMIT= +RETRYDELAY= +RETRYBACKOFF= +KEEPUNTIL= + +# shift after flags to get data +shift $((OPTIND-1)) +DATA=$3 # data + +# handle flags with optargs +while getopts "s:r:d:b:k:" opt; do + case "$opt" in + s) + STARTAFTER=$(date -d "$OPTARG seconds" +"%Y-%m-%d %H:%M:%S.%N") + ;; + r) + RETRYLIMIT=$OPTARG + ;; + d) + RETRYDELAY=$(date -d "$OPTARG seconds" +"%Y-%m-%d %H:%M:%S.%N") + ;; + 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 + +# 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|--help Show this help message + +FLAGS: add/edit + -s|--startafter Start the job after given SECONDS + -r|--retrylimit Set the number of retries on thrown errors + -d|--retrydelay Set the delay between retries in SECONDS + -b|--retrybackoff Enable pgboss exponential backoff between retries + -k|--keepuntil Keep the job until a given date in SECONDS + +EXAMPLES + $ sndev pgboss add jobname "{\"id\": \"test\"}" + $ sndev pgboss edit jobId "{\"id\": \"test\"}" + $ sndev pgboss remove jobId + $ sndev pgboss remove-all jobname + $ sndev pgboss list jobname +EOF +exit 0 +} + +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 "$@" +} + +# TODO: add a function to check if correct args are passed + +add_job() { + shift + if [ -z "$JOB" ]; then + echo "At least a job name is required" + usage + exit 1 + fi + + # Build query dynamically based on present values + query="INSERT INTO pgboss.job (name" + values="VALUES ('$JOB'" + + 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 + + query="$query) $values) RETURNING id;" + + job_id=$(docker__exec db psql -U sn -d stackernews -t -q < Date: Tue, 20 May 2025 11:14:17 -0500 Subject: [PATCH 2/3] portable shebang; DRY build options for queries, show job on add/edit --- scripts/control-pgboss | 177 +++++++++++++++++++++-------------------- 1 file changed, 89 insertions(+), 88 deletions(-) diff --git a/scripts/control-pgboss b/scripts/control-pgboss index a13b5f5b0..1b34b3808 100755 --- a/scripts/control-pgboss +++ b/scripts/control-pgboss @@ -1,7 +1,8 @@ -#!/bin/bash +#!/usr/bin/env bash # Script to handle pgboss jobs # prep +set -e INTENT=$1 # add, edit, remove, remove-all, list JOB=$2 # job name or jobId shift 2 @@ -13,39 +14,6 @@ RETRYDELAY= RETRYBACKOFF= KEEPUNTIL= -# shift after flags to get data -shift $((OPTIND-1)) -DATA=$3 # data - -# handle flags with optargs -while getopts "s:r:d:b:k:" opt; do - case "$opt" in - s) - STARTAFTER=$(date -d "$OPTARG seconds" +"%Y-%m-%d %H:%M:%S.%N") - ;; - r) - RETRYLIMIT=$OPTARG - ;; - d) - RETRYDELAY=$(date -d "$OPTARG seconds" +"%Y-%m-%d %H:%M:%S.%N") - ;; - 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 - # general usage usage() { cat < List jobs FLAGS - -h|--help Show this help message + -h Show this help message FLAGS: add/edit - -s|--startafter Start the job after given SECONDS - -r|--retrylimit Set the number of retries on thrown errors - -d|--retrydelay Set the delay between retries in SECONDS - -b|--retrybackoff Enable pgboss exponential backoff between retries - -k|--keepuntil Keep the job until a given date in SECONDS + -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 "{\"id\": \"test\"}" - $ sndev pgboss edit jobId "{\"id\": \"test\"}" + $ 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 @@ -82,30 +50,44 @@ EOF exit 0 } -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 "$@" -} - -# TODO: add a function to check if correct args are passed - -add_job() { - shift - if [ -z "$JOB" ]; then - echo "At least a job name is required" - usage - exit 1 - fi +# handle flags with optargs +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=$(date -d "$OPTARG seconds" +"%Y-%m-%d %H:%M:%S.%N") + ;; + 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 - # Build query dynamically based on present values - query="INSERT INTO pgboss.job (name" - values="VALUES ('$JOB'" +# shift after flags to get data +shift $((OPTIND-1)) +DATA=$1 # data +# query/values builder for pgboss +# with support for multiple flags +build_opts() { + query=$1 + values=$2 if [ ! -z "$DATA" ]; then query="$query, data" values="$values, '$DATA'" @@ -130,23 +112,42 @@ add_job() { query="$query, keepuntil" values="$values, '$KEEPUNTIL'" fi + echo "$query) $values)" +} - query="$query) $values) RETURNING id;" +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() { + shift + 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 < Date: Tue, 20 May 2025 12:40:56 -0500 Subject: [PATCH 3/3] remove unnecessary shifts, reorganize structure, conditionally compose EDIT command, make help compatible with sndev --- scripts/control-pgboss | 133 +++++++++++++++++++++++++---------------- 1 file changed, 82 insertions(+), 51 deletions(-) diff --git a/scripts/control-pgboss b/scripts/control-pgboss index 1b34b3808..99740b161 100755 --- a/scripts/control-pgboss +++ b/scripts/control-pgboss @@ -3,16 +3,6 @@ # prep set -e -INTENT=$1 # add, edit, remove, remove-all, list -JOB=$2 # job name or jobId -shift 2 - -# flags -STARTAFTER= -RETRYLIMIT= -RETRYDELAY= -RETRYBACKOFF= -KEEPUNTIL= # general usage usage() { @@ -50,41 +40,72 @@ 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 -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=$(date -d "$OPTARG seconds" +"%Y-%m-%d %H:%M:%S.%N") - ;; - 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)) +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 @@ -127,7 +148,6 @@ docker__exec() { # add a job add_job() { - shift if [ -z "$JOB" ]; then echo "At least a job name is required" usage @@ -149,24 +169,36 @@ EOF # edit a job edit_job() { - shift if [ -z "$JOB" ]; then echo "At least a job ID is required" usage exit 1 fi - query="UPDATE pgboss.job" - values="SET data = '$DATA'" - query=$(build_opts "$query" "$values") - query="$query WHERE id = '$JOB';" + declare -a flags=() + [ ! -z "$DATA" ] && flags+=("data = '$DATA'") + [ ! -z "$STARTAFTER" ] && flags+=("startafter = '$STARTAFTER'") + [ ! -z "$RETRYLIMIT" ] && flags+=("retrylimit = '$RETRYLIMIT'") + [ ! -z "$RETRYDELAY" ] && flags+=("retrydelay = '$RETRYDELAY'") + [ ! -z "$RETRYBACKOFF" ] && flags+=("retrybackoff = '$RETRYBACKOFF'") + [ ! -z "$KEEPUNTIL" ] && flags+=("keepuntil = '$KEEPUNTIL'") - job_id=$(docker__exec db psql -U sn -d stackernews -t -q <