Skip to content

Commit

Permalink
Started allowing more general event notifications
Browse files Browse the repository at this point in the history
  • Loading branch information
jtc42 committed May 4, 2020
1 parent 66e6731 commit 282d6c0
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 59 deletions.
18 changes: 14 additions & 4 deletions src/labthings/server/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,10 +180,20 @@ def wrapped(*args, **kwargs):
# Call the update function first to update property value
original_response = func(*args, **kwargs)

# Once updated, then notify all subscribers
subscribers = getattr(current_labthing(), "subscribers", [])
for sub in subscribers:
sub.property_notify(viewcls)
if hasattr(viewcls, "get_value") and callable(viewcls.get_value):
property_value = viewcls().get_value()
else:
property_value = None

property_name = getattr(viewcls, "endpoint", None) or getattr(
viewcls, "__name__", "unknown"
)

if current_labthing():
current_labthing().emit(
{property_name: property_value}, type="propertyStatus"
)

return original_response

return wrapped
Expand Down
13 changes: 13 additions & 0 deletions src/labthings/server/labthing.py
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,19 @@ def _register_view(self, app, view, *urls, endpoint=None, **kwargs):
self.thing_description.property(flask_rules, view)
self._property_views[view.endpoint] = view

# Event stuff
def emit(self, data: dict, type="event"):
"""Emit an event to all subscribers
Arguments:
data {dict} -- Event data
Keyword Arguments:
type {str} -- Event type (default: {"event"})
"""
for sub in self.subscribers:
sub.emit({"messageType": type, "data": data})

# Utilities

def url_for(self, view, **values):
Expand Down
5 changes: 2 additions & 3 deletions src/labthings/server/logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@ def emit(self, record):
log_event = self.rest_format_record(record)

# Broadcast to subscribers
subscribers = getattr(current_labthing(), "subscribers", [])
for sub in subscribers:
sub.event_notify(log_event)
if current_labthing():
current_labthing().emit(log_event)

def rest_format_record(self, record):
data = {
Expand Down
22 changes: 3 additions & 19 deletions src/labthings/server/sockets/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,9 @@ class SocketSubscriber:
def __init__(self, ws):
self.ws = ws

def property_notify(self, viewcls):
if hasattr(viewcls, "get_value") and callable(viewcls.get_value):
property_value = viewcls().get_value()
else:
property_value = None

property_name = getattr(viewcls, "endpoint", None) or getattr(
viewcls, "__name__", "unknown"
)

response = encode_json(
{"messageType": "propertyStatus", "data": {property_name: property_value}}
)

self.ws.send(response)

def event_notify(self, event_dict: dict):
response = encode_json({"messageType": "event", "data": event_dict})

def emit(self, event: dict):
response = encode_json(event)
# TODO: Logic surrounding if this subscriber is subscribed to the requested event type
self.ws.send(response)


Expand Down
33 changes: 0 additions & 33 deletions tests/test_server_sockets.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,39 +4,6 @@
from flask import Blueprint


def test_socket_subscriber_property_notify(view_cls, fake_websocket):
setattr(view_cls, "endpoint", "index")
ws = fake_websocket("", recieve_once=True)
sub = base.SocketSubscriber(ws)

sub.property_notify(view_cls)
assert json.loads(ws.response) == {
"messageType": "propertyStatus",
"data": {"index": "GET"},
}


def test_socket_subscriber_property_notify_empty_view(flask_view_cls, fake_websocket):
ws = fake_websocket("", recieve_once=True)
sub = base.SocketSubscriber(ws)

sub.property_notify(flask_view_cls)
assert json.loads(ws.response) == {
"messageType": "propertyStatus",
"data": {flask_view_cls.__name__: None},
}


def test_socket_subscriber_event_notify(fake_websocket):
ws = fake_websocket("", recieve_once=True)
sub = base.SocketSubscriber(ws)

data = {"key": "value"}

sub.event_notify(data)
assert json.loads(ws.response) == {"messageType": "event", "data": data}


def test_sockets_flask_init(app):
original_wsgi_app = app.wsgi_app
socket = gsocket.Sockets(app)
Expand Down

0 comments on commit 282d6c0

Please sign in to comment.