Wednesday, December 25, 2013

Development Server: Automatic Reload on Code Change

There are actually many ways of automatically reloading code when it is modified.  Some are platform/language specific and some are not, although they do depend on certain common behaviors.  This is one I'm using to develop my Python/Gunicorn application and it isn't specific to Python or Gunicorn; however it does require that you have inotify-tools installed, your server can run in the foreground and that it reloads the project when it receives a SIGHUP signal.

wrapper:

#!/bin/sh

SERVER=$1
WATCHED_DIR=.
$SERVER &
RUNNING_PID=$!

trap 'kill -TERM $RUNNING_PID 2> /dev/null; exit' SIGINT

while /bin/true; do
 echo "Starting '$SERVER'..."
 inotifywait -q --exclude '.*\.py[co]$' \
           -e modify -e close_write -e move \
           -e create -e delete \
           -r $WATCHED_DIR
 kill -HUP $RUNNING_PID
 echo "Hupping '$SERVER'..."
done



You can then call it like this:

wrapper 'gunicorn project:main'

This will watch the current directory your in '.' and anytime a modification, creation, deletion or move occurs on any file in the current directory, inotify will issue the notification and stop waiting.  This will cause kill to send a SIGHUP to the the server forcing it to reload the project.  inotify will then wait on the next filesystem event.

 

Variants/Alternatives

 

There are a few variations on this theme which are fairly simple.

  • If you must kill and then restart the process in order to reload you can move the execution of $SERVER & into the while loop.  You should also change the HUP to a TERM in this case to make sure the process is terminated.
  • If you need to reload when anything changes in multiple directories you can just append the full list to inotifywait or generalize the wrapper and take the directories to watch as an argument.
  • If you want to or have to use something different from inotify-tools you can.  This same process should be usable by any of the file system event notification frameworks as long as the have a script that waits on events or allows you to write a script that waits on event.

§