Fossil SCM

Add the "fossil hook status" command. Embargo post-receive hooks for 60 seconds after an incomplete sync, to give an opportunity for the sync to complete.

drh 2020-07-06 11:08 hooks
Commit 3d191798a62507e5c765d4f992bfe7084903b4720359a01b5896364be7f29e1f
2 files changed +55 -8 +1
+55 -8
--- src/hook.c
+++ src/hook.c
@@ -26,11 +26,12 @@
2626
** "type": "after-receive", // type of hook
2727
** "cmd": "command-to-run", // command to run
2828
** "seq": 50 // run in this order
2929
** }
3030
**
31
-** hook-last-rcvid Number of last rcvid for which hooks were run
31
+** hook-last-rcvid The last rcvid for which post-receive hooks were
32
+** run.
3233
**
3334
** hook-embargo Do not run hooks again before this julianday.
3435
**
3536
** For "after-receive" hooks, a list of the received artifacts is sent
3637
** into the command via standard input. Each line of input begins with
@@ -104,10 +105,31 @@
104105
}
105106
}
106107
blob_str(&r);
107108
return r.aData;
108109
}
110
+
111
+/*
112
+** Record the fact that new artifacts are expected within N seconds
113
+** (N is normally a small number) and so post-receive hooks should
114
+** probably be deferred until after the new artifacts arrive.
115
+**
116
+** If N==0, then there is no expectation of new artifacts arriving
117
+** soon and so post-receive hooks can be run without delay.
118
+*/
119
+void hook_expecting_more_artifacts(int N){
120
+ if( N>0 ){
121
+ db_multi_exec(
122
+ "REPLACE INTO config(name,value,mtime)"
123
+ "VALUES('hook-embargo',now()+%d,now())",
124
+ N
125
+ );
126
+ }else{
127
+ db_unset("hook-embargo",0);
128
+ }
129
+}
130
+
109131
110132
/*
111133
** Fill the Blob pOut with text that describes all artifacts
112134
** received after zBaseRcvid up to and including zNewRcvid.
113135
** Except, never include more than one days worth of changes.
@@ -122,16 +144,21 @@
122144
zBaseRcvid = db_get("hook-last-rcvid","0");
123145
}
124146
if( zNewRcvid==0 ){
125147
zNewRcvid = db_text("0","SELECT max(rcvid) FROM rcvfrom");
126148
}
149
+
150
+ /* Adjust the baseline rcvid to omit change that are more than
151
+ ** 24 hours older than the most recent change.
152
+ */
127153
zBaseRcvid = db_text(0,
128154
"SELECT min(rcvid) FROM rcvfrom"
129155
" WHERE rcvid>=%d"
130156
" AND mtime>=(SELECT mtime FROM rcvfrom WHERE rcvid=%d)-1.0",
131157
atoi(zBaseRcvid), atoi(zNewRcvid)
132158
);
159
+
133160
zWhere = mprintf("IN (SELECT rid FROM blob WHERE rcvid>%d AND rcvid<=%d)",
134161
atoi(zBaseRcvid), atoi(zNewRcvid));
135162
describe_artifacts(zWhere);
136163
fossil_free(zWhere);
137164
db_prepare(&q, "SELECT uuid, summary FROM description");
@@ -146,33 +173,38 @@
146173
**
147174
** Usage: %fossil hook COMMAND ...
148175
**
149176
** Commands include:
150177
**
151
-** > fossil hook list
178
+** > fossil hook add --command COMMAND --type TYPE --sequence NUMBER
152179
**
153
-** Show all current hooks
180
+** Create a new hook. The --command and --type arguments are
181
+** required. --sequence is optional.
154182
**
155183
** > fossil hook delete ID ...
156184
**
157185
** Delete one or more hooks by their IDs. ID can be "all"
158186
** to delete all hooks. Caution: There is no "undo" for
159187
** this operation. Deleted hooks are permanently lost.
160188
**
161
-** > fossil hook add --command COMMAND --type TYPE --sequence NUMBER
162
-**
163
-** Create a new hook. The --command and --type arguments are
164
-** required. --sequence is optional.
165
-**
166189
** > fossil hook edit --command COMMAND --type TYPE --sequence NUMBER ID ...
167190
**
168191
** Make changes to one or more existing hooks. The ID argument
169192
** is either a hook-id, or a list of hook-ids, or the keyword
170193
** "all". For example, to disable hook number 2, use:
171194
**
172195
** fossil hook edit --type disabled 2
173196
**
197
+** > fossil hook list
198
+**
199
+** Show all current hooks
200
+**
201
+** > fossil hook status
202
+**
203
+** Print the values of CONFIG table entries that are relevant to
204
+** hook processing. Used for debugging.
205
+**
174206
** > fossil hook test [OPTIONS] ID
175207
**
176208
** Run the hook script given by ID for testing purposes.
177209
** Options:
178210
**
@@ -301,10 +333,21 @@
301333
fossil_print("%3d: type = %s\n",
302334
db_column_int(&q,0), db_column_text(&q,3));
303335
fossil_print(" command = %s\n", db_column_text(&q,2));
304336
fossil_print(" sequence = %d\n", db_column_int(&q,1));
305337
}
338
+ db_finalize(&q);
339
+ }else
340
+ if( strncmp(zCmd, "status", nCmd)==0 ){
341
+ Stmt q;
342
+ db_prepare(&q,
343
+ "SELECT name, quote(value) FROM config WHERE name IN"
344
+ "('hooks','hook-embargo','hook-last-rcvid') ORDER BY name"
345
+ );
346
+ while( db_step(&q)==SQLITE_ROW ){
347
+ fossil_print("%s: %s\n", db_column_text(&q,0), db_column_text(&q,1));
348
+ }
306349
db_finalize(&q);
307350
}else
308351
if( strncmp(zCmd, "test", nCmd)==0 ){
309352
Stmt q;
310353
int bDryRun = find_option("dry-run", "n", 0)!=0;
@@ -366,10 +409,14 @@
366409
int cnt = 0;
367410
db_begin_write();
368411
if( !db_exists("SELECT 1 FROM config WHERE name='hooks'") ){
369412
goto hook_backoffice_done; /* No hooks */
370413
}
414
+ if( db_int(0, "SELECT now()<value+0 FROM config"
415
+ " WHERE name='hook-embargo'") ){
416
+ goto hook_backoffice_done; /* Within the embargo window */
417
+ }
371418
zLastRcvid = db_get("hook-last-rcvid","0");
372419
zNewRcvid = db_text("0","SELECT max(rcvid) FROM rcvfrom");
373420
if( atoi(zLastRcvid)>=atoi(zNewRcvid) ){
374421
goto hook_backoffice_done; /* no new content */
375422
}
376423
--- src/hook.c
+++ src/hook.c
@@ -26,11 +26,12 @@
26 ** "type": "after-receive", // type of hook
27 ** "cmd": "command-to-run", // command to run
28 ** "seq": 50 // run in this order
29 ** }
30 **
31 ** hook-last-rcvid Number of last rcvid for which hooks were run
 
32 **
33 ** hook-embargo Do not run hooks again before this julianday.
34 **
35 ** For "after-receive" hooks, a list of the received artifacts is sent
36 ** into the command via standard input. Each line of input begins with
@@ -104,10 +105,31 @@
104 }
105 }
106 blob_str(&r);
107 return r.aData;
108 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
110 /*
111 ** Fill the Blob pOut with text that describes all artifacts
112 ** received after zBaseRcvid up to and including zNewRcvid.
113 ** Except, never include more than one days worth of changes.
@@ -122,16 +144,21 @@
122 zBaseRcvid = db_get("hook-last-rcvid","0");
123 }
124 if( zNewRcvid==0 ){
125 zNewRcvid = db_text("0","SELECT max(rcvid) FROM rcvfrom");
126 }
 
 
 
 
127 zBaseRcvid = db_text(0,
128 "SELECT min(rcvid) FROM rcvfrom"
129 " WHERE rcvid>=%d"
130 " AND mtime>=(SELECT mtime FROM rcvfrom WHERE rcvid=%d)-1.0",
131 atoi(zBaseRcvid), atoi(zNewRcvid)
132 );
 
133 zWhere = mprintf("IN (SELECT rid FROM blob WHERE rcvid>%d AND rcvid<=%d)",
134 atoi(zBaseRcvid), atoi(zNewRcvid));
135 describe_artifacts(zWhere);
136 fossil_free(zWhere);
137 db_prepare(&q, "SELECT uuid, summary FROM description");
@@ -146,33 +173,38 @@
146 **
147 ** Usage: %fossil hook COMMAND ...
148 **
149 ** Commands include:
150 **
151 ** > fossil hook list
152 **
153 ** Show all current hooks
 
154 **
155 ** > fossil hook delete ID ...
156 **
157 ** Delete one or more hooks by their IDs. ID can be "all"
158 ** to delete all hooks. Caution: There is no "undo" for
159 ** this operation. Deleted hooks are permanently lost.
160 **
161 ** > fossil hook add --command COMMAND --type TYPE --sequence NUMBER
162 **
163 ** Create a new hook. The --command and --type arguments are
164 ** required. --sequence is optional.
165 **
166 ** > fossil hook edit --command COMMAND --type TYPE --sequence NUMBER ID ...
167 **
168 ** Make changes to one or more existing hooks. The ID argument
169 ** is either a hook-id, or a list of hook-ids, or the keyword
170 ** "all". For example, to disable hook number 2, use:
171 **
172 ** fossil hook edit --type disabled 2
173 **
 
 
 
 
 
 
 
 
 
174 ** > fossil hook test [OPTIONS] ID
175 **
176 ** Run the hook script given by ID for testing purposes.
177 ** Options:
178 **
@@ -301,10 +333,21 @@
301 fossil_print("%3d: type = %s\n",
302 db_column_int(&q,0), db_column_text(&q,3));
303 fossil_print(" command = %s\n", db_column_text(&q,2));
304 fossil_print(" sequence = %d\n", db_column_int(&q,1));
305 }
 
 
 
 
 
 
 
 
 
 
 
306 db_finalize(&q);
307 }else
308 if( strncmp(zCmd, "test", nCmd)==0 ){
309 Stmt q;
310 int bDryRun = find_option("dry-run", "n", 0)!=0;
@@ -366,10 +409,14 @@
366 int cnt = 0;
367 db_begin_write();
368 if( !db_exists("SELECT 1 FROM config WHERE name='hooks'") ){
369 goto hook_backoffice_done; /* No hooks */
370 }
 
 
 
 
371 zLastRcvid = db_get("hook-last-rcvid","0");
372 zNewRcvid = db_text("0","SELECT max(rcvid) FROM rcvfrom");
373 if( atoi(zLastRcvid)>=atoi(zNewRcvid) ){
374 goto hook_backoffice_done; /* no new content */
375 }
376
--- src/hook.c
+++ src/hook.c
@@ -26,11 +26,12 @@
26 ** "type": "after-receive", // type of hook
27 ** "cmd": "command-to-run", // command to run
28 ** "seq": 50 // run in this order
29 ** }
30 **
31 ** hook-last-rcvid The last rcvid for which post-receive hooks were
32 ** run.
33 **
34 ** hook-embargo Do not run hooks again before this julianday.
35 **
36 ** For "after-receive" hooks, a list of the received artifacts is sent
37 ** into the command via standard input. Each line of input begins with
@@ -104,10 +105,31 @@
105 }
106 }
107 blob_str(&r);
108 return r.aData;
109 }
110
111 /*
112 ** Record the fact that new artifacts are expected within N seconds
113 ** (N is normally a small number) and so post-receive hooks should
114 ** probably be deferred until after the new artifacts arrive.
115 **
116 ** If N==0, then there is no expectation of new artifacts arriving
117 ** soon and so post-receive hooks can be run without delay.
118 */
119 void hook_expecting_more_artifacts(int N){
120 if( N>0 ){
121 db_multi_exec(
122 "REPLACE INTO config(name,value,mtime)"
123 "VALUES('hook-embargo',now()+%d,now())",
124 N
125 );
126 }else{
127 db_unset("hook-embargo",0);
128 }
129 }
130
131
132 /*
133 ** Fill the Blob pOut with text that describes all artifacts
134 ** received after zBaseRcvid up to and including zNewRcvid.
135 ** Except, never include more than one days worth of changes.
@@ -122,16 +144,21 @@
144 zBaseRcvid = db_get("hook-last-rcvid","0");
145 }
146 if( zNewRcvid==0 ){
147 zNewRcvid = db_text("0","SELECT max(rcvid) FROM rcvfrom");
148 }
149
150 /* Adjust the baseline rcvid to omit change that are more than
151 ** 24 hours older than the most recent change.
152 */
153 zBaseRcvid = db_text(0,
154 "SELECT min(rcvid) FROM rcvfrom"
155 " WHERE rcvid>=%d"
156 " AND mtime>=(SELECT mtime FROM rcvfrom WHERE rcvid=%d)-1.0",
157 atoi(zBaseRcvid), atoi(zNewRcvid)
158 );
159
160 zWhere = mprintf("IN (SELECT rid FROM blob WHERE rcvid>%d AND rcvid<=%d)",
161 atoi(zBaseRcvid), atoi(zNewRcvid));
162 describe_artifacts(zWhere);
163 fossil_free(zWhere);
164 db_prepare(&q, "SELECT uuid, summary FROM description");
@@ -146,33 +173,38 @@
173 **
174 ** Usage: %fossil hook COMMAND ...
175 **
176 ** Commands include:
177 **
178 ** > fossil hook add --command COMMAND --type TYPE --sequence NUMBER
179 **
180 ** Create a new hook. The --command and --type arguments are
181 ** required. --sequence is optional.
182 **
183 ** > fossil hook delete ID ...
184 **
185 ** Delete one or more hooks by their IDs. ID can be "all"
186 ** to delete all hooks. Caution: There is no "undo" for
187 ** this operation. Deleted hooks are permanently lost.
188 **
 
 
 
 
 
189 ** > fossil hook edit --command COMMAND --type TYPE --sequence NUMBER ID ...
190 **
191 ** Make changes to one or more existing hooks. The ID argument
192 ** is either a hook-id, or a list of hook-ids, or the keyword
193 ** "all". For example, to disable hook number 2, use:
194 **
195 ** fossil hook edit --type disabled 2
196 **
197 ** > fossil hook list
198 **
199 ** Show all current hooks
200 **
201 ** > fossil hook status
202 **
203 ** Print the values of CONFIG table entries that are relevant to
204 ** hook processing. Used for debugging.
205 **
206 ** > fossil hook test [OPTIONS] ID
207 **
208 ** Run the hook script given by ID for testing purposes.
209 ** Options:
210 **
@@ -301,10 +333,21 @@
333 fossil_print("%3d: type = %s\n",
334 db_column_int(&q,0), db_column_text(&q,3));
335 fossil_print(" command = %s\n", db_column_text(&q,2));
336 fossil_print(" sequence = %d\n", db_column_int(&q,1));
337 }
338 db_finalize(&q);
339 }else
340 if( strncmp(zCmd, "status", nCmd)==0 ){
341 Stmt q;
342 db_prepare(&q,
343 "SELECT name, quote(value) FROM config WHERE name IN"
344 "('hooks','hook-embargo','hook-last-rcvid') ORDER BY name"
345 );
346 while( db_step(&q)==SQLITE_ROW ){
347 fossil_print("%s: %s\n", db_column_text(&q,0), db_column_text(&q,1));
348 }
349 db_finalize(&q);
350 }else
351 if( strncmp(zCmd, "test", nCmd)==0 ){
352 Stmt q;
353 int bDryRun = find_option("dry-run", "n", 0)!=0;
@@ -366,10 +409,14 @@
409 int cnt = 0;
410 db_begin_write();
411 if( !db_exists("SELECT 1 FROM config WHERE name='hooks'") ){
412 goto hook_backoffice_done; /* No hooks */
413 }
414 if( db_int(0, "SELECT now()<value+0 FROM config"
415 " WHERE name='hook-embargo'") ){
416 goto hook_backoffice_done; /* Within the embargo window */
417 }
418 zLastRcvid = db_get("hook-last-rcvid","0");
419 zNewRcvid = db_text("0","SELECT max(rcvid) FROM rcvfrom");
420 if( atoi(zLastRcvid)>=atoi(zNewRcvid) ){
421 goto hook_backoffice_done; /* no new content */
422 }
423
+1
--- src/xfer.c
+++ src/xfer.c
@@ -1739,10 +1739,11 @@
17391739
}else if( isPull ){
17401740
create_cluster();
17411741
send_unclustered(&xfer);
17421742
if( xfer.syncPrivate ) send_private(&xfer);
17431743
}
1744
+ hook_expecting_more_artifacts(xfer.nGimmeSent?60:0);
17441745
db_multi_exec("DROP TABLE onremote; DROP TABLE unk;");
17451746
manifest_crosslink_end(MC_PERMIT_HOOKS);
17461747
17471748
/* Send the server timestamp last, in case prior processing happened
17481749
** to use up a significant fraction of our time window.
17491750
--- src/xfer.c
+++ src/xfer.c
@@ -1739,10 +1739,11 @@
1739 }else if( isPull ){
1740 create_cluster();
1741 send_unclustered(&xfer);
1742 if( xfer.syncPrivate ) send_private(&xfer);
1743 }
 
1744 db_multi_exec("DROP TABLE onremote; DROP TABLE unk;");
1745 manifest_crosslink_end(MC_PERMIT_HOOKS);
1746
1747 /* Send the server timestamp last, in case prior processing happened
1748 ** to use up a significant fraction of our time window.
1749
--- src/xfer.c
+++ src/xfer.c
@@ -1739,10 +1739,11 @@
1739 }else if( isPull ){
1740 create_cluster();
1741 send_unclustered(&xfer);
1742 if( xfer.syncPrivate ) send_private(&xfer);
1743 }
1744 hook_expecting_more_artifacts(xfer.nGimmeSent?60:0);
1745 db_multi_exec("DROP TABLE onremote; DROP TABLE unk;");
1746 manifest_crosslink_end(MC_PERMIT_HOOKS);
1747
1748 /* Send the server timestamp last, in case prior processing happened
1749 ** to use up a significant fraction of our time window.
1750

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button