Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/cmdutil.py @ 30515:d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
And call it runservice() because I'll soon add createservice().
The main reason I'm going to introduce the 'server' module is to solve
future dependency cycle between chgserver.py and commandserver.py.
The 'server' module sits at the same layer as the cmdutil. I believe it's
generally good to get rid of things from the big cmdutil module.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Sat, 15 Oct 2016 13:47:43 +0900 |
parents | 002fa4d79466 |
children | 20a42325fdef |
comparison
equal
deleted
inserted
replaced
30514:158b41842fd2 | 30515:d9d8d78e6bc9 |
---|---|
8 from __future__ import absolute_import | 8 from __future__ import absolute_import |
9 | 9 |
10 import errno | 10 import errno |
11 import os | 11 import os |
12 import re | 12 import re |
13 import sys | |
14 import tempfile | 13 import tempfile |
15 | 14 |
16 from .i18n import _ | 15 from .i18n import _ |
17 from .node import ( | 16 from .node import ( |
18 bin, | 17 bin, |
818 | 817 |
819 if errors: | 818 if errors: |
820 ui.warn(_('(consider using --after)\n')) | 819 ui.warn(_('(consider using --after)\n')) |
821 | 820 |
822 return errors != 0 | 821 return errors != 0 |
823 | |
824 def service(opts, parentfn=None, initfn=None, runfn=None, logfile=None, | |
825 runargs=None, appendpid=False): | |
826 '''Run a command as a service.''' | |
827 | |
828 def writepid(pid): | |
829 if opts['pid_file']: | |
830 if appendpid: | |
831 mode = 'a' | |
832 else: | |
833 mode = 'w' | |
834 fp = open(opts['pid_file'], mode) | |
835 fp.write(str(pid) + '\n') | |
836 fp.close() | |
837 | |
838 if opts['daemon'] and not opts['daemon_postexec']: | |
839 # Signal child process startup with file removal | |
840 lockfd, lockpath = tempfile.mkstemp(prefix='hg-service-') | |
841 os.close(lockfd) | |
842 try: | |
843 if not runargs: | |
844 runargs = util.hgcmd() + sys.argv[1:] | |
845 runargs.append('--daemon-postexec=unlink:%s' % lockpath) | |
846 # Don't pass --cwd to the child process, because we've already | |
847 # changed directory. | |
848 for i in xrange(1, len(runargs)): | |
849 if runargs[i].startswith('--cwd='): | |
850 del runargs[i] | |
851 break | |
852 elif runargs[i].startswith('--cwd'): | |
853 del runargs[i:i + 2] | |
854 break | |
855 def condfn(): | |
856 return not os.path.exists(lockpath) | |
857 pid = util.rundetached(runargs, condfn) | |
858 if pid < 0: | |
859 raise error.Abort(_('child process failed to start')) | |
860 writepid(pid) | |
861 finally: | |
862 try: | |
863 os.unlink(lockpath) | |
864 except OSError as e: | |
865 if e.errno != errno.ENOENT: | |
866 raise | |
867 if parentfn: | |
868 return parentfn(pid) | |
869 else: | |
870 return | |
871 | |
872 if initfn: | |
873 initfn() | |
874 | |
875 if not opts['daemon']: | |
876 writepid(util.getpid()) | |
877 | |
878 if opts['daemon_postexec']: | |
879 try: | |
880 os.setsid() | |
881 except AttributeError: | |
882 pass | |
883 for inst in opts['daemon_postexec']: | |
884 if inst.startswith('unlink:'): | |
885 lockpath = inst[7:] | |
886 os.unlink(lockpath) | |
887 elif inst.startswith('chdir:'): | |
888 os.chdir(inst[6:]) | |
889 elif inst != 'none': | |
890 raise error.Abort(_('invalid value for --daemon-postexec: %s') | |
891 % inst) | |
892 util.hidewindow() | |
893 util.stdout.flush() | |
894 util.stderr.flush() | |
895 | |
896 nullfd = os.open(os.devnull, os.O_RDWR) | |
897 logfilefd = nullfd | |
898 if logfile: | |
899 logfilefd = os.open(logfile, os.O_RDWR | os.O_CREAT | os.O_APPEND) | |
900 os.dup2(nullfd, 0) | |
901 os.dup2(logfilefd, 1) | |
902 os.dup2(logfilefd, 2) | |
903 if nullfd not in (0, 1, 2): | |
904 os.close(nullfd) | |
905 if logfile and logfilefd not in (0, 1, 2): | |
906 os.close(logfilefd) | |
907 | |
908 if runfn: | |
909 return runfn() | |
910 | 822 |
911 ## facility to let extension process additional data into an import patch | 823 ## facility to let extension process additional data into an import patch |
912 # list of identifier to be executed in order | 824 # list of identifier to be executed in order |
913 extrapreimport = [] # run before commit | 825 extrapreimport = [] # run before commit |
914 extrapostimport = [] # run after commit | 826 extrapostimport = [] # run after commit |