19
19
# limitations under the License.
20
20
21
21
from collections import deque
22
+ from logging import getLogger
22
23
from ssl import SSLSocket
23
24
from time import perf_counter
25
+
26
+ from neo4j ._exceptions import (
27
+ BoltError ,
28
+ BoltProtocolError ,
29
+ )
30
+ from neo4j .addressing import Address
24
31
from neo4j .api import (
25
- Version ,
26
32
READ_ACCESS ,
33
+ ServerInfo ,
34
+ Version ,
27
35
)
28
- from neo4j .io ._common import (
29
- Inbox ,
30
- Outbox ,
31
- Response ,
32
- InitResponse ,
33
- CommitResponse ,
34
- )
35
- from neo4j .meta import get_user_agent
36
36
from neo4j .exceptions import (
37
37
AuthError ,
38
- DatabaseUnavailable ,
39
38
ConfigurationError ,
39
+ DatabaseUnavailable ,
40
+ DriverError ,
40
41
ForbiddenOnReadOnlyDatabase ,
41
42
IncompleteCommit ,
42
43
NotALeader ,
43
44
ServiceUnavailable ,
44
45
SessionExpired ,
45
46
)
46
- from neo4j ._exceptions import BoltProtocolError
47
- from neo4j .packstream import (
48
- Unpacker ,
49
- Packer ,
50
- )
51
47
from neo4j .io import (
48
+ check_supported_server_product ,
52
49
Bolt ,
53
50
BoltPool ,
54
- check_supported_server_product ,
55
51
)
56
- from neo4j .api import ServerInfo
57
- from neo4j .addressing import Address
52
+ from neo4j .io ._common import (
53
+ CommitResponse ,
54
+ Inbox ,
55
+ InitResponse ,
56
+ Outbox ,
57
+ Response ,
58
+ )
59
+ from neo4j .meta import get_user_agent
60
+ from neo4j .packstream import (
61
+ Packer ,
62
+ Unpacker ,
63
+ )
58
64
59
- from logging import getLogger
60
65
log = getLogger ("neo4j" )
61
66
62
67
@@ -85,7 +90,7 @@ def __init__(self, unresolved_address, sock, max_connection_lifetime, *, auth=No
85
90
self .socket = sock
86
91
self .server_info = ServerInfo (Address (sock .getpeername ()), self .PROTOCOL_VERSION )
87
92
self .outbox = Outbox ()
88
- self .inbox = Inbox (self .socket , on_error = self ._set_defunct )
93
+ self .inbox = Inbox (self .socket , on_error = self ._set_defunct_read )
89
94
self .packer = Packer (self .outbox )
90
95
self .unpacker = Unpacker (self .inbox )
91
96
self .responses = deque ()
@@ -135,7 +140,7 @@ def der_encoded_server_certificate(self):
135
140
def local_port (self ):
136
141
try :
137
142
return self .socket .getsockname ()[1 ]
138
- except IOError :
143
+ except OSError :
139
144
return 0
140
145
141
146
def get_base_headers (self ):
@@ -292,7 +297,10 @@ def fail(metadata):
292
297
def _send_all (self ):
293
298
data = self .outbox .view ()
294
299
if data :
295
- self .socket .sendall (data )
300
+ try :
301
+ self .socket .sendall (data )
302
+ except OSError as error :
303
+ self ._set_defunct_write (error )
296
304
self .outbox .clear ()
297
305
298
306
def send_all (self ):
@@ -306,17 +314,7 @@ def send_all(self):
306
314
raise ServiceUnavailable ("Failed to write to defunct connection {!r} ({!r})" .format (
307
315
self .unresolved_address , self .server_info .address ))
308
316
309
- try :
310
- self ._send_all ()
311
- except (IOError , OSError ) as error :
312
- log .error ("Failed to write data to connection "
313
- "{!r} ({!r}); ({!r})" .
314
- format (self .unresolved_address ,
315
- self .server_info .address ,
316
- "; " .join (map (repr , error .args ))))
317
- if self .pool :
318
- self .pool .deactivate (address = self .unresolved_address )
319
- raise
317
+ self ._send_all ()
320
318
321
319
def fetch_message (self ):
322
320
""" Receive at least one message from the server, if available.
@@ -336,17 +334,7 @@ def fetch_message(self):
336
334
return 0 , 0
337
335
338
336
# Receive exactly one message
339
- try :
340
- details , summary_signature , summary_metadata = next (self .inbox )
341
- except (IOError , OSError ) as error :
342
- log .error ("Failed to read data from connection "
343
- "{!r} ({!r}); ({!r})" .
344
- format (self .unresolved_address ,
345
- self .server_info .address ,
346
- "; " .join (map (repr , error .args ))))
347
- if self .pool :
348
- self .pool .deactivate (address = self .unresolved_address )
349
- raise
337
+ details , summary_signature , summary_metadata = next (self .inbox )
350
338
351
339
if details :
352
340
log .debug ("[#%04X] S: RECORD * %d" , self .local_port , len (details )) # Do not log any data
@@ -380,11 +368,20 @@ def fetch_message(self):
380
368
381
369
return len (details ), 1
382
370
383
- def _set_defunct (self , error = None ):
384
- direct_driver = isinstance (self .pool , BoltPool )
371
+ def _set_defunct_read (self , error = None ):
372
+ message = "Failed to read from defunct connection {!r} ({!r})" .format (
373
+ self .unresolved_address , self .server_info .address
374
+ )
375
+ self ._set_defunct (message , error = error )
385
376
386
- message = ("Failed to read from defunct connection {!r} ({!r})" .format (
387
- self .unresolved_address , self .server_info .address ))
377
+ def _set_defunct_write (self , error = None ):
378
+ message = "Failed to write data to connection {!r} ({!r})" .format (
379
+ self .unresolved_address , self .server_info .address
380
+ )
381
+ self ._set_defunct (message , error = error )
382
+
383
+ def _set_defunct (self , message , error = None ):
384
+ direct_driver = isinstance (self .pool , BoltPool )
388
385
389
386
if error :
390
387
log .error (str (error ))
@@ -445,12 +442,12 @@ def close(self):
445
442
self ._append (b"\x02 " , ())
446
443
try :
447
444
self ._send_all ()
448
- except :
445
+ except ( OSError , BoltError , DriverError ) :
449
446
pass
450
447
log .debug ("[#%04X] C: <CLOSE>" , self .local_port )
451
448
try :
452
449
self .socket .close ()
453
- except IOError :
450
+ except OSError :
454
451
pass
455
452
finally :
456
453
self ._closed = True
0 commit comments