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

Seperate SmartServer{Pipe,Socket}StreamMedium out of SmartServerStreamMedium.  Use recv to make the socket server medium better.

Show diffs side-by-side

added added

removed removed

Lines of Context:
202
202
 
203
203
from cStringIO import StringIO
204
204
import os
 
205
import select
205
206
import socket
206
207
import tempfile
207
208
import threading
335
336
                    self._send_response(self.request.response.args,
336
337
                        self.request.response.body)
337
338
                self.sync_with_request(self.request)
338
 
                return self.request
339
339
            except KeyboardInterrupt:
340
340
                raise
341
341
            except Exception, exception:
343
343
                self._send_response(('error', str(exception)))
344
344
                return None
345
345
 
346
 
        else:
 
346
        if self.has_dispatched:
347
347
            if self.finished_reading:
348
348
                # nothing to do.XXX: this routine should be a single state 
349
349
                # machine too.
517
517
        ## self._out.close()
518
518
        ## self._in.close()
519
519
 
520
 
    def _serve_one_request(self):
521
 
        """Read one request from input, process, send back a response.
522
 
        
 
520
    def serve(self):
 
521
        """Serve requests until the client disconnects."""
 
522
        # Keep a reference to stderr because the sys module's globals get set to
 
523
        # None during interpreter shutdown.
 
524
        from sys import stderr
 
525
        try:
 
526
            while True:
 
527
                protocol = SmartServerRequestProtocolOne(self._out,
 
528
                                                         self.backing_transport)
 
529
                if self._serve_one_request(protocol) == False:
 
530
                    break
 
531
        except Exception, e:
 
532
            stderr.write("%s terminating on exception %s\n" % (self, e))
 
533
            raise
 
534
 
 
535
 
 
536
class SmartServerSocketStreamMedium(SmartServerStreamMedium):
 
537
 
 
538
    def __init__(self, in_socket, out_file, backing_transport):
 
539
        """Constructor.
 
540
 
 
541
        :param in_socket: the socket the server will read from.  It will be put
 
542
            into blocking mode.
 
543
        """
 
544
        in_socket.setblocking(True)
 
545
        SmartServerStreamMedium.__init__(
 
546
            self, in_socket, out_file, backing_transport)
 
547
        self.push_back = ''
 
548
        
 
549
    def _serve_one_request(self, protocol):
 
550
        """Read one request from input, process, send back a response.
 
551
        
 
552
        :param protocol: a SmartServerRequestProtocol.
 
553
        :return: False if the server should terminate, otherwise None.
 
554
        """
 
555
        while not protocol.finished_reading:
 
556
            if self.push_back:
 
557
                protocol.accept_bytes(self.push_back)
 
558
                self.push_back = ''
 
559
            else:
 
560
                bytes = self._in.recv(4096)
 
561
                if bytes == '':
 
562
                    return False
 
563
                protocol.accept_bytes(bytes)
 
564
 
 
565
        self.push_back = protocol.excess_buffer
 
566
    
 
567
 
 
568
class SmartServerPipeStreamMedium(SmartServerStreamMedium):
 
569
 
 
570
    def __init__(self, in_file, out_file, backing_transport):
 
571
        """Construct new server.
 
572
 
 
573
        :param in_file: Python file from which requests can be read.
 
574
        :param out_file: Python file to write responses.
 
575
        :param backing_transport: Transport for the directory served.
 
576
        """
 
577
        SmartServerStreamMedium.__init__(self, in_file, out_file, backing_transport)
 
578
        self._in = in_file
 
579
        self._out = out_file
 
580
 
 
581
    def _serve_one_request(self, protocol):
 
582
        """Read one request from input, process, send back a response.
 
583
        
 
584
        :param protocol: a SmartServerRequestProtocol.
523
585
        :return: False if the server should terminate, otherwise None.
524
586
        """
525
587
        # ** deserialise, read bytes, serialise and write bytes
529
591
            # client closed connection
530
592
            return False  # shutdown server
531
593
        try:
532
 
            protocol = SmartServerRequestProtocolOne(self._out,
533
 
                self.backing_transport)
534
594
            protocol.accept_bytes(req_line)
535
595
            if not protocol.finished_reading:
536
596
                # this boils down to readline which wont block on open sockets
543
603
                # might be nice to do protocol.end_of_bytes()
544
604
                # because self._recv_bulk reads all the bytes, this must finish
545
605
                # after one delivery of data rather than looping.
546
 
                assert protocol.finished_reading
 
606
                assert protocol.finished_reading, 'was not finished reading'
547
607
        except KeyboardInterrupt:
548
608
            raise
549
609
        except Exception, e:
551
611
            self._send_error_and_disconnect(e)
552
612
            return False
553
613
 
554
 
    def serve(self):
555
 
        """Serve requests until the client disconnects."""
556
 
        # Keep a reference to stderr because the sys module's globals get set to
557
 
        # None during interpreter shutdown.
558
 
        from sys import stderr
559
 
        try:
560
 
            while self._serve_one_request() != False:
561
 
                pass
562
 
        except Exception, e:
563
 
            stderr.write("%s terminating on exception %s\n" % (self, e))
564
 
            raise
565
 
 
566
614
 
567
615
class SmartServerResponse(object):
568
616
    """Response generated by SmartServerRequestHandler."""
851
899
        conn.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
852
900
        from_client = conn.makefile('r')
853
901
        to_client = conn.makefile('w')
854
 
        handler = SmartServerStreamMedium(from_client, to_client,
 
902
        handler = SmartServerSocketStreamMedium(conn, to_client,
855
903
                self.backing_transport)
856
904
        connection_thread = threading.Thread(None, handler.serve, name='smart-server-child')
857
905
        connection_thread.setDaemon(True)
1516
1564
        """Receive a tuple from the medium request."""
1517
1565
        line = ''
1518
1566
        while not line or line[-1] != '\n':
1519
 
            # yes, this is inefficient - but tuples are short.
 
1567
            # TODO: this is inefficient - but tuples are short.
1520
1568
            new_char = self._request.read_bytes(1)
1521
1569
            line += new_char
1522
1570
            assert new_char != '', "end of file reading from server."