Skip to content

Commit c9379cd

Browse files
committed
Merge branch 'feature/support-center' of github.com:odeimaiz/osparc-simcore into feature/support-center
2 parents 8f9cca7 + 139a830 commit c9379cd

File tree

90 files changed

+1570
-217
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

90 files changed

+1570
-217
lines changed

.env-devel

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,8 @@ POSTGRES_HOST=postgres
194194
POSTGRES_PASSWORD=adminadmin
195195
POSTGRES_PORT=5432
196196
POSTGRES_USER=scu
197-
197+
POSTGRES_MINSIZE=2 # see https://github.com/ITISFoundation/osparc-simcore/pull/8199
198+
POSTGRES_MAXSIZE=50
198199
POSTGRES_READONLY_PASSWORD=readonly
199200
POSTGRES_READONLY_USER=postgres_readonly
200201

packages/models-library/src/models_library/api_schemas_webserver/projects.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,7 @@ class ProjectPatch(InputSchema):
278278
] = None
279279
quality: dict[str, Any] | None = None
280280
template_type: ProjectTemplateType | None = None
281+
hidden: bool | None = None
281282

282283
def to_domain_model(self) -> dict[str, Any]:
283284
return self.model_dump(exclude_unset=True, by_alias=False)

packages/models-library/src/models_library/rpc/webserver/projects.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ class ProjectJobRpcGet(BaseModel):
9090

9191
# Specific to jobs
9292
job_parent_resource_name: str
93+
storage_assets_deleted: bool
9394

9495
@staticmethod
9596
def _update_json_schema_extra(schema: JsonDict) -> None:
@@ -105,6 +106,7 @@ def _update_json_schema_extra(schema: JsonDict) -> None:
105106
"created_at": "2023-01-01T00:00:00Z",
106107
"modified_at": "2023-01-01T00:00:00Z",
107108
"job_parent_resource_name": "solvers/simcore%2Fservices%2Fcomp%2Fitis%2Fsleeper/releases/2.0.2",
109+
"storage_assets_deleted": "false",
108110
},
109111
{
110112
"uuid": "00000000-1234-5678-1234-123456789012",
@@ -114,6 +116,7 @@ def _update_json_schema_extra(schema: JsonDict) -> None:
114116
"created_at": "2023-02-01T00:00:00Z",
115117
"modified_at": "2023-02-01T00:00:00Z",
116118
"job_parent_resource_name": "studies/96642f2a-a72c-11ef-8776-02420a00087d",
119+
"storage_assets_deleted": "true",
117120
},
118121
{
119122
"uuid": "00000000-0000-5678-1234-123456789012",
@@ -123,6 +126,7 @@ def _update_json_schema_extra(schema: JsonDict) -> None:
123126
"created_at": "2023-03-01T00:00:00Z",
124127
"modified_at": "2023-03-01T00:00:00Z",
125128
"job_parent_resource_name": "program/simcore%2Fservices%2Fdynamic%2Fjupyter/releases/5.0.2",
129+
"storage_assets_deleted": "false",
126130
},
127131
]
128132
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
"""introduce data_deleted in projects_to_jobs table
2+
3+
Revision ID: 5b998370916a
4+
Revises: 5679165336c8
5+
Create Date: 2025-08-11 13:58:38.424398+00:00
6+
7+
"""
8+
9+
import sqlalchemy as sa
10+
from alembic import op
11+
12+
# revision identifiers, used by Alembic.
13+
revision = "5b998370916a"
14+
down_revision = "5679165336c8"
15+
branch_labels = None
16+
depends_on = None
17+
18+
19+
def upgrade():
20+
# ### commands auto generated by Alembic - please adjust! ###
21+
op.add_column(
22+
"projects_to_jobs",
23+
sa.Column("storage_assets_deleted", sa.Boolean(), nullable=True),
24+
)
25+
26+
op.execute("UPDATE projects_to_jobs SET storage_assets_deleted = false")
27+
28+
op.alter_column(
29+
"projects_to_jobs",
30+
"storage_assets_deleted",
31+
existing_type=sa.BOOLEAN(),
32+
nullable=False,
33+
)
34+
# ### end Alembic commands ###
35+
36+
37+
def downgrade():
38+
# ### commands auto generated by Alembic - please adjust! ###
39+
op.drop_column("projects_to_jobs", "storage_assets_deleted")
40+
# ### end Alembic commands ###

packages/postgres-database/src/simcore_postgres_database/models/projects_to_jobs.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@
2828
"the relative resource name is shelves/shelf1/jobs/job2, "
2929
"the parent resource name is shelves/shelf1.",
3030
),
31+
sa.Column(
32+
"storage_assets_deleted",
33+
sa.Boolean,
34+
nullable=False,
35+
doc="Indicates whether the job's S3 assets have been actively deleted.",
36+
),
3137
# Composite key (project_uuid, job_parent_resource_name) uniquely identifies very row
3238
sa.UniqueConstraint(
3339
"project_uuid",

packages/postgres-database/tests/conftest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ def sync_engine(postgres_service: str) -> Iterable[sqlalchemy.engine.Engine]:
8181
def _make_asyncpg_engine(postgres_service: str) -> Callable[[bool], AsyncEngine]:
8282
# NOTE: users is responsible of `await engine.dispose()`
8383
dsn = postgres_service.replace("postgresql://", "postgresql+asyncpg://")
84-
minsize = 1
84+
minsize = 2
8585
maxsize = 50
8686

8787
def _(echo: bool):

packages/pytest-simcore/src/pytest_simcore/helpers/webserver_rpc_server.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@
2626
class WebserverRpcSideEffects:
2727
# pylint: disable=no-self-use
2828

29+
def __init__(
30+
self,
31+
project_job_rpc_get: ProjectJobRpcGet = ProjectJobRpcGet.model_validate(
32+
ProjectJobRpcGet.model_json_schema()["examples"][0]
33+
),
34+
):
35+
self.project_job_rpc_get = project_job_rpc_get
36+
2937
@validate_call(config={"arbitrary_types_allowed": True})
3038
async def mark_project_as_job(
3139
self,
@@ -35,12 +43,14 @@ async def mark_project_as_job(
3543
user_id: UserID,
3644
project_uuid: ProjectID,
3745
job_parent_resource_name: str,
46+
storage_assets_deleted: bool,
3847
) -> None:
3948
assert rpc_client
4049

4150
assert not job_parent_resource_name.startswith("/") # nosec
4251
assert "/" in job_parent_resource_name # nosec
4352
assert not job_parent_resource_name.endswith("/") # nosec
53+
assert isinstance(storage_assets_deleted, bool)
4454

4555
assert product_name
4656
assert user_id
@@ -84,3 +94,25 @@ async def list_projects_marked_as_jobs(
8494
limit=limit,
8595
offset=offset,
8696
)
97+
98+
@validate_call(config={"arbitrary_types_allowed": True})
99+
async def get_project_marked_as_job(
100+
self,
101+
rpc_client: RabbitMQRPCClient | MockType,
102+
*,
103+
product_name: ProductName,
104+
user_id: UserID,
105+
project_uuid: ProjectID,
106+
job_parent_resource_name: str,
107+
) -> ProjectJobRpcGet:
108+
assert rpc_client
109+
assert product_name
110+
assert user_id
111+
assert project_uuid
112+
assert job_parent_resource_name
113+
114+
# Return a valid example from the schema
115+
_data = self.project_job_rpc_get.model_dump()
116+
_data["uuid"] = str(project_uuid)
117+
_data["job_parent_resource_name"] = job_parent_resource_name
118+
return ProjectJobRpcGet.model_validate(_data)

packages/pytest-simcore/src/pytest_simcore/simcore_services.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
"whoami",
4141
"sto-worker",
4242
"sto-worker-cpu-bound",
43-
"traefik-configuration-placeholder",
43+
"traefik-config-placeholder",
4444
}
4545
# TODO: unify healthcheck policies see https://github.com/ITISFoundation/osparc-simcore/pull/2281
4646
DEFAULT_SERVICE_HEALTHCHECK_ENTRYPOINT: Final[str] = "/v0/"

packages/service-library/src/servicelib/aiohttp/db_asyncpg_engine.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,23 +38,22 @@ def get_async_engine(app: web.Application) -> AsyncEngine:
3838
return engine
3939

4040

41-
async def connect_to_db(app: web.Application, settings: PostgresSettings) -> None:
41+
async def connect_to_db(
42+
app: web.Application, settings: PostgresSettings, application_name: str
43+
) -> None:
4244
"""
4345
- db services up, data migrated and ready to use
4446
- sets an engine in app state (use `get_async_engine(app)` to retrieve)
4547
"""
46-
if settings.POSTGRES_CLIENT_NAME:
47-
settings = settings.model_copy(
48-
update={"POSTGRES_CLIENT_NAME": settings.POSTGRES_CLIENT_NAME + "-asyncpg"}
49-
)
50-
5148
with log_context(
5249
_logger,
5350
logging.INFO,
5451
"Connecting app[APP_DB_ASYNC_ENGINE_KEY] to postgres with %s",
5552
f"{settings=}",
5653
):
57-
engine = await create_async_engine_and_database_ready(settings)
54+
engine = await create_async_engine_and_database_ready(
55+
settings, application_name
56+
)
5857
_set_async_engine_to_app_state(app, engine)
5958

6059
_logger.info(

packages/service-library/src/servicelib/db_asyncpg_utils.py

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
@retry(**PostgresRetryPolicyUponInitialization(_logger).kwargs)
2020
async def create_async_engine_and_database_ready(
21-
settings: PostgresSettings,
21+
settings: PostgresSettings, application_name: str
2222
) -> AsyncEngine:
2323
"""
2424
- creates asyncio engine
@@ -30,12 +30,12 @@ async def create_async_engine_and_database_ready(
3030
raise_if_migration_not_ready,
3131
)
3232

33-
server_settings = None
34-
if settings.POSTGRES_CLIENT_NAME:
35-
assert isinstance(settings.POSTGRES_CLIENT_NAME, str) # nosec
36-
server_settings = {
37-
"application_name": settings.POSTGRES_CLIENT_NAME,
38-
}
33+
server_settings = {
34+
"jit": "off",
35+
"application_name": settings.client_name(
36+
f"{application_name}", suffix="asyncpg"
37+
),
38+
}
3939

4040
engine = create_async_engine(
4141
settings.dsn_with_async_sqlalchemy,
@@ -71,7 +71,7 @@ async def check_postgres_liveness(engine: AsyncEngine) -> LivenessResult:
7171

7272
@contextlib.asynccontextmanager
7373
async def with_async_pg_engine(
74-
settings: PostgresSettings,
74+
settings: PostgresSettings, *, application_name: str
7575
) -> AsyncIterator[AsyncEngine]:
7676
"""
7777
Creates an asyncpg engine and ensures it is properly closed after use.
@@ -82,9 +82,11 @@ async def with_async_pg_engine(
8282
logging.DEBUG,
8383
f"connection to db {settings.dsn_with_async_sqlalchemy}",
8484
):
85-
server_settings = None
86-
if settings.POSTGRES_CLIENT_NAME:
87-
assert isinstance(settings.POSTGRES_CLIENT_NAME, str)
85+
server_settings = {
86+
"application_name": settings.client_name(
87+
application_name, suffix="asyncpg"
88+
),
89+
}
8890

8991
engine = create_async_engine(
9092
settings.dsn_with_async_sqlalchemy,

0 commit comments

Comments
 (0)