Jobs: with keep_completed, success and error records outlive the rows they describe
Les mainteneurs répondent en général sous 1 jour
Personne n'a encore pris cette issue.
Évaluation
- Difficulté
- 3/5
- Temps estimé
- Une demi-journée
- Accessibilité débutants
- 65/100
- Type d'issue
- Bug
- Clarté
- Clairement spécifiée
- Activité
- Active
- Stack technique
- mysql, python
- Domaine
- data-engineering, databases
Piste de recherche
Start from Job.refresh(), specifically step 3, which removes stale job records only when they are older than stale_timeout and their keys are missing from key_source. Run the reproduction in the issue to see that success rows for deleted keys survive refresh(stale_timeout=0). Done means those orphaned success and error rows are removed without waiting for the timeout, while pending rows keep the age check. The issue also offers an alternative change to the meaning of stale_timeout=0, so check with maintainers which one they want.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Description
Summary
With config.jobs.keep_completed = True, a table's jobs table keeps a success record for every computed key. When upstream rows are deleted and the cascade removes the computed rows, their success records stay. jobs.refresh() does not remove them until they are older than stale_timeout (3600 s by default). Passing stale_timeout=0 skips the cleanup entirely instead of forcing it. For up to an hour, then, status counts read from the jobs table overstate what the table holds. Records with status='error' for keys that no longer exist behave the same way.
Reproduction
DataJoint 2.3.5.dev2 (master), MySQL 8.0:
import datajoint as dj
dj.config.jobs.keep_completed = True
schema = dj.Schema("scratch_jobs")
@schema
class Raw(dj.Manual):
definition = """
raw_id : int32
---
v : float32
"""
@schema
class Proc(dj.Computed):
definition = """
-> Raw
---
w : float32
"""
def make(self, key):
self.insert1(dict(key, w=2 * (Raw & key).fetch1("v")))
def counts():
j = Proc.jobs
return {s: len(j & f"status='{s}'") for s in ("pending", "reserved", "success", "error")}
Raw.insert([dict(raw_id=i, v=float(i)) for i in range(3)])
Proc.populate(reserve_jobs=True)
print("after populate:", "rows", len(Proc()), "jobs", counts())
(Raw & "raw_id = 0").delete(prompt=False)
print("after deleting raw_id=0:", "rows", len(Proc()), "key_source", len(Proc.key_source), "jobs", counts())
print("refresh:", Proc.jobs.refresh())
print("refresh(stale_timeout=0):", Proc.jobs.refresh(stale_timeout=0), "jobs", counts())
Output:
after populate: rows 3 jobs {'pending': 0, 'reserved': 0, 'success': 3, 'error': 0}
after deleting raw_id=0: rows 2 key_source 2 jobs {'pending': 0, 'reserved': 0, 'success': 3, 'error': 0}
refresh: {'added': 0, 'removed': 0, 'orphaned': 0, 're_pended': 0}
refresh(stale_timeout=0): {'added': 0, 'removed': 0, 'orphaned': 0, 're_pended': 0} jobs {'pending': 0, 'reserved': 0, 'success': 3, 'error': 0}
Two rows exist and three successes are recorded. After a larger delete (removing a parameter set, say), anything that reports progress from the jobs table shows completed work that no longer exists, for an hour.
Where it comes from
Job.refresh() step 3 removes only records older than stale_timeout whose keys are no longer in key_source. The age condition makes sense for pending records, which can race a key_source that is still being filled, and the setting's description says so: "Seconds before pending job is checked for staleness". It is applied to every status except ignore, though, including success and error. And stale_timeout=0 means "skip this step", so there is no way to request the cleanup now.
Proposal
In refresh(), remove success and error records whose keys are in neither key_source nor the target, regardless of age. Keep the age condition for pending, which it was written for. Neither kind of record describes anything that exists, and neither is retried. Alternatively, make stale_timeout=0 mean "no grace period" rather than "skip", and give the skip its own value (None).
- Langage dominant
- Python
- Étoiles
- 197
- Forks
- 98
- Merge moyen
- 15 h 31 min
- PR mergées (30 j)
- 9
Préparer son environnement
- Fournit un Dockerfile ou un fichier Docker Compose
- Aucun modèle de pull request
- Lire le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Autres issues de datajoint/datajoint-python
-
Difficulté 2/5 1-3 heures Accessibilité débutants 70/100
datajoint/datajoint-python#1581 ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 2/5 1-3 heures Accessibilité débutants 76/100
datajoint/datajoint-python#1539 · 3 commentaires ·
Les mainteneurs répondent en général sous 1 jour
-
_job_start_time records the populating host's local time, with no zonePeut-être pris @dimitri-yatsenko l’a pris aujourd’hui. Ouverte
datajoint/datajoint-python#1584 · 1 personne assignée ·
Les mainteneurs répondent en général sous 1 jour
-
database.name should namespace schema names on MySQL, as it does on PostgreSQLPeut-être pris @dimitri-yatsenko l’a pris il y a 3 jours. Ouvertefeature
Difficulté 4/5 3-5 jours Accessibilité débutants 15/100
datajoint/datajoint-python#1582 ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 3/5 1-2 jours Accessibilité débutants 40/100
datajoint/datajoint-python#1580 ·
Les mainteneurs répondent en général sous 1 jour
Toutes les issues de datajoint/datajoint-python
Issues similaires
-
bug
Difficulté 1/5 Moins d'une heure Accessibilité débutants 88/100
openwisp/openwisp-utils#777 ·
-
Boolean statistics (Covered, Confident, JaccardDistant) aggregate to 1.0 without float weightsOuverte
Difficulté 2/5 1-3 heures Accessibilité débutants 63/100
google-research/weatherbenchX#310 ·
Les mainteneurs répondent en général sous 3 jours
-
Difficulté 2/5 1-3 heures Accessibilité débutants 78/100
huggingface/peft#3955 ·
Les mainteneurs répondent en général sous 1 jour
-
author-page correction
Difficulté 2/5 1-3 heures Accessibilité débutants 60/100
acl-org/acl-anthology#10313 ·
Les mainteneurs répondent en général sous 1 jour
-
bug
Difficulté 2/5 1-3 heures Accessibilité débutants 76/100
AOSSIE-Org/Gitcord-GithubDiscordBot#147 · 1 commentaire ·
Les mainteneurs répondent en général sous 1 jour