##// END OF EJS Templates
commandserver: add IPC channel to teach repository path on command finished...
Yuya Nishihara -
r41034:042ed354 default
parent child Browse files
Show More
@@ -506,12 +506,19 b' class unixforkingservice(object):'
506 raise error.Abort(_('no socket path specified with --address'))
506 raise error.Abort(_('no socket path specified with --address'))
507 self._servicehandler = handler or unixservicehandler(ui)
507 self._servicehandler = handler or unixservicehandler(ui)
508 self._sock = None
508 self._sock = None
509 self._mainipc = None
510 self._workeripc = None
509 self._oldsigchldhandler = None
511 self._oldsigchldhandler = None
510 self._workerpids = set() # updated by signal handler; do not iterate
512 self._workerpids = set() # updated by signal handler; do not iterate
511 self._socketunlinked = None
513 self._socketunlinked = None
512
514
513 def init(self):
515 def init(self):
514 self._sock = socket.socket(socket.AF_UNIX)
516 self._sock = socket.socket(socket.AF_UNIX)
517 # IPC channel from many workers to one main process; this is actually
518 # a uni-directional pipe, but is backed by a DGRAM socket so each
519 # message can be easily separated.
520 o = socket.socketpair(socket.AF_UNIX, socket.SOCK_DGRAM)
521 self._mainipc, self._workeripc = o
515 self._servicehandler.bindsocket(self._sock, self.address)
522 self._servicehandler.bindsocket(self._sock, self.address)
516 if util.safehasattr(procutil, 'unblocksignal'):
523 if util.safehasattr(procutil, 'unblocksignal'):
517 procutil.unblocksignal(signal.SIGCHLD)
524 procutil.unblocksignal(signal.SIGCHLD)
@@ -527,6 +534,8 b' class unixforkingservice(object):'
527 def _cleanup(self):
534 def _cleanup(self):
528 signal.signal(signal.SIGCHLD, self._oldsigchldhandler)
535 signal.signal(signal.SIGCHLD, self._oldsigchldhandler)
529 self._sock.close()
536 self._sock.close()
537 self._mainipc.close()
538 self._workeripc.close()
530 self._unlinksocket()
539 self._unlinksocket()
531 # don't kill child processes as they have active clients, just wait
540 # don't kill child processes as they have active clients, just wait
532 self._reapworkers(0)
541 self._reapworkers(0)
@@ -543,6 +552,8 b' class unixforkingservice(object):'
543 selector = selectors.DefaultSelector()
552 selector = selectors.DefaultSelector()
544 selector.register(self._sock, selectors.EVENT_READ,
553 selector.register(self._sock, selectors.EVENT_READ,
545 self._acceptnewconnection)
554 self._acceptnewconnection)
555 selector.register(self._mainipc, selectors.EVENT_READ,
556 self._handlemainipc)
546 while True:
557 while True:
547 if not exiting and h.shouldexit():
558 if not exiting and h.shouldexit():
548 # clients can no longer connect() to the domain socket, so
559 # clients can no longer connect() to the domain socket, so
@@ -592,8 +603,10 b' class unixforkingservice(object):'
592 try:
603 try:
593 selector.close()
604 selector.close()
594 sock.close()
605 sock.close()
606 self._mainipc.close()
595 self._runworker(conn)
607 self._runworker(conn)
596 conn.close()
608 conn.close()
609 self._workeripc.close()
597 os._exit(0)
610 os._exit(0)
598 except: # never return, hence no re-raises
611 except: # never return, hence no re-raises
599 try:
612 try:
@@ -601,6 +614,17 b' class unixforkingservice(object):'
601 finally:
614 finally:
602 os._exit(255)
615 os._exit(255)
603
616
617 def _handlemainipc(self, sock, selector):
618 """Process messages sent from a worker"""
619 try:
620 path = sock.recv(32768) # large enough to receive path
621 except socket.error as inst:
622 if inst.args[0] == errno.EINTR:
623 return
624 raise
625
626 self.ui.log(b'cmdserver', b'repository: %s\n', path)
627
604 def _sigchldhandler(self, signal, frame):
628 def _sigchldhandler(self, signal, frame):
605 self._reapworkers(os.WNOHANG)
629 self._reapworkers(os.WNOHANG)
606
630
@@ -628,6 +652,22 b' class unixforkingservice(object):'
628 h = self._servicehandler
652 h = self._servicehandler
629 try:
653 try:
630 _serverequest(self.ui, self.repo, conn, h.createcmdserver,
654 _serverequest(self.ui, self.repo, conn, h.createcmdserver,
631 prereposetups=None) # TODO: pass in hook functions
655 prereposetups=[self._reposetup])
632 finally:
656 finally:
633 gc.collect() # trigger __del__ since worker process uses os._exit
657 gc.collect() # trigger __del__ since worker process uses os._exit
658
659 def _reposetup(self, ui, repo):
660 if not repo.local():
661 return
662
663 class unixcmdserverrepo(repo.__class__):
664 def close(self):
665 super(unixcmdserverrepo, self).close()
666 try:
667 self._cmdserveripc.send(self.root)
668 except socket.error:
669 self.ui.log(b'cmdserver',
670 b'failed to send repo root to master\n')
671
672 repo.__class__ = unixcmdserverrepo
673 repo._cmdserveripc = self._workeripc
@@ -230,7 +230,6 b' print only the last 10 lines, since we a'
230 preserved:
230 preserved:
231
231
232 $ cat log/server.log.1 log/server.log | tail -10 | filterlog
232 $ cat log/server.log.1 log/server.log | tail -10 | filterlog
233 YYYY/MM/DD HH:MM:SS (PID)> forked worker process (pid=...)
234 YYYY/MM/DD HH:MM:SS (PID)> setprocname: ...
233 YYYY/MM/DD HH:MM:SS (PID)> setprocname: ...
235 YYYY/MM/DD HH:MM:SS (PID)> received fds: ...
234 YYYY/MM/DD HH:MM:SS (PID)> received fds: ...
236 YYYY/MM/DD HH:MM:SS (PID)> chdir to '$TESTTMP/extreload'
235 YYYY/MM/DD HH:MM:SS (PID)> chdir to '$TESTTMP/extreload'
@@ -238,5 +237,6 b' preserved:'
238 YYYY/MM/DD HH:MM:SS (PID)> setenv: ...
237 YYYY/MM/DD HH:MM:SS (PID)> setenv: ...
239 YYYY/MM/DD HH:MM:SS (PID)> confighash = ... mtimehash = ...
238 YYYY/MM/DD HH:MM:SS (PID)> confighash = ... mtimehash = ...
240 YYYY/MM/DD HH:MM:SS (PID)> validate: []
239 YYYY/MM/DD HH:MM:SS (PID)> validate: []
240 YYYY/MM/DD HH:MM:SS (PID)> repository: $TESTTMP/extreload
241 YYYY/MM/DD HH:MM:SS (PID)> worker process exited (pid=...)
241 YYYY/MM/DD HH:MM:SS (PID)> worker process exited (pid=...)
242 YYYY/MM/DD HH:MM:SS (PID)> $TESTTMP/extreload/chgsock/server-... is not owned, exiting.
242 YYYY/MM/DD HH:MM:SS (PID)> $TESTTMP/extreload/chgsock/server-... is not owned, exiting.
General Comments 0
You need to be logged in to leave comments. Login now