comparison hgext/chgserver.py @ 28326:ea400a4f32e6

chgserver: mangle server address to include confighash Before this patch, chgserver will use the address provided by the client. The new design is one server per confighash. This patch appends "-$confighash" to the address the client provides. To maintain the compatibility and make sure the client can connect to the server, a symbolic link is created at the original address pointing to the new address. The address is intentionally mangled at the server, instead of being pre- calculated by some other process (eg. a previous server). In this way, we can avoid file system race conditions.
author Jun Wu <quark@fb.com>
date Wed, 02 Mar 2016 10:10:06 +0000
parents 9fec3cb8d128
children 3ab370f84a23
comparison
equal deleted inserted replaced
28325:9fec3cb8d128 28326:ea400a4f32e6
33 33
34 :: 34 ::
35 35
36 [chgserver] 36 [chgserver]
37 idletimeout = 3600 # seconds, after which an idle server will exit 37 idletimeout = 3600 # seconds, after which an idle server will exit
38 skiphash = False # whether to skip config or env change checks
38 """ 39 """
39 40
40 from __future__ import absolute_import 41 from __future__ import absolute_import
41 42
42 import SocketServer 43 import SocketServer
514 raise 515 raise
515 516
516 def _tempaddress(address): 517 def _tempaddress(address):
517 return '%s.%d.tmp' % (address, os.getpid()) 518 return '%s.%d.tmp' % (address, os.getpid())
518 519
520 def _hashaddress(address, hashstr):
521 return '%s-%s' % (address, hashstr)
522
519 class AutoExitMixIn: # use old-style to comply with SocketServer design 523 class AutoExitMixIn: # use old-style to comply with SocketServer design
520 lastactive = time.time() 524 lastactive = time.time()
521 idletimeout = 3600 # default 1 hour 525 idletimeout = 3600 # default 1 hour
522 526
523 def startautoexitthread(self): 527 def startautoexitthread(self):
579 class chgunixservice(commandserver.unixservice): 583 class chgunixservice(commandserver.unixservice):
580 def init(self): 584 def init(self):
581 # drop options set for "hg serve --cmdserver" command 585 # drop options set for "hg serve --cmdserver" command
582 self.ui.setconfig('progress', 'assume-tty', None) 586 self.ui.setconfig('progress', 'assume-tty', None)
583 signal.signal(signal.SIGHUP, self._reloadconfig) 587 signal.signal(signal.SIGHUP, self._reloadconfig)
588 self._inithashstate()
584 class cls(AutoExitMixIn, SocketServer.ForkingMixIn, 589 class cls(AutoExitMixIn, SocketServer.ForkingMixIn,
585 SocketServer.UnixStreamServer): 590 SocketServer.UnixStreamServer):
586 ui = self.ui 591 ui = self.ui
587 repo = self.repo 592 repo = self.repo
588 self.server = cls(self.address, _requesthandler) 593 self.server = cls(self.address, _requesthandler)
589 self.server.idletimeout = self.ui.configint( 594 self.server.idletimeout = self.ui.configint(
590 'chgserver', 'idletimeout', self.server.idletimeout) 595 'chgserver', 'idletimeout', self.server.idletimeout)
591 self.server.startautoexitthread() 596 self.server.startautoexitthread()
597 self._createsymlink()
592 # avoid writing "listening at" message to stdout before attachio 598 # avoid writing "listening at" message to stdout before attachio
593 # request, which calls setvbuf() 599 # request, which calls setvbuf()
600
601 def _inithashstate(self):
602 self.baseaddress = self.address
603 if self.ui.configbool('chgserver', 'skiphash', False):
604 self.hashstate = None
605 return
606 self.hashstate = hashstate.fromui(self.ui)
607 self.address = _hashaddress(self.address, self.hashstate.confighash)
608
609 def _createsymlink(self):
610 if self.baseaddress == self.address:
611 return
612 tempaddress = _tempaddress(self.baseaddress)
613 os.symlink(self.address, tempaddress)
614 util.rename(tempaddress, self.baseaddress)
594 615
595 def _reloadconfig(self, signum, frame): 616 def _reloadconfig(self, signum, frame):
596 self.ui = self.server.ui = _renewui(self.ui) 617 self.ui = self.server.ui = _renewui(self.ui)
597 618
598 def run(self): 619 def run(self):