~mnordhoff/loggerhead/cheezum

« back to all changes in this revision

Viewing changes to loggerhead/util.py

  • Committer: Guillermo Gonzalez
  • Date: 2008-09-10 23:12:59 UTC
  • mfrom: (164.18.30 trunk)
  • mto: (164.35.3 trunk)
  • mto: This revision was merged to the branch mainline in revision 242.
  • Revision ID: guillo.gonzo@gmail.com-20080910231259-4wnfmu30f4n90w6x
 * merge with trunk (resolve conflicts in NEWS and serve-branches)

Show diffs side-by-side

added added

removed removed

Lines of Context:
32
32
import struct
33
33
import threading
34
34
import time
35
 
 
 
35
import sys
 
36
import os
 
37
import subprocess
36
38
 
37
39
log = logging.getLogger("loggerhead.controllers")
38
40
 
510
512
    overrides = dict((k, v) for (k, v) in overrides.iteritems() if k in _valid)
511
513
    map.update(overrides)
512
514
    return map
 
515
 
 
516
 
 
517
class Reloader(object):
 
518
    """
 
519
    This class wraps all paste.reloader logic. All methods are @classmethod.
 
520
    """
 
521
 
 
522
    _reloader_environ_key = 'PYTHON_RELOADER_SHOULD_RUN'
 
523
 
 
524
    @classmethod
 
525
    def _turn_sigterm_into_systemexit(self):
 
526
        """
 
527
        Attempts to turn a SIGTERM exception into a SystemExit exception.
 
528
        """
 
529
        try:
 
530
            import signal
 
531
        except ImportError:
 
532
            return
 
533
        def handle_term(signo, frame):
 
534
            raise SystemExit
 
535
        signal.signal(signal.SIGTERM, handle_term)
 
536
 
 
537
    @classmethod
 
538
    def is_installed(self):
 
539
        return os.environ.get(self._reloader_environ_key)
 
540
    
 
541
    @classmethod
 
542
    def install(self):
 
543
        from paste import reloader
 
544
        reloader.install(int(1))
 
545
    
 
546
    @classmethod    
 
547
    def restart_with_reloader(self):
 
548
        """Based on restart_with_monitor from paste.script.serve."""
 
549
        print 'Starting subprocess with file monitor'
 
550
        while 1:
 
551
            args = [sys.executable] + sys.argv
 
552
            new_environ = os.environ.copy()
 
553
            new_environ[self._reloader_environ_key] = 'true'
 
554
            proc = None
 
555
            try:
 
556
                try:
 
557
                    self._turn_sigterm_into_systemexit()
 
558
                    proc = subprocess.Popen(args, env=new_environ)
 
559
                    exit_code = proc.wait()
 
560
                    proc = None
 
561
                except KeyboardInterrupt:
 
562
                    print '^C caught in monitor process'
 
563
                    return 1
 
564
            finally:
 
565
                if (proc is not None
 
566
                    and hasattr(os, 'kill')):
 
567
                    import signal
 
568
                    try:
 
569
                        os.kill(proc.pid, signal.SIGTERM)
 
570
                    except (OSError, IOError):
 
571
                        pass
 
572
                
 
573
            # Reloader always exits with code 3; but if we are
 
574
            # a monitor, any exit code will restart
 
575
            if exit_code != 3:
 
576
                return exit_code
 
577
            print '-'*20, 'Restarting', '-'*20