4343_log .setLevel (logging .DEBUG )
4444
4545
46+ # Absolute path on this worker's system where local repos may be created
47+ local_repos = os .environ .get ("LOCAL_REPOS" , "/tmp" )
48+
49+
4650class LocalRepoTracker :
4751 """A mapping of process IDs to repo locations.
4852
@@ -56,7 +60,10 @@ class LocalRepoTracker:
5660 """
5761 _instance : typing .Self | None = None
5862
59- _BACKEND_FILE = os .path .join (os .path .expanduser ("~" ), ".repo.tracker.csv" )
63+ # Temp space is guaranteed to be in persistent storage (local disk
64+ # in unit tests, ephemeral in container). The same is NOT true for
65+ # ~ or /app.
66+ _BACKEND_FILE = os .path .join (local_repos , ".repo.tracker.csv" )
6067
6168 @staticmethod
6269 def get () -> typing .Self :
@@ -71,19 +78,46 @@ def init_tracker(self):
7178 This method should be called by the parent process of any processes
7279 that will use the tracker, or at least a process that is guaranteed
7380 to outlast the client processes.
81+
82+ Return
83+ ------
84+ old_repos : collection [`str`]
85+ The contents of any pre-existing registry.
7486 """
75- with self ._open_exclusive (self ._BACKEND_FILE , mode = "x" ) as f :
76- self ._write_data (f , {})
77- _log .info ("Local repo tracker is ready for use." )
87+ try :
88+ with self ._open_exclusive (self ._BACKEND_FILE , mode = "x" ) as f :
89+ self ._write_data (f , {})
90+ return set ()
91+ except FileExistsError :
92+ # Don't log a stack trace, because this is likely to be called from
93+ # a non-JSON logger.
94+ with self ._open_exclusive (self ._BACKEND_FILE , mode = "r+" ) as f :
95+ data = self ._read_data (f )
96+ self ._write_data (f , {})
97+ _log .warning ("Dangling repo registry found with the following repos: %s" , data .values ())
98+ return data .values ()
99+ finally :
100+ _log .info ("Local repo tracker is ready for use." )
78101
79102 def cleanup_tracker (self ):
80103 """Remove the tracker and delete all state.
104+
105+ Return
106+ ------
107+ repos : collection [`str`]
108+ The (hopefully empty) set of repos that were still registered.
81109 """
82110 try :
111+ with self ._open_exclusive (self ._BACKEND_FILE , mode = "r" ) as f :
112+ data = self ._read_data (f )
113+ repos = data .values ()
83114 os .remove (self ._BACKEND_FILE )
84115 except FileNotFoundError :
85- pass
116+ repos = set ()
86117 _log .info ("Local repo tracker has been cleaned up." )
118+ if repos :
119+ _log .warning ("The following repos were still registered: %s" , repos )
120+ return repos
87121
88122 @staticmethod
89123 @contextlib .contextmanager
0 commit comments