comparison hgext/fsmonitor/__init__.py @ 32335:354329178dee

fsmonitor: don't attempt state-leave if we didn't state-enter The state-enter command may not have been successful; for example, the watchman client session may have timed out if the user was busy/idle for a long period during a merge conflict resolution earlier in processing a rebase for a stack of diffs. It's cleaner (from the perspective of the watchman logs) to avoid issuing the state-leave command in these cases. Test Plan: ran `hg rebase --tool :merge -r '(draft() & date(-14)) - master::' -d master` and didn't observe any errors in the watchman logs or in the output from `watchman -p -j <<<'["subscribe", "/data/users/wez/fbsource", "wez", {"expression": ["name", ".hg/updatestate"]}]'`
author Wez Furlong <wez@fb.com>
date Thu, 18 May 2017 12:49:10 -0700
parents 6e0d1043e8fc
children bdc4861ffe59
comparison
equal deleted inserted replaced
32334:6e0d1043e8fc 32335:354329178dee
599 self.repo = repo 599 self.repo = repo
600 self.node = node 600 self.node = node
601 self.distance = distance 601 self.distance = distance
602 self.partial = partial 602 self.partial = partial
603 self._lock = None 603 self._lock = None
604 self.need_leave = False
604 605
605 def __enter__(self): 606 def __enter__(self):
606 # We explicitly need to take a lock here, before we proceed to update 607 # We explicitly need to take a lock here, before we proceed to update
607 # watchman about the update operation, so that we don't race with 608 # watchman about the update operation, so that we don't race with
608 # some other actor. merge.update is going to take the wlock almost 609 # some other actor. merge.update is going to take the wlock almost
609 # immediately anyway, so this is effectively extending the lock 610 # immediately anyway, so this is effectively extending the lock
610 # around a couple of short sanity checks. 611 # around a couple of short sanity checks.
611 self._lock = self.repo.wlock() 612 self._lock = self.repo.wlock()
612 self._state('state-enter') 613 self.need_leave = self._state('state-enter')
613 return self 614 return self
614 615
615 def __exit__(self, type_, value, tb): 616 def __exit__(self, type_, value, tb):
616 try: 617 try:
617 status = 'ok' if type_ is None else 'failed' 618 if self.need_leave:
618 self._state('state-leave', status=status) 619 status = 'ok' if type_ is None else 'failed'
620 self._state('state-leave', status=status)
619 finally: 621 finally:
620 if self._lock: 622 if self._lock:
621 self._lock.release() 623 self._lock.release()
622 624
623 def _state(self, cmd, status='ok'): 625 def _state(self, cmd, status='ok'):
624 if not util.safehasattr(self.repo, '_watchmanclient'): 626 if not util.safehasattr(self.repo, '_watchmanclient'):
625 return 627 return False
626 try: 628 try:
627 commithash = self.repo[self.node].hex() 629 commithash = self.repo[self.node].hex()
628 self.repo._watchmanclient.command(cmd, { 630 self.repo._watchmanclient.command(cmd, {
629 'name': 'hg.update', 631 'name': 'hg.update',
630 'metadata': { 632 'metadata': {
635 # success/failure (only really meaningful for state-leave) 637 # success/failure (only really meaningful for state-leave)
636 'status': status, 638 'status': status,
637 # whether the working copy parent is changing 639 # whether the working copy parent is changing
638 'partial': self.partial, 640 'partial': self.partial,
639 }}) 641 }})
642 return True
640 except Exception as e: 643 except Exception as e:
641 # Swallow any errors; fire and forget 644 # Swallow any errors; fire and forget
642 self.repo.ui.log( 645 self.repo.ui.log(
643 'watchman', 'Exception %s while running %s\n', e, cmd) 646 'watchman', 'Exception %s while running %s\n', e, cmd)
647 return False
644 648
645 # Bracket working copy updates with calls to the watchman state-enter 649 # Bracket working copy updates with calls to the watchman state-enter
646 # and state-leave commands. This allows clients to perform more intelligent 650 # and state-leave commands. This allows clients to perform more intelligent
647 # settling during bulk file change scenarios 651 # settling during bulk file change scenarios
648 # https://facebook.github.io/watchman/docs/cmd/subscribe.html#advanced-settling 652 # https://facebook.github.io/watchman/docs/cmd/subscribe.html#advanced-settling