/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/inter.py

  • Committer: v.ladeuil+lp at free
  • Date: 2006-12-01 15:06:29 UTC
  • mto: (2172.3.1 bzr.73948)
  • mto: This revision was merged to the branch mainline in revision 2181.
  • Revision ID: v.ladeuil+lp@free.fr-20061201150629-zjd2an87u0r7nhhw
The tests that would have help avoid bug #73948 and all that mess :)

* bzrlib/transport/http/response.py:
(handle_response): Translate a 416 http error code into a bzr
exception.

* bzrlib/transport/http/_urllib2_wrappers.py:
(HTTPDefaultErrorHandler.http_error_default): Translate a 416 http
error code into a bzr exception.

* bzrlib/transport/http/_pycurl.py:
(PyCurlTransport._curl_perform): It could happen that pycrul
itself detect a short read.

* bzrlib/transport/http/__init__.py:
(HttpTransportBase._retry_get): New method, factorizing the retry
logic.
(HttpTransportBase.readv): We can have exception during the
initial GET worth degrading the range requirements (i.e. retrying
the GET request with either single or not ranges).

* bzrlib/tests/test_transport_implementations.py:
(TransportTests.test_readv_short_read): InvalidRange can also be
raised.

* bzrlib/tests/test_http.py:
(TestRangeRequestServer.test_readv_invalid_ranges): Was named
test_readv_short_read, the new name make the intent
clearer. Depending of the code path used (urllib or pycurl), both
exceptions can be raised.

* bzrlib/tests/HttpServer.py:
(TestingHTTPRequestHandler.do_GET): If invalid ranges are
specified, returns a 416 instead of the whole file (both are valid
according to the RFC).

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
    operations with another of similar type - they will always forward to
30
30
    a subclass of InterObject - i.e. 
31
31
    InterVersionedFile.get(other).method_name(parameters).
 
32
 
 
33
    If the source and target objects implement the locking protocol - 
 
34
    lock_read, lock_write, unlock, then the InterObject's lock_read,
 
35
    lock_write and unlock methods may be used (optionally in conjunction with
 
36
    the needs_read_lock and needs_write_lock decorators.)
32
37
    """
33
38
 
34
 
    # _optimisers = set()
35
 
    # Each concrete InterObject type should have its own optimisers set.
 
39
    # _optimisers = list()
 
40
    # Each concrete InterObject type should have its own optimisers list.
36
41
 
37
42
    def __init__(self, source, target):
38
43
        """Construct a default InterObject instance. Please use 'get'.
47
52
        self.source = source
48
53
        self.target = target
49
54
 
 
55
    def _double_lock(self, lock_source, lock_target):
 
56
        """Take out two locks, rolling back the first if the second throws."""
 
57
        lock_source()
 
58
        try:
 
59
            lock_target()
 
60
        except Exception:
 
61
            # we want to ensure that we don't leave source locked by mistake.
 
62
            # and any error on target should not confuse source.
 
63
            self.source.unlock()
 
64
            raise
 
65
 
50
66
    @classmethod
51
67
    def get(klass, source, target):
52
68
        """Retrieve a Inter worker object for these objects.
58
74
        If an optimised worker exists it will be used otherwise
59
75
        a default Inter worker instance will be created.
60
76
        """
61
 
        for provider in klass._optimisers:
 
77
        for provider in reversed(klass._optimisers):
62
78
            if provider.is_compatible(source, target):
63
79
                return provider(source, target)
64
80
        return klass(source, target)
65
81
 
 
82
    def lock_read(self):
 
83
        """Take out a logical read lock.
 
84
 
 
85
        This will lock the source branch and the target branch. The source gets
 
86
        a read lock and the target a read lock.
 
87
        """
 
88
        self._double_lock(self.source.lock_read, self.target.lock_read)
 
89
 
 
90
    def lock_write(self):
 
91
        """Take out a logical write lock.
 
92
 
 
93
        This will lock the source branch and the target branch. The source gets
 
94
        a read lock and the target a write lock.
 
95
        """
 
96
        self._double_lock(self.source.lock_read, self.target.lock_write)
 
97
 
66
98
    @classmethod
67
99
    def register_optimiser(klass, optimiser):
68
100
        """Register an InterObject optimiser."""
69
 
        klass._optimisers.add(optimiser)
 
101
        klass._optimisers.append(optimiser)
 
102
 
 
103
    def unlock(self):
 
104
        """Release the locks on source and target."""
 
105
        try:
 
106
            self.target.unlock()
 
107
        finally:
 
108
            self.source.unlock()
70
109
 
71
110
    @classmethod
72
111
    def unregister_optimiser(klass, optimiser):