diff options
author | Joffrey F <joffrey@docker.com> | 2016-10-26 18:04:25 -0700 |
---|---|---|
committer | Joffrey F <joffrey@docker.com> | 2016-10-27 12:06:53 -0700 |
commit | 0bba27cfed4b038c7f931bf8044e248e71f525de (patch) | |
tree | 0f1cc111a0196365296d9436b4689a09a137597d | |
parent | 20be7d50f089e576ea19c069a57e8588b2af8f6b (diff) | |
download | docker-py-0bba27cfed4b038c7f931bf8044e248e71f525de.tar.gz |
Implement retry logic when the npipe open procedure fails
with ERROR_PIPE_BUSY
Signed-off-by: Joffrey F <joffrey@docker.com>
-rw-r--r-- | docker/transport/npipesocket.py | 34 |
1 files changed, 24 insertions, 10 deletions
diff --git a/docker/transport/npipesocket.py b/docker/transport/npipesocket.py index 527f0ab..48a9f92 100644 --- a/docker/transport/npipesocket.py +++ b/docker/transport/npipesocket.py @@ -5,9 +5,11 @@ import six import win32file import win32pipe +cERROR_PIPE_BUSY = 0xe7 cSECURITY_SQOS_PRESENT = 0x100000 cSECURITY_ANONYMOUS = 0 -cPIPE_READMODE_MESSAGE = 2 + +RETRY_WAIT_TIMEOUT = 10000 def check_closed(f): @@ -45,15 +47,27 @@ class NpipeSocket(object): @check_closed def connect(self, address): win32pipe.WaitNamedPipe(address, self._timeout) - handle = win32file.CreateFile( - address, - win32file.GENERIC_READ | win32file.GENERIC_WRITE, - 0, - None, - win32file.OPEN_EXISTING, - cSECURITY_ANONYMOUS | cSECURITY_SQOS_PRESENT, - 0 - ) + try: + handle = win32file.CreateFile( + address, + win32file.GENERIC_READ | win32file.GENERIC_WRITE, + 0, + None, + win32file.OPEN_EXISTING, + cSECURITY_ANONYMOUS | cSECURITY_SQOS_PRESENT, + 0 + ) + except win32pipe.error as e: + # See Remarks: + # https://msdn.microsoft.com/en-us/library/aa365800.aspx + if e.winerror == cERROR_PIPE_BUSY: + # Another program or thread has grabbed our pipe instance + # before we got to it. Wait for availability and attempt to + # connect again. + win32pipe.WaitNamedPipe(address, RETRY_WAIT_TIMEOUT) + return self.connect(address) + raise e + self.flags = win32pipe.GetNamedPipeInfo(handle)[0] self._handle = handle |