Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | More sync fixes: The previous version was not pulling new branches off of the server. This should fix that. |
|---|---|
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA1: |
50150adeecefe2019e9a8ef00b136245 |
| User & Date: | drh 2007-08-10 03:50:25.000 |
Context
|
2007-08-10
| ||
| 03:52 | Fix a C++-ism in the previous check-in. check-in: f5588c800b user: drh tags: trunk | |
| 03:50 | More sync fixes: The previous version was not pulling new branches off of the server. This should fix that. check-in: 50150adeec user: drh tags: trunk | |
| 02:59 | The xfer mechanism has been completely reworked to better support delta compression and to require fewer round-trips. The wire protocol is roughly the same but is different enough that you will need to recompile before sync will work. check-in: edbb332d54 user: drh tags: trunk | |
Changes
Changes to src/xfer.c.
| ︙ | ︙ | |||
189 190 191 192 193 194 195 |
** file to delta against. If srcId is negative, the file is sent
** without deltaing.
*/
static void send_file(Xfer *pXfer, int rid, Blob *pUuid, int srcId){
Blob content, uuid;
int size = 0;
| | | 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
** file to delta against. If srcId is negative, the file is sent
** without deltaing.
*/
static void send_file(Xfer *pXfer, int rid, Blob *pUuid, int srcId){
Blob content, uuid;
int size = 0;
if( db_exists("SELECT 1 FROM onremote WHERE rid=%d", rid) ){
return;
}
blob_zero(&uuid);
if( pUuid==0 ){
db_blob(&uuid, "SELECT uuid FROM blob WHERE rid=%d AND size>=0", rid);
if( blob_size(&uuid)==0 ){
return;
|
| ︙ | ︙ | |||
219 220 221 222 223 224 225 |
int size = blob_size(&content);
blob_appendf(pXfer->pOut, "file %b %d\n", pUuid, size);
blob_append(pXfer->pOut, blob_buffer(&content), size);
pXfer->nFileSent++;
}else{
pXfer->nDeltaSent++;
}
| | | 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 |
int size = blob_size(&content);
blob_appendf(pXfer->pOut, "file %b %d\n", pUuid, size);
blob_append(pXfer->pOut, blob_buffer(&content), size);
pXfer->nFileSent++;
}else{
pXfer->nDeltaSent++;
}
db_multi_exec("INSERT INTO onremote VALUES(%d)", rid);
blob_reset(&uuid);
}
/*
** This routine runs when either client or server is notified that
** the other side things rid is a leaf manifest. If we hold
** children of rid, then send them over to the other side.
|
| ︙ | ︙ | |||
377 378 379 380 381 382 383 |
blob_zero(&xfer.err);
xfer.pIn = &g.cgiIn;
xfer.pOut = cgi_output_blob();
xfer.mxSend = db_get_int("max-download", 1000000);
db_begin_transaction();
db_multi_exec(
| | | | 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 |
blob_zero(&xfer.err);
xfer.pIn = &g.cgiIn;
xfer.pOut = cgi_output_blob();
xfer.mxSend = db_get_int("max-download", 1000000);
db_begin_transaction();
db_multi_exec(
"CREATE TEMP TABLE onremote(rid INTEGER PRIMARY KEY);"
);
while( blob_line(xfer.pIn, &xfer.line) ){
xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken, count(xfer.aToken));
/* file UUID SIZE \n CONTENT
** file UUID DELTASRC SIZE \n CONTENT
**
** Accept a file from the client.
*/
if( blob_eq(&xfer.aToken[0], "file") ){
if( !isPush ){
cgi_reset_content();
@ error not\sauthorized\sto\swrite
nErr++;
break;
}
xfer_accept_file(&xfer);
if( blob_size(&xfer.err) ){
|
| ︙ | ︙ | |||
411 412 413 414 415 416 417 |
**
** Client is requesting a file
*/
if( blob_eq(&xfer.aToken[0], "gimme")
&& xfer.nToken==2
&& blob_is_uuid(&xfer.aToken[1])
){
| | | | > > > < | > > > > | 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 |
**
** Client is requesting a file
*/
if( blob_eq(&xfer.aToken[0], "gimme")
&& xfer.nToken==2
&& blob_is_uuid(&xfer.aToken[1])
){
if( isPull ){
int rid = rid_from_uuid(&xfer.aToken[1], 0);
if( rid ){
send_file(&xfer, rid, &xfer.aToken[1], 0);
}
}
}else
/* igot UUID
**
** Client announces that it has a particular file
*/
if( xfer.nToken==2
&& blob_eq(&xfer.aToken[0], "igot")
&& blob_is_uuid(&xfer.aToken[1])
){
if( isPush ){
rid_from_uuid(&xfer.aToken[1], 1);
}
}else
/* leaf UUID
**
** Client announces that it has a particular manifest. If
** the server has children of this leaf, then send those
** children back to the client. If the server lacks this
** leaf, request it.
*/
if( xfer.nToken==2
&& blob_eq(&xfer.aToken[0], "leaf")
&& blob_is_uuid(&xfer.aToken[1])
){
int rid = rid_from_uuid(&xfer.aToken[1], 0);
if( isPull && rid ){
leaf_response(&xfer, rid);
}
if( isPush && !rid ){
content_put(0, blob_str(&xfer.aToken[1]), 0);
}
}else
/* pull SERVERCODE PROJECTCODE
** push SERVERCODE PROJECTCODE
**
** The client wants either send or receive
*/
|
| ︙ | ︙ | |||
617 618 619 620 621 622 623 |
xfer.mxSend = db_get_int("max-upload", 250000);
assert( pushFlag || pullFlag || cloneFlag );
assert( !g.urlIsFile ); /* This only works for networking */
db_begin_transaction();
db_multi_exec(
| | | < < < | | < | | | | | | | | > > > > > > > > > > > > > > < < < < > > > > > > > > > > > > > | 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 |
xfer.mxSend = db_get_int("max-upload", 250000);
assert( pushFlag || pullFlag || cloneFlag );
assert( !g.urlIsFile ); /* This only works for networking */
db_begin_transaction();
db_multi_exec(
"CREATE TEMP TABLE onremote(rid INTEGER PRIMARY KEY);"
);
blobarray_zero(xfer.aToken, count(xfer.aToken));
blob_zero(&send);
blob_zero(&recv);
blob_zero(&xfer.err);
blob_zero(&xfer.line);
/*
** Always begin with a clone, pull, or push message
*/
if( cloneFlag ){
blob_appendf(&send, "clone\n");
pushFlag = 0;
pullFlag = 0;
nMsg++;
}else if( pullFlag ){
blob_appendf(&send, "pull %s %s\n", zSCode, zPCode);
nMsg++;
}
if( pushFlag ){
blob_appendf(&send, "push %s %s\n", zSCode, zPCode);
nMsg++;
}
while( go ){
int newPhantom = 0;
/* Generate gimme messages for phantoms and leaf messages
** for all leaves.
*/
if( pullFlag ){
request_phantoms(&xfer);
send_leaves(&xfer);
}
/* Exchange messages with the server */
nFileSend = xfer.nFileSent + xfer.nDeltaSent;
printf("Send: %10d bytes, %3d messages, %3d files (%d+%d)\n",
blob_size(&send), nMsg+xfer.nGimmeSent+xfer.nIGotSent,
nFileSend, xfer.nFileSent, xfer.nDeltaSent);
nMsg = 0;
xfer.nFileSent = 0;
xfer.nDeltaSent = 0;
xfer.nGimmeSent = 0;
http_exchange(&send, &recv);
blob_reset(&send);
/* Begin constructing the next message (which might never be
** sent) by beginning with the pull or push messages
*/
if( pullFlag ){
blob_appendf(&send, "pull %s %s\n", zSCode, zPCode);
nMsg++;
}
if( pushFlag ){
blob_appendf(&send, "push %s %s\n", zSCode, zPCode);
nMsg++;
}
/* Process the reply that came back from the server */
while( blob_line(&recv, &xfer.line) ){
if( blob_buffer(&xfer.line)[0]=='#' ){
continue;
}
xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken, count(xfer.aToken));
|
| ︙ | ︙ | |||
704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 |
&& blob_is_uuid(&xfer.aToken[1])
){
nMsg++;
if( pullFlag ){
if( !db_exists("SELECT 1 FROM blob WHERE uuid='%b' AND size>=0",
&xfer.aToken[1]) ){
content_put(0, blob_str(&xfer.aToken[1]), 0);
}
}
}else
/* leaf UUID
**
** Server announces that it has a particular manifest
*/
if( xfer.nToken==2
&& blob_eq(&xfer.aToken[0], "leaf")
&& blob_is_uuid(&xfer.aToken[1])
){
nMsg++;
| > < | > > > > > | 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 |
&& blob_is_uuid(&xfer.aToken[1])
){
nMsg++;
if( pullFlag ){
if( !db_exists("SELECT 1 FROM blob WHERE uuid='%b' AND size>=0",
&xfer.aToken[1]) ){
content_put(0, blob_str(&xfer.aToken[1]), 0);
newPhantom = 1;
}
}
}else
/* leaf UUID
**
** Server announces that it has a particular manifest
*/
if( xfer.nToken==2
&& blob_eq(&xfer.aToken[0], "leaf")
&& blob_is_uuid(&xfer.aToken[1])
){
nMsg++;
int rid = rid_from_uuid(&xfer.aToken[1], 0);
if( pushFlag && rid ){
leaf_response(&xfer, rid);
}
if( pullFlag && rid==0 ){
content_put(0, blob_str(&xfer.aToken[1]), 0);
newPhantom = 1;
}
}else
/* push SERVERCODE PRODUCTCODE
**
** Should only happen in response to a clone.
|
| ︙ | ︙ | |||
745 746 747 748 749 750 751 752 753 754 755 756 757 758 |
nMsg++;
if( zPCode==0 ){
zPCode = mprintf("%b", &xfer.aToken[2]);
db_set("project-code", zPCode);
}
cloneFlag = 0;
pullFlag = 1;
}else
/* error MESSAGE
**
** Report an error
*/
if( blob_eq(&xfer.aToken[0],"error") && xfer.nToken==2 ){
| > > | 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 |
nMsg++;
if( zPCode==0 ){
zPCode = mprintf("%b", &xfer.aToken[2]);
db_set("project-code", zPCode);
}
cloneFlag = 0;
pullFlag = 1;
blob_appendf(&send, "pull %s %s\n", zSCode, zPCode);
nMsg++;
}else
/* error MESSAGE
**
** Report an error
*/
if( blob_eq(&xfer.aToken[0],"error") && xfer.nToken==2 ){
|
| ︙ | ︙ | |||
781 782 783 784 785 786 787 |
nMsg = 0;
xfer.nFileRcvd = 0;
xfer.nDeltaRcvd = 0;
xfer.nDanglingFile = 0;
nCycle++;
go = 0;
| | > | > | | 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 |
nMsg = 0;
xfer.nFileRcvd = 0;
xfer.nDeltaRcvd = 0;
xfer.nDanglingFile = 0;
nCycle++;
go = 0;
/* If we have received one or more files on this cycle or if
** we have received information that has caused us to create
** new phantoms and we have one or more phantoms, then go for
** another round
*/
if( (xfer.nFileRcvd+xfer.nDeltaRcvd+xfer.nDanglingFile>0 || newPhantom)
&& db_exists("SELECT 1 FROM phantom")
){
go = 1;
}
/* If we have one or more files queued to send, then go
** another round
|
| ︙ | ︙ |