Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F91489140
wsgi_reload.py
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Mon, Nov 11, 15:09
Size
3 KB
Mime Type
text/x-python
Expires
Wed, Nov 13, 15:09 (2 d)
Engine
blob
Format
Raw Data
Handle
22270272
Attached To
R3600 invenio-infoscience
wsgi_reload.py
View Options
# This file is part of Invenio.
# Copyright (C) 2011 CERN.
#
# Invenio is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of the
# License, or (at your option) any later version.
#
# Invenio is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Invenio; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
from
__future__
import
print_function
"""
Invenio utility to monitor and automatically reload modules when edits
are done in-live.
This module was inspired by examples from: http://code.google.com/p/modwsgi/wiki/ReloadingSourceCode
(C) Graham Dumpleton
"""
import
os
import
sys
import
time
import
signal
import
threading
import
atexit
import
Queue
_interval
=
1.0
_times
=
{}
_files
=
[]
_running
=
False
_queue
=
Queue
.
Queue
()
_lock
=
threading
.
Lock
()
def
_restart
(
path
):
_queue
.
put
(
True
)
prefix
=
'monitor (pid=
%d
):'
%
os
.
getpid
()
print
(
'
%s
Change detected to
\'
%s
\'
.'
%
(
prefix
,
path
),
file
=
sys
.
stderr
)
print
(
'
%s
Triggering process restart.'
%
prefix
,
file
=
sys
.
stderr
)
os
.
kill
(
os
.
getpid
(),
signal
.
SIGINT
)
def
_modified
(
path
):
try
:
# If path doesn't denote a file and were previously
# tracking it, then it has been removed or the file type
# has changed so force a restart. If not previously
# tracking the file then we can ignore it as probably
# pseudo reference such as when file extracted from a
# collection of modules contained in a zip file.
if
not
os
.
path
.
isfile
(
path
):
return
path
in
_times
# Check for when file last modified.
mtime
=
os
.
stat
(
path
)
.
st_mtime
if
path
not
in
_times
:
_times
[
path
]
=
mtime
# Force restart when modification time has changed, even
# if time now older, as that could indicate older file
# has been restored.
if
mtime
!=
_times
[
path
]:
return
True
except
:
# If any exception occured, likely that file has been
# been removed just before stat(), so force a restart.
return
True
return
False
def
_monitor
():
while
1
:
# Check modification times on all files in sys.modules.
for
module
in
sys
.
modules
.
values
():
if
not
hasattr
(
module
,
'__file__'
):
continue
path
=
getattr
(
module
,
'__file__'
)
if
not
path
:
continue
if
os
.
path
.
splitext
(
path
)[
1
]
in
[
'.pyc'
,
'.pyo'
,
'.pyd'
]:
path
=
path
[:
-
1
]
if
_modified
(
path
):
return
_restart
(
path
)
# Check modification times on files which have
# specifically been registered for monitoring.
for
path
in
_files
:
if
_modified
(
path
):
return
_restart
(
path
)
# Go to sleep for specified interval.
try
:
return
_queue
.
get
(
timeout
=
_interval
)
except
:
pass
_thread
=
threading
.
Thread
(
target
=
_monitor
)
_thread
.
setDaemon
(
True
)
def
_exiting
():
try
:
_queue
.
put
(
True
)
except
:
pass
_thread
.
join
()
atexit
.
register
(
_exiting
)
def
track
(
path
):
if
not
path
in
_files
:
_files
.
append
(
path
)
def
start
(
interval
=
1.0
):
global
_interval
if
interval
<
_interval
:
_interval
=
interval
global
_running
_lock
.
acquire
()
if
not
_running
:
prefix
=
'monitor (pid=
%d
):'
%
os
.
getpid
()
print
(
'
%s
Starting change monitor.'
%
prefix
,
file
=
sys
.
stderr
)
_running
=
True
_thread
.
start
()
_lock
.
release
()
Event Timeline
Log In to Comment