There could be a condition where jobs were added to a queue that is not longer being watched,
yet the jobs in those queues would continue appearing in the pending job list because
the query to get pending jobs did not filter by queues being watched.
Instead of passing a single connection into the pending job processor,
use the connection pool to pull a new connection on every loop, releasing
it after every use.
The previous release attempted to fix an issue where, when LISTEN connections
drop an reconnect, some job announcements might be missed.
This fix reduces the number of connections required to do so.
When jobs are inserted into the 'neoq_jobs', the `announce_job` trigger announces the job to
listeners of the job's queue. However, if no workers are available to receive the announcement,
or the announcement is somehow lost, it meant those jobs were marooned on the queue.
This fix adds a periodic check for post-due pending jobs to ensure that a neoq restart is
not necessary to catch marooned, overdue jobs.
This makes it so that channel names for NOTIFY/LISTEN/UNLISTEN are
consistent. That is that they are double quoted in all instances except
for when they are referenced by `pg_notify`. This way the channel names
are no longer case-insensitive.
This happens because of how PostgreSQL parses the SQL statements for
NOTIFY/LISTEN/UNLISTEN and treats the arguments as an identifier. Where
as it treats the arguments to `pg_notify` as only a string. This causes
arguments that are not double quoted to be adjusted to lower case when
passed to the SQL statement.
By making all usages consistent, we no longer have to worry about
channel names being odd.
When the queue name is uppercase, the listener will never receive the
notification when the job is enqueued. This is done specifically with
the enqueuer and consumer being separate neoq instances (server A kicks
off a job, server B is listening to perform the work).
I want to be able to know what job a log message is in regards to, so
this adds the queue to all of the log messages where its available. It
also makes some of the `error` logs more consistent with each other.
Since these values are being written in a separate go routine, it is
possible for a datarace to happen since we are reading them
unatomically. This just makes it so that both the reads ands writes are
done atomically.
Resolves#76