Skip to content

Commit

Permalink
Add instant autoreload on platforms supporting kqueue.
Browse files Browse the repository at this point in the history
  • Loading branch information
aaugustin committed Oct 30, 2013
1 parent 8faaf03 commit 8f09ec6
Showing 1 changed file with 45 additions and 0 deletions.
45 changes: 45 additions & 0 deletions django/utils/autoreload.py
Expand Up @@ -65,6 +65,16 @@
except ImportError: except ImportError:
pass pass


try:
import select
select.kevent, select.kqueue
USE_KQUEUE = True

import resource
NOFILES_SOFT, NOFILES_HARD = resource.getrlimit(resource.RLIMIT_NOFILE)
except AttributeError:
USE_KQUEUE = False

RUN_RELOADER = True RUN_RELOADER = True


_mtimes = {} _mtimes = {}
Expand Down Expand Up @@ -119,6 +129,39 @@ def update_watch(sender=None, **kwargs):
# If we are here the code must have changed. # If we are here the code must have changed.
return True return True


def kqueue_code_changed():
"""
Checks for changed code using kqueue. After being called
it blocks until a change event has been fired.
"""
# Maximum number of open file descriptors is typically too low (256).
filenames = list(gen_filenames())
resource.setrlimit(resource.RLIMIT_NOFILE,
(NOFILES_SOFT + len(filenames), NOFILES_HARD))

kqueue = select.kqueue()
fds = [open(filename) for filename in filenames]

_filter = select.KQ_FILTER_VNODE
flags = select.KQ_EV_ADD
fflags = (
select.KQ_NOTE_DELETE |
select.KQ_NOTE_WRITE |
select.KQ_NOTE_EXTEND |
select.KQ_NOTE_ATTRIB |
select.KQ_NOTE_LINK |
select.KQ_NOTE_RENAME |
select.KQ_NOTE_REVOKE
)
kevents = [select.kevent(fd, _filter, flags, fflags) for fd in fds]
kqueue.control(kevents, 1)

for fd in fds:
fd.close()
kqueue.close()

return True

def code_changed(): def code_changed():
global _mtimes, _win global _mtimes, _win
for filename in gen_filenames(): for filename in gen_filenames():
Expand Down Expand Up @@ -178,6 +221,8 @@ def reloader_thread():
ensure_echo_on() ensure_echo_on()
if USE_INOTIFY: if USE_INOTIFY:
fn = inotify_code_changed fn = inotify_code_changed
elif USE_KQUEUE:
fn = kqueue_code_changed
else: else:
fn = code_changed fn = code_changed
while RUN_RELOADER: while RUN_RELOADER:
Expand Down

0 comments on commit 8f09ec6

Please sign in to comment.