##// END OF EJS Templates
server: move cmdutil.service() to new module (API)...
Yuya Nishihara -
r30506:d9d8d78e default
parent child Browse files
Show More
@@ -0,0 +1,107 b''
1 # server.py - utility and factory of server
2 #
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 #
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
7
8 from __future__ import absolute_import
9
10 import errno
11 import os
12 import sys
13 import tempfile
14
15 from .i18n import _
16
17 from . import (
18 error,
19 util,
20 )
21
22 def runservice(opts, parentfn=None, initfn=None, runfn=None, logfile=None,
23 runargs=None, appendpid=False):
24 '''Run a command as a service.'''
25
26 def writepid(pid):
27 if opts['pid_file']:
28 if appendpid:
29 mode = 'a'
30 else:
31 mode = 'w'
32 fp = open(opts['pid_file'], mode)
33 fp.write(str(pid) + '\n')
34 fp.close()
35
36 if opts['daemon'] and not opts['daemon_postexec']:
37 # Signal child process startup with file removal
38 lockfd, lockpath = tempfile.mkstemp(prefix='hg-service-')
39 os.close(lockfd)
40 try:
41 if not runargs:
42 runargs = util.hgcmd() + sys.argv[1:]
43 runargs.append('--daemon-postexec=unlink:%s' % lockpath)
44 # Don't pass --cwd to the child process, because we've already
45 # changed directory.
46 for i in xrange(1, len(runargs)):
47 if runargs[i].startswith('--cwd='):
48 del runargs[i]
49 break
50 elif runargs[i].startswith('--cwd'):
51 del runargs[i:i + 2]
52 break
53 def condfn():
54 return not os.path.exists(lockpath)
55 pid = util.rundetached(runargs, condfn)
56 if pid < 0:
57 raise error.Abort(_('child process failed to start'))
58 writepid(pid)
59 finally:
60 try:
61 os.unlink(lockpath)
62 except OSError as e:
63 if e.errno != errno.ENOENT:
64 raise
65 if parentfn:
66 return parentfn(pid)
67 else:
68 return
69
70 if initfn:
71 initfn()
72
73 if not opts['daemon']:
74 writepid(util.getpid())
75
76 if opts['daemon_postexec']:
77 try:
78 os.setsid()
79 except AttributeError:
80 pass
81 for inst in opts['daemon_postexec']:
82 if inst.startswith('unlink:'):
83 lockpath = inst[7:]
84 os.unlink(lockpath)
85 elif inst.startswith('chdir:'):
86 os.chdir(inst[6:])
87 elif inst != 'none':
88 raise error.Abort(_('invalid value for --daemon-postexec: %s')
89 % inst)
90 util.hidewindow()
91 util.stdout.flush()
92 util.stderr.flush()
93
94 nullfd = os.open(os.devnull, os.O_RDWR)
95 logfilefd = nullfd
96 if logfile:
97 logfilefd = os.open(logfile, os.O_RDWR | os.O_CREAT | os.O_APPEND)
98 os.dup2(nullfd, 0)
99 os.dup2(logfilefd, 1)
100 os.dup2(logfilefd, 2)
101 if nullfd not in (0, 1, 2):
102 os.close(nullfd)
103 if logfile and logfilefd not in (0, 1, 2):
104 os.close(logfilefd)
105
106 if runfn:
107 return runfn()
@@ -10,7 +10,6 b' from __future__ import absolute_import'
10 10 import errno
11 11 import os
12 12 import re
13 import sys
14 13 import tempfile
15 14
16 15 from .i18n import _
@@ -821,93 +820,6 b' def copy(ui, repo, pats, opts, rename=Fa'
821 820
822 821 return errors != 0
823 822
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
911 823 ## facility to let extension process additional data into an import patch
912 824 # list of identifier to be executed in order
913 825 extrapreimport = [] # run before commit
@@ -67,6 +67,7 b' from . import ('
67 67 revlog,
68 68 revset,
69 69 scmutil,
70 server,
70 71 setdiscovery,
71 72 sshserver,
72 73 sslutil,
@@ -6301,7 +6302,7 b' def serve(ui, repo, **opts):'
6301 6302 service = commandserver.createservice(ui, repo, opts)
6302 6303 else:
6303 6304 service = hgweb.createservice(ui, repo, opts)
6304 return cmdutil.service(opts, initfn=service.init, runfn=service.run)
6305 return server.runservice(opts, initfn=service.init, runfn=service.run)
6305 6306
6306 6307 @command('^status|st',
6307 6308 [('A', 'all', None, _('show status of all files')),
@@ -11,7 +11,7 b' import signal'
11 11 import sys
12 12
13 13 from mercurial import (
14 cmdutil,
14 server,
15 15 util,
16 16 )
17 17
@@ -51,5 +51,5 b" if __name__ == '__main__':"
51 51 'daemon': not options.foreground,
52 52 'daemon_postexec': options.daemon_postexec}
53 53 service = simplehttpservice(options.host, options.port)
54 cmdutil.service(opts, initfn=service.init, runfn=service.run,
55 runargs=[sys.executable, __file__] + sys.argv[1:])
54 server.runservice(opts, initfn=service.init, runfn=service.run,
55 runargs=[sys.executable, __file__] + sys.argv[1:])
@@ -11,7 +11,7 b' import ssl'
11 11 import sys
12 12
13 13 from mercurial import (
14 cmdutil,
14 server,
15 15 sslutil,
16 16 ui as uimod,
17 17 )
@@ -75,8 +75,8 b' def main():'
75 75 dummysmtpsecureserver(addr, opts.certificate)
76 76 log('listening at %s:%d\n' % addr)
77 77
78 cmdutil.service(vars(opts), initfn=init, runfn=run,
79 runargs=[sys.executable, __file__] + sys.argv[1:])
78 server.runservice(vars(opts), initfn=init, runfn=run,
79 runargs=[sys.executable, __file__] + sys.argv[1:])
80 80
81 81 if __name__ == '__main__':
82 82 main()
General Comments 0
You need to be logged in to leave comments. Login now