root/galaxy-central/eggs/Paste-1.6-py2.6.egg/paste/reloader.py @ 3

リビジョン 3, 3.5 KB (コミッタ: kohda, 14 年 前)

Install Unix tools  http://hannonlab.cshl.edu/galaxy_unix_tools/galaxy.html

行番号 
1# (c) 2005 Ian Bicking and contributors; written for Paste (http://pythonpaste.org)
2# Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
3"""
4A file monitor and server restarter.
5
6Use this like:
7
8..code-block:: Python
9
10    import reloader
11    reloader.install()
12
13Then make sure your server is installed with a shell script like::
14
15    err=3
16    while test "$err" -eq 3 ; do
17        python server.py
18        err="$?"
19    done
20
21or is run from this .bat file (if you use Windows)::
22
23    @echo off
24    :repeat
25        python server.py
26    if %errorlevel% == 3 goto repeat
27
28or run a monitoring process in Python (``paster serve --reload`` does
29this).  Use the watch_file(filename) function to cause a
30reload/restart for other other non-Python files (e.g., configuration
31files).
32"""
33
34import os
35import sys
36import time
37import threading
38from paste.util.classinstance import classinstancemethod
39
40def install(poll_interval=1):
41    """
42    Install the reloading monitor.
43
44    On some platforms server threads may not terminate when the main
45    thread does, causing ports to remain open/locked.  The
46    ``raise_keyboard_interrupt`` option creates a unignorable signal
47    which causes the whole application to shut-down (rudely).
48    """
49    mon = Monitor(poll_interval=poll_interval)
50    t = threading.Thread(target=mon.periodic_reload)
51    t.setDaemon(True)
52    t.start()
53
54class Monitor(object):
55
56    instances = []
57    global_extra_files = []
58
59    def __init__(self, poll_interval):
60        self.module_mtimes = {}
61        self.keep_running = True
62        self.poll_interval = poll_interval
63        self.extra_files = self.global_extra_files[:]
64        self.instances.append(self)
65
66    def periodic_reload(self):
67        while 1:
68            if not self.check_reload():
69                # use os._exit() here and not sys.exit() since within a
70                # thread sys.exit() just closes the given thread and
71                # won't kill the process; note os._exit does not call
72                # any atexit callbacks, nor does it do finally blocks,
73                # flush open files, etc.  In otherwords, it is rude.
74                os._exit(3)
75                break
76            time.sleep(self.poll_interval)
77
78    def check_reload(self):
79        filenames = self.extra_files[:]
80        for module in sys.modules.values():
81            try:
82                filenames.append(module.__file__)
83            except AttributeError:
84                continue
85        for filename in filenames:
86            try:
87                stat = os.stat(filename)
88                if stat:
89                    mtime = stat.st_mtime
90                else:
91                    mtime = 0
92            except (OSError, IOError):
93                continue
94            if filename.endswith('.pyc') and os.path.exists(filename[:-1]):
95                mtime = max(os.stat(filename[:-1]).st_mtime, mtime)
96            if not self.module_mtimes.has_key(filename):
97                self.module_mtimes[filename] = mtime
98            elif self.module_mtimes[filename] < mtime:
99                print >> sys.stderr, (
100                    "%s changed; reloading..." % filename)
101                return False
102        return True
103
104    def watch_file(self, cls, filename):
105        filename = os.path.abspath(filename)
106        if self is None:
107            for instance in cls.instances:
108                instance.watch_file(filename)
109            cls.global_extra_files.append(filename)
110        else:
111            self.extra_files.append(filename)
112
113    watch_file = classinstancemethod(watch_file)
114
115watch_file = Monitor.watch_file
Note: リポジトリブラウザについてのヘルプは TracBrowser を参照してください。