# # # patch "ChangeLog" # from [e7a6f81345bf185e0d0d0881a81e5f3ace88d5f5] # to [c28aa2d4f7e593f1ec364eac9225f0312f00441d] # # patch "mtn.py" # from [10bae73eaa4b6b891d434bfcffa8ca66968b204b] # to [0d4cebb009164df2416ea03172a37654f5c95f69] # # patch "viewmtn.py" # from [159580044206e361ce64df05991673365ca0deab] # to [98f47f0cb6a2e5a78413850f6c0015ba3d3f16bd] # ============================================================ --- ChangeLog e7a6f81345bf185e0d0d0881a81e5f3ace88d5f5 +++ ChangeLog c28aa2d4f7e593f1ec364eac9225f0312f00441d @@ -1,5 +1,11 @@ 2007-03-30 Grahame Bowland
+ * in Automate, check per request with stat to see if the + database has changed. If so, stop the automate process - + it'll be restarted when the next request comes along anyway. + +2007-03-30 Grahame Bowland + * add new branch tag view, showing all tags on a given branch ============================================================ --- mtn.py 10bae73eaa4b6b891d434bfcffa8ca66968b204b +++ mtn.py 0d4cebb009164df2416ea03172a37654f5c95f69 @@ -43,8 +43,9 @@ class Author(str): str.__init__(v) self.obj_type = "author" -class Runner: +class Runner(object): def __init__(self, monotone, database): + self.database = database self.base_command = [monotone, "--db=%s" % pipes.quote(database)] packet_header_re = re.compile(r'^(\d+):(\d+):([lm]):(\d+):') @@ -63,17 +64,27 @@ class Automate(Runner): Runner.__init__(*[self] + list(args), **kwargs) self.lock = threading.Lock() self.process = None + self.running_mtime = None def stop(self): if not self.process: return terminate_popen3(self.process) self.process = None + + def database_mtime(self): + return os.stat(self.database).st_mtime + + def check_current(self): + if self.process != None and self.database_mtime() > self.running_mtime: + debug("stopped process, database has changed.") + self.stop() def __process_required(self): if self.process != None: return to_run = self.base_command + ['automate', 'stdio'] + self.running_mtime = self.database_mtime() self.process = popen2.Popen3(to_run, capturestderr=True) map (set_nonblocking, [ self.process.fromchild, self.process.tochild, @@ -335,7 +346,13 @@ class Operations: def __init__(self, runner_args): self.standalone = apply(Standalone, runner_args) self.automate = apply(Automate, runner_args) - + + def per_request(self): + """"Call this method every distinct request, to allow Operations to do any + cleanup operations. + """ + self.automate.check_current() + def tags(self): for stanza in basic_io_from_stream(self.automate.run('tags', [])): if stanza[0] == 'tag': ============================================================ --- viewmtn.py 159580044206e361ce64df05991673365ca0deab +++ viewmtn.py 98f47f0cb6a2e5a78413850f6c0015ba3d3f16bd @@ -314,6 +314,10 @@ class Renderer: self._templates_loaded = True def render(self, template, **kwargs): + # technically it'd be better to do this before serving the + # request, however this is about the only per-request + # spot that runs for every handler.. + ops.per_request() self.load_templates() terms = self.terms.copy() terms.update(kwargs)