Fossil

Check-in [4ee118a6]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:More improvements to network sync.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:4ee118a6b4a48494736426fbb4b693de28c26acc
User & Date: drh 2007-07-23 20:40:16
Context
2007-07-23
20:42
Always do another sync round if any file is received. check-in: 0feed850 user: drh tags: trunk
20:40
More improvements to network sync. check-in: 4ee118a6 user: drh tags: trunk
20:33
Work on network synchronization check-in: 75c476cc user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/xfer.c.

481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
...
508
509
510
511
512
513
514

515
516
517
518

519
520
521
522

523
524

525
526
527

528
529
530
531
532
533
534
535
536
537

538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556

557
558
559
560
561
562


563
564
565
566
567
568
569
...
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585

586
587
588
589
590
591
592
...
598
599
600
601
602
603
604

605
606
607
608
609
610
611
...
630
631
632
633
634
635
636

637
638
639
640
641
642
643
...
659
660
661
662
663
664
665
666
667

668
669
670
671
672
673
674
675
** true.
*/
void client_sync(int pushFlag, int pullFlag, int cloneFlag){
  int go = 1;        /* Loop until zero */
  int nToken;
  const char *zSCode = db_get("server-code", "x");
  const char *zPCode = db_get("project-code", 0);
  int nSent = 0;
  int nRcvd = 0;
  int nCycle = 0;
  Blob send;        /* Text we are sending to the server */
  Blob recv;        /* Reply we got back from the server */
  Blob line;        /* A single line of the reply */
  Blob aToken[5];   /* A tokenization of line */
  Blob errmsg;      /* Error message */

  assert( pushFlag || pullFlag || cloneFlag );
................................................................................
  blob_zero(&send);
  blob_zero(&recv);
  blob_zero(&errmsg);


  while( go ){
    go = 0;


    /* Generate a request to be sent to the server.
    ** Always begin with a clone, pull, or push message
    */

    if( cloneFlag ){
      blob_appendf(&send, "clone\n");
      pushFlag = 0;
      pullFlag = 0;

    }else if( pullFlag ){
      blob_appendf(&send, "pull %s %s\n", zSCode, zPCode);

    }
    if( pushFlag ){
      blob_appendf(&send, "push %s %s\n", zSCode, zPCode);

    }

    if( pullFlag ){
      /* Send gimme message for every phantom that we hold.
      */
      Stmt q;
      db_prepare(&q, "SELECT uuid FROM blob WHERE size<0");
      while( db_step(&q)==SQLITE_ROW ){
        const char *zUuid = db_column_text(&q, 0);
        blob_appendf(&send,"gimme %s\n", zUuid);

      }
      db_finalize(&q);
    }

    if( pushFlag ){
      /* Send the server any files that the server has requested */
      nSent += send_all_pending(&send);
    }

    if( pullFlag || pushFlag ){
      /* Always send our leaves */
      Stmt q;
      db_prepare(&q, 
         "SELECT uuid FROM blob WHERE rid IN"
         "  (SELECT cid FROM plink EXCEPT SELECT pid FROM plink)"
      );
      while( db_step(&q)==SQLITE_ROW ){
        const char *zUuid = db_column_text(&q, 0);
        blob_appendf(&send, "leaf %s\n", zUuid);

      }
      db_finalize(&q);
    }

    /* Exchange messages with the server */
    printf("Sending %d files to server\n", nSent);


    http_exchange(&send, &recv);
    blob_reset(&send);

    /* Process the reply that came back from the server */
    while( blob_line(&recv, &line) ){
      nToken = blob_tokenize(&line, aToken, count(aToken));

................................................................................
      /*   file UUID SIZE \n CONTENT
      **   file UUID DELTASRC SIZE \n CONTENT
      **
      ** Receive a file transmitted from the other side
      */
      if( blob_eq(&aToken[0],"file") ){
        xfer_accept_file(&recv, aToken, nToken, &errmsg);
        nRcvd++;
      }else

      /*   gimme UUID
      **
      ** Server is requesting a file
      */
      if( blob_eq(&aToken[0], "gimme") && nToken==2
               && blob_is_uuid(&aToken[1]) ){

        if( pushFlag ){
          db_multi_exec(
            "INSERT OR IGNORE INTO pending(rid) "
            "SELECT rid FROM blob WHERE uuid=%B AND size>=0", &aToken[1]
          );
          go = 1;
        }
................................................................................
      ** Server proclaims that it has a particular file.  A leaf message
      ** means that the file is a leaf manifest on the server.
      */
      if( nToken==2
              && (blob_eq(&aToken[0], "igot") || blob_eq(&aToken[0], "leaf"))
              && blob_is_uuid(&aToken[1]) ){
        int rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%B", &aToken[1]);

        if( rid>0 ){
          db_multi_exec(
            "INSERT OR IGNORE INTO onremote(rid) VALUES(%d)", rid
          );
          /* Add to the pending set all children of the server's leaves */
          if( pushFlag && blob_eq(&aToken[0], "leaf") ){
            db_multi_exec(
................................................................................
      */
      if( blob_eq(&aToken[0],"push") && nToken==3 && cloneFlag
              && blob_is_uuid(&aToken[1]) && blob_is_uuid(&aToken[2]) ){

        if( blob_eq_str(&aToken[1], zSCode, -1) ){
          fossil_fatal("server loop");
        }

        if( zPCode==0 ){
          zPCode = mprintf("%b", &aToken[2]);
          db_set("project-code", zPCode);
        }
        cloneFlag = 0;
        pullFlag = 1;
      }else
................................................................................

      if( blob_size(&errmsg) ){
        fossil_fatal("%b", &errmsg);
      }
      blobarray_reset(aToken, nToken);
    }
    blob_reset(&recv);
    printf("Received %d files from server\n", nRcvd);
    nSent = nRcvd = 0;

  };
  http_close();
  db_end_transaction(0);
  db_multi_exec(
    "DROP TABLE onremote;"
    "DROP TABLE pending;"
  );
}







|
|
|







 







>




>




>


>



>










>






|












>





|
>
>







 







|








>







 







>







 







>







 







|
|
>








481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
...
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
...
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
...
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
...
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
...
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
** true.
*/
void client_sync(int pushFlag, int pullFlag, int cloneFlag){
  int go = 1;        /* Loop until zero */
  int nToken;
  const char *zSCode = db_get("server-code", "x");
  const char *zPCode = db_get("project-code", 0);
  int nFile = 0;
  int nMsg = 0;
  int nReq = 0;
  Blob send;        /* Text we are sending to the server */
  Blob recv;        /* Reply we got back from the server */
  Blob line;        /* A single line of the reply */
  Blob aToken[5];   /* A tokenization of line */
  Blob errmsg;      /* Error message */

  assert( pushFlag || pullFlag || cloneFlag );
................................................................................
  blob_zero(&send);
  blob_zero(&recv);
  blob_zero(&errmsg);


  while( go ){
    go = 0;
    nFile = nReq = nMsg = 0;

    /* Generate a request to be sent to the server.
    ** 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++;
    }

    if( pullFlag ){
      /* Send gimme message for every phantom that we hold.
      */
      Stmt q;
      db_prepare(&q, "SELECT uuid FROM blob WHERE size<0");
      while( db_step(&q)==SQLITE_ROW ){
        const char *zUuid = db_column_text(&q, 0);
        blob_appendf(&send,"gimme %s\n", zUuid);
        nReq++;
      }
      db_finalize(&q);
    }

    if( pushFlag ){
      /* Send the server any files that the server has requested */
      nFile += send_all_pending(&send);
    }

    if( pullFlag || pushFlag ){
      /* Always send our leaves */
      Stmt q;
      db_prepare(&q, 
         "SELECT uuid FROM blob WHERE rid IN"
         "  (SELECT cid FROM plink EXCEPT SELECT pid FROM plink)"
      );
      while( db_step(&q)==SQLITE_ROW ){
        const char *zUuid = db_column_text(&q, 0);
        blob_appendf(&send, "leaf %s\n", zUuid);
        nMsg++;
      }
      db_finalize(&q);
    }

    /* Exchange messages with the server */
    printf("Send:      %d files, %d requests, %d other messages\n",
            nFile, nReq, nMsg);
    nFile = nReq = nMsg = 0;
    http_exchange(&send, &recv);
    blob_reset(&send);

    /* Process the reply that came back from the server */
    while( blob_line(&recv, &line) ){
      nToken = blob_tokenize(&line, aToken, count(aToken));

................................................................................
      /*   file UUID SIZE \n CONTENT
      **   file UUID DELTASRC SIZE \n CONTENT
      **
      ** Receive a file transmitted from the other side
      */
      if( blob_eq(&aToken[0],"file") ){
        xfer_accept_file(&recv, aToken, nToken, &errmsg);
        nFile++;
      }else

      /*   gimme UUID
      **
      ** Server is requesting a file
      */
      if( blob_eq(&aToken[0], "gimme") && nToken==2
               && blob_is_uuid(&aToken[1]) ){
        nReq++;
        if( pushFlag ){
          db_multi_exec(
            "INSERT OR IGNORE INTO pending(rid) "
            "SELECT rid FROM blob WHERE uuid=%B AND size>=0", &aToken[1]
          );
          go = 1;
        }
................................................................................
      ** Server proclaims that it has a particular file.  A leaf message
      ** means that the file is a leaf manifest on the server.
      */
      if( nToken==2
              && (blob_eq(&aToken[0], "igot") || blob_eq(&aToken[0], "leaf"))
              && blob_is_uuid(&aToken[1]) ){
        int rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%B", &aToken[1]);
        nMsg++;
        if( rid>0 ){
          db_multi_exec(
            "INSERT OR IGNORE INTO onremote(rid) VALUES(%d)", rid
          );
          /* Add to the pending set all children of the server's leaves */
          if( pushFlag && blob_eq(&aToken[0], "leaf") ){
            db_multi_exec(
................................................................................
      */
      if( blob_eq(&aToken[0],"push") && nToken==3 && cloneFlag
              && blob_is_uuid(&aToken[1]) && blob_is_uuid(&aToken[2]) ){

        if( blob_eq_str(&aToken[1], zSCode, -1) ){
          fossil_fatal("server loop");
        }
        nMsg++;
        if( zPCode==0 ){
          zPCode = mprintf("%b", &aToken[2]);
          db_set("project-code", zPCode);
        }
        cloneFlag = 0;
        pullFlag = 1;
      }else
................................................................................

      if( blob_size(&errmsg) ){
        fossil_fatal("%b", &errmsg);
      }
      blobarray_reset(aToken, nToken);
    }
    blob_reset(&recv);
    printf("Received:  %d files, %d requests, %d other messages\n",
            nFile, nReq, nMsg);
    nFile = nReq = nMsg = 0;
  };
  http_close();
  db_end_transaction(0);
  db_multi_exec(
    "DROP TABLE onremote;"
    "DROP TABLE pending;"
  );
}