mirror of
https://github.com/avatao-content/baseimage-tutorial-framework
synced 2024-11-22 12:51:32 +00:00
Rename ServerConnector interface to Connector ¯\_(ツ)_/¯
This commit is contained in:
parent
fd92c443b2
commit
30223fe99f
@ -7,12 +7,12 @@ class FrontendHandler:
|
|||||||
keys = ['message', 'queueMessages', 'dashboard', 'console']
|
keys = ['message', 'queueMessages', 'dashboard', 'console']
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.server_connector = None
|
self.connector = None
|
||||||
self.keys = [*type(self).keys, 'recover']
|
self.keys = [*type(self).keys, 'recover']
|
||||||
self._frontend_message_storage = FrontendMessageStorage(type(self).keys)
|
self._frontend_message_storage = FrontendMessageStorage(type(self).keys)
|
||||||
|
|
||||||
def send_message(self, message):
|
def send_message(self, message):
|
||||||
self.server_connector.send_message(message, scope=Scope.WEBSOCKET)
|
self.connector.send_message(message, scope=Scope.WEBSOCKET)
|
||||||
|
|
||||||
def handle_event(self, message, _):
|
def handle_event(self, message, _):
|
||||||
self._frontend_message_storage.save_message(message)
|
self._frontend_message_storage.save_message(message)
|
||||||
|
@ -35,14 +35,14 @@ class FSMHandler:
|
|||||||
'update': self.handle_update
|
'update': self.handle_update
|
||||||
}
|
}
|
||||||
|
|
||||||
def handle_event(self, message, server_connector):
|
def handle_event(self, message, connector):
|
||||||
try:
|
try:
|
||||||
message = self.command_handlers[message['data']['command']](message)
|
message = self.command_handlers[message['data']['command']](message)
|
||||||
if message:
|
if message:
|
||||||
fsm_update_message = self._fsm_updater.fsm_update
|
fsm_update_message = self._fsm_updater.fsm_update
|
||||||
sign_message(self.auth_key, message)
|
sign_message(self.auth_key, message)
|
||||||
sign_message(self.auth_key, fsm_update_message)
|
sign_message(self.auth_key, fsm_update_message)
|
||||||
server_connector.send_message(fsm_update_message, Scope.BROADCAST)
|
connector.send_message(fsm_update_message, Scope.BROADCAST)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
LOG.error('IGNORING MESSAGE: Invalid message received: %s', message)
|
LOG.error('IGNORING MESSAGE: Invalid message received: %s', message)
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ class IdeHandler:
|
|||||||
:param selected_file: file that is selected by default
|
:param selected_file: file that is selected by default
|
||||||
:param exclude: list of filenames that should not appear between files (for .o, .pyc, etc.)
|
:param exclude: list of filenames that should not appear between files (for .o, .pyc, etc.)
|
||||||
"""
|
"""
|
||||||
self.server_connector = None
|
self.connector = None
|
||||||
try:
|
try:
|
||||||
self.filemanager = FileManager(
|
self.filemanager = FileManager(
|
||||||
allowed_directories=allowed_directories,
|
allowed_directories=allowed_directories,
|
||||||
@ -90,7 +90,7 @@ class IdeHandler:
|
|||||||
})
|
})
|
||||||
|
|
||||||
def send_message(self, message):
|
def send_message(self, message):
|
||||||
self.server_connector.send_message(message, scope=Scope.WEBSOCKET)
|
self.connector.send_message(message, scope=Scope.WEBSOCKET)
|
||||||
|
|
||||||
def read(self, data):
|
def read(self, data):
|
||||||
"""
|
"""
|
||||||
|
@ -20,7 +20,7 @@ class PipeIOHandlerBase:
|
|||||||
keys = ['']
|
keys = ['']
|
||||||
|
|
||||||
def __init__(self, in_pipe_path, out_pipe_path, permissions=DEFAULT_PERMISSIONS):
|
def __init__(self, in_pipe_path, out_pipe_path, permissions=DEFAULT_PERMISSIONS):
|
||||||
self.server_connector = None
|
self.connector = None
|
||||||
self.pipe_io = CallbackPipeIOServer(
|
self.pipe_io = CallbackPipeIOServer(
|
||||||
in_pipe_path,
|
in_pipe_path,
|
||||||
out_pipe_path,
|
out_pipe_path,
|
||||||
@ -56,7 +56,7 @@ class PipeIOHandler(PipeIOHandlerBase):
|
|||||||
|
|
||||||
def handle_pipe_event(self, message_bytes):
|
def handle_pipe_event(self, message_bytes):
|
||||||
json = loads(message_bytes)
|
json = loads(message_bytes)
|
||||||
self.server_connector.send_message(json)
|
self.connector.send_message(json)
|
||||||
|
|
||||||
|
|
||||||
class TransformerPipeIOHandler(PipeIOHandlerBase):
|
class TransformerPipeIOHandler(PipeIOHandlerBase):
|
||||||
@ -93,7 +93,7 @@ class TransformerPipeIOHandler(PipeIOHandlerBase):
|
|||||||
transformed_bytes = self._transform_in(message_bytes)
|
transformed_bytes = self._transform_in(message_bytes)
|
||||||
if transformed_bytes:
|
if transformed_bytes:
|
||||||
json_message = loads(transformed_bytes)
|
json_message = loads(transformed_bytes)
|
||||||
self.server_connector.send_message(json_message)
|
self.connector.send_message(json_message)
|
||||||
|
|
||||||
|
|
||||||
class CommandHandler(PipeIOHandler):
|
class CommandHandler(PipeIOHandler):
|
||||||
|
@ -7,9 +7,9 @@ from .supervisor import ProcessLogManager
|
|||||||
|
|
||||||
|
|
||||||
class LogInotifyObserver(InotifyObserver, ProcessLogManager):
|
class LogInotifyObserver(InotifyObserver, ProcessLogManager):
|
||||||
def __init__(self, server_connector, supervisor_uri, process_name, log_tail=0):
|
def __init__(self, connector, supervisor_uri, process_name, log_tail=0):
|
||||||
self._prevent_log_recursion()
|
self._prevent_log_recursion()
|
||||||
self._server_connector = server_connector
|
self._connector = connector
|
||||||
self._process_name = process_name
|
self._process_name = process_name
|
||||||
self.log_tail = log_tail
|
self.log_tail = log_tail
|
||||||
self._procinfo = None
|
self._procinfo = None
|
||||||
@ -35,7 +35,7 @@ class LogInotifyObserver(InotifyObserver, ProcessLogManager):
|
|||||||
self.paths = self._get_logfiles()
|
self.paths = self._get_logfiles()
|
||||||
|
|
||||||
def on_modified(self, event):
|
def on_modified(self, event):
|
||||||
self._server_connector.send_message({
|
self._connector.send_message({
|
||||||
'key': 'processlog',
|
'key': 'processlog',
|
||||||
'data': {
|
'data': {
|
||||||
'command': 'new_log',
|
'command': 'new_log',
|
||||||
|
@ -32,7 +32,7 @@ class ProcessHandler(ProcessManager, ProcessLogManager):
|
|||||||
'restart': self.restart_process
|
'restart': self.restart_process
|
||||||
}
|
}
|
||||||
|
|
||||||
def handle_event(self, message, server_connector):
|
def handle_event(self, message, connector):
|
||||||
try:
|
try:
|
||||||
data = message['data']
|
data = message['data']
|
||||||
try:
|
try:
|
||||||
@ -48,6 +48,6 @@ class ProcessHandler(ProcessManager, ProcessLogManager):
|
|||||||
data['process_name'],
|
data['process_name'],
|
||||||
self.log_tail
|
self.log_tail
|
||||||
)
|
)
|
||||||
server_connector.send_message(message, scope=Scope.WEBSOCKET)
|
connector.send_message(message, scope=Scope.WEBSOCKET)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
LOG.error('IGNORING MESSAGE: Invalid message received: %s', message)
|
LOG.error('IGNORING MESSAGE: Invalid message received: %s', message)
|
||||||
|
@ -17,7 +17,7 @@ class ProcessLogHandler:
|
|||||||
The API of each command is documented in their respective handler.
|
The API of each command is documented in their respective handler.
|
||||||
"""
|
"""
|
||||||
def __init__(self, *, process_name, supervisor_uri, log_tail=0):
|
def __init__(self, *, process_name, supervisor_uri, log_tail=0):
|
||||||
self.server_connector = None
|
self.connector = None
|
||||||
self.process_name = process_name
|
self.process_name = process_name
|
||||||
self._supervisor_uri = supervisor_uri
|
self._supervisor_uri = supervisor_uri
|
||||||
self._initial_log_tail = log_tail
|
self._initial_log_tail = log_tail
|
||||||
@ -30,7 +30,7 @@ class ProcessLogHandler:
|
|||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
self._monitor = LogInotifyObserver(
|
self._monitor = LogInotifyObserver(
|
||||||
server_connector=self.server_connector,
|
connector=self.connector,
|
||||||
supervisor_uri=self._supervisor_uri,
|
supervisor_uri=self._supervisor_uri,
|
||||||
process_name=self.process_name,
|
process_name=self.process_name,
|
||||||
log_tail=self._initial_log_tail
|
log_tail=self._initial_log_tail
|
||||||
|
@ -45,11 +45,11 @@ class SnapshotHandler:
|
|||||||
makedirs(git_dir, exist_ok=True)
|
makedirs(git_dir, exist_ok=True)
|
||||||
return git_dir
|
return git_dir
|
||||||
|
|
||||||
def handle_event(self, message, server_connector):
|
def handle_event(self, message, connector):
|
||||||
try:
|
try:
|
||||||
data = message['data']
|
data = message['data']
|
||||||
message['data'] = self.command_handlers[data['command']](data)
|
message['data'] = self.command_handlers[data['command']](data)
|
||||||
server_connector.send_message(message, scope=Scope.WEBSOCKET)
|
connector.send_message(message, scope=Scope.WEBSOCKET)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
LOG.error('IGNORING MESSAGE: Invalid message received: %s', message)
|
LOG.error('IGNORING MESSAGE: Invalid message received: %s', message)
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ class TerminalHandler:
|
|||||||
:param key: key this EventHandler listens to
|
:param key: key this EventHandler listens to
|
||||||
:param monitor: tfw.components.HistoryMonitor instance to read command history from
|
:param monitor: tfw.components.HistoryMonitor instance to read command history from
|
||||||
"""
|
"""
|
||||||
self.server_connector = None
|
self.connector = None
|
||||||
self._histfile = histfile
|
self._histfile = histfile
|
||||||
self._historymonitor = None
|
self._historymonitor = None
|
||||||
bash_as_user_cmd = ['sudo', '-u', user, 'bash']
|
bash_as_user_cmd = ['sudo', '-u', user, 'bash']
|
||||||
@ -42,7 +42,7 @@ class TerminalHandler:
|
|||||||
self.terminado_server.listen()
|
self.terminado_server.listen()
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
self._historymonitor = BashMonitor(self.server_connector, self._histfile)
|
self._historymonitor = BashMonitor(self.connector, self._histfile)
|
||||||
self._historymonitor.start()
|
self._historymonitor.start()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
class EventHandler:
|
class EventHandler:
|
||||||
_instances = set()
|
_instances = set()
|
||||||
|
|
||||||
def __init__(self, server_connector):
|
def __init__(self, connector):
|
||||||
type(self)._instances.add(self)
|
type(self)._instances.add(self)
|
||||||
self.server_connector = server_connector
|
self.connector = connector
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
self.server_connector.register_callback(self._event_callback)
|
self.connector.register_callback(self._event_callback)
|
||||||
|
|
||||||
def _event_callback(self, message):
|
def _event_callback(self, message):
|
||||||
self.handle_event(message, self.server_connector)
|
self.handle_event(message, self.connector)
|
||||||
|
|
||||||
def handle_event(self, message, server_connector):
|
def handle_event(self, message, connector):
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -20,7 +20,7 @@ class EventHandler:
|
|||||||
instance.stop()
|
instance.stop()
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
self.server_connector.close()
|
self.connector.close()
|
||||||
self.cleanup()
|
self.cleanup()
|
||||||
|
|
||||||
def cleanup(self):
|
def cleanup(self):
|
||||||
|
@ -6,15 +6,15 @@ from .event_handler import EventHandler
|
|||||||
class EventHandlerFactoryBase:
|
class EventHandlerFactoryBase:
|
||||||
def build(self, handler_stub, *, keys=None, event_handler_type=EventHandler):
|
def build(self, handler_stub, *, keys=None, event_handler_type=EventHandler):
|
||||||
builder = EventHandlerBuilder(handler_stub, keys, event_handler_type)
|
builder = EventHandlerBuilder(handler_stub, keys, event_handler_type)
|
||||||
server_connector = self._build_server_connector()
|
connector = self._build_connector()
|
||||||
event_handler = builder.build(server_connector)
|
event_handler = builder.build(connector)
|
||||||
handler_stub.server_connector = server_connector
|
handler_stub.connector = connector
|
||||||
with suppress(AttributeError):
|
with suppress(AttributeError):
|
||||||
handler_stub.start()
|
handler_stub.start()
|
||||||
event_handler.start()
|
event_handler.start()
|
||||||
return event_handler
|
return event_handler
|
||||||
|
|
||||||
def _build_server_connector(self):
|
def _build_connector(self):
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
|
||||||
@ -23,9 +23,9 @@ class EventHandlerBuilder:
|
|||||||
self._analyzer = HandlerStubAnalyzer(event_handler, supplied_keys)
|
self._analyzer = HandlerStubAnalyzer(event_handler, supplied_keys)
|
||||||
self._event_handler_type = event_handler_type
|
self._event_handler_type = event_handler_type
|
||||||
|
|
||||||
def build(self, server_connector):
|
def build(self, connector):
|
||||||
event_handler = self._event_handler_type(server_connector)
|
event_handler = self._event_handler_type(connector)
|
||||||
server_connector.subscribe(*self._try_get_keys(event_handler))
|
connector.subscribe(*self._try_get_keys(event_handler))
|
||||||
event_handler.handle_event = self._analyzer.handle_event
|
event_handler.handle_event = self._analyzer.handle_event
|
||||||
with suppress(AttributeError):
|
with suppress(AttributeError):
|
||||||
event_handler.cleanup = self._analyzer.cleanup
|
event_handler.cleanup = self._analyzer.cleanup
|
||||||
|
@ -8,12 +8,12 @@ class FSMAwareEventHandler(EventHandler, FSMAware):
|
|||||||
Abstract base class for EventHandlers which automatically
|
Abstract base class for EventHandlers which automatically
|
||||||
keep track of the state of the TFW FSM.
|
keep track of the state of the TFW FSM.
|
||||||
"""
|
"""
|
||||||
def __init__(self, server_connector):
|
def __init__(self, connector):
|
||||||
EventHandler.__init__(self, server_connector)
|
EventHandler.__init__(self, connector)
|
||||||
FSMAware.__init__(self)
|
FSMAware.__init__(self)
|
||||||
|
|
||||||
def _event_callback(self, message):
|
def _event_callback(self, message):
|
||||||
self.process_message(message)
|
self.process_message(message)
|
||||||
|
|
||||||
def handle_fsm_step(self, message):
|
def handle_fsm_step(self, message):
|
||||||
self.handle_event(message, self.server_connector)
|
self.handle_event(message, self.connector)
|
||||||
|
@ -9,11 +9,11 @@ from .event_handler import EventHandler
|
|||||||
|
|
||||||
|
|
||||||
class MockEventHandlerFactory(EventHandlerFactoryBase):
|
class MockEventHandlerFactory(EventHandlerFactoryBase):
|
||||||
def _build_server_connector(self):
|
def _build_connector(self):
|
||||||
return MockServerConnector()
|
return MockConnector()
|
||||||
|
|
||||||
|
|
||||||
class MockServerConnector:
|
class MockConnector:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.keys = []
|
self.keys = []
|
||||||
self._on_message = None
|
self._on_message = None
|
||||||
@ -40,7 +40,7 @@ class MockServerConnector:
|
|||||||
|
|
||||||
class MockEventHandlerStub:
|
class MockEventHandlerStub:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.server_connector = None
|
self.connector = None
|
||||||
self.last_message = None
|
self.last_message = None
|
||||||
self.cleaned_up = False
|
self.cleaned_up = False
|
||||||
self.started = False
|
self.started = False
|
||||||
@ -54,12 +54,12 @@ class MockEventHandlerStub:
|
|||||||
|
|
||||||
class MockEventHandler(MockEventHandlerStub):
|
class MockEventHandler(MockEventHandlerStub):
|
||||||
# pylint: disable=unused-argument
|
# pylint: disable=unused-argument
|
||||||
def handle_event(self, message, server_connector):
|
def handle_event(self, message, connector):
|
||||||
self.last_message = message
|
self.last_message = message
|
||||||
|
|
||||||
|
|
||||||
class MockCallable(MockEventHandlerStub):
|
class MockCallable(MockEventHandlerStub):
|
||||||
def __call__(self, message, server_connector):
|
def __call__(self, message, connector):
|
||||||
self.last_message = message
|
self.last_message = message
|
||||||
|
|
||||||
|
|
||||||
@ -78,17 +78,17 @@ def test_keys():
|
|||||||
|
|
||||||
def test_build_from_object(test_keys, test_msg):
|
def test_build_from_object(test_keys, test_msg):
|
||||||
mock_eh = MockEventHandlerStub()
|
mock_eh = MockEventHandlerStub()
|
||||||
def handle_event(message, server_connector):
|
def handle_event(message, connector):
|
||||||
raise RuntimeError(message, server_connector.keys)
|
raise RuntimeError(message, connector.keys)
|
||||||
mock_eh.handle_event = handle_event
|
mock_eh.handle_event = handle_event
|
||||||
|
|
||||||
assert not mock_eh.started
|
assert not mock_eh.started
|
||||||
eh = MockEventHandlerFactory().build(mock_eh, keys=test_keys)
|
eh = MockEventHandlerFactory().build(mock_eh, keys=test_keys)
|
||||||
|
|
||||||
assert mock_eh.started
|
assert mock_eh.started
|
||||||
assert mock_eh.server_connector is eh.server_connector
|
assert mock_eh.connector is eh.connector
|
||||||
with pytest.raises(RuntimeError) as err:
|
with pytest.raises(RuntimeError) as err:
|
||||||
eh.server_connector.simulate_message(test_msg)
|
eh.connector.simulate_message(test_msg)
|
||||||
msg, keys = err.args
|
msg, keys = err.args
|
||||||
assert msg == test_msg
|
assert msg == test_msg
|
||||||
assert keys == test_keys
|
assert keys == test_keys
|
||||||
@ -104,11 +104,11 @@ def test_build_from_object_with_keys(test_keys, test_msg):
|
|||||||
assert not mock_eh.started
|
assert not mock_eh.started
|
||||||
eh = MockEventHandlerFactory().build(mock_eh)
|
eh = MockEventHandlerFactory().build(mock_eh)
|
||||||
|
|
||||||
assert mock_eh.server_connector.keys == test_keys
|
assert mock_eh.connector.keys == test_keys
|
||||||
assert eh.server_connector is mock_eh.server_connector
|
assert eh.connector is mock_eh.connector
|
||||||
assert mock_eh.started
|
assert mock_eh.started
|
||||||
assert not mock_eh.last_message
|
assert not mock_eh.last_message
|
||||||
eh.server_connector.simulate_message(test_msg)
|
eh.connector.simulate_message(test_msg)
|
||||||
assert mock_eh.last_message == test_msg
|
assert mock_eh.last_message == test_msg
|
||||||
assert not mock_eh.cleaned_up
|
assert not mock_eh.cleaned_up
|
||||||
EventHandler.stop_all_instances()
|
EventHandler.stop_all_instances()
|
||||||
@ -118,14 +118,14 @@ def test_build_from_object_with_keys(test_keys, test_msg):
|
|||||||
def test_build_from_simple_object(test_keys, test_msg):
|
def test_build_from_simple_object(test_keys, test_msg):
|
||||||
class SimpleMockEventHandler:
|
class SimpleMockEventHandler:
|
||||||
# pylint: disable=no-self-use
|
# pylint: disable=no-self-use
|
||||||
def handle_event(self, message, server_connector):
|
def handle_event(self, message, connector):
|
||||||
raise RuntimeError(message, server_connector)
|
raise RuntimeError(message, connector)
|
||||||
|
|
||||||
mock_eh = SimpleMockEventHandler()
|
mock_eh = SimpleMockEventHandler()
|
||||||
eh = MockEventHandlerFactory().build(mock_eh, keys=test_keys)
|
eh = MockEventHandlerFactory().build(mock_eh, keys=test_keys)
|
||||||
|
|
||||||
with pytest.raises(RuntimeError) as err:
|
with pytest.raises(RuntimeError) as err:
|
||||||
eh.server_connector.simulate_message(test_msg)
|
eh.connector.simulate_message(test_msg)
|
||||||
msg, keys = err.args
|
msg, keys = err.args
|
||||||
assert msg == test_msg
|
assert msg == test_msg
|
||||||
assert keys == test_keys
|
assert keys == test_keys
|
||||||
@ -138,10 +138,10 @@ def test_build_from_callable(test_keys, test_msg):
|
|||||||
eh = MockEventHandlerFactory().build(mock_eh, keys=test_keys)
|
eh = MockEventHandlerFactory().build(mock_eh, keys=test_keys)
|
||||||
|
|
||||||
assert mock_eh.started
|
assert mock_eh.started
|
||||||
assert mock_eh.server_connector is eh.server_connector
|
assert mock_eh.connector is eh.connector
|
||||||
assert eh.server_connector.keys == test_keys
|
assert eh.connector.keys == test_keys
|
||||||
assert not mock_eh.last_message
|
assert not mock_eh.last_message
|
||||||
eh.server_connector.simulate_message(test_msg)
|
eh.connector.simulate_message(test_msg)
|
||||||
assert mock_eh.last_message == test_msg
|
assert mock_eh.last_message == test_msg
|
||||||
assert not mock_eh.cleaned_up
|
assert not mock_eh.cleaned_up
|
||||||
eh.stop()
|
eh.stop()
|
||||||
@ -149,13 +149,13 @@ def test_build_from_callable(test_keys, test_msg):
|
|||||||
|
|
||||||
|
|
||||||
def test_build_from_function(test_keys, test_msg):
|
def test_build_from_function(test_keys, test_msg):
|
||||||
def some_function(message, server_connector):
|
def some_function(message, connector):
|
||||||
raise RuntimeError(message, server_connector.keys)
|
raise RuntimeError(message, connector.keys)
|
||||||
eh = MockEventHandlerFactory().build(some_function, keys=test_keys)
|
eh = MockEventHandlerFactory().build(some_function, keys=test_keys)
|
||||||
|
|
||||||
assert eh.server_connector.keys == test_keys
|
assert eh.connector.keys == test_keys
|
||||||
with pytest.raises(RuntimeError) as err:
|
with pytest.raises(RuntimeError) as err:
|
||||||
eh.server_connector.simulate_message(test_msg)
|
eh.connector.simulate_message(test_msg)
|
||||||
msg, keys = err.args
|
msg, keys = err.args
|
||||||
assert msg == test_msg
|
assert msg == test_msg
|
||||||
assert keys == test_keys
|
assert keys == test_keys
|
||||||
@ -166,7 +166,7 @@ def test_build_from_lambda(test_keys, test_msg):
|
|||||||
assert msg == test_msg
|
assert msg == test_msg
|
||||||
fun = lambda msg, sc: assert_messages_equal(msg)
|
fun = lambda msg, sc: assert_messages_equal(msg)
|
||||||
eh = MockEventHandlerFactory().build(fun, keys=test_keys)
|
eh = MockEventHandlerFactory().build(fun, keys=test_keys)
|
||||||
eh.server_connector.simulate_message(test_msg)
|
eh.connector.simulate_message(test_msg)
|
||||||
|
|
||||||
|
|
||||||
def test_build_raises_if_no_key(test_keys):
|
def test_build_raises_if_no_key(test_keys):
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
from .serialization import serialize_tfw_msg, deserialize_tfw_msg, with_deserialize_tfw_msg, message_bytes
|
from .serialization import serialize_tfw_msg, deserialize_tfw_msg, with_deserialize_tfw_msg, message_bytes
|
||||||
from .server_connector import ServerUplinkConnector, ServerDownlinkConnector, ServerConnector
|
from .zmq_connector import ZMQConnector, ZMQDownlinkConnector, ZMQUplinkConnector
|
||||||
from .event_handler_connector import EventHandlerConnector
|
from .zmq_listener import ZMQListener
|
||||||
from .scope import Scope
|
from .scope import Scope
|
||||||
|
@ -7,34 +7,34 @@ from tempfile import TemporaryDirectory
|
|||||||
import pytest
|
import pytest
|
||||||
from tornado.ioloop import IOLoop
|
from tornado.ioloop import IOLoop
|
||||||
|
|
||||||
from tfw.internals.networking import EventHandlerConnector, ServerConnector
|
from tfw.internals.networking import ZMQListener, ZMQConnector
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def _connectors():
|
def _listener_and_connector():
|
||||||
with TemporaryDirectory() as tmpdir:
|
with TemporaryDirectory() as tmpdir:
|
||||||
down_sock = join(tmpdir, 'down')
|
down_sock = join(tmpdir, 'down')
|
||||||
up_sock = join(tmpdir, 'up')
|
up_sock = join(tmpdir, 'up')
|
||||||
server_downlink = f'ipc://{down_sock}'
|
server_downlink = f'ipc://{down_sock}'
|
||||||
server_uplink = f'ipc://{up_sock}'
|
server_uplink = f'ipc://{up_sock}'
|
||||||
|
|
||||||
ec = EventHandlerConnector(server_downlink, server_uplink)
|
listener = ZMQListener(server_downlink, server_uplink)
|
||||||
sc = ServerConnector(server_uplink, server_downlink)
|
connector = ZMQConnector(server_uplink, server_downlink)
|
||||||
yield ec, sc
|
yield listener, connector
|
||||||
sc.close()
|
listener.close()
|
||||||
ec.close()
|
connector.close()
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def eh_connector(_connectors):
|
def zmq_listener(_listener_and_connector):
|
||||||
eh_connector, _ = _connectors
|
listener, _ = _listener_and_connector
|
||||||
yield eh_connector
|
yield listener
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def server_connector(_connectors):
|
def zmq_connector(_listener_and_connector):
|
||||||
_, server_connector = _connectors
|
_, connector = _listener_and_connector
|
||||||
yield server_connector
|
yield connector
|
||||||
|
|
||||||
|
|
||||||
def run_ioloop_once():
|
def run_ioloop_once():
|
||||||
@ -63,42 +63,42 @@ def test_messages():
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def test_server_downlink(eh_connector, server_connector, test_messages):
|
def test_server_downlink(zmq_listener, zmq_connector, test_messages):
|
||||||
messages = []
|
messages = []
|
||||||
eh_connector.register_callback(messages.append)
|
zmq_listener.register_callback(messages.append)
|
||||||
|
|
||||||
for message in test_messages:
|
for message in test_messages:
|
||||||
server_connector.send_message(message)
|
zmq_connector.send_message(message)
|
||||||
|
|
||||||
run_ioloop_once()
|
run_ioloop_once()
|
||||||
|
|
||||||
assert messages == test_messages
|
assert messages == test_messages
|
||||||
|
|
||||||
|
|
||||||
def test_server_uplink(eh_connector, server_connector, test_messages):
|
def test_server_uplink(zmq_listener, zmq_connector, test_messages):
|
||||||
messages = []
|
messages = []
|
||||||
server_connector.subscribe('')
|
zmq_connector.subscribe('')
|
||||||
server_connector.register_callback(messages.append)
|
zmq_connector.register_callback(messages.append)
|
||||||
|
|
||||||
for message in test_messages:
|
for message in test_messages:
|
||||||
eh_connector.send_message(message)
|
zmq_listener.send_message(message)
|
||||||
|
|
||||||
run_ioloop_once()
|
run_ioloop_once()
|
||||||
|
|
||||||
assert messages == test_messages
|
assert messages == test_messages
|
||||||
|
|
||||||
|
|
||||||
def test_connector_downlink_subscribe(eh_connector, server_connector):
|
def test_connector_downlink_subscribe(zmq_listener, zmq_connector):
|
||||||
key1_messages = [{'key': '1', 'data': i} for i in range(randint(128, 256))]
|
key1_messages = [{'key': '1', 'data': i} for i in range(randint(128, 256))]
|
||||||
key2_messages = [{'key': '2', 'data': i} for i in range(randint(128, 256))]
|
key2_messages = [{'key': '2', 'data': i} for i in range(randint(128, 256))]
|
||||||
all_messages = key1_messages + key2_messages
|
all_messages = key1_messages + key2_messages
|
||||||
|
|
||||||
messages = []
|
messages = []
|
||||||
server_connector.subscribe('1')
|
zmq_connector.subscribe('1')
|
||||||
server_connector.register_callback(messages.append)
|
zmq_connector.register_callback(messages.append)
|
||||||
|
|
||||||
for message in all_messages:
|
for message in all_messages:
|
||||||
eh_connector.send_message(message)
|
zmq_listener.send_message(message)
|
||||||
|
|
||||||
run_ioloop_once()
|
run_ioloop_once()
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ from .serialization import serialize_tfw_msg, with_deserialize_tfw_msg
|
|||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class ServerDownlinkConnector:
|
class ZMQDownlinkConnector:
|
||||||
def __init__(self, connect_addr):
|
def __init__(self, connect_addr):
|
||||||
self.keys = []
|
self.keys = []
|
||||||
self._on_recv_callback = None
|
self._on_recv_callback = None
|
||||||
@ -41,7 +41,7 @@ class ServerDownlinkConnector:
|
|||||||
self._zmq_sub_stream.close()
|
self._zmq_sub_stream.close()
|
||||||
|
|
||||||
|
|
||||||
class ServerUplinkConnector:
|
class ZMQUplinkConnector:
|
||||||
def __init__(self, connect_addr):
|
def __init__(self, connect_addr):
|
||||||
self._zmq_push_socket = zmq.Context.instance().socket(zmq.PUSH)
|
self._zmq_push_socket = zmq.Context.instance().socket(zmq.PUSH)
|
||||||
self._zmq_push_socket.setsockopt(zmq.SNDHWM, 0)
|
self._zmq_push_socket.setsockopt(zmq.SNDHWM, 0)
|
||||||
@ -55,11 +55,11 @@ class ServerUplinkConnector:
|
|||||||
self._zmq_push_socket.close()
|
self._zmq_push_socket.close()
|
||||||
|
|
||||||
|
|
||||||
class ServerConnector(ServerDownlinkConnector, ServerUplinkConnector):
|
class ZMQConnector(ZMQDownlinkConnector, ZMQUplinkConnector):
|
||||||
def __init__(self, downlink_connect_addr, uplink_connect_addr):
|
def __init__(self, downlink_connect_addr, uplink_connect_addr):
|
||||||
ServerDownlinkConnector.__init__(self, downlink_connect_addr)
|
ZMQDownlinkConnector.__init__(self, downlink_connect_addr)
|
||||||
ServerUplinkConnector.__init__(self, uplink_connect_addr)
|
ZMQUplinkConnector.__init__(self, uplink_connect_addr)
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
ServerDownlinkConnector.close(self)
|
ZMQDownlinkConnector.close(self)
|
||||||
ServerUplinkConnector.close(self)
|
ZMQUplinkConnector.close(self)
|
@ -8,7 +8,7 @@ from .serialization import serialize_tfw_msg, with_deserialize_tfw_msg
|
|||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class EventHandlerDownlinkConnector:
|
class ZMQDownlinkListener:
|
||||||
def __init__(self, bind_addr):
|
def __init__(self, bind_addr):
|
||||||
self._zmq_pull_socket = zmq.Context.instance().socket(zmq.PULL)
|
self._zmq_pull_socket = zmq.Context.instance().socket(zmq.PULL)
|
||||||
self._zmq_pull_socket.setsockopt(zmq.RCVHWM, 0)
|
self._zmq_pull_socket.setsockopt(zmq.RCVHWM, 0)
|
||||||
@ -24,7 +24,7 @@ class EventHandlerDownlinkConnector:
|
|||||||
self._zmq_pull_stream.close()
|
self._zmq_pull_stream.close()
|
||||||
|
|
||||||
|
|
||||||
class EventHandlerUplinkConnector:
|
class ZMQUplinkListener:
|
||||||
def __init__(self, bind_addr):
|
def __init__(self, bind_addr):
|
||||||
self._zmq_pub_socket = zmq.Context.instance().socket(zmq.PUB)
|
self._zmq_pub_socket = zmq.Context.instance().socket(zmq.PUB)
|
||||||
self._zmq_pub_socket.setsockopt(zmq.SNDHWM, 0)
|
self._zmq_pub_socket.setsockopt(zmq.SNDHWM, 0)
|
||||||
@ -38,11 +38,11 @@ class EventHandlerUplinkConnector:
|
|||||||
self._zmq_pub_socket.close()
|
self._zmq_pub_socket.close()
|
||||||
|
|
||||||
|
|
||||||
class EventHandlerConnector(EventHandlerDownlinkConnector, EventHandlerUplinkConnector):
|
class ZMQListener(ZMQDownlinkListener, ZMQUplinkListener):
|
||||||
def __init__(self, downlink_bind_addr, uplink_bind_addr):
|
def __init__(self, downlink_bind_addr, uplink_bind_addr):
|
||||||
EventHandlerDownlinkConnector.__init__(self, downlink_bind_addr)
|
ZMQDownlinkListener.__init__(self, downlink_bind_addr)
|
||||||
EventHandlerUplinkConnector.__init__(self, uplink_bind_addr)
|
ZMQUplinkListener.__init__(self, uplink_bind_addr)
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
EventHandlerDownlinkConnector.close(self)
|
ZMQDownlinkListener.close(self)
|
||||||
EventHandlerUplinkConnector.close(self)
|
ZMQUplinkListener.close(self)
|
@ -13,11 +13,11 @@ class ZMQWebSocketRouter(WebSocketHandler):
|
|||||||
instances = set()
|
instances = set()
|
||||||
|
|
||||||
def initialize(self, **kwargs):
|
def initialize(self, **kwargs):
|
||||||
self.event_handler_connector = kwargs['event_handler_connector']
|
self._listener = kwargs['listener']
|
||||||
self.tfw_router = TFWRouter(self.send_to_zmq, self.send_to_websockets)
|
self.tfw_router = TFWRouter(self.send_to_zmq, self.send_to_websockets)
|
||||||
|
|
||||||
def send_to_zmq(self, message):
|
def send_to_zmq(self, message):
|
||||||
self.event_handler_connector.send_message(message)
|
self._listener.send_message(message)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def send_to_websockets(cls, message):
|
def send_to_websockets(cls, message):
|
||||||
@ -32,7 +32,7 @@ class ZMQWebSocketRouter(WebSocketHandler):
|
|||||||
|
|
||||||
def open(self, *args, **kwargs):
|
def open(self, *args, **kwargs):
|
||||||
LOG.debug('WebSocket connection initiated!')
|
LOG.debug('WebSocket connection initiated!')
|
||||||
self.event_handler_connector.register_callback(self.zmq_callback)
|
self._listener.register_callback(self.zmq_callback)
|
||||||
|
|
||||||
def zmq_callback(self, message):
|
def zmq_callback(self, message):
|
||||||
LOG.debug('Received on ZMQ pull socket: %s', message)
|
LOG.debug('Received on ZMQ pull socket: %s', message)
|
||||||
|
@ -4,5 +4,5 @@ from .tfw_connector import TFWConnector
|
|||||||
|
|
||||||
|
|
||||||
class EventHandlerFactory(EventHandlerFactoryBase):
|
class EventHandlerFactory(EventHandlerFactoryBase):
|
||||||
def _build_server_connector(self):
|
def _build_connector(self):
|
||||||
return TFWConnector()
|
return TFWConnector()
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
from tfw.internals.networking import ServerConnector, ServerUplinkConnector
|
from tfw.internals.networking import ZMQConnector, ZMQUplinkConnector
|
||||||
from tfw.config import TFWENV
|
from tfw.config import TFWENV
|
||||||
|
|
||||||
|
|
||||||
@ -12,12 +12,12 @@ class ConnAddrMixin:
|
|||||||
return f'tcp://localhost:{TFWENV.PUB_PORT}'
|
return f'tcp://localhost:{TFWENV.PUB_PORT}'
|
||||||
|
|
||||||
|
|
||||||
class TFWUplinkConnector(ServerUplinkConnector, ConnAddrMixin):
|
class TFWUplinkConnector(ZMQUplinkConnector, ConnAddrMixin):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__(self.uplink_conn_addr)
|
super().__init__(self.uplink_conn_addr)
|
||||||
|
|
||||||
|
|
||||||
class TFWConnector(ServerConnector, ConnAddrMixin):
|
class TFWConnector(ZMQConnector, ConnAddrMixin):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__(
|
super().__init__(
|
||||||
self.downlink_conn_addr,
|
self.downlink_conn_addr,
|
||||||
|
@ -2,7 +2,7 @@ import logging
|
|||||||
|
|
||||||
from tornado.web import Application
|
from tornado.web import Application
|
||||||
|
|
||||||
from tfw.internals.networking import EventHandlerConnector
|
from tfw.internals.networking import ZMQListener
|
||||||
from tfw.internals.server import ZMQWebSocketRouter
|
from tfw.internals.server import ZMQWebSocketRouter
|
||||||
from tfw.config import TFWENV
|
from tfw.config import TFWENV
|
||||||
|
|
||||||
@ -16,13 +16,13 @@ class TFWServer:
|
|||||||
SUB socket.
|
SUB socket.
|
||||||
"""
|
"""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._event_handler_connector = EventHandlerConnector(
|
self._listener = ZMQListener(
|
||||||
downlink_bind_addr=f'tcp://*:{TFWENV.PULL_PORT}',
|
downlink_bind_addr=f'tcp://*:{TFWENV.PULL_PORT}',
|
||||||
uplink_bind_addr=f'tcp://*:{TFWENV.PUB_PORT}'
|
uplink_bind_addr=f'tcp://*:{TFWENV.PUB_PORT}'
|
||||||
)
|
)
|
||||||
self.application = Application([(
|
self.application = Application([(
|
||||||
r'/ws', ZMQWebSocketRouter, {
|
r'/ws', ZMQWebSocketRouter, {
|
||||||
'event_handler_connector': self._event_handler_connector,
|
'listener': self._listener,
|
||||||
}
|
}
|
||||||
)])
|
)])
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user