QTZPOC-20

QTZPOC-20: Refactor model import workflow, introduce atomic model ID generation, and clarify MinIO expiry.

Fuses bundle download, decryption, MLflow experiment creation, and artifact upload into a single activity to prevent cross-worker issues. Implements an atomic counter for MongoDB model IDs, replacing the max(id) + 1 scan to avoid collisions during concurrent imports. Adds comprehensive documentation for MinIO object expiry mechanisms and refines lifecycle rule application. Improves error handling with clearer responsibility classification and centralizes MLflow repository injection.
This commit is contained in:
2026-09-08 17:06:25 -03:00
parent e4fc12e529
commit 192834bde3
34 changed files with 1485 additions and 531 deletions

View File

@@ -102,6 +102,9 @@ IMPORT_BUCKET = 'sientia-import'
IMPORT_PREFIX = 'imported_models/'
MODELS_COLLECTION = 'models'
MONGO_DATABASE = 'sientia'
# Must track `IMPORT_MODEL_ID_COUNTERS_COLLECTION`'s default in connectors_config.py — the harness
# never sets that env var, so production's default is what the worker under test actually reads from.
MODEL_ID_COUNTERS_COLLECTION = 'model_id_counters'
IMPORT_TASK_QUEUE = 'import-model-e2e-queue'
# Deliberately gapped, and deliberately strings: the baseline migration stores `id` as a string and
@@ -119,10 +122,7 @@ IMPORT_ACTIVITY_NAMES = (
'record_import_terminal_status',
'report_import_status_write_failure',
'report_import_pipeline_failure',
'download_import_bundle',
'open_import_bundle',
'create_import_experiment',
'upload_import_artifacts',
'prepare_and_upload_import_bundle',
'register_import_model_version',
'write_import_model_document',
'cleanup_import_files',
@@ -331,6 +331,12 @@ def import_models_collection(import_mongo_client: MongoClient) -> Any:
The index is the assertion's teeth: without it "the id continues the collection" and "a name
already present is left alone" would both pass against a collection that quietly took a
duplicate.
New ids no longer come from scanning this collection — `_next_model_document_id` reads an
atomic counter in a separate `model_id_counters` collection instead (a different database, no
less), so it survives this drop untouched. Reset it here too, to the same seeded high-water
mark, or the next id handed out silently carries over from whatever an earlier test in the same
run already claimed.
"""
collection = import_mongo_client[MONGO_DATABASE][MODELS_COLLECTION]
collection.drop()
@@ -351,6 +357,13 @@ def import_models_collection(import_mongo_client: MongoClient) -> Any:
]
)
collection.create_index('id', unique=True)
counters = import_mongo_client[MONGO_DATABASE][MODEL_ID_COUNTERS_COLLECTION]
counters.replace_one(
{'_id': MODELS_COLLECTION},
{'_id': MODELS_COLLECTION, 'seq': max(int(seeded) for seeded in SEEDED_MODEL_IDS)},
upsert=True,
)
return collection