postjob 0.4.5 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/postjob.rb +22 -13
- data/lib/postjob/cli/events.rb +60 -0
- data/lib/postjob/cli/heartbeat.rb +55 -0
- data/lib/postjob/cli/hosts.rb +67 -0
- data/lib/postjob/cli/ps.rb +1 -13
- data/lib/postjob/cli/sessions.rb +83 -0
- data/lib/postjob/job.rb +4 -15
- data/lib/postjob/migrations/003_postjobs.sql +10 -8
- data/lib/postjob/migrations/003b_processing_columns.sql +8 -8
- data/lib/postjob/migrations/005_helpers.sql +3 -1
- data/lib/postjob/migrations/006_enqueue.sql +3 -0
- data/lib/postjob/migrations/006a_processing.sql +6 -26
- data/lib/postjob/migrations/007_job_results.sql +32 -13
- data/lib/postjob/migrations/008_checkout_runnable.sql +15 -21
- data/lib/postjob/migrations/008a_childjobs.sql +13 -0
- data/lib/postjob/migrations/010_settings.sql +18 -3
- data/lib/postjob/migrations/011_null_uuid.sql +7 -0
- data/lib/postjob/migrations/012_hosts.sql +42 -0
- data/lib/postjob/migrations/013_worker_sessions.sql +44 -0
- data/lib/postjob/migrations/014_postjob_session_id.sql +17 -0
- data/lib/postjob/migrations/015_events.sql +76 -0
- data/lib/postjob/migrations/016_sessions_functions.sql +16 -0
- data/lib/postjob/migrations/017_zombie_check.sql +58 -0
- data/lib/postjob/migrations/018_heartbeat.sql +28 -0
- data/lib/postjob/migrations/019_heartbeat_indices.sql +5 -0
- data/lib/postjob/queue.rb +41 -27
- data/lib/postjob/queue/notifications.rb +5 -4
- data/lib/postjob/queue/search.rb +2 -0
- data/lib/postjob/queue/settings.rb +11 -1
- data/lib/postjob/record.rb +17 -0
- data/lib/postjob/runner.rb +9 -2
- data/lib/postjob/worker_session.rb +76 -0
- data/lib/postjob/workflow.rb +0 -4
- data/lib/tools/atomic_store.rb +17 -0
- data/lib/tools/heartbeat.rb +151 -0
- data/lib/tools/history.rb +25 -0
- data/spec/postjob/events/heartbeat_event_spec.rb +85 -0
- data/spec/postjob/events/job_event_spec.rb +80 -0
- data/spec/postjob/job_control/max_attempts_spec.rb +0 -2
- data/spec/postjob/queue/search_spec.rb +0 -14
- data/spec/postjob/worker_session_spec.rb +41 -0
- data/spec/spec_helper.rb +9 -0
- data/spec/support/test_helper.rb +11 -1
- metadata +43 -3
- data/spec/postjob/job_control/workflow_status_spec.rb +0 -52
| @@ -1,31 +1,31 @@ | |
| 1 1 | 
             
            DO $$
         | 
| 2 2 | 
             
              BEGIN
         | 
| 3 | 
            -
                ALTER TABLE {SCHEMA_NAME}.postjobs  | 
| 3 | 
            +
                ALTER TABLE {SCHEMA_NAME}.postjobs DROP COLUMN processing_client;
         | 
| 4 4 | 
             
              EXCEPTION
         | 
| 5 | 
            -
                WHEN  | 
| 5 | 
            +
                WHEN undefined_column THEN RAISE DEBUG 'column {SCHEMA_NAME}.postjobs.processing_client already dropped';
         | 
| 6 6 | 
             
              END;
         | 
| 7 7 | 
             
            $$;
         | 
| 8 8 |  | 
| 9 9 | 
             
            DO $$
         | 
| 10 10 | 
             
              BEGIN
         | 
| 11 | 
            -
                ALTER TABLE {SCHEMA_NAME}.postjobs  | 
| 11 | 
            +
                ALTER TABLE {SCHEMA_NAME}.postjobs DROP COLUMN processing_client_identifier;
         | 
| 12 12 | 
             
              EXCEPTION
         | 
| 13 | 
            -
                WHEN  | 
| 13 | 
            +
                WHEN undefined_column THEN RAISE DEBUG 'column {SCHEMA_NAME}.postjobs.processing_client_identifier already dropped';
         | 
| 14 14 | 
             
              END;
         | 
| 15 15 | 
             
            $$;
         | 
| 16 16 |  | 
| 17 17 | 
             
            DO $$
         | 
| 18 18 | 
             
              BEGIN
         | 
| 19 | 
            -
                ALTER TABLE {SCHEMA_NAME}.postjobs  | 
| 19 | 
            +
                ALTER TABLE {SCHEMA_NAME}.postjobs DROP COLUMN processing_started_at;
         | 
| 20 20 | 
             
              EXCEPTION
         | 
| 21 | 
            -
                WHEN  | 
| 21 | 
            +
                WHEN undefined_column THEN RAISE DEBUG 'column {SCHEMA_NAME}.postjobs.processing_started_at already dropped';
         | 
| 22 22 | 
             
              END;
         | 
| 23 23 | 
             
            $$;
         | 
| 24 24 |  | 
| 25 25 | 
             
            DO $$
         | 
| 26 26 | 
             
              BEGIN
         | 
| 27 | 
            -
                ALTER TABLE {SCHEMA_NAME}.postjobs  | 
| 27 | 
            +
                ALTER TABLE {SCHEMA_NAME}.postjobs DROP COLUMN processing_max_duration;
         | 
| 28 28 | 
             
              EXCEPTION
         | 
| 29 | 
            -
                WHEN  | 
| 29 | 
            +
                WHEN undefined_column THEN RAISE DEBUG 'column {SCHEMA_NAME}.postjobs.processing_max_duration already dropped';
         | 
| 30 30 | 
             
              END;
         | 
| 31 31 | 
             
            $$;
         | 
| @@ -14,10 +14,12 @@ BEGIN; | |
| 14 14 | 
             
                EXECUTE PROCEDURE {SCHEMA_NAME}._wakeup_runners();
         | 
| 15 15 | 
             
            COMMIT;
         | 
| 16 16 |  | 
| 17 | 
            -
             | 
| 17 | 
            +
            DROP FUNCTION IF EXISTS {SCHEMA_NAME}._wakeup_parent_job(job_id BIGINT);  -- removed in 0.5.0
         | 
| 18 | 
            +
            CREATE OR REPLACE FUNCTION {SCHEMA_NAME}._wakeup_parent_job(worker_session_id UUID, job_id BIGINT) RETURNS VOID AS $$
         | 
| 18 19 | 
             
            BEGIN
         | 
| 19 20 | 
             
              UPDATE {SCHEMA_NAME}.postjobs
         | 
| 20 21 | 
             
              SET
         | 
| 22 | 
            +
                last_worker_session_id=worker_session_id,
         | 
| 21 23 | 
             
                status='ready',
         | 
| 22 24 | 
             
                next_run_at=(now() at time zone 'utc'),
         | 
| 23 25 | 
             
                updated_at=(now() at time zone 'utc')
         | 
| @@ -1,4 +1,5 @@ | |
| 1 1 | 
             
            CREATE OR REPLACE FUNCTION {SCHEMA_NAME}.enqueue(
         | 
| 2 | 
            +
                p_worker_session_id UUID,
         | 
| 2 3 | 
             
                queue VARCHAR,
         | 
| 3 4 | 
             
                workflow VARCHAR,
         | 
| 4 5 | 
             
                workflow_method VARCHAR,
         | 
| @@ -25,11 +26,13 @@ AS $$ | |
| 25 26 |  | 
| 26 27 | 
             
                -- create postjobs entry ------------------------------------------
         | 
| 27 28 | 
             
                INSERT INTO {SCHEMA_NAME}.postjobs (
         | 
| 29 | 
            +
                  last_worker_session_id,
         | 
| 28 30 | 
             
                  queue, workflow, workflow_method, workflow_version, args,
         | 
| 29 31 | 
             
                  parent_id, tags, max_attempts,
         | 
| 30 32 | 
             
                  timing_out_at
         | 
| 31 33 | 
             
                )
         | 
| 32 34 | 
             
                VALUES(
         | 
| 35 | 
            +
                  p_worker_session_id,
         | 
| 33 36 | 
             
                  queue, workflow, workflow_method, workflow_version, args,
         | 
| 34 37 | 
             
                  parent_id, tags, max_attempts,
         | 
| 35 38 | 
             
                  (now() at time zone 'utc') + timeout * interval '1 second'
         | 
| @@ -1,20 +1,5 @@ | |
| 1 | 
            -
             | 
| 2 | 
            -
             | 
| 3 | 
            -
              PERFORM set_config('{SCHEMA_NAME}.client_identifier', client_identifier, false);
         | 
| 4 | 
            -
            END;
         | 
| 5 | 
            -
            $$ LANGUAGE plpgsql;
         | 
| 6 | 
            -
             | 
| 7 | 
            -
            --SELECT {SCHEMA_NAME}.set_client_identifier('nope');
         | 
| 8 | 
            -
             | 
| 9 | 
            -
            CREATE OR REPLACE FUNCTION {SCHEMA_NAME}._client_identifier() RETURNS varchar AS $$
         | 
| 10 | 
            -
            BEGIN
         | 
| 11 | 
            -
              RETURN current_setting('{SCHEMA_NAME}.client_identifier');
         | 
| 12 | 
            -
            EXCEPTION
         | 
| 13 | 
            -
              WHEN OTHERS THEN RETURN NULL;
         | 
| 14 | 
            -
            END;
         | 
| 15 | 
            -
            $$ LANGUAGE plpgsql;
         | 
| 16 | 
            -
             | 
| 17 | 
            -
            CREATE OR REPLACE FUNCTION {SCHEMA_NAME}._set_job_processing(job_id BIGINT) RETURNS VOID AS $$
         | 
| 1 | 
            +
            DROP FUNCTION IF EXISTS {SCHEMA_NAME}._set_job_processing(job_id BIGINT);  -- removed in 0.5.0
         | 
| 2 | 
            +
            CREATE OR REPLACE FUNCTION {SCHEMA_NAME}._set_job_processing(worker_session_id UUID, job_id BIGINT) RETURNS VOID AS $$
         | 
| 18 3 | 
             
            DECLARE
         | 
| 19 4 | 
             
              v_pid int;
         | 
| 20 5 | 
             
            BEGIN
         | 
| @@ -22,11 +7,8 @@ BEGIN | |
| 22 7 |  | 
| 23 8 | 
             
              UPDATE {SCHEMA_NAME}.postjobs
         | 
| 24 9 | 
             
              SET
         | 
| 10 | 
            +
                last_worker_session_id=worker_session_id,
         | 
| 25 11 | 
             
                status='processing',
         | 
| 26 | 
            -
                processing_client=(SELECT client_addr || ':' || client_port FROM pg_stat_activity WHERE pid = v_pid),
         | 
| 27 | 
            -
                processing_client_identifier={SCHEMA_NAME}._client_identifier(),
         | 
| 28 | 
            -
                processing_started_at=now() at time zone 'utc',
         | 
| 29 | 
            -
                processing_max_duration=30 * 60, -- default max duration of processing: 30 minutes.
         | 
| 30 12 | 
             
                error=NULL,
         | 
| 31 13 | 
             
                error_message=NULL,
         | 
| 32 14 | 
             
                error_backtrace=NULL,
         | 
| @@ -35,14 +17,12 @@ BEGIN | |
| 35 17 | 
             
            END;
         | 
| 36 18 | 
             
            $$ LANGUAGE plpgsql;
         | 
| 37 19 |  | 
| 38 | 
            -
             | 
| 20 | 
            +
            DROP FUNCTION IF EXISTS {SCHEMA_NAME}._reset_job_processing(job_id BIGINT);  -- removed in 0.5.0
         | 
| 21 | 
            +
            CREATE OR REPLACE FUNCTION {SCHEMA_NAME}._reset_job_processing(worker_session_id UUID, job_id BIGINT) RETURNS VOID AS $$
         | 
| 39 22 | 
             
            BEGIN
         | 
| 40 23 | 
             
              UPDATE {SCHEMA_NAME}.postjobs
         | 
| 41 24 | 
             
              SET
         | 
| 42 | 
            -
                 | 
| 43 | 
            -
                processing_client_identifier=NULL,
         | 
| 44 | 
            -
                processing_started_at=NULL,
         | 
| 45 | 
            -
                processing_max_duration=NULL
         | 
| 25 | 
            +
                last_worker_session_id=worker_session_id
         | 
| 46 26 | 
             
              WHERE id=job_id;
         | 
| 47 27 | 
             
            END;
         | 
| 48 28 | 
             
            $$ LANGUAGE plpgsql;
         | 
| @@ -10,10 +10,11 @@ BEGIN | |
| 10 10 | 
             
            END;
         | 
| 11 11 | 
             
            $$ LANGUAGE plpgsql;
         | 
| 12 12 |  | 
| 13 | 
            -
             | 
| 13 | 
            +
            DROP FUNCTION IF EXISTS {SCHEMA_NAME}.set_job_result(job_id BIGINT, p_results JSONB, p_version VARCHAR);  -- removed in 0.5.0
         | 
| 14 | 
            +
            CREATE OR REPLACE FUNCTION {SCHEMA_NAME}.set_job_result(p_worker_session_id UUID, job_id BIGINT, p_results JSONB, p_version VARCHAR) RETURNS VOID AS $$
         | 
| 14 15 | 
             
            BEGIN
         | 
| 15 16 | 
             
              PERFORM {SCHEMA_NAME}._update_job_version(job_id, p_version);
         | 
| 16 | 
            -
              PERFORM {SCHEMA_NAME}._reset_job_processing(job_id);
         | 
| 17 | 
            +
              PERFORM {SCHEMA_NAME}._reset_job_processing(p_worker_session_id, job_id);
         | 
| 17 18 |  | 
| 18 19 | 
             
              UPDATE {SCHEMA_NAME}.postjobs
         | 
| 19 20 | 
             
              SET
         | 
| @@ -25,17 +26,21 @@ BEGIN | |
| 25 26 | 
             
                next_run_at=NULL
         | 
| 26 27 | 
             
              WHERE id=job_id;
         | 
| 27 28 |  | 
| 28 | 
            -
              PERFORM {SCHEMA_NAME}._wakeup_parent_job(job_id);
         | 
| 29 | 
            +
              PERFORM {SCHEMA_NAME}._wakeup_parent_job(p_worker_session_id, job_id);
         | 
| 29 30 | 
             
            END;
         | 
| 30 31 | 
             
            $$ LANGUAGE plpgsql;
         | 
| 31 32 |  | 
| 32 | 
            -
             | 
| 33 | 
            +
            DROP FUNCTION IF EXISTS {SCHEMA_NAME}.set_job_pending(job_id BIGINT, p_version VARCHAR);  -- removed in 0.5.0
         | 
| 34 | 
            +
            CREATE OR REPLACE FUNCTION {SCHEMA_NAME}.set_job_pending(p_worker_session_id UUID, job_id BIGINT, p_version VARCHAR) RETURNS VOID AS $$
         | 
| 33 35 | 
             
            BEGIN
         | 
| 34 36 | 
             
              PERFORM {SCHEMA_NAME}._update_job_version(job_id, p_version);
         | 
| 35 | 
            -
              PERFORM {SCHEMA_NAME}._reset_job_processing(job_id);
         | 
| 37 | 
            +
              PERFORM {SCHEMA_NAME}._reset_job_processing(p_worker_session_id, job_id);
         | 
| 36 38 |  | 
| 37 39 | 
             
              UPDATE {SCHEMA_NAME}.postjobs
         | 
| 38 | 
            -
              SET | 
| 40 | 
            +
              SET
         | 
| 41 | 
            +
                last_worker_session_id=p_worker_session_id,
         | 
| 42 | 
            +
                status='sleep',
         | 
| 43 | 
            +
                next_run_at=NULL
         | 
| 39 44 | 
             
              WHERE id=job_id;
         | 
| 40 45 | 
             
            END;
         | 
| 41 46 | 
             
            $$ LANGUAGE plpgsql;
         | 
| @@ -82,7 +87,16 @@ BEGIN | |
| 82 87 | 
             
            END;
         | 
| 83 88 | 
             
            $$ LANGUAGE plpgsql;
         | 
| 84 89 |  | 
| 90 | 
            +
            DROP FUNCTION IF EXISTS {SCHEMA_NAME}.set_job_error(
         | 
| 91 | 
            +
              job_id BIGINT,
         | 
| 92 | 
            +
              p_error VARCHAR,
         | 
| 93 | 
            +
              p_error_message VARCHAR,
         | 
| 94 | 
            +
              p_error_backtrace JSONB,
         | 
| 95 | 
            +
              p_status {SCHEMA_NAME}.statuses,
         | 
| 96 | 
            +
              p_version VARCHAR,
         | 
| 97 | 
            +
              p_fast_mode BOOLEAN);  -- removed in 0.5.0
         | 
| 85 98 | 
             
            CREATE OR REPLACE FUNCTION {SCHEMA_NAME}.set_job_error(
         | 
| 99 | 
            +
              p_worker_session_id UUID,
         | 
| 86 100 | 
             
              job_id BIGINT,
         | 
| 87 101 | 
             
              p_error VARCHAR,
         | 
| 88 102 | 
             
              p_error_message VARCHAR,
         | 
| @@ -92,11 +106,12 @@ CREATE OR REPLACE FUNCTION {SCHEMA_NAME}.set_job_error( | |
| 92 106 | 
             
              p_fast_mode BOOLEAN) RETURNS VOID AS $$
         | 
| 93 107 | 
             
            BEGIN
         | 
| 94 108 | 
             
              PERFORM {SCHEMA_NAME}._update_job_version(job_id, p_version);
         | 
| 95 | 
            -
              PERFORM {SCHEMA_NAME}._reset_job_processing(job_id);
         | 
| 109 | 
            +
              PERFORM {SCHEMA_NAME}._reset_job_processing(p_worker_session_id, job_id);
         | 
| 96 110 |  | 
| 97 111 | 
             
              -- write error info
         | 
| 98 112 | 
             
              UPDATE {SCHEMA_NAME}.postjobs
         | 
| 99 113 | 
             
              SET
         | 
| 114 | 
            +
                last_worker_session_id=p_worker_session_id,
         | 
| 100 115 | 
             
                error=p_error,
         | 
| 101 116 | 
             
                error_message=p_error_message,
         | 
| 102 117 | 
             
                error_backtrace=p_error_backtrace,
         | 
| @@ -106,15 +121,17 @@ BEGIN | |
| 106 121 |  | 
| 107 122 | 
             
              -- prepare next run, if any
         | 
| 108 123 | 
             
              PERFORM {SCHEMA_NAME}._prepare_next_run(job_id, p_status, p_fast_mode);
         | 
| 109 | 
            -
              PERFORM {SCHEMA_NAME}._wakeup_parent_job(job_id);
         | 
| 124 | 
            +
              PERFORM {SCHEMA_NAME}._wakeup_parent_job(p_worker_session_id, job_id);
         | 
| 110 125 | 
             
            END;
         | 
| 111 126 | 
             
            $$ LANGUAGE plpgsql;
         | 
| 112 127 |  | 
| 128 | 
            +
            DROP FUNCTION IF EXISTS {SCHEMA_NAME}._set_job_timeout(job_id BIGINT, p_fast_mode BOOLEAN);  -- removed in 0.5.0
         | 
| 113 129 | 
             
            CREATE OR REPLACE FUNCTION {SCHEMA_NAME}._set_job_timeout(
         | 
| 130 | 
            +
              p_worker_session_id UUID,
         | 
| 114 131 | 
             
              job_id BIGINT,
         | 
| 115 132 | 
             
              p_fast_mode BOOLEAN) RETURNS VOID AS $$
         | 
| 116 133 | 
             
            BEGIN
         | 
| 117 | 
            -
              PERFORM {SCHEMA_NAME}._reset_job_processing(job_id);
         | 
| 134 | 
            +
              PERFORM {SCHEMA_NAME}._reset_job_processing(p_worker_session_id, job_id);
         | 
| 118 135 |  | 
| 119 136 | 
             
              -- write error info
         | 
| 120 137 | 
             
              UPDATE {SCHEMA_NAME}.postjobs
         | 
| @@ -128,17 +145,19 @@ BEGIN | |
| 128 145 |  | 
| 129 146 | 
             
              -- prepare next run, if any
         | 
| 130 147 | 
             
              PERFORM {SCHEMA_NAME}._prepare_next_run(job_id, 'timeout', p_fast_mode);
         | 
| 131 | 
            -
              PERFORM {SCHEMA_NAME}._wakeup_parent_job(job_id);
         | 
| 148 | 
            +
              PERFORM {SCHEMA_NAME}._wakeup_parent_job(p_worker_session_id, job_id);
         | 
| 132 149 | 
             
            END;
         | 
| 133 150 | 
             
            $$ LANGUAGE plpgsql;
         | 
| 134 151 |  | 
| 135 152 | 
             
            CREATE OR REPLACE FUNCTION {SCHEMA_NAME}._set_job_zombie(
         | 
| 136 153 | 
             
              job_id BIGINT,
         | 
| 137 154 | 
             
              p_fast_mode BOOLEAN) RETURNS VOID AS $$
         | 
| 155 | 
            +
            DECLARE
         | 
| 156 | 
            +
              p_worker_session_id UUID;
         | 
| 138 157 | 
             
            BEGIN
         | 
| 139 | 
            -
               | 
| 158 | 
            +
              p_worker_session_id := {SCHEMA_NAME}._null_uuid();
         | 
| 140 159 |  | 
| 141 | 
            -
               | 
| 160 | 
            +
              PERFORM {SCHEMA_NAME}._reset_job_processing(p_worker_session_id, job_id);
         | 
| 142 161 |  | 
| 143 162 | 
             
              -- write error info
         | 
| 144 163 | 
             
              UPDATE {SCHEMA_NAME}.postjobs
         | 
| @@ -152,6 +171,6 @@ BEGIN | |
| 152 171 |  | 
| 153 172 | 
             
              -- prepare next run, if any
         | 
| 154 173 | 
             
              PERFORM {SCHEMA_NAME}._prepare_next_run(job_id, 'err', p_fast_mode);
         | 
| 155 | 
            -
              PERFORM {SCHEMA_NAME}._wakeup_parent_job(job_id);
         | 
| 174 | 
            +
              PERFORM {SCHEMA_NAME}._wakeup_parent_job(p_worker_session_id, job_id);
         | 
| 156 175 | 
             
            END;
         | 
| 157 176 | 
             
            $$ LANGUAGE plpgsql;
         | 
| @@ -1,14 +1,14 @@ | |
| 1 | 
            -
             | 
| 1 | 
            +
            DROP FUNCTION IF EXISTS {SCHEMA_NAME}.time_to_next_job(workflows_with_versions varchar[]);  -- removed in 0.5.0
         | 
| 2 | 
            +
            CREATE OR REPLACE FUNCTION {SCHEMA_NAME}.time_to_next_job(p_worker_session_id UUID)
         | 
| 2 3 | 
             
              RETURNS float
         | 
| 3 4 | 
             
            AS $$
         | 
| 4 5 | 
             
            DECLARE
         | 
| 5 6 | 
             
              p_processable_at timestamp;
         | 
| 7 | 
            +
              p_workflows_with_version varchar[];
         | 
| 6 8 | 
             
            BEGIN
         | 
| 9 | 
            +
              SELECT workflows INTO p_workflows_with_version FROM {SCHEMA_NAME}.worker_sessions WHERE id=p_worker_session_id;
         | 
| 10 | 
            +
             | 
| 7 11 | 
             
              SELECT MIN(processable_at) INTO p_processable_at FROM (
         | 
| 8 | 
            -
                  SELECT MIN(processing_started_at + processing_max_duration * interval '1 second') AS processable_at
         | 
| 9 | 
            -
                  FROM {SCHEMA_NAME}.postjobs
         | 
| 10 | 
            -
                  WHERE status IN ('processing')
         | 
| 11 | 
            -
                UNION
         | 
| 12 12 | 
             
                  SELECT MIN(timing_out_at) AS processable_at
         | 
| 13 13 | 
             
                  FROM {SCHEMA_NAME}.postjobs
         | 
| 14 14 | 
             
                  WHERE status IN ('ready', 'err', 'sleep')
         | 
| @@ -16,30 +16,29 @@ BEGIN | |
| 16 16 | 
             
                  SELECT MIN(next_run_at) AS processable_at
         | 
| 17 17 | 
             
                  FROM {SCHEMA_NAME}.postjobs
         | 
| 18 18 | 
             
                  WHERE status IN ('ready', 'err')
         | 
| 19 | 
            -
                    AND workflow || workflow_version = ANY ( | 
| 19 | 
            +
                    AND workflow || workflow_version = ANY (p_workflows_with_version)
         | 
| 20 20 | 
             
              ) sq;
         | 
| 21 21 |  | 
| 22 22 | 
             
              RETURN EXTRACT(EPOCH FROM  p_processable_at - (now() at time zone 'utc'));
         | 
| 23 23 | 
             
            END;
         | 
| 24 24 | 
             
            $$ LANGUAGE plpgsql;
         | 
| 25 25 |  | 
| 26 | 
            -
             | 
| 26 | 
            +
            DROP FUNCTION IF EXISTS {SCHEMA_NAME}.checkout(workflows_with_versions varchar[], p_fast_mode BOOLEAN);  -- removed in 0.5.0
         | 
| 27 | 
            +
            CREATE OR REPLACE FUNCTION {SCHEMA_NAME}.checkout(p_worker_session_id UUID, p_fast_mode BOOLEAN)
         | 
| 27 28 | 
             
              RETURNS SETOF {SCHEMA_NAME}.postjobs
         | 
| 28 29 | 
             
            AS $$
         | 
| 29 30 | 
             
            DECLARE
         | 
| 30 31 | 
             
              job {SCHEMA_NAME}.postjobs;
         | 
| 32 | 
            +
              p_workflows_with_version varchar[];
         | 
| 31 33 | 
             
            BEGIN
         | 
| 34 | 
            +
              SELECT workflows INTO p_workflows_with_version FROM {SCHEMA_NAME}.worker_sessions WHERE id=p_worker_session_id;
         | 
| 35 | 
            +
             | 
| 32 36 | 
             
              LOOP
         | 
| 33 37 | 
             
                -- try to checkout a job. Each of the conditions here is matching
         | 
| 34 38 | 
             
                -- one of the CASE .. WHEN clauses below.
         | 
| 35 39 | 
             
                SELECT INTO job *
         | 
| 36 40 | 
             
                FROM {SCHEMA_NAME}.postjobs s
         | 
| 37 41 | 
             
                WHERE
         | 
| 38 | 
            -
                  (
         | 
| 39 | 
            -
                    s.status IN ('processing')
         | 
| 40 | 
            -
                    AND (s.processing_started_at + s.processing_max_duration * interval '1 second') <= (now() at time zone 'utc')
         | 
| 41 | 
            -
                  )
         | 
| 42 | 
            -
                  OR
         | 
| 43 42 | 
             
                  (
         | 
| 44 43 | 
             
                    s.status IN ('ready', 'err', 'sleep')
         | 
| 45 44 | 
             
                    AND s.timing_out_at <= (now() at time zone 'utc')
         | 
| @@ -48,9 +47,9 @@ BEGIN | |
| 48 47 | 
             
                  (
         | 
| 49 48 | 
             
                    s.status IN ('ready', 'err')
         | 
| 50 49 | 
             
                    AND s.next_run_at <= (now() at time zone 'utc')
         | 
| 51 | 
            -
                    AND s.workflow || s.workflow_version = ANY ( | 
| 50 | 
            +
                    AND (s.workflow || s.workflow_version) = ANY (p_workflows_with_version)
         | 
| 52 51 | 
             
                  )
         | 
| 53 | 
            -
                ORDER BY (LEAST(s.next_run_at, s.timing_out_at | 
| 52 | 
            +
                ORDER BY (LEAST(s.next_run_at, s.timing_out_at))
         | 
| 54 53 | 
             
                FOR UPDATE SKIP LOCKED
         | 
| 55 54 | 
             
                LIMIT 1;
         | 
| 56 55 |  | 
| @@ -58,18 +57,13 @@ BEGIN | |
| 58 57 | 
             
                  WHEN job.id IS NULL THEN
         | 
| 59 58 | 
             
                    -- couldn't find a job?
         | 
| 60 59 | 
             
                    EXIT;
         | 
| 61 | 
            -
                  WHEN job.status='processing' AND
         | 
| 62 | 
            -
                    (job.processing_started_at + job.processing_max_duration * interval '1 second') <= (now() at time zone 'utc') THEN
         | 
| 63 | 
            -
                    -- a zombie: the worker probably died.
         | 
| 64 | 
            -
                    PERFORM {SCHEMA_NAME}._set_job_zombie(job.id, p_fast_mode);
         | 
| 65 | 
            -
                    CONTINUE;
         | 
| 66 60 | 
             
                  WHEN job.status IN ('ready', 'err', 'sleep') AND job.timing_out_at <= (now() at time zone 'utc') THEN
         | 
| 67 61 | 
             
                    -- job timed out? mark it as such, and try next one.
         | 
| 68 | 
            -
                    PERFORM {SCHEMA_NAME}._set_job_timeout(job.id, p_fast_mode);
         | 
| 62 | 
            +
                    PERFORM {SCHEMA_NAME}._set_job_timeout(p_worker_session_id, job.id, p_fast_mode);
         | 
| 69 63 | 
             
                    CONTINUE;
         | 
| 70 64 | 
             
                  ELSE
         | 
| 71 65 | 
             
                    -- set job to processing
         | 
| 72 | 
            -
                    PERFORM {SCHEMA_NAME}._set_job_processing(job.id);
         | 
| 66 | 
            +
                    PERFORM {SCHEMA_NAME}._set_job_processing(p_worker_session_id, job.id);
         | 
| 73 67 | 
             
                    RETURN QUERY SELECT * FROM {SCHEMA_NAME}.postjobs WHERE id=job.id;
         | 
| 74 68 | 
             
                    EXIT;
         | 
| 75 69 | 
             
                END CASE;
         | 
| @@ -18,7 +18,19 @@ BEGIN | |
| 18 18 | 
             
            END;
         | 
| 19 19 | 
             
            $$ LANGUAGE plpgsql;
         | 
| 20 20 |  | 
| 21 | 
            +
            DROP FUNCTION IF EXISTS {SCHEMA_NAME}.find_or_create_childjob(
         | 
| 22 | 
            +
              v_queue VARCHAR,
         | 
| 23 | 
            +
              v_workflow VARCHAR,
         | 
| 24 | 
            +
              v_workflow_method VARCHAR,
         | 
| 25 | 
            +
              v_workflow_version VARCHAR,
         | 
| 26 | 
            +
              v_args JSONB,
         | 
| 27 | 
            +
              v_parent_id BIGINT,
         | 
| 28 | 
            +
              v_tags JSONB,
         | 
| 29 | 
            +
              v_max_attempts INTEGER,
         | 
| 30 | 
            +
              v_timeout DOUBLE PRECISION);  -- removed in 0.5.0
         | 
| 31 | 
            +
             | 
| 21 32 | 
             
            CREATE OR REPLACE FUNCTION {SCHEMA_NAME}.find_or_create_childjob(
         | 
| 33 | 
            +
              p_worker_session_id UUID,
         | 
| 22 34 | 
             
              v_queue VARCHAR,
         | 
| 23 35 | 
             
              v_workflow VARCHAR,
         | 
| 24 36 | 
             
              v_workflow_method VARCHAR,
         | 
| @@ -67,6 +79,7 @@ BEGIN | |
| 67 79 |  | 
| 68 80 | 
             
                  RETURN QUERY
         | 
| 69 81 | 
             
                    SELECT * FROM {SCHEMA_NAME}.enqueue(
         | 
| 82 | 
            +
                      p_worker_session_id,
         | 
| 70 83 | 
             
                      COALESCE(v_queue, parent.queue),  -- queue VARCHAR,
         | 
| 71 84 | 
             
                      v_workflow,                       -- workflow VARCHAR,
         | 
| 72 85 | 
             
                      v_workflow_method,                -- workflow_method VARCHAR,
         | 
| @@ -3,7 +3,9 @@ CREATE TABLE IF NOT EXISTS {SCHEMA_NAME}.settings ( | |
| 3 3 | 
             
              value       VARCHAR
         | 
| 4 4 | 
             
            );
         | 
| 5 5 |  | 
| 6 | 
            -
             | 
| 6 | 
            +
            DROP FUNCTION IF EXISTS {SCHEMA_NAME}.update_settings(p_name VARCHAR, p_value VARCHAR);
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            CREATE OR REPLACE FUNCTION {SCHEMA_NAME}.settings_set(p_name VARCHAR, p_value VARCHAR)
         | 
| 7 9 | 
             
              RETURNS VOID
         | 
| 8 10 | 
             
            AS $$
         | 
| 9 11 | 
             
              BEGIN
         | 
| @@ -12,5 +14,18 @@ AS $$ | |
| 12 14 | 
             
              END;
         | 
| 13 15 | 
             
            $$ LANGUAGE plpgsql;
         | 
| 14 16 |  | 
| 15 | 
            -
             | 
| 16 | 
            -
             | 
| 17 | 
            +
            CREATE OR REPLACE FUNCTION {SCHEMA_NAME}.settings_get(p_name VARCHAR)
         | 
| 18 | 
            +
              RETURNS varchar
         | 
| 19 | 
            +
            AS $$
         | 
| 20 | 
            +
              DECLARE
         | 
| 21 | 
            +
                p_result varchar;
         | 
| 22 | 
            +
              BEGIN
         | 
| 23 | 
            +
                SELECT value INTO p_result FROM {SCHEMA_NAME}.settings WHERE name=$1;
         | 
| 24 | 
            +
                RETURN p_result;
         | 
| 25 | 
            +
              END;
         | 
| 26 | 
            +
            $$ LANGUAGE plpgsql;
         | 
| 27 | 
            +
             | 
| 28 | 
            +
            -- define version settings ----------------------------------------------------
         | 
| 29 | 
            +
             | 
| 30 | 
            +
            SELECT {SCHEMA_NAME}.settings_set('version', '0.5.0');
         | 
| 31 | 
            +
            SELECT {SCHEMA_NAME}.settings_set('client_version', '{CLIENT_VERSION}');
         | 
| @@ -0,0 +1,42 @@ | |
| 1 | 
            +
            -- hosts ----------------------------------------------------------------------
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            -- The hosts table records available hosts. hosts are the basis for the
         | 
| 4 | 
            +
            -- sticky jobs feature - a sticky job is a job which can only be checked
         | 
| 5 | 
            +
            -- out by a specific host.
         | 
| 6 | 
            +
            --
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            CREATE TABLE IF NOT EXISTS {SCHEMA_NAME}.hosts (
         | 
| 9 | 
            +
              id UUID PRIMARY KEY  DEFAULT (gen_random_uuid()),     -- UUID identifying a worker **host**
         | 
| 10 | 
            +
              attributes JSONB NOT NULL DEFAULT '{}'::JSONB,
         | 
| 11 | 
            +
              created_at timestamp NOT NULL DEFAULT (now() at time zone 'utc')
         | 
| 12 | 
            +
            );
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            CREATE INDEX IF NOT EXISTS hosts_attributes_idx
         | 
| 15 | 
            +
              ON {SCHEMA_NAME}.hosts USING GIN (attributes jsonb_path_ops);
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            -- returns _null_host_id ------------------------------------------------------
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            DO $$
         | 
| 20 | 
            +
              DECLARE
         | 
| 21 | 
            +
                null_uuid UUID := {SCHEMA_NAME}._null_uuid();
         | 
| 22 | 
            +
              BEGIN
         | 
| 23 | 
            +
                IF NOT EXISTS (SELECT 1 FROM {SCHEMA_NAME}.hosts WHERE id = null_uuid) THEN
         | 
| 24 | 
            +
                  INSERT INTO {SCHEMA_NAME}.hosts(id, attributes) VALUES(null_uuid, '{}');
         | 
| 25 | 
            +
                END IF;
         | 
| 26 | 
            +
              END;
         | 
| 27 | 
            +
            $$ LANGUAGE plpgsql;
         | 
| 28 | 
            +
             | 
| 29 | 
            +
            -- host_register: registers a host --------------------------------------------
         | 
| 30 | 
            +
             | 
| 31 | 
            +
            CREATE OR REPLACE FUNCTION {SCHEMA_NAME}.host_register(p_attrs JSONB)
         | 
| 32 | 
            +
              RETURNS UUID
         | 
| 33 | 
            +
            AS $$
         | 
| 34 | 
            +
              DECLARE
         | 
| 35 | 
            +
                v_id UUID;
         | 
| 36 | 
            +
              BEGIN
         | 
| 37 | 
            +
                v_id := gen_random_uuid();
         | 
| 38 | 
            +
                INSERT INTO {SCHEMA_NAME}.hosts (id, attributes)
         | 
| 39 | 
            +
                  VALUES (v_id, p_attrs);
         | 
| 40 | 
            +
                RETURN v_id;
         | 
| 41 | 
            +
              END;
         | 
| 42 | 
            +
            $$ LANGUAGE plpgsql;
         |