@pgflow/core 0.2.3 → 0.2.4

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.
package/dist/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # @pgflow/core
2
2
 
3
+ ## 0.2.4
4
+
5
+ ### Patch Changes
6
+
7
+ - 2f13e8b: Fix `poll_for_tasks` latency
8
+
9
+ The previous implementation were calling `read_with_poll` in same statement
10
+ as the `SELECT FROM step_tasks`, which resulted in new tasks that were inserted
11
+ after the `read_with_poll` started were not discovered as those were not visible
12
+ in the statement.
13
+
14
+ Now `poll_for_tasks` is split to separate statements so step tasks created
15
+ during the `poll_for_tasks` will be immediately picked up.
16
+
17
+ - @pgflow/dsl@0.2.4
18
+
3
19
  ## 0.2.3
4
20
 
5
21
  ### Patch Changes
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pgflow/core",
3
- "version": "0.2.3",
3
+ "version": "0.2.4",
4
4
  "license": "AGPL-3.0",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -0,0 +1,101 @@
1
+ -- Modify "poll_for_tasks" function
2
+ CREATE OR REPLACE FUNCTION "pgflow"."poll_for_tasks" ("queue_name" text, "vt" integer, "qty" integer, "max_poll_seconds" integer DEFAULT 5, "poll_interval_ms" integer DEFAULT 100) RETURNS SETOF "pgflow"."step_task_record" LANGUAGE plpgsql SET "search_path" = '' AS $$
3
+ declare
4
+ msg_ids bigint[];
5
+ begin
6
+ -- First statement: Read messages and capture their IDs
7
+ -- This gets its own snapshot and can see newly committed messages
8
+ select array_agg(msg_id)
9
+ into msg_ids
10
+ from pgflow.read_with_poll(
11
+ queue_name,
12
+ vt,
13
+ qty,
14
+ max_poll_seconds,
15
+ poll_interval_ms
16
+ );
17
+
18
+ -- If no messages were read, return empty set
19
+ if msg_ids is null or array_length(msg_ids, 1) is null then
20
+ return;
21
+ end if;
22
+
23
+ -- Second statement: Process tasks with fresh snapshot
24
+ -- This can now see step_tasks that were committed during the poll
25
+ return query
26
+ with tasks as (
27
+ select
28
+ task.flow_slug,
29
+ task.run_id,
30
+ task.step_slug,
31
+ task.task_index,
32
+ task.message_id
33
+ from pgflow.step_tasks as task
34
+ where task.message_id = any(msg_ids)
35
+ and task.status = 'queued'
36
+ ),
37
+ increment_attempts as (
38
+ update pgflow.step_tasks
39
+ set attempts_count = attempts_count + 1
40
+ from tasks
41
+ where step_tasks.message_id = tasks.message_id
42
+ and status = 'queued'
43
+ ),
44
+ runs as (
45
+ select
46
+ r.run_id,
47
+ r.input
48
+ from pgflow.runs r
49
+ where r.run_id in (select run_id from tasks)
50
+ ),
51
+ deps as (
52
+ select
53
+ st.run_id,
54
+ st.step_slug,
55
+ dep.dep_slug,
56
+ dep_task.output as dep_output
57
+ from tasks st
58
+ join pgflow.deps dep on dep.flow_slug = st.flow_slug and dep.step_slug = st.step_slug
59
+ join pgflow.step_tasks dep_task on
60
+ dep_task.run_id = st.run_id and
61
+ dep_task.step_slug = dep.dep_slug and
62
+ dep_task.status = 'completed'
63
+ ),
64
+ deps_outputs as (
65
+ select
66
+ d.run_id,
67
+ d.step_slug,
68
+ jsonb_object_agg(d.dep_slug, d.dep_output) as deps_output
69
+ from deps d
70
+ group by d.run_id, d.step_slug
71
+ ),
72
+ timeouts as (
73
+ select
74
+ task.message_id,
75
+ coalesce(step.opt_timeout, flow.opt_timeout) + 2 as vt_delay
76
+ from tasks task
77
+ join pgflow.flows flow on flow.flow_slug = task.flow_slug
78
+ join pgflow.steps step on step.flow_slug = task.flow_slug and step.step_slug = task.step_slug
79
+ )
80
+ select
81
+ st.flow_slug,
82
+ st.run_id,
83
+ st.step_slug,
84
+ jsonb_build_object('run', r.input) ||
85
+ coalesce(dep_out.deps_output, '{}'::jsonb) as input,
86
+ st.message_id as msg_id
87
+ from tasks st
88
+ join runs r on st.run_id = r.run_id
89
+ left join deps_outputs dep_out on
90
+ dep_out.run_id = st.run_id and
91
+ dep_out.step_slug = st.step_slug
92
+ cross join lateral (
93
+ -- TODO: this is slow because it calls set_vt for each row, and set_vt
94
+ -- builds dynamic query from string every time it is called
95
+ -- implement set_vt_batch(msgs_ids bigint[], vt_delays int[])
96
+ select pgmq.set_vt(queue_name, st.message_id,
97
+ (select t.vt_delay from timeouts t where t.message_id = st.message_id)
98
+ )
99
+ ) set_vt;
100
+ end;
101
+ $$;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pgflow/core",
3
- "version": "0.2.3",
3
+ "version": "0.2.4",
4
4
  "license": "AGPL-3.0",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -24,7 +24,7 @@
24
24
  },
25
25
  "dependencies": {
26
26
  "postgres": "^3.4.5",
27
- "@pgflow/dsl": "0.2.3"
27
+ "@pgflow/dsl": "0.2.4"
28
28
  },
29
29
  "publishConfig": {
30
30
  "access": "public"