/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/smart/server.py

  • Committer: Alexander Belchenko
  • Date: 2011-01-31 22:09:46 UTC
  • mto: (5609.2.6 2.3)
  • mto: This revision was merged to the branch mainline in revision 5642.
  • Revision ID: bialix@ukr.net-20110131220946-hjrabl6hneithjkw
correct singular form, thanks John

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
 
19
19
import errno
20
20
import os.path
 
21
import select
21
22
import socket
22
23
import sys
23
24
import threading
26
27
from bzrlib import (
27
28
    errors,
28
29
    trace,
29
 
    transport,
 
30
    transport as _mod_transport,
30
31
)
31
32
from bzrlib.lazy_import import lazy_import
32
33
lazy_import(globals(), """
33
34
from bzrlib.smart import medium
34
35
from bzrlib.transport import (
35
36
    chroot,
36
 
    get_transport,
37
37
    pathfilter,
38
38
    )
39
39
from bzrlib import (
51
51
    hooks: An instance of SmartServerHooks.
52
52
    """
53
53
 
54
 
    def __init__(self, backing_transport, host='127.0.0.1', port=0,
55
 
                 root_client_path='/'):
 
54
    def __init__(self, backing_transport, root_client_path='/'):
56
55
        """Construct a new server.
57
56
 
58
57
        To actually start it running, call either start_background_thread or
59
58
        serve.
60
59
 
61
60
        :param backing_transport: The transport to serve.
 
61
        :param root_client_path: The client path that will correspond to root
 
62
            of backing_transport.
 
63
        """
 
64
        self.backing_transport = backing_transport
 
65
        self.root_client_path = root_client_path
 
66
 
 
67
    def start_server(self, host, port):
 
68
        """Create the server listening socket.
 
69
 
62
70
        :param host: Name of the interface to listen on.
63
71
        :param port: TCP port to listen on, or 0 to allocate a transient port.
64
 
        :param root_client_path: The client path that will correspond to root
65
 
            of backing_transport.
66
72
        """
67
73
        # let connections timeout so that we get a chance to terminate
68
74
        # Keep a reference to the exceptions we want to catch because the socket
89
95
        self.port = self._sockname[1]
90
96
        self._server_socket.listen(1)
91
97
        self._server_socket.settimeout(1)
92
 
        self.backing_transport = backing_transport
93
98
        self._started = threading.Event()
94
99
        self._stopped = threading.Event()
95
 
        self.root_client_path = root_client_path
96
100
 
97
 
    def serve(self, thread_name_suffix=''):
98
 
        self._should_terminate = False
99
 
        # for hooks we are letting code know that a server has started (and
100
 
        # later stopped).
 
101
    def _backing_urls(self):
101
102
        # There are three interesting urls:
102
103
        # The URL the server can be contacted on. (e.g. bzr://host/)
103
104
        # The URL that a commit done on the same machine as the server will
113
114
        # The latter two urls are different aliases to the servers url,
114
115
        # so we group those in a list - as there might be more aliases
115
116
        # in the future.
116
 
        backing_urls = [self.backing_transport.base]
 
117
        urls = [self.backing_transport.base]
117
118
        try:
118
 
            backing_urls.append(self.backing_transport.external_url())
 
119
            urls.append(self.backing_transport.external_url())
119
120
        except errors.InProcessTransport:
120
121
            pass
 
122
        return urls
 
123
 
 
124
    def run_server_started_hooks(self, backing_urls=None):
 
125
        if backing_urls is None:
 
126
            backing_urls = self._backing_urls()
121
127
        for hook in SmartTCPServer.hooks['server_started']:
122
128
            hook(backing_urls, self.get_url())
123
129
        for hook in SmartTCPServer.hooks['server_started_ex']:
124
130
            hook(backing_urls, self)
 
131
 
 
132
    def run_server_stopped_hooks(self, backing_urls=None):
 
133
        if backing_urls is None:
 
134
            backing_urls = self._backing_urls()
 
135
        for hook in SmartTCPServer.hooks['server_stopped']:
 
136
            hook(backing_urls, self.get_url())
 
137
 
 
138
    def serve(self, thread_name_suffix=''):
 
139
        self._should_terminate = False
 
140
        # for hooks we are letting code know that a server has started (and
 
141
        # later stopped).
 
142
        self.run_server_started_hooks()
125
143
        self._started.set()
126
144
        try:
127
145
            try:
155
173
            except self._socket_error:
156
174
                # ignore errors on close
157
175
                pass
158
 
            for hook in SmartTCPServer.hooks['server_stopped']:
159
 
                hook(backing_urls, self.get_url())
 
176
            self.run_server_stopped_hooks()
160
177
 
161
178
    def get_url(self):
162
179
        """Return the url of the server"""
172
189
        thread_name = 'smart-server-child' + thread_name_suffix
173
190
        connection_thread = threading.Thread(
174
191
            None, handler.serve, name=thread_name)
 
192
        # FIXME: This thread is never joined, it should at least be collected
 
193
        # somewhere so that tests that want to check for leaked threads can get
 
194
        # rid of them -- vila 20100531
175
195
        connection_thread.setDaemon(True)
176
196
        connection_thread.start()
 
197
        return connection_thread
177
198
 
178
199
    def start_background_thread(self, thread_name_suffix=''):
179
200
        self._started.clear()
305
326
        chroot_server = chroot.ChrootServer(transport)
306
327
        chroot_server.start_server()
307
328
        self.cleanups.append(chroot_server.stop_server)
308
 
        transport = get_transport(chroot_server.get_url())
 
329
        transport = _mod_transport.get_transport(chroot_server.get_url())
309
330
        if self.base_path is not None:
310
331
            # Decorate the server's backing transport with a filter that can
311
332
            # expand homedirs.
312
333
            expand_userdirs = self._make_expand_userdirs_filter(transport)
313
334
            expand_userdirs.start_server()
314
335
            self.cleanups.append(expand_userdirs.stop_server)
315
 
            transport = get_transport(expand_userdirs.get_url())
 
336
            transport = _mod_transport.get_transport(expand_userdirs.get_url())
316
337
        self.transport = transport
317
338
 
318
339
    def _make_smart_server(self, host, port, inet):
324
345
                host = medium.BZR_DEFAULT_INTERFACE
325
346
            if port is None:
326
347
                port = medium.BZR_DEFAULT_PORT
327
 
            smart_server = SmartTCPServer(self.transport, host=host, port=port)
 
348
            smart_server = SmartTCPServer(self.transport)
 
349
            smart_server.start_server(host, port)
328
350
            trace.note('listening on port: %s' % smart_server.port)
329
351
        self.smart_server = smart_server
330
352