Skip to content

Commit 6d223c8

Browse files
authored
🐛Webserver: Improve slow synchronous calls (#4753)
1 parent 063653b commit 6d223c8

File tree

3 files changed

+49
-17
lines changed

3 files changed

+49
-17
lines changed

services/web/server/src/simcore_service_webserver/catalog/_api.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import asyncio
12
import logging
23
from collections.abc import Iterator
34
from typing import Any
@@ -69,8 +70,11 @@ async def list_services(
6970
)
7071
for service in services:
7172
try:
72-
replace_service_input_outputs(
73-
service, unit_registry=unit_registry, **RESPONSE_MODEL_POLICY
73+
await asyncio.to_thread(
74+
replace_service_input_outputs,
75+
service,
76+
unit_registry=unit_registry,
77+
**RESPONSE_MODEL_POLICY,
7478
)
7579
except KeyError: # noqa: PERF203
7680
# This will limit the effect of a any error in the formatting of
@@ -93,8 +97,11 @@ async def get_service(
9397
service = await client.get_service(
9498
ctx.app, ctx.user_id, service_key, service_version, ctx.product_name
9599
)
96-
replace_service_input_outputs(
97-
service, unit_registry=ctx.unit_registry, **RESPONSE_MODEL_POLICY
100+
await asyncio.to_thread(
101+
replace_service_input_outputs,
102+
service,
103+
unit_registry=ctx.unit_registry,
104+
**RESPONSE_MODEL_POLICY,
98105
)
99106
return service
100107

@@ -113,8 +120,11 @@ async def update_service(
113120
ctx.product_name,
114121
update_data,
115122
)
116-
replace_service_input_outputs(
117-
service, unit_registry=ctx.unit_registry, **RESPONSE_MODEL_POLICY
123+
await asyncio.to_thread(
124+
replace_service_input_outputs,
125+
service,
126+
unit_registry=ctx.unit_registry,
127+
**RESPONSE_MODEL_POLICY,
118128
)
119129
return service
120130

services/web/server/src/simcore_service_webserver/catalog/_handlers.py

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
should live in the catalog service in his final version
55
66
"""
7+
import asyncio
78
import logging
89
import urllib.parse
910
from typing import Any, Final
@@ -76,7 +77,9 @@ async def list_services(request: Request):
7677
# assert parse_obj_as(list[ServiceGet], data_array) is not None # nosec
7778
#
7879

79-
return envelope_json_response(data_array)
80+
return await asyncio.get_event_loop().run_in_executor(
81+
None, envelope_json_response, data_array
82+
)
8083

8184

8285
@routes.get(
@@ -92,7 +95,9 @@ async def get_service(request: Request):
9295
path_params.service_key, path_params.service_version, ctx
9396
)
9497
assert parse_obj_as(ServiceGet, data) is not None # nosec
95-
return envelope_json_response(data)
98+
return await asyncio.get_event_loop().run_in_executor(
99+
None, envelope_json_response, data
100+
)
96101

97102

98103
@routes.patch(
@@ -117,7 +122,9 @@ async def update_service(request: Request):
117122
)
118123

119124
assert parse_obj_as(ServiceGet, data) is not None # nosec
120-
return envelope_json_response(data)
125+
return await asyncio.get_event_loop().run_in_executor(
126+
None, envelope_json_response, data
127+
)
121128

122129

123130
@routes.get(
@@ -136,7 +143,9 @@ async def list_service_inputs(request: Request):
136143
)
137144

138145
data = [m.dict(**RESPONSE_MODEL_POLICY) for m in response_model]
139-
return envelope_json_response(data)
146+
return await asyncio.get_event_loop().run_in_executor(
147+
None, envelope_json_response, data
148+
)
140149

141150

142151
class _ServiceInputsPathParams(ServicePathParams):
@@ -162,7 +171,9 @@ async def get_service_input(request: Request):
162171
)
163172

164173
data = response_model.dict(**RESPONSE_MODEL_POLICY)
165-
return envelope_json_response(data)
174+
return await asyncio.get_event_loop().run_in_executor(
175+
None, envelope_json_response, data
176+
)
166177

167178

168179
class _FromServiceOutputParams(BaseModel):
@@ -192,7 +203,9 @@ async def get_compatible_inputs_given_source_output(request: Request):
192203
ctx,
193204
)
194205

195-
return envelope_json_response(data)
206+
return await asyncio.get_event_loop().run_in_executor(
207+
None, envelope_json_response, data
208+
)
196209

197210

198211
@routes.get(
@@ -211,7 +224,9 @@ async def list_service_outputs(request: Request):
211224
)
212225

213226
data = [m.dict(**RESPONSE_MODEL_POLICY) for m in response_model]
214-
return envelope_json_response(data)
227+
return await asyncio.get_event_loop().run_in_executor(
228+
None, envelope_json_response, data
229+
)
215230

216231

217232
class _ServiceOutputsPathParams(ServicePathParams):
@@ -237,7 +252,9 @@ async def get_service_output(request: Request):
237252
)
238253

239254
data = response_model.dict(**RESPONSE_MODEL_POLICY)
240-
return envelope_json_response(data)
255+
return await asyncio.get_event_loop().run_in_executor(
256+
None, envelope_json_response, data
257+
)
241258

242259

243260
class _ToServiceInputsParams(BaseModel):
@@ -271,7 +288,9 @@ async def get_compatible_outputs_given_target_input(request: Request):
271288
ctx,
272289
)
273290

274-
return envelope_json_response(data)
291+
return await asyncio.get_event_loop().run_in_executor(
292+
None, envelope_json_response, data
293+
)
275294

276295

277296
@routes.get(
@@ -296,4 +315,6 @@ async def get_service_resources(request: Request):
296315
)
297316

298317
data = ServiceResourcesDictHelpers.create_jsonable(service_resources)
299-
return envelope_json_response(data)
318+
return await asyncio.get_event_loop().run_in_executor(
319+
None, envelope_json_response, data
320+
)

services/web/server/src/simcore_service_webserver/catalog/_models.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,8 @@ def from_catalog_service_api_model(
8585
if "defaultValue" in data:
8686
data.pop("defaultValue")
8787

88-
port = ServiceOutputGet(key_id=output_key, **data) # validated
88+
# NOTE: this call must be validated if port property type is "ref_contentSchema"
89+
port = ServiceOutputGet(key_id=output_key, **data)
8990

9091
unit_html: UnitHtmlFormat | None
9192
if ureg and (unit_html := get_html_formatted_unit(port, ureg)):

0 commit comments

Comments
 (0)