|
10 | 10 | from models_library.api_schemas_catalog.services import ServiceGet, ServiceUpdate |
11 | 11 | from models_library.services import ServiceKey, ServiceType, ServiceVersion |
12 | 12 | from models_library.services_metadata_published import ServiceMetaDataPublished |
| 13 | +from opentelemetry import trace |
13 | 14 | from pydantic import ValidationError |
14 | 15 | from pydantic.types import PositiveInt |
15 | 16 | from servicelib.fastapi.requests_decorators import cancel_on_disconnect |
|
32 | 33 | _logger = logging.getLogger(__name__) |
33 | 34 |
|
34 | 35 | ServicesSelection: TypeAlias = set[tuple[str, str]] |
| 36 | +# Obtain the tracer from the global tracer provider |
| 37 | +_tracer = trace.get_tracer(__name__) |
35 | 38 |
|
36 | 39 |
|
37 | 40 | def _compose_service_details( |
@@ -105,56 +108,67 @@ async def list_services( |
105 | 108 | ) |
106 | 109 |
|
107 | 110 | # now get the executable or writable services |
108 | | - services_in_db = { |
109 | | - (s.key, s.version): s |
110 | | - for s in await services_repo.list_services( |
111 | | - gids=[group.gid for group in user_groups], |
112 | | - execute_access=True, |
113 | | - write_access=True, |
114 | | - combine_access_with_and=False, |
115 | | - product_name=x_simcore_products_name, |
116 | | - ) |
117 | | - } |
| 111 | + with _tracer.start_as_current_span("services_repo.list_services") as span: |
| 112 | + span.set_attribute("osparc-gids", f"{[group.gid for group in user_groups]}") |
| 113 | + span.set_attribute("osparc-productname", f"{x_simcore_products_name}") |
| 114 | + services_in_db = { |
| 115 | + (s.key, s.version): s |
| 116 | + for s in await services_repo.list_services( |
| 117 | + gids=[group.gid for group in user_groups], |
| 118 | + execute_access=True, |
| 119 | + write_access=True, |
| 120 | + combine_access_with_and=False, |
| 121 | + product_name=x_simcore_products_name, |
| 122 | + ) |
| 123 | + } |
118 | 124 | # Non-detailed views from the services_repo database |
119 | 125 | if not details: |
120 | 126 | # only return a stripped down version |
121 | 127 | # NOTE: here validation is not necessary since key,version were already validated |
122 | 128 | # in terms of time, this takes the most |
123 | | - return [ |
124 | | - ServiceGet.construct( |
125 | | - key=key, |
126 | | - version=version, |
127 | | - name="nodetails", |
128 | | - description="nodetails", |
129 | | - type=ServiceType.COMPUTATIONAL, |
130 | | - authors=[{ "name": "nodetails", "email": "[email protected]"}], |
131 | | - |
132 | | - inputs={}, |
133 | | - outputs={}, |
134 | | - deprecated=services_in_db[(key, version)].deprecated, |
135 | | - ) |
136 | | - for key, version in services_in_db |
137 | | - ] |
| 129 | + with _tracer.start_as_current_span("return-non-detailed-view") as span: |
| 130 | + span.set_attribute("osparc-gids", f"{[group.gid for group in user_groups]}") |
| 131 | + span.set_attribute("osparc-productname", f"{x_simcore_products_name}") |
| 132 | + return [ |
| 133 | + ServiceGet.construct( |
| 134 | + key=key, |
| 135 | + version=version, |
| 136 | + name="nodetails", |
| 137 | + description="nodetails", |
| 138 | + type=ServiceType.COMPUTATIONAL, |
| 139 | + authors=[{ "name": "nodetails", "email": "[email protected]"}], |
| 140 | + |
| 141 | + inputs={}, |
| 142 | + outputs={}, |
| 143 | + deprecated=services_in_db[(key, version)].deprecated, |
| 144 | + ) |
| 145 | + for key, version in services_in_db |
| 146 | + ] |
138 | 147 |
|
139 | 148 | # caching this steps brings down the time to generate it at the expense of being sometimes a bit out of date |
140 | 149 | @cached(ttl=DIRECTOR_CACHING_TTL) |
141 | 150 | async def cached_registry_services() -> dict[str, Any]: |
142 | 151 | return cast(dict[str, Any], await director_client.get("/services")) |
143 | 152 |
|
144 | | - ( |
145 | | - services_in_registry, |
146 | | - services_access_rights, |
147 | | - services_owner_emails, |
148 | | - ) = await asyncio.gather( |
149 | | - cached_registry_services(), |
150 | | - services_repo.list_services_access_rights( |
151 | | - key_versions=services_in_db, |
152 | | - product_name=x_simcore_products_name, |
153 | | - ), |
154 | | - groups_repository.list_user_emails_from_gids( |
155 | | - {s.owner for s in services_in_db.values() if s.owner} |
156 | | - ), |
157 | | - ) |
| 153 | + with _tracer.start_as_current_span( |
| 154 | + "services_repo.list_services_access_rights" |
| 155 | + ) as span: |
| 156 | + span.set_attribute("osparc-gids", f"{[group.gid for group in user_groups]}") |
| 157 | + span.set_attribute("osparc-productname", f"{x_simcore_products_name}") |
| 158 | + ( |
| 159 | + services_in_registry, |
| 160 | + services_access_rights, |
| 161 | + services_owner_emails, |
| 162 | + ) = await asyncio.gather( |
| 163 | + cached_registry_services(), |
| 164 | + services_repo.list_services_access_rights( |
| 165 | + key_versions=services_in_db, |
| 166 | + product_name=x_simcore_products_name, |
| 167 | + ), |
| 168 | + groups_repository.list_user_emails_from_gids( |
| 169 | + {s.owner for s in services_in_db.values() if s.owner} |
| 170 | + ), |
| 171 | + ) |
158 | 172 |
|
159 | 173 | # NOTE: for the details of the services: |
160 | 174 | # 1. we get all the services from the director-v0 (TODO: move the registry to the catalog) |
|
0 commit comments