Skip to content

Commit

Permalink
More changes for event listener portability between 2.x and 3.x.
Browse files Browse the repository at this point in the history
  • Loading branch information
vsajip committed Dec 30, 2016
1 parent 9ad37ae commit baf3dc1
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 57 deletions.
5 changes: 3 additions & 2 deletions supervisor/childutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from supervisor.compat import xmlrpclib
from supervisor.compat import long
from supervisor.compat import as_string

from supervisor.xmlrpc import SupervisorTransport
from supervisor.events import ProcessCommunicationEvent
Expand Down Expand Up @@ -58,7 +59,7 @@ def wait(self, stdin=sys.stdin, stdout=sys.stdout):
return headers, payload

def ready(self, stdout=sys.stdout):
stdout.write(PEventListenerDispatcher.READY_FOR_EVENTS_TOKEN)
stdout.write(as_string(PEventListenerDispatcher.READY_FOR_EVENTS_TOKEN))
stdout.flush()

def ok(self, stdout=sys.stdout):
Expand All @@ -69,7 +70,7 @@ def fail(self, stdout=sys.stdout):

def send(self, data, stdout=sys.stdout):
resultlen = len(data)
result = '%s%s\n%s' % (PEventListenerDispatcher.RESULT_TOKEN_START,
result = '%s%s\n%s' % (as_string(PEventListenerDispatcher.RESULT_TOKEN_START),
str(resultlen),
data)
stdout.write(result)
Expand Down
37 changes: 21 additions & 16 deletions supervisor/dispatchers.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import errno
from supervisor.medusa.asyncore_25 import compact_traceback

from supervisor.compat import as_string
from supervisor.events import notify
from supervisor.events import EventRejectedEvent
from supervisor.events import ProcessLogStderrEvent
Expand Down Expand Up @@ -277,10 +278,10 @@ class PEventListenerDispatcher(PDispatcher):
""" An output dispatcher that monitors and changes a process'
listener_state """
childlog = None # the logger
state_buffer = '' # data waiting to be reviewed for state changes
state_buffer = b'' # data waiting to be reviewed for state changes

READY_FOR_EVENTS_TOKEN = 'READY\n'
RESULT_TOKEN_START = 'RESULT '
READY_FOR_EVENTS_TOKEN = b'READY\n'
RESULT_TOKEN_START = b'RESULT '
READY_FOR_EVENTS_LEN = len(READY_FOR_EVENTS_TOKEN)
RESULT_TOKEN_START_LEN = len(RESULT_TOKEN_START)

Expand All @@ -290,7 +291,7 @@ def __init__(self, process, channel, fd):
# "busy" state that implies we're awaiting a READY_FOR_EVENTS_TOKEN
self.process.listener_state = EventListenerStates.ACKNOWLEDGED
self.process.event = None
self.result = ''
self.result = b''
self.resultlen = None

logfile = getattr(process.config, '%s_logfile' % channel)
Expand Down Expand Up @@ -359,7 +360,7 @@ def handle_listener_state_change(self):

if state == EventListenerStates.UNKNOWN:
# this is a fatal state
self.state_buffer = ''
self.state_buffer = b''
return

if state == EventListenerStates.ACKNOWLEDGED:
Expand All @@ -373,7 +374,7 @@ def handle_listener_state_change(self):
process.event = None
else:
self._change_listener_state(EventListenerStates.UNKNOWN)
self.state_buffer = ''
self.state_buffer = b''
process.event = None
if self.state_buffer:
# keep going til its too short
Expand All @@ -384,14 +385,14 @@ def handle_listener_state_change(self):
elif state == EventListenerStates.READY:
# the process sent some spurious data, be strict about it
self._change_listener_state(EventListenerStates.UNKNOWN)
self.state_buffer = ''
self.state_buffer = b''
process.event = None
return

elif state == EventListenerStates.BUSY:
if self.resultlen is None:
# we haven't begun gathering result data yet
pos = data.find('\n')
pos = data.find(b'\n')
if pos == -1:
# we can't make a determination yet, we dont have a full
# results line
Expand All @@ -403,11 +404,15 @@ def handle_listener_state_change(self):
try:
self.resultlen = int(resultlen)
except ValueError:
try:
result_line = as_string(result_line)
except UnicodeDecodeError:
result_line = 'Undecodable: %r' % result_line
process.config.options.logger.warn(
'%s: bad result line: %r' % (procname, result_line)
'%s: bad result line: \'%s\'' % (procname, result_line)
)
self._change_listener_state(EventListenerStates.UNKNOWN)
self.state_buffer = ''
self.state_buffer = b''
notify(EventRejectedEvent(process, process.event))
process.event = None
return
Expand Down Expand Up @@ -499,20 +504,20 @@ def handle_write_event(self):
else:
raise

ANSI_ESCAPE_BEGIN = '\x1b['
ANSI_TERMINATORS = ('H', 'f', 'A', 'B', 'C', 'D', 'R', 's', 'u', 'J',
'K', 'h', 'l', 'p', 'm')
ANSI_ESCAPE_BEGIN = b'\x1b['
ANSI_TERMINATORS = (b'H', b'f', b'A', b'B', b'C', b'D', b'R', b's', b'u', b'J',
b'K', b'h', b'l', b'p', b'm')

def stripEscapes(s):
"""
Remove all ANSI color escapes from the given string.
"""
result = ''
result = b''
show = 1
i = 0
L = len(s)
while i < L:
if show == 0 and s[i] in ANSI_TERMINATORS:
if show == 0 and s[i:i + 1] in ANSI_TERMINATORS:
show = 1
elif show:
n = s.find(ANSI_ESCAPE_BEGIN, i)
Expand All @@ -530,5 +535,5 @@ class RejectEvent(Exception):
to reject an event """

def default_handler(event, response):
if response != 'OK':
if response != b'OK':
raise RejectEvent(response)
9 changes: 5 additions & 4 deletions supervisor/tests/test_childutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import time
import unittest
from supervisor.compat import StringIO
from supervisor.compat import as_string

class ChildUtilsTests(unittest.TestCase):
def test_getRPCInterface(self):
Expand Down Expand Up @@ -101,31 +102,31 @@ def read(self, *ignored):
def test_token(self):
from supervisor.childutils import listener
from supervisor.dispatchers import PEventListenerDispatcher
token = PEventListenerDispatcher.READY_FOR_EVENTS_TOKEN
token = as_string(PEventListenerDispatcher.READY_FOR_EVENTS_TOKEN)
stdout = StringIO()
listener.ready(stdout)
self.assertEqual(stdout.getvalue(), token)

def test_ok(self):
from supervisor.childutils import listener
from supervisor.dispatchers import PEventListenerDispatcher
begin = PEventListenerDispatcher.RESULT_TOKEN_START
begin = as_string(PEventListenerDispatcher.RESULT_TOKEN_START)
stdout = StringIO()
listener.ok(stdout)
self.assertEqual(stdout.getvalue(), begin + '2\nOK')

def test_fail(self):
from supervisor.childutils import listener
from supervisor.dispatchers import PEventListenerDispatcher
begin = PEventListenerDispatcher.RESULT_TOKEN_START
begin = as_string(PEventListenerDispatcher.RESULT_TOKEN_START)
stdout = StringIO()
listener.fail(stdout)
self.assertEqual(stdout.getvalue(), begin + '4\nFAIL')

def test_send(self):
from supervisor.childutils import listener
from supervisor.dispatchers import PEventListenerDispatcher
begin = PEventListenerDispatcher.RESULT_TOKEN_START
begin = as_string(PEventListenerDispatcher.RESULT_TOKEN_START)
stdout = StringIO()
msg = 'the body data ya fool\n'
listener.send(msg, stdout)
Expand Down
Loading

0 comments on commit baf3dc1

Please sign in to comment.