~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/smart/repository.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2011-08-17 08:40:16 UTC
  • mfrom: (5642.4.6 712474-module-available)
  • Revision ID: pqm@pqm.ubuntu.com-20110817084016-600z65qzqmmt44w7
(vila) ModuleAvailableFeature don't try to imported already imported
 modules. (Vincent Ladeuil)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006, 2007, 2010 Canonical Ltd
 
1
# Copyright (C) 2006-2010 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
30
30
    osutils,
31
31
    pack,
32
32
    ui,
33
 
    versionedfile,
34
33
    )
35
34
from bzrlib.bzrdir import BzrDir
36
35
from bzrlib.smart.request import (
82
81
            recreate_search trusts that clients will look for missing things
83
82
            they expected and get it from elsewhere.
84
83
        """
 
84
        if search_bytes == 'everything':
 
85
            return graph.EverythingResult(repository), None
85
86
        lines = search_bytes.split('\n')
86
87
        if lines[0] == 'ancestry-of':
87
88
            heads = lines[1:]
392
393
        if token == '':
393
394
            token = None
394
395
        try:
395
 
            token = repository.lock_write(token=token)
 
396
            token = repository.lock_write(token=token).repository_token
396
397
        except errors.LockContention, e:
397
398
            return FailedSmartServerResponse(('LockContention',))
398
399
        except errors.UnlockableTransport:
413
414
    def do_repository_request(self, repository, to_network_name):
414
415
        """Get a stream for inserting into a to_format repository.
415
416
 
 
417
        The request body is 'search_bytes', a description of the revisions
 
418
        being requested.
 
419
 
 
420
        In 2.3 this verb added support for search_bytes == 'everything'.  Older
 
421
        implementations will respond with a BadSearch error, and clients should
 
422
        catch this and fallback appropriately.
 
423
 
416
424
        :param repository: The repository to stream from.
417
425
        :param to_network_name: The network name of the format of the target
418
426
            repository.
490
498
 
491
499
 
492
500
class SmartServerRepositoryGetStream_1_19(SmartServerRepositoryGetStream):
 
501
    """The same as Repository.get_stream, but will return stream CHK formats to
 
502
    clients.
 
503
 
 
504
    See SmartServerRepositoryGetStream._should_fake_unknown.
 
505
    
 
506
    New in 1.19.
 
507
    """
493
508
 
494
509
    def _should_fake_unknown(self):
495
510
        """Returns False; we don't need to workaround bugs in 1.19+ clients."""
502
517
    yield pack_writer.begin()
503
518
    yield pack_writer.bytes_record(src_format.network_name(), '')
504
519
    for substream_type, substream in stream:
505
 
        if substream_type == 'inventory-deltas':
506
 
            # This doesn't feel like the ideal place to issue this warning;
507
 
            # however we don't want to do it in the Repository that's
508
 
            # generating the stream, because that might be on the server.
509
 
            # Instead we try to observe it as the stream goes by.
510
 
            ui.ui_factory.warn_cross_format_fetch(src_format,
511
 
                '(remote)')
512
520
        for record in substream:
513
521
            if record.storage_kind in ('chunked', 'fulltext'):
514
522
                serialised = record_to_fulltext_bytes(record)
515
 
            elif record.storage_kind == 'inventory-delta':
516
 
                serialised = record_to_inventory_delta_bytes(record)
517
523
            elif record.storage_kind == 'absent':
518
524
                raise ValueError("Absent factory for %s" % (record.key,))
519
525
            else:
551
557
    :ivar first_bytes: The first bytes to give the next NetworkRecordStream.
552
558
    """
553
559
 
554
 
    def __init__(self, byte_stream):
 
560
    def __init__(self, byte_stream, record_counter):
555
561
        """Create a _ByteStreamDecoder."""
556
562
        self.stream_decoder = pack.ContainerPushParser()
557
563
        self.current_type = None
558
564
        self.first_bytes = None
559
565
        self.byte_stream = byte_stream
 
566
        self._record_counter = record_counter
 
567
        self.key_count = 0
560
568
 
561
569
    def iter_stream_decoder(self):
562
570
        """Iterate the contents of the pack from stream_decoder."""
587
595
 
588
596
    def record_stream(self):
589
597
        """Yield substream_type, substream from the byte stream."""
 
598
        def wrap_and_count(pb, rc, substream):
 
599
            """Yield records from stream while showing progress."""
 
600
            counter = 0
 
601
            if rc:
 
602
                if self.current_type != 'revisions' and self.key_count != 0:
 
603
                    # As we know the number of revisions now (in self.key_count)
 
604
                    # we can setup and use record_counter (rc).
 
605
                    if not rc.is_initialized():
 
606
                        rc.setup(self.key_count, self.key_count)
 
607
            for record in substream.read():
 
608
                if rc:
 
609
                    if rc.is_initialized() and counter == rc.STEP:
 
610
                        rc.increment(counter)
 
611
                        pb.update('Estimate', rc.current, rc.max)
 
612
                        counter = 0
 
613
                    if self.current_type == 'revisions':
 
614
                        # Total records is proportional to number of revs
 
615
                        # to fetch. With remote, we used self.key_count to
 
616
                        # track the number of revs. Once we have the revs
 
617
                        # counts in self.key_count, the progress bar changes
 
618
                        # from 'Estimating..' to 'Estimate' above.
 
619
                        self.key_count += 1
 
620
                        if counter == rc.STEP:
 
621
                            pb.update('Estimating..', self.key_count)
 
622
                            counter = 0
 
623
                counter += 1
 
624
                yield record
 
625
 
590
626
        self.seed_state()
 
627
        pb = ui.ui_factory.nested_progress_bar()
 
628
        rc = self._record_counter
591
629
        # Make and consume sub generators, one per substream type:
592
630
        while self.first_bytes is not None:
593
631
            substream = NetworkRecordStream(self.iter_substream_bytes())
594
632
            # after substream is fully consumed, self.current_type is set to
595
633
            # the next type, and self.first_bytes is set to the matching bytes.
596
 
            yield self.current_type, substream.read()
 
634
            yield self.current_type, wrap_and_count(pb, rc, substream)
 
635
        if rc:
 
636
            pb.update('Done', rc.max, rc.max)
 
637
        pb.finished()
597
638
 
598
639
    def seed_state(self):
599
640
        """Prepare the _ByteStreamDecoder to decode from the pack stream."""
604
645
        list(self.iter_substream_bytes())
605
646
 
606
647
 
607
 
def _byte_stream_to_stream(byte_stream):
 
648
def _byte_stream_to_stream(byte_stream, record_counter=None):
608
649
    """Convert a byte stream into a format and a stream.
609
650
 
610
651
    :param byte_stream: A bytes iterator, as output by _stream_to_byte_stream.
611
652
    :return: (RepositoryFormat, stream_generator)
612
653
    """
613
 
    decoder = _ByteStreamDecoder(byte_stream)
 
654
    decoder = _ByteStreamDecoder(byte_stream, record_counter)
614
655
    for bytes in byte_stream:
615
656
        decoder.stream_decoder.accept_bytes(bytes)
616
657
        for record in decoder.stream_decoder.read_pending_records(max=1):