Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commita929ab2

Browse files
committed
Merge pull request#354 from dpursehouse/execute-timeout
Include 'timeout' parameter in Git execute
2 parentsed8939d +dbbcaf7 commita929ab2

File tree

1 file changed

+50
-1
lines changed

1 file changed

+50
-1
lines changed

‎git/cmd.py

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
importmmap
1515

1616
fromcontextlibimportcontextmanager
17+
fromsignalimportSIGKILL
1718
fromsubprocessimport (
1819
call,
1920
Popen,
@@ -41,7 +42,7 @@
4142

4243
execute_kwargs= ('istream','with_keep_cwd','with_extended_output',
4344
'with_exceptions','as_process','stdout_as_string',
44-
'output_stream','with_stdout')
45+
'output_stream','with_stdout','kill_after_timeout')
4546

4647
log=logging.getLogger('git.cmd')
4748
log.addHandler(logging.NullHandler())
@@ -476,6 +477,7 @@ def execute(self, command,
476477
as_process=False,
477478
output_stream=None,
478479
stdout_as_string=True,
480+
kill_after_timeout=None,
479481
with_stdout=True,
480482
**subprocess_kwargs
481483
):
@@ -532,6 +534,16 @@ def execute(self, command,
532534
533535
:param with_stdout: If True, default True, we open stdout on the created process
534536
537+
:param kill_after_timeout:
538+
To specify a timeout in seconds for the git command, after which the process
539+
should be killed. This will have no effect if as_process is set to True. It is
540+
set to None by default and will let the process run until the timeout is
541+
explicitly specified. This feature is not supported on Windows. It's also worth
542+
noting that kill_after_timeout uses SIGKILL, which can have negative side
543+
effects on a repository. For example, stale locks in case of git gc could
544+
render the repository incapable of accepting changes until the lock is manually
545+
removed.
546+
535547
:return:
536548
* str(output) if extended_output = False (Default)
537549
* tuple(int(status), str(stdout), str(stderr)) if extended_output = True
@@ -569,6 +581,8 @@ def execute(self, command,
569581

570582
ifsys.platform=='win32':
571583
cmd_not_found_exception=WindowsError
584+
ifkill_after_timeout:
585+
raiseGitCommandError('"kill_after_timeout" feature is not supported on Windows.')
572586
else:
573587
ifsys.version_info[0]>2:
574588
cmd_not_found_exception=FileNotFoundError# NOQA # this is defined, but flake8 doesn't know
@@ -593,13 +607,48 @@ def execute(self, command,
593607
ifas_process:
594608
returnself.AutoInterrupt(proc,command)
595609

610+
def_kill_process(pid):
611+
""" Callback method to kill a process. """
612+
p=Popen(['ps','--ppid',str(pid)],stdout=PIPE)
613+
child_pids= []
614+
forlineinp.stdout:
615+
iflen(line.split())>0:
616+
local_pid= (line.split())[0]
617+
iflocal_pid.isdigit():
618+
child_pids.append(int(local_pid))
619+
try:
620+
os.kill(pid,SIGKILL)
621+
forchild_pidinchild_pids:
622+
try:
623+
os.kill(child_pid,SIGKILL)
624+
exceptOSError:
625+
pass
626+
kill_check.set()# tell the main routine that the process was killed
627+
exceptOSError:
628+
# It is possible that the process gets completed in the duration after timeout
629+
# happens and before we try to kill the process.
630+
pass
631+
return
632+
# end
633+
634+
ifkill_after_timeout:
635+
kill_check=threading.Event()
636+
watchdog=threading.Timer(kill_after_timeout,_kill_process,args=(proc.pid, ))
637+
596638
# Wait for the process to return
597639
status=0
598640
stdout_value=b''
599641
stderr_value=b''
600642
try:
601643
ifoutput_streamisNone:
644+
ifkill_after_timeout:
645+
watchdog.start()
602646
stdout_value,stderr_value=proc.communicate()
647+
ifkill_after_timeout:
648+
watchdog.cancel()
649+
ifkill_check.isSet():
650+
stderr_value='Timeout: the command "%s" did not complete in %d ' \
651+
'secs.'% (" ".join(command),kill_after_timeout)
603652
# strip trailing "\n"
604653
ifstdout_value.endswith(b"\n"):
605654
stdout_value=stdout_value[:-1]

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp