Fossil SCM

Add new option max-download-time to limit the processing time of pull/sync /clone requests. This helps to significantly cut down the number of time outs clients receive on busy server with reverse proxy configuration. It generally provides better response times.

joerg 2013-01-18 22:05 trunk
Commit ee6ae580eee084d28279cc84c3e6e7596345e291
2 files changed +9 +8 -2
--- src/setup.c
+++ src/setup.c
@@ -917,10 +917,19 @@
917917
@ to this many bytes, uncompressed. If the client requires more data
918918
@ than this, then the client will issue multiple HTTP requests.
919919
@ Values below 1 million are not recommended. 5 million is a
920920
@ reasonable number.</p>
921921
922
+ @ <hr />
923
+ entry_attribute("Download time limit", 11, "max-download-time", "mxdwnt",
924
+ "30");
925
+
926
+ @ <p>Fossil tries to spend less than this many seconds gathering
927
+ @ the out-bound data of sync, clone, and pull packets.
928
+ @ If the client request takes longer, a partial reply is given similar
929
+ @ to the download packet limit. 30s is a reasonable default.</p>
930
+
922931
@ <hr />
923932
onoff_attribute(
924933
"Enable hyperlinks for \"nobody\" based on User-Agent and Javascript",
925934
"auto-hyperlink", "autohyperlink", 1);
926935
@ <p>Enable hyperlinks (the equivalent of the "h" permission) for all users
927936
--- src/setup.c
+++ src/setup.c
@@ -917,10 +917,19 @@
917 @ to this many bytes, uncompressed. If the client requires more data
918 @ than this, then the client will issue multiple HTTP requests.
919 @ Values below 1 million are not recommended. 5 million is a
920 @ reasonable number.</p>
921
 
 
 
 
 
 
 
 
 
922 @ <hr />
923 onoff_attribute(
924 "Enable hyperlinks for \"nobody\" based on User-Agent and Javascript",
925 "auto-hyperlink", "autohyperlink", 1);
926 @ <p>Enable hyperlinks (the equivalent of the "h" permission) for all users
927
--- src/setup.c
+++ src/setup.c
@@ -917,10 +917,19 @@
917 @ to this many bytes, uncompressed. If the client requires more data
918 @ than this, then the client will issue multiple HTTP requests.
919 @ Values below 1 million are not recommended. 5 million is a
920 @ reasonable number.</p>
921
922 @ <hr />
923 entry_attribute("Download time limit", 11, "max-download-time", "mxdwnt",
924 "30");
925
926 @ <p>Fossil tries to spend less than this many seconds gathering
927 @ the out-bound data of sync, clone, and pull packets.
928 @ If the client request takes longer, a partial reply is given similar
929 @ to the download packet limit. 30s is a reasonable default.</p>
930
931 @ <hr />
932 onoff_attribute(
933 "Enable hyperlinks for \"nobody\" based on User-Agent and Javascript",
934 "auto-hyperlink", "autohyperlink", 1);
935 @ <p>Enable hyperlinks (the equivalent of the "h" permission) for all users
936
+8 -2
--- src/xfer.c
+++ src/xfer.c
@@ -18,10 +18,12 @@
1818
** This file contains code to implement the file transfer protocol.
1919
*/
2020
#include "config.h"
2121
#include "xfer.h"
2222
23
+#include <time.h>
24
+
2325
/*
2426
** This structure holds information about the current state of either
2527
** a client or a server that is participating in xfer.
2628
*/
2729
typedef struct Xfer Xfer;
@@ -40,10 +42,11 @@
4042
int nDeltaRcvd; /* Number of deltas received */
4143
int nDanglingFile; /* Number of dangling deltas received */
4244
int mxSend; /* Stop sending "file" with pOut reaches this size */
4345
u8 syncPrivate; /* True to enable syncing private content */
4446
u8 nextIsPrivate; /* If true, next "file" received is a private */
47
+ time_t maxTime; /* Time when this transfer should be finished */
4548
};
4649
4750
4851
/*
4952
** The input blob contains a UUID. Convert it into a record ID.
@@ -393,11 +396,11 @@
393396
}
394397
if( uuid_is_shunned(blob_str(pUuid)) ){
395398
blob_reset(&uuid);
396399
return;
397400
}
398
- if( pXfer->mxSend<=blob_size(pXfer->pOut) ){
401
+ if( time(NULL) >= pXfer->maxTime || pXfer->mxSend<=blob_size(pXfer->pOut) ){
399402
const char *zFormat = isPriv ? "igot %b 1\n" : "igot %b\n";
400403
blob_appendf(pXfer->pOut, zFormat, pUuid);
401404
pXfer->nIGotSent++;
402405
blob_reset(&uuid);
403406
return;
@@ -867,10 +870,11 @@
867870
}
868871
blob_zero(&xfer.err);
869872
xfer.pIn = &g.cgiIn;
870873
xfer.pOut = cgi_output_blob();
871874
xfer.mxSend = db_get_int("max-download", 5000000);
875
+ xfer.maxTime = time(NULL) + db_get_int("max-download-time", 30);
872876
g.xferPanic = 1;
873877
874878
db_begin_transaction();
875879
db_multi_exec(
876880
"CREATE TEMP TABLE onremote(rid INTEGER PRIMARY KEY);"
@@ -1034,11 +1038,12 @@
10341038
if( iVers>=3 ){
10351039
cgi_set_content_type("application/x-fossil-uncompressed");
10361040
}
10371041
blob_is_int(&xfer.aToken[2], &seqno);
10381042
max = db_int(0, "SELECT max(rid) FROM blob");
1039
- while( xfer.mxSend>blob_size(xfer.pOut) && seqno<=max ){
1043
+ while( xfer.mxSend>blob_size(xfer.pOut) && seqno<=max){
1044
+ if( time(NULL) >= xfer.maxTime ) break;
10401045
if( iVers>=3 ){
10411046
send_compressed_file(&xfer, seqno);
10421047
}else{
10431048
send_file(&xfer, seqno, 0, 1);
10441049
}
@@ -1328,10 +1333,11 @@
13281333
socket_global_init();
13291334
memset(&xfer, 0, sizeof(xfer));
13301335
xfer.pIn = &recv;
13311336
xfer.pOut = &send;
13321337
xfer.mxSend = db_get_int("max-upload", 250000);
1338
+ xfer.maxTime = -1;
13331339
if( syncFlags & SYNC_PRIVATE ){
13341340
g.perm.Private = 1;
13351341
xfer.syncPrivate = 1;
13361342
}
13371343
13381344
--- src/xfer.c
+++ src/xfer.c
@@ -18,10 +18,12 @@
18 ** This file contains code to implement the file transfer protocol.
19 */
20 #include "config.h"
21 #include "xfer.h"
22
 
 
23 /*
24 ** This structure holds information about the current state of either
25 ** a client or a server that is participating in xfer.
26 */
27 typedef struct Xfer Xfer;
@@ -40,10 +42,11 @@
40 int nDeltaRcvd; /* Number of deltas received */
41 int nDanglingFile; /* Number of dangling deltas received */
42 int mxSend; /* Stop sending "file" with pOut reaches this size */
43 u8 syncPrivate; /* True to enable syncing private content */
44 u8 nextIsPrivate; /* If true, next "file" received is a private */
 
45 };
46
47
48 /*
49 ** The input blob contains a UUID. Convert it into a record ID.
@@ -393,11 +396,11 @@
393 }
394 if( uuid_is_shunned(blob_str(pUuid)) ){
395 blob_reset(&uuid);
396 return;
397 }
398 if( pXfer->mxSend<=blob_size(pXfer->pOut) ){
399 const char *zFormat = isPriv ? "igot %b 1\n" : "igot %b\n";
400 blob_appendf(pXfer->pOut, zFormat, pUuid);
401 pXfer->nIGotSent++;
402 blob_reset(&uuid);
403 return;
@@ -867,10 +870,11 @@
867 }
868 blob_zero(&xfer.err);
869 xfer.pIn = &g.cgiIn;
870 xfer.pOut = cgi_output_blob();
871 xfer.mxSend = db_get_int("max-download", 5000000);
 
872 g.xferPanic = 1;
873
874 db_begin_transaction();
875 db_multi_exec(
876 "CREATE TEMP TABLE onremote(rid INTEGER PRIMARY KEY);"
@@ -1034,11 +1038,12 @@
1034 if( iVers>=3 ){
1035 cgi_set_content_type("application/x-fossil-uncompressed");
1036 }
1037 blob_is_int(&xfer.aToken[2], &seqno);
1038 max = db_int(0, "SELECT max(rid) FROM blob");
1039 while( xfer.mxSend>blob_size(xfer.pOut) && seqno<=max ){
 
1040 if( iVers>=3 ){
1041 send_compressed_file(&xfer, seqno);
1042 }else{
1043 send_file(&xfer, seqno, 0, 1);
1044 }
@@ -1328,10 +1333,11 @@
1328 socket_global_init();
1329 memset(&xfer, 0, sizeof(xfer));
1330 xfer.pIn = &recv;
1331 xfer.pOut = &send;
1332 xfer.mxSend = db_get_int("max-upload", 250000);
 
1333 if( syncFlags & SYNC_PRIVATE ){
1334 g.perm.Private = 1;
1335 xfer.syncPrivate = 1;
1336 }
1337
1338
--- src/xfer.c
+++ src/xfer.c
@@ -18,10 +18,12 @@
18 ** This file contains code to implement the file transfer protocol.
19 */
20 #include "config.h"
21 #include "xfer.h"
22
23 #include <time.h>
24
25 /*
26 ** This structure holds information about the current state of either
27 ** a client or a server that is participating in xfer.
28 */
29 typedef struct Xfer Xfer;
@@ -40,10 +42,11 @@
42 int nDeltaRcvd; /* Number of deltas received */
43 int nDanglingFile; /* Number of dangling deltas received */
44 int mxSend; /* Stop sending "file" with pOut reaches this size */
45 u8 syncPrivate; /* True to enable syncing private content */
46 u8 nextIsPrivate; /* If true, next "file" received is a private */
47 time_t maxTime; /* Time when this transfer should be finished */
48 };
49
50
51 /*
52 ** The input blob contains a UUID. Convert it into a record ID.
@@ -393,11 +396,11 @@
396 }
397 if( uuid_is_shunned(blob_str(pUuid)) ){
398 blob_reset(&uuid);
399 return;
400 }
401 if( time(NULL) >= pXfer->maxTime || pXfer->mxSend<=blob_size(pXfer->pOut) ){
402 const char *zFormat = isPriv ? "igot %b 1\n" : "igot %b\n";
403 blob_appendf(pXfer->pOut, zFormat, pUuid);
404 pXfer->nIGotSent++;
405 blob_reset(&uuid);
406 return;
@@ -867,10 +870,11 @@
870 }
871 blob_zero(&xfer.err);
872 xfer.pIn = &g.cgiIn;
873 xfer.pOut = cgi_output_blob();
874 xfer.mxSend = db_get_int("max-download", 5000000);
875 xfer.maxTime = time(NULL) + db_get_int("max-download-time", 30);
876 g.xferPanic = 1;
877
878 db_begin_transaction();
879 db_multi_exec(
880 "CREATE TEMP TABLE onremote(rid INTEGER PRIMARY KEY);"
@@ -1034,11 +1038,12 @@
1038 if( iVers>=3 ){
1039 cgi_set_content_type("application/x-fossil-uncompressed");
1040 }
1041 blob_is_int(&xfer.aToken[2], &seqno);
1042 max = db_int(0, "SELECT max(rid) FROM blob");
1043 while( xfer.mxSend>blob_size(xfer.pOut) && seqno<=max){
1044 if( time(NULL) >= xfer.maxTime ) break;
1045 if( iVers>=3 ){
1046 send_compressed_file(&xfer, seqno);
1047 }else{
1048 send_file(&xfer, seqno, 0, 1);
1049 }
@@ -1328,10 +1333,11 @@
1333 socket_global_init();
1334 memset(&xfer, 0, sizeof(xfer));
1335 xfer.pIn = &recv;
1336 xfer.pOut = &send;
1337 xfer.mxSend = db_get_int("max-upload", 250000);
1338 xfer.maxTime = -1;
1339 if( syncFlags & SYNC_PRIVATE ){
1340 g.perm.Private = 1;
1341 xfer.syncPrivate = 1;
1342 }
1343
1344

Keyboard Shortcuts

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