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

Update Experiment details background task #172

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 0 additions & 12 deletions autosubmit_api/bgtasks/bgtask.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
from abc import ABC, abstractmethod
import traceback
from autosubmit_api.logger import logger
from autosubmit_api.config.basicConfig import APIBasicConfig
from autosubmit_api.workers.business import process_graph_drawings
from autosubmit_api.workers.populate_details.populate import DetailsProcessor


class BackgroundTaskTemplate(ABC):
Expand Down Expand Up @@ -41,16 +39,6 @@ def trigger_options(self) -> dict:
raise NotImplementedError


class PopulateDetailsDB(BackgroundTaskTemplate):
id = "TASK_POPDET"
trigger_options = {"trigger": "interval", "hours": 4}

@classmethod
def procedure(cls):
APIBasicConfig.read()
return DetailsProcessor(APIBasicConfig).process()


class PopulateGraph(BackgroundTaskTemplate):
id = "TASK_POPGRPH"
trigger_options = {"trigger": "interval", "hours": 24}
Expand Down
2 changes: 1 addition & 1 deletion autosubmit_api/bgtasks/scheduler.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
from apscheduler.triggers.cron import CronTrigger
from autosubmit_api.bgtasks.bgtask import (
BackgroundTaskTemplate,
PopulateDetailsDB,
PopulateGraph,
)
from autosubmit_api.bgtasks.tasks.details_updater import PopulateDetailsDB
from autosubmit_api.bgtasks.tasks.status_updater import StatusUpdater
from autosubmit_api.config import (
get_disable_background_tasks,
Expand Down
88 changes: 88 additions & 0 deletions autosubmit_api/bgtasks/tasks/details_updater.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
from typing import List
from autosubmit_api.bgtasks.bgtask import BackgroundTaskTemplate
from autosubmit_api.builders.configuration_facade_builder import (
AutosubmitConfigurationFacadeBuilder,
ConfigurationFacadeDirector,
)
from autosubmit_api.repositories.experiment import (
ExperimentModel,
create_experiment_repository,
)
from autosubmit_api.repositories.experiment_details import (
create_experiment_details_repository,
ExperimentDetailsModel,
)


class PopulateDetailsDB(BackgroundTaskTemplate):
id = "TASK_POPDET"
trigger_options = {"trigger": "interval", "hours": 4}

@classmethod
def procedure(cls):
"""
Procedure to populate the details table
"""

# Get experiments
experiments = cls._get_experiments()

rows_added = 0

for experiment in experiments:
try:
# Get details data from the experiment
details_data = cls._build_details_data_from_experiment(
experiment.id, experiment.name
)

# Insert details data into the details table
rows_added += cls._upsert_details_data(details_data)
except Exception as exc:
cls.logger.error(
f"[{cls.id}] Error while processing experiment {experiment.name}: {exc}"
)

return rows_added

@classmethod
def _get_experiments(cls) -> List[ExperimentModel]:
"""
Get the experiments list
"""
experiment_repository = create_experiment_repository()
return experiment_repository.get_all()

@classmethod
def _build_details_data_from_experiment(
self, exp_id: int, expid: str
) -> ExperimentDetailsModel:
"""
Build the details data from the experiment
"""
autosubmit_config = ConfigurationFacadeDirector(
AutosubmitConfigurationFacadeBuilder(expid)
).build_autosubmit_configuration_facade()
return ExperimentDetailsModel(
exp_id=exp_id,
user=autosubmit_config.get_owner_name(),
created=autosubmit_config.get_experiment_created_time_as_datetime(),
model=autosubmit_config.get_model(),
branch=autosubmit_config.get_branch(),
hpc=autosubmit_config.get_main_platform(),
)

@classmethod
def _upsert_details_data(cls, details_data: ExperimentDetailsModel):
"""
Insert or update details data into the details table
"""
details_repository = create_experiment_details_repository()
return details_repository.upsert_details(
details_data.exp_id,
details_data.user,
details_data.created,
details_data.model,
details_data.branch,
details_data.hpc,
)
39 changes: 38 additions & 1 deletion autosubmit_api/repositories/experiment_details.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,22 @@ def get_by_exp_id(self, exp_id: int) -> ExperimentDetailsModel:
:raises ValueError: If the experiment detail is not found
"""

@abstractmethod
def upsert_details(
self, exp_id: int, user: str, created: str, model: str, branch: str, hpc: str
) -> int:
"""
Upsert the experiment details

:param exp_id: The numerical experiment id
:param user: The user who created the experiment
:param created: The creation date of the experiment
:param model: The model used in the experiment
:param branch: The branch of the model
:param hpc: The HPC used in the experiment
:return: The number of rows affected
"""


class ExperimentDetailsSQLRepository(ExperimentDetailsRepository):
def __init__(self, engine: Engine, table: Table):
Expand All @@ -58,7 +74,7 @@ def delete_all(self) -> int:
conn.commit()
return result.rowcount

def get_by_exp_id(self, exp_id):
def get_by_exp_id(self, exp_id: int):
with self.engine.connect() as conn:
statement = self.table.select().where(self.table.c.exp_id == exp_id)
result = conn.execute(statement).first()
Expand All @@ -73,6 +89,27 @@ def get_by_exp_id(self, exp_id):
hpc=result.hpc,
)

def upsert_details(self, exp_id, user, created, model, branch, hpc):
with self.engine.connect() as conn:
with conn.begin():
try:
del_stmnt = self.table.delete().where(self.table.c.exp_id == exp_id)
ins_stmnt = self.table.insert().values(
exp_id=exp_id,
user=user,
created=created,
model=model,
branch=branch,
hpc=hpc,
)
conn.execute(del_stmnt)
result = conn.execute(ins_stmnt)
conn.commit()
return result.rowcount
except Exception as exc:
conn.rollback()
raise exc


def create_experiment_details_repository() -> ExperimentDetailsRepository:
engine = create_autosubmit_db_engine()
Expand Down
7 changes: 3 additions & 4 deletions autosubmit_api/repositories/experiment_status.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def get_only_running_expids(self) -> List[str]:
"""
Gets list of running experiments expids
"""

@abstractmethod
def delete_all(self) -> int:
"""
Expand Down Expand Up @@ -99,18 +99,17 @@ def upsert_status(self, exp_id: int, expid: str, status: str):
conn.execute(del_stmnt)
result = conn.execute(ins_stmnt)
conn.commit()
return result.rowcount
except Exception as exc:
conn.rollback()
raise exc

return result.rowcount

def get_only_running_expids(self):
with self.engine.connect() as conn:
statement = self.table.select().where(self.table.c.status == "RUNNING")
result = conn.execute(statement).all()
return [row.name for row in result]

def delete_all(self):
with self.engine.connect() as conn:
statement = delete(self.table)
Expand Down
Empty file.
86 changes: 0 additions & 86 deletions autosubmit_api/workers/populate_details/populate.py

This file was deleted.

2 changes: 1 addition & 1 deletion autosubmit_api/workers/populate_details_db.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from autosubmit_api.bgtasks.bgtask import PopulateDetailsDB
from autosubmit_api.bgtasks.tasks.details_updater import PopulateDetailsDB

def main():
PopulateDetailsDB.run()
Expand Down
4 changes: 2 additions & 2 deletions tests/test_bg_tasks.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
from autosubmit_api.bgtasks.tasks.details_updater import PopulateDetailsDB
from autosubmit_api.config.basicConfig import APIBasicConfig
from autosubmit_api.database import tables
from autosubmit_api.database.common import create_autosubmit_db_engine
from autosubmit_api.repositories.experiment_details import (
create_experiment_details_repository,
)
from autosubmit_api.workers.populate_details.populate import DetailsProcessor


class TestDetailsPopulate:
Expand All @@ -16,7 +16,7 @@ def test_process(self, fixture_mock_basic_config: APIBasicConfig):
rows = conn.execute(tables.details_table.select()).all()
assert len(rows) == 0

count = DetailsProcessor(fixture_mock_basic_config).process()
count = PopulateDetailsDB.procedure()

rows = conn.execute(tables.details_table.select()).all()

Expand Down
Loading