AllenNeuralDynamics / AllenNeuralDynamics/brainwasher
Use observer pattern for sending alerts
- Lingua principale
- Python
- Stelle
- 0
- Fork
- 1
- Metriche di merge delle PR
- Nessuna PR unita negli ultimi 30g
Descrizione
Currently, we add alert (email) functionality to the brainslosher by polling for state changes in `RouterServer` and then sending an email from `RouterServer`. This adds business logic to the `RouterServer,` making it more than just a message-dispatcher to one-or-more `RouterClients`. Here are two alternate ways of adding alert functionality that respect our "instrument/infrastructure-agnostic" architecture diagram.
## Option 1: Observer Pattern
This is the most straightforward option.
In the instrument base class we add two functions: `add_alert_handler` and `send_alert`.
The `add_alert_handler(fn)` adds a function to a list of callback functions to be called when we call `send_alert`. The `send_alert` function just iterates through the list of callback functions and calls them with any input data that comes with the alert (maybe a string?). Something like this:
```python
# in instrument base class
def add_alert_handler(func: callable):
self.alert_handlers.append(func)
def send_alert(message: str):
for alert_func in self.alert_handlers:
alert_func(message) # call the function
```
In the `Brainslosher` business logic, we just call `send_alert` and trust that the attached callback function knows how to do this.
```python
try:
# do brainslosher steps
except Exception as e:
self.send_alert("Brainsloshing failed to complete job!")
```
In the above case, there's no need to incorporate `RouterServer` at all, we just attach a callback function, and the `Brainslosher` instrument calls it.
(More deets on this pattern here: https://refactoring.guru/design-patterns/observer)
## Option 2: Observer Pattern + `one-liner` to external system
This is more of a "microservices" approach. In the case where Option 1 is not sufficient or you truly want decoupled behavior to silo failures, I would suggest this option.
Here, I would do the same as above: create `add_alert_handler` and `send_alert` functions. Then I would generate a custom stream function in one-liner using `get_stream_fn`. ([Example](https://github.com/AllenNeuralDynamics/one-liner/blob/main/examples/streaming/broadcast_app_regulated/server.py#L15C5-L15C21) of how to generate this callback function. )
Finally, I would create a one-liner `RouterClient` to listen to received alerts from this stream and invoke the attached alert system. The benefit to this approach is that the separate alert system can be a monolithic, cumbersome, or slow process to deal with, but it wont slow down the instrument operation. The instrument just needs to send the alert, and the one-liner Server/Client connection sends it to this system separately. Finally, it can also be a separate process (or PC!) so it can fail separately.
Guida per i contributori
Nessuna guida per i contributori indicizzata per questo repository
Valutazione
Questa issue non è ancora stata valutata.