• A daemon process class in python


    In everbright task schedule project, we need some daemon process to do certain work, here is a example of daemon class:

      1 #encoding=utf-8
      2 #!/usr/bin/env python
      3 
      4 import sys, os, time, atexit
      5 from signal import SIGTERM 
      6 Basedir='/home/ronglian/project/taskschedule'
      7 class Daemon:
      8     """
      9     A generic daemon class.
     10     
     11     Usage: subclass the Daemon class and override the run() method
     12     """
     13     def __init__(self, pidfile, stderr=Basedir+'/logs/deamon_err.log', stdout=Basedir+'/logs/deamon_out.log', stdin='/dev/null'):
     14         self.stdin = stdin
     15         self.stdout = stdout
     16         self.stderr = stderr
     17         self.pidfile = pidfile
     18     
     19     def daemonize(self):
     20         """
     21         do the UNIX double-fork magic, see Stevens' "Advanced 
     22         Programming in the UNIX Environment" for details (ISBN 0201563177)
     23         http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16
     24         """
     25         try: 
     26             pid = os.fork() 
     27             if pid > 0:
     28                 # exit first parent
     29                 sys.exit(0) 
     30         except OSError, e: 
     31             sys.stderr.write("fork #1 failed: %d (%s)
    " % (e.errno, e.strerror))
     32             sys.exit(1)
     33     
     34         # decouple from parent environment
     35         os.chdir("/") 
     36         os.setsid() 
     37         os.umask(0) 
     38     
     39         # do second fork
     40         try: 
     41             pid = os.fork() 
     42             if pid > 0:
     43                 # exit from second parent
     44                 sys.exit(0) 
     45         except OSError, e: 
     46             sys.stderr.write("fork #2 failed: %d (%s)
    " % (e.errno, e.strerror))
     47             sys.exit(1) 
     48     
     49         # redirect standard file descriptors
     50         sys.stdout.flush()
     51         sys.stderr.flush()
     52         si = file(self.stdin, 'r')
     53         so = file(self.stdout, 'a+')
     54         se = file(self.stderr, 'a+', 0)
     55         os.dup2(si.fileno(), sys.stdin.fileno())
     56         os.dup2(so.fileno(), sys.stdout.fileno())
     57         os.dup2(se.fileno(), sys.stderr.fileno())
     58     
     59         # write pidfile
     60         atexit.register(self.delpid)
     61         pid = str(os.getpid())
     62         file(self.pidfile,'w+').write("%s
    " % pid)
     63     
     64     def delpid(self):
     65         os.remove(self.pidfile)
     66 
     67     def start(self):
     68         """
     69         Start the daemon
     70         """
     71         # Check for a pidfile to see if the daemon already runs
     72         try:
     73             pf = file(self.pidfile,'r')
     74             pid = int(pf.read().strip())
     75             pf.close()
     76         except IOError:
     77             pid = None
     78     
     79         if pid:
     80             message = "pidfile %s already exist. Daemon already running?
    "
     81             sys.stderr.write(message % self.pidfile)
     82             sys.exit(1)
     83         
     84         # Start the daemon
     85         self.daemonize()
     86         self.run()
     87 
     88     def stop(self):
     89         """
     90         Stop the daemon
     91         """
     92         # Get the pid from the pidfile
     93         try:
     94             pf = file(self.pidfile,'r')
     95             pid = int(pf.read().strip())
     96             pf.close()
     97         except IOError:
     98             pid = None
     99     
    100         if not pid:
    101             message = "pidfile %s does not exist. Daemon not running?
    "
    102             sys.stderr.write(message % self.pidfile)
    103             return # not an error in a restart
    104 
    105         # Try killing the daemon process    
    106         try:
    107             while 1:
    108                 os.kill(pid, SIGTERM)
    109                 time.sleep(0.1)
    110         except OSError, err:
    111             err = str(err)
    112             if err.find("No such process") > 0:
    113                 if os.path.exists(self.pidfile):
    114                     os.remove(self.pidfile)
    115             else:
    116                 print str(err)
    117                 sys.exit(1)
    118 
    119     def restart(self):
    120         """
    121         Restart the daemon
    122         """
    123         self.stop()
    124         self.start()
    125 
    126     def run(self):
    127         """
    128         You should override this method when you subclass Daemon. It will be called after the process has been
    129         daemonized by start() or restart().
    130         """

    Here is a example how to use the class, need to rewrite the run function in parent calss:

     1 #encoding=utf-8
     2 
     3 import sys, time
     4 from daemon import Daemon
     5 import dbaction
     6 import Task
     7 import getdependency
     8 from  tslogging import GlobalLogging as Logging
     9 
    10 class sys_sync_task_mgr(Daemon):
    11     def __init__(self,temppath,starttime,frequency):
    12         Daemon.__init__(self,temppath)
    13         self.starttime = starttime
    14         self.frequency = frequency
    15 
    16     def run(self):
    17 
    18         
    19         while True:
    20             tasknolist= self.get_task_list()
    21             
    22             if len(tasknolist['sys_task']) > 0:
    23                 if time.ctime()>self.starttime:
    24                     Logging.getLog().info('Available system task list:%s'%(str(tasknolist['sys_task'])))
    25                     try:
    26                         for taskno in tasknolist['sys_task']:
    27                             Logging.getLog().info('Start running system task:%s'%str(taskno))
    28                             task = Task.sys_sync_task(taskno)
    29                             task.task_run()
    30                     except Exception, ex:
    31                         print 'hello'
    32                         Logging.getLog().error( "Exception in class: 'sys_sync_task_mgr' function:'run' :"+str(ex))
    33                 else:
    34                     print 'hello'
    35                     Logging.getLog().warn('Time to run the tasks still not reach.')
    36             time.sleep(self.frequency)
    37     def get_task_list(self):
    38         tasklist = getdependency.task_dependency([],3,1).get_executable_task()
    39         return tasklist
    40 
    41 #main function        
    42 if __name__ == "__main__":
    43     daemon = sys_sync_task_mgr('/tmp/daemon_sys_sync_task_mgr.pid',time.ctime(),20)
    44     if len(sys.argv) == 2:
    45         if 'start' == sys.argv[1]:
    46             daemon.start()
    47         elif 'stop' == sys.argv[1]:
    48             daemon.stop()
    49         elif 'restart' == sys.argv[1]:
    50             daemon.restart()
    51         else:
    52             print "Unknown command"
    53             sys.exit(2)
    54         sys.exit(0)
    55     else:
    56         print "usage: %s start|stop|restart" % sys.argv[0]
    57         sys.exit(2)
  • 相关阅读:
    mock static方法
    Spring Boot 例一 实现jsonp接口
    安装Linux虚拟机到执行Java程序
    Mock单元测试
    通用分页请求返回类
    Collectors.groupingBy分组后的排序问题
    按权重分配任务
    Java正则表达式-捕获组
    远程抓取图片
    正则
  • 原文地址:https://www.cnblogs.com/allenz/p/4756111.html
Copyright © 2020-2023  润新知