acep-uaf / camio-meter-streams

0 stars 0 forks source link

Alora/add lock file #122

Closed aloralove closed 2 months ago

aloralove commented 2 months ago

This PR is responsible for adding a locking system to ensure that only one instance of the meter fetch program runs at any time. It uses flock and a dedicated file descriptor (LOCKFD=99) to manage exclusive access to the program resources.

The implementation:

I added comments here to explain in more detail.

LOCKFILE="/var/lock/`basename $0`"           # Define the lock file path using script's basename (data_pipeline.sh)
LOCKFD=99                                    # Assign a high file descriptor number for locking

# PRIVATE
_lock()             { flock -$1 $LOCKFD; }   # Lock function: apply flock with given argument to LOCKFD
_no_more_locking()  {                        # Cleanup function: unlock and potentially remove the lock file
  _lock u                                    # Unlock the file descriptor
  _lock xn && rm -f $LOCKFILE                # Try to lock it exclusively without blocking; if succeeds, remove lock file
}
_prepare_locking()  {                        # Set up locking mechanism
  eval "exec $LOCKFD>\"$LOCKFILE\"";         # Open lock file for writing and assign to LOCKFD
  trap _no_more_locking EXIT;                # Ensure lock cleanup runs on script exit
}
_failed_locking()   { echo "Another instance is already running!"; exit 1; } # Error message for failed locking

# ON START
_prepare_locking                             # Initialize locking setup

# PUBLIC
exlock_now()        { _lock xn; }            # Public function: obtain an exclusive lock immediately or fail
exlock()            { _lock x; }             # Public function: obtain an exclusive lock, blocking until available
shlock()            { _lock s; }             # Public function: obtain a shared lock
unlock()            { _lock u; }             # Public function: release the lock

### BEGINNING OF SCRIPT ###

exlock_now || _failed_locked()                 # Try to lock exclusively without waiting; exit if another instance is running