@ -19,79 +19,82 @@ const fetchQuery = `
LIMIT : resultLimit
` ;
const fillQuery = `
function makeFillQuery ( withDependencies ) {
return `
WITH
dependency _tasks AS (
SELECT * FROM
json _to _recordset ( : dependencyTaskDefinitions ) AS x ( task text , task _version text )
$ { withDependencies ? `
dependencies AS (
SELECT * FROM json _to _recordset ( : dependencyTaskDefinitions ) AS x ( task text , task _version text )
) ,
matching _items AS (
SELECT
srap _items . * ,
results . updated _at AS result _date ,
results . task _version ,
(
results . is _successful = TRUE
AND (
results . expires _at < NOW ( )
OR results . is _invalidated = TRUE
)
) AS is _candidate
FROM srap _items
INNER JOIN srap _tags
ON srap _tags . item _id = srap _items . id
AND srap _tags . name = ANY ( : tags )
satisfied AS (
SELECT results . * FROM dependencies
LEFT JOIN srap _task _results AS results
ON results . item _id = srap _items . id
AND results . task = : task
ON dependencies . task = results . task
AND dependencies . task _version = results . task _version
WHERE
results . is _successful = TRUE
AND results . is _invalidated = FALSE
AND results . expires _at > NOW ( )
) ,
candidates AS (
SELECT * FROM matching _items
WHERE result _date IS NULL
UNION ALL
SELECT * FROM matching _items
WHERE is _candidate = TRUE
OR NOT ( task _version = : taskVersion )
counts AS (
SELECT item _id , COUNT ( task ) AS count FROM satisfied GROUP BY item _id
) ,
dependency _candidates AS (
SELECT item _id FROM counts WHERE count = : dependencyCount
) ,
` : "" }
tag _candidates AS (
SELECT item _id FROM srap _tags WHERE name = ANY ( : tags )
) ,
full _candidates AS MATERIALIZED (
$ { withDependencies
? `
SELECT tag _candidates . item _id FROM dependency _candidates
INNER JOIN tag _candidates
ON dependency _candidates . item _id = tag _candidates . item _id
`
: `
SELECT item _id FROM tag _candidates
`
}
)
(
SELECT
: task AS task ,
id AS item _id
FROM
candidates
WHERE
NOT EXISTS (
SELECT
results . *
FROM dependency _tasks
LEFT JOIN srap _task _results AS results
ON dependency _tasks . task = results . task
AND dependency _tasks . task _version = results . task _version
AND results . item _id = candidates . id
item _id
FROM full _candidates
WHERE NOT EXISTS (
SELECT item _id FROM srap _task _results AS results
WHERE
results . is _successful IS NULL
OR results . is _successful = FALSE
OR (
results . is _successful = TRUE
AND (
results . expires _at < NOW ( )
OR results . is _invalidated = TRUE
)
)
)
item _id = full _candidates . item _id
AND results . task = : task
AND results . task _version = : taskVersion
AND results . is _successful = TRUE
AND results . is _invalidated = FALSE
AND results . expires _at > NOW ( )
)
` ;
}
const fillQueryWithDependencies = makeFillQuery ( true ) ;
const fillQueryWithoutDependencies = makeFillQuery ( false ) ;
module . exports = function ( { metrics , backendSettings , knex } ) {
return function ( tx , { task } ) {
let hasDependencies = ( task . dependencies . length > 0 ) ;
let refillParameters = {
tags : task . tags ,
task : task . name ,
taskVersion : task . version ,
... hasDependencies
? {
dependencyCount : task . dependencies . length ,
dependencyTaskDefinitions : JSON . stringify ( task . dependencies . map ( ( dependency ) => {
// Case-mapping for SQL compatibility
return { task _version : dependency . version , task : dependency . name } ;
} ) )
}
: { }
} ;
let fetchParameters = {
@ -104,6 +107,10 @@ module.exports = function ({ metrics, backendSettings, knex }) {
let startTime = Date . now ( ) ;
return Promise . try ( ( ) => {
let fillQuery = ( hasDependencies )
? fillQueryWithDependencies
: fillQueryWithoutDependencies ;
// NOTE: We are deliberately bypassing the transaction here! Also deliberately not using VALUES, since we're inserting from the results of another query instead
return knex . raw ( `
INSERT INTO srap _queue ( task , item _id )