ℹ️ Select 'Choose Exercise', or randomize 'Next Random Exercise' in selected language.

Choose Exercise:
Timer 00:00
WPM --
Score --
Acc --
Correct chars --

PL/pgSQL Background Job Scheduler

PL/pgSQL

Goal -- WPM

Ready
Exercise Algorithm Area
1CREATE TABLE job_queue (
2job_id SERIAL PRIMARY KEY,
3job_name VARCHAR(100) NOT NULL,
4job_params JSONB,
5scheduled_at TIMESTAMP WITH TIME ZONE NOT NULL,
6created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
7status VARCHAR(20) DEFAULT 'PENDING' -- PENDING, RUNNING, COMPLETED, FAILED
8);
9
10CREATE UNIQUE INDEX idx_job_queue_unique_pending ON job_queue (job_name, job_params) WHERE status = 'PENDING';
11
12CREATE OR REPLACE FUNCTION enqueue_background_job(
13p_job_name VARCHAR,
14p_job_params JSONB,
15p_delay_seconds INTEGER
16) RETURNS BIGINT AS $$
17DECLARE
18v_job_id BIGINT;
19v_scheduled_at TIMESTAMP WITH TIME ZONE;
20BEGIN
21-- Calculate the scheduled execution time
22v_scheduled_at := NOW() + (p_delay_seconds * INTERVAL '1 second');
23
24-- Attempt to insert the job. The unique index will prevent duplicates.
25-- If a duplicate exists, an exception will be raised.
26BEGIN
27INSERT INTO job_queue (job_name, job_params, scheduled_at)
28VALUES (p_job_name, p_job_params, v_scheduled_at)
29RETURNING job_id INTO v_job_id;
30
31RAISE NOTICE 'Job ''%'' enqueued successfully with ID %.', p_job_name, v_job_id;
32RETURN v_job_id;
33EXCEPTION
34WHEN unique_violation THEN
35RAISE NOTICE 'Job ''%'' with parameters % is already pending. Skipping enqueue.', p_job_name, p_job_params;
36-- Optionally, you could fetch and return the existing job_id here
37-- SELECT job_id INTO v_job_id FROM job_queue WHERE job_name = p_job_name AND job_params = p_job_params AND status = 'PENDING';
38RETURN NULL; -- Indicate that no new job was enqueued
39WHEN OTHERS THEN
40RAISE EXCEPTION 'An unexpected error occurred while enqueuing job ''%''.', p_job_name;
41END;
42END;
43$$ LANGUAGE plpgsql;
Algorithm description viewbox

PL/pgSQL Background Job Scheduler

Algorithm description:

This PL/pgSQL solution provides a mechanism for scheduling background jobs. The `enqueue_background_job` function allows users to define a job by its name, parameters (as JSONB), and a delay in seconds before execution. It stores this information in a `job_queue` table. A unique constraint on `job_name`, `job_params`, and `status = 'PENDING'` prevents duplicate jobs from being enqueued for the same task. This is fundamental for building asynchronous processing systems, handling tasks like sending emails, generating reports, or performing periodic maintenance without blocking the main application flow.

Algorithm explanation:

The `enqueue_background_job` function calculates the `scheduled_at` timestamp by adding `p_delay_seconds` to the current time. It then attempts to `INSERT` a new record into the `job_queue` table. The key to preventing duplicate jobs is the `CREATE UNIQUE INDEX` statement, which enforces uniqueness for pending jobs based on `job_name` and `job_params`. If an `INSERT` violates this unique constraint (meaning a job with the same name and parameters is already pending), a `unique_violation` exception is caught, and a notice is raised. Otherwise, the `job_id` of the newly inserted job is returned. The time complexity for enqueuing a job is dominated by the `INSERT` operation and the index check, which is typically O(log N) on average for a balanced index, where N is the number of pending jobs. Space complexity is O(1) for the function's variables, plus the storage for the `job_queue` table itself.

Pseudocode:

CREATE TABLE job_queue (...)
CREATE UNIQUE INDEX ON job_queue (job_name, job_params) WHERE status = 'PENDING'

FUNCTION enqueue_background_job(job_name, job_params, delay_seconds):
  scheduled_time = NOW() + delay_seconds seconds

  TRY:
    INSERT INTO job_queue (job_name, job_params, scheduled_at)
    VALUES (job_name, job_params, scheduled_time)
    RETURNING job_id INTO new_job_id
    LOG 'Job enqueued with ID ' + new_job_id
    RETURN new_job_id
  CATCH unique_violation:
    LOG 'Job ' + job_name + ' with params ' + job_params + ' already pending. Skipping.'
    RETURN NULL
  CATCH other_error:
    RAISE EXCEPTION 'Error enqueuing job ' + job_name
END FUNCTION