aboutsummaryrefslogtreecommitdiff
path: root/queue/queue_worker.sh
blob: 8b2b0b28a14a912b89be5a5a4a2e81d0f8e6fb42 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#!/bin/bash
# SPDX-FileCopyrightText: 2023 Brian Woods
# SPDX-License-Identifier: GPL-2.0-or-later

# settings
CMD=""
TIME_BASE=10		# always wait this time
TIME_RND=0		# above plus 0-120

# pathes
LOCK="queue.lock"
QUEUE="queue.file"
WORKER_PID="queue_worker.pid"

# references for why I went with sed, that and ease use
# https://www.baeldung.com/linux/remove-first-line-text-file

queue_shift ()
{
	queue_item=""
	local lock_fd="3"
	# aquire lock
	if ! exec {lock_fd}>"$LOCK" ; then
		echo "Can't get lockfile fd"
		return
	fi

	if ! flock -w 10 "$lock_fd" ; then
		echo "couldn't get lock"
		return
	fi

	if [ -f "$QUEUE" ] ; then
		local line="$(head -n 1 $QUEUE)"
		sed -i '1d' "$QUEUE"

		#delete if empty
		if [ ! -s "$QUEUE" ] ; then
			rm "$QUEUE"
		fi
	fi

	# release lock
	flock -u "$lock_fd"
	exec {lock_fd}>&-

	queue_item="$line"
}

queue_work ()
{
	local rv=1
	local lock_fd="3"
	# aquire lock
	if ! exec {lock_fd}>"$LOCK" ; then
		echo "Can't get lockfile fd"
		return
	fi

	if ! flock -w 10 "$lock_fd" ; then
		echo "couldn't get lock"
		return
	fi

	# we have work
	if [ -f "$QUEUE" ] ; then
		rv=0
	fi

	# release lock
	flock -u "$lock_fd"
	exec {lock_fd}>&-

	return $rv
}

sleep_pause ()
{
	if [ "$TIME_RND" = "0" ] ; then
		local sleep_period="$TIME_BASE"
	else
		local sleep_period=$(( RANDOM % TIME_RND + TIME_BASE ))
	fi
	sleep "$sleep_period"
}

# FIRST thing is to create PID file
if [ ! -f "$WORKER_PID" ] ; then
	echo "$$" > "$WORKER_PID"
else
	echo "worker already running, exiting"
	exit 1
fi

# XXX
# add checks for PID file every .1 seconds so sleep for x2 that just to
# make sure
sleep .2

while queue_work ; do
	queue_shift
	if [ ! -z "$queue_item" ] ; then
		if [ ! -z "$CMD" ] ; then
			$CMD $queue_item
		else
			eval "$queue_item"
		fi
	fi
	sleep_pause
done

# remove PID file right before exiting
rm -f "$WORKER_PID"