Skip to content
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

Open
wants to merge 14 commits into
base: master
Choose a base branch
from

Conversation

GitHK
Copy link
Contributor

@GitHK GitHK commented Sep 19, 2024

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 it downloads data (we never upload data form an input port)
  • output port when it uploads data (outputs are downloaded and they have a progress bar when the service starts)

Input ports

Notification message for each input port download:
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:

DOWNLOAD_STARTED
DOWNLOAD_WAS_ABORTED
DOWNLOAD_FINISHED_SUCCESSFULLY
DOWNLOAD_FINISHED_WITH_ERRROR

Output ports

Notification message for each output port upload:
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:

UPLOAD_STARTED
UPLOAD_WAS_ABORTED
UPLOAD_FINISHED_SUCCESSFULLY
UPLOAD_FINISHED_WITH_ERRROR

Related issue/s

How to test

Dev-ops checklist

@GitHK GitHK self-assigned this Sep 19, 2024
@GitHK GitHK added this to the MartinKippenberger milestone Sep 19, 2024
Copy link

codecov bot commented Sep 19, 2024

Codecov Report

Attention: Patch coverage is 76.31579% with 36 lines in your changes missing coverage. Please review.

Project coverage is 88.8%. Comparing base (cafbf96) to head (9f2854f).
Report is 562 commits behind head on master.

Files with missing lines Patch % Lines
...mcore_service_dynamic_sidecar/modules/nodeports.py 21.6% 29 Missing ⚠️
...-sdk/src/simcore_sdk/node_ports_v2/nodeports_v2.py 58.8% 6 Missing and 1 partial ⚠️
Additional details and impacted files

Impacted file tree graph

@@            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     
Flag Coverage Δ
integrationtests 64.7% <58.7%> (?)
unittests 86.5% <76.3%> (+1.9%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...odels_library/api_schemas_dynamic_sidecar/ports.py 100.0% <100.0%> (ø)
...ls_library/api_schemas_dynamic_sidecar/socketio.py 100.0% <100.0%> (ø)
...namic_sidecar/api/containers_long_running_tasks.py 100.0% <ø> (ø)
...imcore_service_dynamic_sidecar/core/application.py 98.2% <100.0%> (ø)
...vice_dynamic_sidecar/modules/long_running_tasks.py 94.4% <100.0%> (ø)
..._dynamic_sidecar/modules/notifications/__init__.py 100.0% <100.0%> (ø)
...ecar/modules/notifications/_notifications_ports.py 100.0% <100.0%> (ø)
...les/notifications/_notifications_system_monitor.py 100.0% <100.0%> (ø)
...dynamic_sidecar/modules/notifications/_notifier.py 100.0% <100.0%> (ø)
...ce_dynamic_sidecar/modules/notifications/_setup.py 100.0% <100.0%> (ø)
... and 6 more

... and 1198 files with indirect coverage changes

@GitHK GitHK marked this pull request as ready for review September 20, 2024 07:34
Copy link
Member

@pcrespov pcrespov left a 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

await outputs_callbacks.aborted(port_key)
raise
except Exception:
await outputs_callbacks.finished_with_error(port_key)
Copy link
Member

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?

Copy link
Member

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

Copy link

sonarcloud bot commented Sep 20, 2024

Copy link
Member

@sanderegg sanderegg left a 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(),
Copy link
Member

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):
Copy link
Member

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):
Copy link
Member

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:

  1. 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?
  2. The tests you added do not check anything regarding how this callbacks work,
  3. 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)
Copy link
Member

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)
Copy link
Member

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 (
Copy link
Member

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):
Copy link
Member

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(
Copy link
Member

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)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. please use limited_gather.
    Also there is an asyncGenerator available.

  2. 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
Copy link
Member

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

backend provides port notifications
3 participants