Among our users at Google, we're still seeing several percent of
commands fail with exit code 255. I suspect keyboard interrupts is an
important remaining reason.
This is a resend of D10086 with some fixes for pager handling added
ahead of it.
( )
pulkit |
hg-reviewers |
Among our users at Google, we're still seeing several percent of
commands fail with exit code 255. I suspect keyboard interrupts is an
important remaining reason.
This is a resend of D10086 with some fixes for pager handling added
ahead of it.
No Linters Available |
No Unit Test Coverage |
Path | Packages | |||
---|---|---|---|---|
M | mercurial/dispatch.py (5 lines) | |||
M | tests/test-chg.t (4 lines) | |||
M | tests/test-commandserver.t (2 lines) | |||
M | tests/test-nointerrupt.t (6 lines) |
Commit | Parents | Author | Summary | Date |
---|---|---|---|---|
5cc9d97a2b69 | da43c53e6b6d | Martin von Zweigbergk | Mar 2 2021, 12:33 PM |
Status | Author | Revision | |
---|---|---|---|
Closed | martinvonz | ||
Closed | martinvonz | ||
Closed | martinvonz |
req.ui.error(msg) | req.ui.error(msg) | ||||
except error.SignalInterrupt: | except error.SignalInterrupt: | ||||
# maybe pager would quit without consuming all the output, and | # maybe pager would quit without consuming all the output, and | ||||
# SIGPIPE was raised. we cannot print anything in this case. | # SIGPIPE was raised. we cannot print anything in this case. | ||||
pass | pass | ||||
except IOError as inst: | except IOError as inst: | ||||
if inst.errno != errno.EPIPE: | if inst.errno != errno.EPIPE: | ||||
raise | raise | ||||
if req.ui.configbool(b'ui', b'detailed-exit-code'): | |||||
ret = 250 | |||||
else: | |||||
ret = -1 | ret = -1 | ||||
finally: | finally: | ||||
duration = util.timer() - starttime | duration = util.timer() - starttime | ||||
try: | try: | ||||
req.ui.flush() # record blocked times | req.ui.flush() # record blocked times | ||||
except BaseException: | except BaseException: | ||||
pass | pass | ||||
if req.ui.logblockedtimes: | if req.ui.logblockedtimes: | ||||
req.ui._blockedtimes[b'command_duration'] = duration * 1000 | req.ui._blockedtimes[b'command_duration'] = duration * 1000 |
$ cat >> .hg/hgrc <<EOF | $ cat >> .hg/hgrc <<EOF | ||||
> [extensions] | > [extensions] | ||||
> bulkwrite = $TESTTMP/bulkwrite.py | > bulkwrite = $TESTTMP/bulkwrite.py | ||||
> EOF | > EOF | ||||
$ chg bulkwrite --pager=on --color no --config ui.formatted=True | $ chg bulkwrite --pager=on --color no --config ui.formatted=True | ||||
paged! 'going to write massive data\n' | paged! 'going to write massive data\n' | ||||
killed! (?) | killed! (?) | ||||
[255] | [250] | ||||
$ chg bulkwrite --pager=on --color no --config ui.formatted=True | $ chg bulkwrite --pager=on --color no --config ui.formatted=True | ||||
paged! 'going to write massive data\n' | paged! 'going to write massive data\n' | ||||
killed! (?) | killed! (?) | ||||
[255] | [250] | ||||
$ cd .. | $ cd .. | ||||
missing stdio | missing stdio | ||||
------------- | ------------- | ||||
$ CHGDEBUG=1 chg version -q 0<&- | $ CHGDEBUG=1 chg version -q 0<&- | ||||
chg: debug: * stdio fds are missing (glob) | chg: debug: * stdio fds are missing (glob) |
... runcommand(server, [b'debugsuicide']) # command can be interrupted | ... runcommand(server, [b'debugsuicide']) # command can be interrupted | ||||
... server.send_signal(signal.SIGTERM) # server will be terminated | ... server.send_signal(signal.SIGTERM) # server will be terminated | ||||
... time.sleep(1) | ... time.sleep(1) | ||||
*** runcommand debugsleep | *** runcommand debugsleep | ||||
*** runcommand debugsleep | *** runcommand debugsleep | ||||
*** runcommand debugsuicide | *** runcommand debugsuicide | ||||
interrupted! | interrupted! | ||||
killed! | killed! | ||||
[255] | [250] | ||||
#endif | #endif | ||||
structured message channel: | structured message channel: | ||||
$ cat <<'EOF' >> repo2/.hg/hgrc | $ cat <<'EOF' >> repo2/.hg/hgrc | ||||
> [ui] | > [ui] |
> EOF | > EOF | ||||
Test ctrl-c | Test ctrl-c | ||||
$ rm -f $SYNC_FILE $DONE_FILE | $ rm -f $SYNC_FILE $DONE_FILE | ||||
$ sh -c "../send-signal.sh INT" & | $ sh -c "../send-signal.sh INT" & | ||||
$ hg wait-signal | $ hg wait-signal | ||||
interrupted! | interrupted! | ||||
[255] | [250] | ||||
$ cat >> $HGRCPATH << EOF | $ cat >> $HGRCPATH << EOF | ||||
> [experimental] | > [experimental] | ||||
> nointerrupt = yes | > nointerrupt = yes | ||||
> EOF | > EOF | ||||
$ rm -f $SYNC_FILE $DONE_FILE | $ rm -f $SYNC_FILE $DONE_FILE | ||||
$ sh -c "../send-signal.sh INT" & | $ sh -c "../send-signal.sh INT" & | ||||
$ hg wait-signal | $ hg wait-signal | ||||
interrupted! | interrupted! | ||||
[255] | [250] | ||||
$ cat >> $HGRCPATH << EOF | $ cat >> $HGRCPATH << EOF | ||||
> [experimental] | > [experimental] | ||||
> nointerrupt-interactiveonly = False | > nointerrupt-interactiveonly = False | ||||
> EOF | > EOF | ||||
$ rm -f $SYNC_FILE $DONE_FILE | $ rm -f $SYNC_FILE $DONE_FILE | ||||
$ sh -c "../send-signal.sh INT" & | $ sh -c "../send-signal.sh INT" & | ||||
$ hg wait-signal | $ hg wait-signal | ||||
shutting down cleanly | shutting down cleanly | ||||
press ^C again to terminate immediately (dangerous) | press ^C again to terminate immediately (dangerous) | ||||
end of unsafe operation | end of unsafe operation | ||||
interrupted! | interrupted! | ||||
[255] | [250] |