-
Notifications
You must be signed in to change notification settings - Fork 27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
🎨 publish port events to frontend #6396
base: master
Are you sure you want to change the base?
🎨 publish port events to frontend #6396
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #6396 +/- ##
=========================================
+ Coverage 84.5% 88.8% +4.2%
=========================================
Files 10 1227 +1217
Lines 214 54047 +53833
Branches 25 867 +842
=========================================
+ Hits 181 48024 +47843
- Misses 23 5891 +5868
- Partials 10 132 +122
Flags with carried forward coverage won't be shown. Click here to find out more.
|
…ange-notifications
…ange-notifications
…ange-notifications
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thx, left some suggests to consider
packages/models-library/src/models_library/api_schemas_dynamic_sidecar/ports.py
Outdated
Show resolved
Hide resolved
await outputs_callbacks.aborted(port_key) | ||
raise | ||
except Exception: | ||
await outputs_callbacks.finished_with_error(port_key) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Q: So if there is an **unexpected ** error, you want to notify simply that it failed? Since this reaches the user , I would use the technique of logging the error on the server side and sending an OEC to the front-end.
wait, you are reraising it ... so perhaps report it when you catch it?
BTW why do not you need to reraise?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
THOUGHT: this approach is growing faster than we anticipated. I believe it is time we redirect everything via notifiers service as we discussed sometime ago #1828
Quality Gate passedIssues Measures |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a few comments. Good luck with it ! see you later!
@@ -138,6 +139,7 @@ async def mock_node_port_creator_cb(*args, **kwargs): | |||
+ list(original_outputs.values()) | |||
}, | |||
progress_bar=progress_bar, | |||
outputs_callbacks=AsyncMock(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure I understand here. you do not test anything of what you added right?
from pydantic import BaseModel | ||
|
||
|
||
class OutputStatus(StrAutoEnum): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am a bit concerned that we have many of these states and status all over the place... duplication is evil, and makes everything more complex. be careful please.
@@ -27,6 +29,20 @@ | |||
log = logging.getLogger(__name__) | |||
|
|||
|
|||
class OutputsCallbacks(ABC): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here I have a few comments:
- this OutputsCallbacks, and actually set_multiple are only used by the dynamic sidecar, why are they coming with this >complex stuff inside the node ports package? Would it not make sense that you build on top instead of creating these weird constructs?
- The tests you added do not check anything regarding how this callbacks work,
- Sorry, but this looks like C++ man... ;)
@@ -172,6 +173,7 @@ def create_app(): | |||
setup_rabbitmq(app) | |||
setup_background_log_fetcher(app) | |||
setup_resource_tracking(app) | |||
setup_notifications(app) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this not already a copy paste of something else? I have the feeling this notifications thing comes up several time in the repo
async def _send_output_port_status( | ||
self, port_key: ServicePortKey, status: OutputStatus | ||
) -> None: | ||
notifier: Notifier = Notifier.get_from_app_state(self.app) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thought: Would this not be more generic if it would not depend on the app? you would need to pass the notifier.
@@ -19,6 +19,9 @@ | |||
from servicelib.progress_bar import ProgressBarData | |||
from servicelib.utils import logged_gather | |||
from simcore_sdk.node_data import data_manager | |||
from simcore_service_dynamic_sidecar.modules.notifications._notifications_ports import ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
relative imports
@@ -70,13 +72,28 @@ def _get_size_of_value(value: tuple[ItemConcreteValue | None, SetKWargs | None]) | |||
) | |||
|
|||
|
|||
class OutputCallbacksWrapper(OutputsCallbacks): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as I said... this thing should live entirely in the dynamic sidecar. nobody else needs it.
port_value | ||
for port_value in (await PORTS.outputs).values() | ||
if (not port_keys) or (port_value.key in port_keys) | ||
] | ||
|
||
await logged_gather( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
limited_gather?
# NOTE: if one archiving task fails/cancelled all the ports are affected | ||
# setting all other ports as finished with error/cancelled | ||
try: | ||
await logged_gather(*archiving_tasks) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-
please use limited_gather.
Also there is an asyncGenerator available. -
Why not create a specific function that does all this stuff instead of that weird thing? you know that if an exception is raised in one of them coroutine it will not stop the others? Please double check these things...
[RabbitSettings], _AsyncGeneratorContextManager[AsyncServer] | ||
], | ||
) -> AsyncIterable[AsyncServer]: | ||
# Same configuration as simcore_service_webserver/socketio/server.py |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So in this file you basically test that notifier thing. Please move it out of the node ports. this is indirect testing.
If we do not need that thing anywhere else (which is the case) there is no need to have it in the node ports.
What do these changes do?
To provide better feedback for users in the UI we are adding notifications for ports during the runtime of the platform. Notifications are send from the backend for each individual port. Even when all ports are required to download/upload notifications are sent one port at a time.
The only notifications that make sense are:
input
port when itdownloads
data (we never upload data form an input port)output
port when ituploads
data (outputs are downloaded and they have a progress bar when the service starts)Input ports
Notification message for each
input
portdownload
:42["stateInputPorts",{"project_id":"b4a03e00-7691-11ef-a0a5-0242ac14001a","node_id":"81e4a4d9-e8f8-4816-ad22-58ce586f46e5","port_key":"input_20","status":"DOWNLOAD_FINISHED_SUCCESSFULLY"}]
.It can have one of the following
status
states:Output ports
Notification message for each
output
portupload
:42["stateOutputPorts",{"project_id":"b4a03e00-7691-11ef-a0a5-0242ac14001a","node_id":"81e4a4d9-e8f8-4816-ad22-58ce586f46e5","port_key":"output_2","status":"UPLOAD_STARTED"}]
.It can have one of the following
status
states:Related issue/s
How to test
Dev-ops checklist