AllenNeuralDynamics / AllenNeuralDynamics/brainwasher

Use observer pattern for sending alerts

Đang mở
#40 1 bình luận 0 reaction 2 người được giao Được @micahwoodard nhận Xem trên GitHub
Ngôn ngữ chính
Python
Star
0
Fork
1
Chỉ số merge pull request
Không có pull request nào được merge trong 30 ngày

Mô tả

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.

Hướng dẫn đóng góp

Chưa lập chỉ mục được hướng dẫn đóng góp cho kho mã nguồn này

Đánh giá

Issue này chưa được đánh giá.

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.