Don't concurrently delete unrendered timelapses
Could trigger lots of errors if an unrendered timelapse currently being collected was deleted from a separate thread from right under the collection thread. Also only log errors while processing already deleted files if debug logging is enabled. Finally trigger MovieDone event AFTER deleting unrendered files (otherwise just rendered timelapse might still be present when list of timelapses is queried right after). Should solve #1326
This commit is contained in:
parent
51a1953d99
commit
21a4033f73
1 changed files with 38 additions and 25 deletions
|
|
@ -44,6 +44,9 @@ _valid_timelapse_types = ["off", "timed", "zchange"]
|
|||
# callbacks for timelapse config updates
|
||||
_update_callbacks = []
|
||||
|
||||
# lock for timelapse cleanup, must be re-entrant
|
||||
_cleanup_lock = threading.RLock()
|
||||
|
||||
|
||||
def _extract_prefix(filename):
|
||||
"""
|
||||
|
|
@ -103,13 +106,17 @@ def get_unrendered_timelapses():
|
|||
|
||||
|
||||
def delete_unrendered_timelapse(name):
|
||||
global _cleanup_lock
|
||||
|
||||
basedir = settings().getBaseFolder("timelapse_tmp")
|
||||
for filename in os.listdir(basedir):
|
||||
try:
|
||||
if fnmatch.fnmatch(filename, "{}*.jpg".format(name)):
|
||||
os.remove(os.path.join(basedir, filename))
|
||||
except:
|
||||
logging.getLogger(__name__).exception("Error while processing file {} during cleanup".format(filename))
|
||||
with _cleanup_lock:
|
||||
for filename in os.listdir(basedir):
|
||||
try:
|
||||
if fnmatch.fnmatch(filename, "{}*.jpg".format(name)):
|
||||
os.remove(os.path.join(basedir, filename))
|
||||
except:
|
||||
if logging.getLogger(__name__).isEnabledFor(logging.DEBUG):
|
||||
logging.getLogger(__name__).exception("Error while processing file {} during cleanup".format(filename))
|
||||
|
||||
|
||||
def render_unrendered_timelapse(name, gcode=None, postfix=None, fps=25):
|
||||
|
|
@ -131,33 +138,39 @@ def render_unrendered_timelapse(name, gcode=None, postfix=None, fps=25):
|
|||
|
||||
|
||||
def delete_old_unrendered_timelapses():
|
||||
global _cleanup_lock
|
||||
|
||||
basedir = settings().getBaseFolder("timelapse_tmp")
|
||||
clean_after_days = settings().getInt(["webcam", "cleanTmpAfterDays"])
|
||||
cutoff = time.time() - clean_after_days * 24 * 60 * 60
|
||||
|
||||
prefixes_to_clean = []
|
||||
for filename in os.listdir(basedir):
|
||||
try:
|
||||
path = os.path.join(basedir, filename)
|
||||
|
||||
prefix = _extract_prefix(filename)
|
||||
if prefix is None:
|
||||
# might be an old tmp_00000.jpg kinda frame. we can't
|
||||
# render those easily anymore, so delete that stuff
|
||||
if _old_capture_format_re.match(filename):
|
||||
os.remove(path)
|
||||
continue
|
||||
with _cleanup_lock:
|
||||
for filename in os.listdir(basedir):
|
||||
try:
|
||||
path = os.path.join(basedir, filename)
|
||||
|
||||
if prefix in prefixes_to_clean:
|
||||
continue
|
||||
prefix = _extract_prefix(filename)
|
||||
if prefix is None:
|
||||
# might be an old tmp_00000.jpg kinda frame. we can't
|
||||
# render those easily anymore, so delete that stuff
|
||||
if _old_capture_format_re.match(filename):
|
||||
os.remove(path)
|
||||
continue
|
||||
|
||||
if os.path.getmtime(path) < cutoff:
|
||||
prefixes_to_clean.append(prefix)
|
||||
except:
|
||||
logging.getLogger(__name__).exception("Error while processing file {} during cleanup".format(filename))
|
||||
if prefix in prefixes_to_clean:
|
||||
continue
|
||||
|
||||
for prefix in prefixes_to_clean:
|
||||
delete_unrendered_timelapse(prefix)
|
||||
if os.path.getmtime(path) < cutoff:
|
||||
prefixes_to_clean.append(prefix)
|
||||
except:
|
||||
if logging.getLogger(__name__).isEnabledFor(logging.DEBUG):
|
||||
logging.getLogger(__name__).exception("Error while processing file {} during cleanup".format(filename))
|
||||
|
||||
for prefix in prefixes_to_clean:
|
||||
delete_unrendered_timelapse(prefix)
|
||||
logging.getLogger(__name__).info("Deleted old unrendered timelapse {}".format(prefix))
|
||||
|
||||
|
||||
def _create_render_start_handler(name, gcode=None):
|
||||
|
|
@ -173,11 +186,11 @@ def _create_render_start_handler(name, gcode=None):
|
|||
|
||||
def _create_render_success_handler(name, gcode=None):
|
||||
def f(movie):
|
||||
delete_unrendered_timelapse(name)
|
||||
event_payload = {"gcode": gcode if gcode is not None else "unknown",
|
||||
"movie": movie,
|
||||
"movie_basename": os.path.basename(movie)}
|
||||
eventManager().fire(Events.MOVIE_DONE, event_payload)
|
||||
delete_unrendered_timelapse(name)
|
||||
return f
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue