network: Respond to messages before closing connections

This makes a connection tell the actor to stop the connection, instead
of stopping it itself. This is preferable, because other messages sent
to the actor that is not processed yet, may now send data to the client.

E.g. it makes this work:
$ echo status | nc localhost 6600
This commit is contained in:
Trygve Aaberge 2014-04-25 06:01:04 +02:00
parent 203b13aad7
commit d62ad966af
3 changed files with 18 additions and 2 deletions

View File

@ -267,7 +267,8 @@ class Connection(object):
return True
if not data:
self.stop('Client most likely disconnected.')
self.actor_ref.tell({'close': True})
self.disable_recv()
return True
try:
@ -348,6 +349,10 @@ class LineProtocol(pykka.ThreadingActor):
def on_receive(self, message):
"""Handle messages with new data from server."""
if 'close' in message:
self.connection.stop('Client most likely disconnected.')
return
if 'received' not in message:
return

View File

@ -416,7 +416,8 @@ class ConnectionTest(unittest.TestCase):
self.assertTrue(network.Connection.recv_callback(
self.mock, sentinel.fd, gobject.IO_IN))
self.mock.stop.assert_called_once_with(any_unicode)
self.mock.actor_ref.tell.assert_called_once_with({'close': True})
self.mock.disable_recv.assert_called_once_with()
def test_recv_callback_recoverable_error(self):
self.mock.sock = Mock(spec=socket.SocketType)

View File

@ -8,6 +8,8 @@ import unittest
from mopidy.utils import network
from tests import any_unicode
class LineProtocolTest(unittest.TestCase):
def setUp(self):
@ -33,6 +35,14 @@ class LineProtocolTest(unittest.TestCase):
network.LineProtocol.__init__(self.mock, sentinel.connection)
self.assertEqual(delimiter, self.mock.delimiter)
def test_on_receive_close_calls_stop(self):
self.mock.connection = Mock(spec=network.Connection)
self.mock.recv_buffer = ''
self.mock.parse_lines.return_value = []
network.LineProtocol.on_receive(self.mock, {'close': True})
self.mock.connection.stop.assert_called_once_with(any_unicode)
def test_on_receive_no_new_lines_adds_to_recv_buffer(self):
self.mock.connection = Mock(spec=network.Connection)
self.mock.recv_buffer = ''