Add the addCronTask helper to make registering cron tasks easier#982
Conversation
f3b7f73 to
099e1d2
Compare
eb3f6ff to
8fc5ae7
Compare
6d1b20a to
e48eb3b
Compare
|
/rebase |
e48eb3b to
9229557
Compare
| Necessity: each task has exactly one attempt limit | ||
| Necessity: each task has an attempt limit that is greater than or equal to 1 | ||
|
|
||
| Rule: It is necessary that each handler that executes a task that is scheduled with a cron expression and has a status that is equal to "queued", executes at most one task that is scheduled with a cron expression and has a status that is equal to "queued". |
There was a problem hiding this comment.
I think this can be simplified to:
| Rule: It is necessary that each handler that executes a task that is scheduled with a cron expression and has a status that is equal to "queued", executes at most one task that is scheduled with a cron expression and has a status that is equal to "queued". | |
| Rule: It is necessary that each handler executes at most one task that is scheduled with a cron expression and has a status that is equal to "queued". |
There was a problem hiding this comment.
@Page- It seems that the affected IDs optimization doesn't like it that rule (I also tried adding a comma, but that lead to "no match" errors):
Error: Only queries in the form of:
SELECT (SELECT COUNT(*) ...) = 0
SELECT NOT EXISTS (SELECT ...)
are supported for affected IDs insertion.
I also realized that this should also work (the sentence makes sense) but
a) Afaict filtering on both sides generates much faster queries, since allows the db to use indexes & cut down rows much sooner.
If we fake the generated sql (by filtering on the fields and then commenting them out), the generated query is prohibitively slow:
SELECT NOT EXISTS (
SELECT "task.1"."is executed by-handler"
FROM "task" AS "task.1"
WHERE TRUE
-- AND "task.1"."is scheduled with-cron expression" IS NOT NULL
-- AND 'queued' = "task.1"."status"
-- AND "task.1"."status" IS NOT NULL
AND (
SELECT COUNT(*)
FROM "task" AS "task.4"
WHERE "task.4"."is scheduled with-cron expression" IS NOT NULL
AND 'queued' = "task.4"."status"
AND "task.4"."status" IS NOT NULL
AND "task.4"."is executed by-handler" = "task.1"."is executed by-handler"
) >= 2
) AS "result";
QUERY PLAN
Result (cost=4.90..4.91 rows=1 width=1) (actual time=25883.233..25883.235 rows=1 loops=1)
Output: (NOT (InitPlan 2).col1)
InitPlan 2
-> Seq Scan on public.task task_1 (cost=0.00..6711290.02 rows=1368708 width=0) (actual time=25883.231..25883.231 rows=0 loops=1)
Filter: ((SubPlan 1) >= 2)
Rows Removed by Filter: 4112852
SubPlan 1
-> Aggregate (cost=1.59..1.60 rows=1 width=8) (actual time=0.006..0.006 rows=1 loops=4112852)
Output: count(*)
-> Index Scan using idx_task_poll on public.task (cost=0.12..1.58 rows=1 width=0) (actual time=0.005..0.005 rows=0 loops=4112852)
Index Cond: ((task."is executed by-handler")::text = (task_1."is executed by-handler")::text)
Filter: (task."is scheduled with-cron expression" IS NOT NULL)
Planning Time: 0.326 ms
Execution Time: 25883.270 mson the other hand w/ the filters present on both sides the query is much faster:
QUERY PLAN
Result (cost=3.18..3.19 rows=1 width=1) (actual time=5.364..5.365 rows=1 loops=1)
Output: (NOT (InitPlan 2).col1)
InitPlan 2
-> Index Scan using idx_task_poll on public.task task_1 (cost=0.12..3.18 rows=1 width=0) (actual time=5.362..5.363 rows=0 loops=1)
Filter: ((task_1."is scheduled with-cron expression" IS NOT NULL) AND ((SubPlan 1) >= 2))
SubPlan 1
-> Aggregate (cost=1.59..1.60 rows=1 width=8) (never executed)
Output: count(*)
-> Index Scan using idx_task_poll on public.task (cost=0.12..1.58 rows=1 width=0) (never executed)
Index Cond: ((task."is executed by-handler")::text = (task_1."is executed by-handler")::text)
Filter: (task."is scheduled with-cron expression" IS NOT NULL)
Planning Time: 0.305 ms
Execution Time: 5.393 msb) I followed the pattern that we use in all other cases where we mirror the where clauses in both sides.
Necessity: each name (Auth) that is of an application membership role that belongs to an organization, is of at most one application membership role that belongs to the organization.
Rule: It is necessary that each application that owns a release1 that has a status that is equal to "success" and is not invalidated and has a release version, owns at most one release2 that has a status that is equal to "success" and is not invalidated and has a release version that is of the release1.
Rule: It is necessary that each image that is produced by a delta1 that has a status that is equal to "success" and originates from an image1, is produced by at most one delta that originates from the image1 and has a version that is of the delta1 and has a status that is equal to "success".
fwiw, given the benefits of the pattern of having the "where clauses" on both sides & that we use it in all such rules atm, it's the pattern that my partial unique index auto generation PR v is attempting to detect:
balena-io-modules/abstract-sql-compiler#316
There was a problem hiding this comment.
Yeah I realized that it's specifically the pattern of each $column that is of ... $table ..., is of ... $table ... that needs to happen, since in this case handler isn't really something that exists in its own right and so not having the that predicate means things get particularly weird with the sql generation
|
/rebase |
9229557 to
c5a049b
Compare
c5a049b to
95ee017
Compare
|
/rebase |
95ee017 to
4026b57
Compare
| Necessity: each task has exactly one attempt limit | ||
| Necessity: each task has an attempt limit that is greater than or equal to 1 | ||
|
|
||
| Rule: It is necessary that each handler that executes a task that is scheduled with a cron expression and has a status that is equal to "queued", executes at most one task that is scheduled with a cron expression and has a status that is equal to "queued". |
There was a problem hiding this comment.
Yeah I realized that it's specifically the pattern of each $column that is of ... $table ..., is of ... $table ... that needs to happen, since in this case handler isn't really something that exists in its own right and so not having the that predicate means things get particularly weird with the sql generation
|
/rebae |
|
/rebase |
4026b57 to
a132a08
Compare
Change-type: minor
See: https://balena.fibery.io/Work/Project/961