Skip to content

Commit 9fbb5eb

Browse files
author
Vladimir Ershov
committed
bug fix slots move
web client for tests
1 parent f0e7402 commit 9fbb5eb

File tree

8 files changed

+453
-1
lines changed

8 files changed

+453
-1
lines changed

src/pgpro_scheduler.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,17 @@
1010
#define PGPRO_SCHEDULER_DBNAME_MAX 128
1111
#define PGPRO_SCHEDULER_NODENAME_MAX 128
1212
#define PGPRO_SCHEDULER_EXECUTOR_MESSAGE_MAX 1024
13+
#define PPGS_DEBUG 1
1314

15+
#ifdef PPGS_DEBUG
16+
#ifdef HAVE__VA_ARGS
17+
#define _pdebug(...) elog(LOG, __VA_ARGS__);
18+
#else
19+
#define _pdebug(...)
20+
#endif
21+
#else
22+
#define _pdebug(...)
23+
#endif
1424

1525
extern void worker_spi_sighup(SIGNAL_ARGS);
1626
extern void worker_spi_sigterm(SIGNAL_ARGS);

src/scheduler_manager.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -816,7 +816,7 @@ void destroy_slot_item(scheduler_manager_slot_t *item)
816816

817817
int scheduler_check_slots(scheduler_manager_ctx_t *ctx)
818818
{
819-
int i, busy;
819+
int i, j, busy;
820820
scheduler_rm_item_t *toremove;
821821
int nremove = 0;
822822
scheduler_manager_slot_t *item;
@@ -861,11 +861,14 @@ int scheduler_check_slots(scheduler_manager_ctx_t *ctx)
861861
}
862862
if(nremove)
863863
{
864+
_pdebug("do need to remove: %d", nremove);
864865
for(i=0; i < nremove; i++)
865866
{
866867
removeJob = true;
867868
job_status = false;
869+
_pdebug("=== remove position: %d", toremove[i].pos);
868870
item = ctx->slots[toremove[i].pos];
871+
_pdebug("=== remove cron_id: %d", item->job->cron_id);
869872

870873
if(toremove[i].reason == RmTimeout) /* TIME OUT */
871874
{
@@ -947,11 +950,23 @@ int scheduler_check_slots(scheduler_manager_ctx_t *ctx)
947950

948951
if(toremove[i].pos != last)
949952
{
953+
_pdebug("--- move from %d to %d", last, toremove[i].pos);
950954
ctx->slots[toremove[i].pos] = ctx->slots[last];
955+
ctx->slots[last] = NULL;
956+
for(j=i+1; j < nremove; j++)
957+
{
958+
if(toremove[j].pos == last)
959+
{
960+
toremove[j].pos = toremove[i].pos;
961+
break;
962+
}
963+
}
951964
}
952965
ctx->free_slots++;
966+
_pdebug("--- free slots: %d", ctx->free_slots);
953967
}
954968
}
969+
_pdebug("done remove: %d", nremove);
955970
}
956971
pfree(toremove);
957972
return 1;
@@ -1298,8 +1313,10 @@ void manager_worker_main(Datum arg)
12981313
{
12991314
if(rc & WL_LATCH_SET)
13001315
{
1316+
_pdebug("got latch from some bgworker");
13011317
scheduler_check_slots(ctx);
13021318
set_slots_stat_report(ctx);
1319+
_pdebug("quit got latch");
13031320
}
13041321
else if(rc & WL_TIMEOUT)
13051322
{

test/make_test_env.sql

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
-- DROP existent
2+
3+
DROP EXTENSION IF EXISTS pgpro_scheduler;
4+
DROP TABLE IF EXISTS result1;
5+
DROP TABLE IF EXISTS result2;
6+
DROP TABLE IF EXISTS result3;
7+
DROP TABLE IF EXISTS result5;
8+
DROP TABLE IF EXISTS result6;
9+
DROP TABLE IF EXISTS result7;
10+
11+
-- CREATE SCHEMA
12+
13+
CREATE EXTENSION pgpro_scheduler;
14+
15+
CREATE TABLE result1 (
16+
time_mark timestamp,
17+
text text
18+
);
19+
20+
CREATE TABLE result2 (
21+
time_mark timestamp,
22+
n int,
23+
text text
24+
);
25+
26+
CREATE TABLE result3 (
27+
time_mark timestamp,
28+
n int,
29+
text text
30+
);
31+
32+
CREATE TABLE result5 (
33+
time_mark timestamp,
34+
text text
35+
);
36+
37+
CREATE TABLE result6 (
38+
time_mark timestamp,
39+
text text
40+
);
41+
42+
CREATE TABLE result7 (
43+
time_mark timestamp,
44+
n int,
45+
text text,
46+
status text
47+
);
48+
49+
GRANT SELECT ON result1 TO robot;
50+
GRANT SELECT ON result2 TO robot;
51+
GRANT SELECT ON result3 TO robot;
52+
GRANT SELECT ON result5 TO robot;
53+
GRANT SELECT ON result6 TO robot;
54+
GRANT SELECT ON result7 TO robot;
55+
56+
GRANT INSERT ON result1 TO robot;
57+
GRANT INSERT ON result2 TO robot;
58+
GRANT INSERT ON result3 TO robot;
59+
GRANT INSERT ON result5 TO robot;
60+
GRANT INSERT ON result6 TO robot;
61+
GRANT INSERT ON result7 TO robot;
62+
63+
-- CREATE HELPER FUNCTIONS
64+
65+
CREATE OR REPLACE FUNCTION random_finish() RETURNS TEXT
66+
AS $BODY$
67+
DECLARE
68+
result INTEGER;
69+
BEGIN
70+
EXECUTE 'select (random() * 100)::int % 2' INTO result;
71+
IF result = 1 THEN
72+
RETURN 'done returned from function';
73+
ELSE
74+
RAISE EXCEPTION 'random failure of transaction';
75+
END IF;
76+
77+
RETURN 'miracle happend';
78+
END
79+
$BODY$ LANGUAGE plpgsql;
80+
81+
CREATE OR REPLACE FUNCTION get_next_time() RETURNS TIMESTAMP WITH TIME ZONE
82+
AS $BODY$
83+
DECLARE
84+
result INTEGER;
85+
DECLARE
86+
state text;
87+
BEGIN
88+
EXECUTE 'show schedule.transaction_state' INTO state;
89+
INSERT INTO result5 (time_mark, text) values (now(), 'transaction result: ' || state);
90+
RETURN now() + '00:05:15'::interval;
91+
END
92+
$BODY$ LANGUAGE plpgsql;
93+
94+
95+
-- CREATE JOBS
96+
97+
SELECT schedule.create_job(
98+
'{
99+
"name": "Test #1: every minute",
100+
"cron": "* * * * *",
101+
"command": "insert into result1 (time_mark, text) values (now(), ''result of job'')",
102+
"run_as": "robot"
103+
}'
104+
);
105+
106+
SELECT schedule.create_job(
107+
'{
108+
"name": "Test #2: every 15 minute, not sngl transaction",
109+
"cron": "*/15 * * * *",
110+
"cron": "* * * * *",
111+
"commands": [
112+
"insert into result2 (time_mark, n, text) values (now(), 1, ''start job'')",
113+
"insert into result2 (time_mark, n, text) values (now(), 2, random_finish())"
114+
],
115+
"run_as": "robot",
116+
"use_same_transaction": "false"
117+
}'
118+
);
119+
120+
SELECT schedule.create_job(
121+
'{
122+
"name": "Test #3: 2/3 minute, sngl transaction",
123+
"cron": "*/15 * * * *",
124+
"cron": "* * * * *",
125+
"commands": [
126+
"insert into result3 (time_mark, n, text) values (now(), 1, ''start job'')",
127+
"insert into result3 (time_mark, n, text) values (now(), 2, random_finish())"
128+
],
129+
"run_as": "robot",
130+
"use_same_transaction": "true"
131+
}'
132+
);
133+
134+
SELECT schedule.create_job(
135+
'{
136+
"name": "Test #4: sleep 160 timeout 120",
137+
"cron": "* * * * *",
138+
"command": "select pg_sleep(160)",
139+
"run_as": "robot",
140+
"use_same_transaction": "true",
141+
"max_run_time": "120 seconds"
142+
}'
143+
);
144+
145+
SELECT schedule.create_job(
146+
'{
147+
"name": "Test #5: writes nexttime in 05:15 min",
148+
"cron": "* * * * *",
149+
"command": "INSERT into result5 (time_mark, text) values (now(), random_finish())",
150+
"next_time_statement": "select get_next_time()",
151+
"run_as": "robot"
152+
}'
153+
);
154+
155+
SELECT schedule.create_job(
156+
jsonb_build_object(
157+
'name', 'Test #6: timearray',
158+
'command', 'insert into result6 (time_mark, text) values (now(), ''result date job'')',
159+
'dates',
160+
jsonb_build_array(
161+
now() + '5 minutes'::interval,
162+
now() + '15 minutes'::interval,
163+
now() + '25 minutes'::interval,
164+
now() + '35 minutes'::interval,
165+
now() + '45 minutes'::interval,
166+
now() + '55 minutes'::interval,
167+
now() + '65 minutes'::interval,
168+
now() + '75 minutes'::interval,
169+
now() + '85 minutes'::interval
170+
),
171+
'run_as', 'robot'
172+
)
173+
);
174+
175+
SELECT schedule.create_job(
176+
'{
177+
"name": "Test #7: on rollback",
178+
"cron": "*/10 * * * *",
179+
"commands": [
180+
"insert into result7 (time_mark, n, text) values (now(),1, ''start'')",
181+
"insert into result7 (time_mark, n, text) values (now(), 2, random_finish())"
182+
],
183+
"onrollback": "insert into result7 (time_mark,n, text) values (now(),3, ''on rollback'')",
184+
"run_as": "robot"
185+
}'
186+
);

web/htdocs/css/pgps.css

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
td.done {
2+
color: green;
3+
}
4+
5+
td.error {
6+
color: red;
7+
}
8+
9+
td.time {
10+
font-size: 80%;
11+
}
12+
13+
td.td-dig {
14+
text-align: right;
15+
}
16+
17+
h1.centered {
18+
text-align: center;
19+
}
20+
21+
div.container {
22+
margin-left:20px;
23+
margin-right:20px;
24+
}
25+
26+
div.uplod-indicator {
27+
float: right;
28+
margin-left: 10px;
29+
}
30+
31+
img#pj-ind, img#aj-ind {
32+
display: none;
33+
}

web/htdocs/img/ajax-loader.gif

847 Bytes
Loading

web/htdocs/index.html

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<HTML>
2+
<HEAD>
3+
<link rel="stylesheet" href="http://yui.yahooapis.com/pure/0.6.0/base-min.css">
4+
<link rel="stylesheet" href="http://yui.yahooapis.com/pure/0.6.0/tables-min.css">
5+
<link rel="stylesheet" href="/css/pgps.css">
6+
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
7+
<script src="/js/pgps.js"></script>
8+
<meta name="viewport" content="width=device-width, initial-scale=1">
9+
<title>PostgresPro Scheduler</title>
10+
</HEAD>
11+
<BODY>
12+
<h1 class="centered">*** PostgresPro Scheduler jobs ***</h1>
13+
<div class="container">
14+
<h2>Active jobs <img id="pj-ind" src="/img/ajax-loader.gif"></h2>
15+
<table class="pure-table pure-table-bordered" id="aj" width="100%">
16+
<thead>
17+
<tr>
18+
<th>cron_id</th>
19+
<th>start_at</th>
20+
<th>started</th>
21+
<th>running</th>
22+
<th>name</th>
23+
<th>user</th>
24+
<th>owner</th>
25+
</tr>
26+
</thead>
27+
<tbody>
28+
</tbody>
29+
</table>
30+
31+
<h2>Processed jobs <img id="pj-ind" src="/img/ajax-loader.gif"></h2>
32+
<table class="pure-table pure-table-bordered" id="pj" width="100%">
33+
<thead>
34+
<tr>
35+
<th>cron_id</th>
36+
<th>start_at</th>
37+
<th>started</th>
38+
<th>finished</th>
39+
<th>name</th>
40+
<th>user</th>
41+
<th>owner</th>
42+
<th>status</th>
43+
<th>message</th>
44+
</tr>
45+
</thead>
46+
<tbody>
47+
</tbody>
48+
</table>
49+
</div>
50+
</BODY>
51+
</HTML>

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy