MCPcopy Create free account
hub / github.com/datapane/datapane / FileCheckerThread

Class FileCheckerThread

python-client/src/datapane/_vendor/bottle.py:3738–3777  ·  view source on GitHub ↗

Interrupt main-thread as soon as a changed module file is detected, the lockfile gets deleted or gets too old.

Source from the content-addressed store, hash-verified

3736
3737
3738class FileCheckerThread(threading.Thread):
3739 """ Interrupt main-thread as soon as a changed module file is detected,
3740 the lockfile gets deleted or gets too old. """
3741
3742 def __init__(self, lockfile, interval):
3743 threading.Thread.__init__(self)
3744 self.daemon = True
3745 self.lockfile, self.interval = lockfile, interval
3746 #: Is one of 'reload', 'error' or 'exit'
3747 self.status = None
3748
3749 def run(self):
3750 exists = os.path.exists
3751 mtime = lambda p: os.stat(p).st_mtime
3752 files = dict()
3753
3754 for module in list(sys.modules.values()):
3755 path = getattr(module, '__file__', '') or ''
3756 if path[-4:] in ('.pyo', '.pyc'): path = path[:-1]
3757 if path and exists(path): files[path] = mtime(path)
3758
3759 while not self.status:
3760 if not exists(self.lockfile)\
3761 or mtime(self.lockfile) < time.time() - self.interval - 5:
3762 self.status = 'error'
3763 thread.interrupt_main()
3764 for path, lmtime in list(files.items()):
3765 if not exists(path) or mtime(path) > lmtime:
3766 self.status = 'reload'
3767 thread.interrupt_main()
3768 break
3769 time.sleep(self.interval)
3770
3771 def __enter__(self):
3772 self.start()
3773
3774 def __exit__(self, exc_type, *_):
3775 if not self.status: self.status = 'exit' # silent exit
3776 self.join()
3777 return exc_type is not None and issubclass(exc_type, KeyboardInterrupt)
3778
3779###############################################################################
3780# Template Adapters ############################################################

Callers 1

runFunction · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected