25
25
from collections .abc import Mapping
26
26
from concurrent .futures import ThreadPoolExecutor , FIRST_COMPLETED , wait as wait_futures
27
27
from copy import copy
28
- from functools import partial , wraps
28
+ from functools import partial , reduce , wraps
29
29
from itertools import groupby , count , chain
30
30
import json
31
31
import logging
45
45
from cassandra import (ConsistencyLevel , AuthenticationFailed , InvalidRequest ,
46
46
OperationTimedOut , UnsupportedOperation ,
47
47
SchemaTargetType , DriverException , ProtocolVersion ,
48
- UnresolvableContactPoints )
48
+ UnresolvableContactPoints , DependencyException )
49
49
from cassandra .auth import _proxy_execute_key , PlainTextAuthProvider
50
50
from cassandra .connection import (ConnectionException , ConnectionShutdown ,
51
51
ConnectionHeartbeat , ProtocolVersionUnsupported ,
113
113
except ImportError :
114
114
from cassandra .util import WeakSet # NOQA
115
115
116
+
117
+ def _is_gevent_monkey_patched ():
118
+ if 'gevent.monkey' not in sys .modules :
119
+ return False
120
+ import gevent .socket
121
+ return socket .socket is gevent .socket .socket
122
+
123
+
124
+ def _try_gevent_import ():
125
+ if _is_gevent_monkey_patched ():
126
+ from cassandra .io .geventreactor import GeventConnection
127
+ return (GeventConnection ,None )
128
+ else :
129
+ return (None ,None )
130
+
131
+
116
132
def _is_eventlet_monkey_patched ():
117
133
if 'eventlet.patcher' not in sys .modules :
118
134
return False
@@ -124,6 +140,7 @@ def _is_eventlet_monkey_patched():
124
140
# TODO: remove it when eventlet issue would be fixed
125
141
return False
126
142
143
+
127
144
def _is_gevent_monkey_patched ():
128
145
if 'gevent.monkey' not in sys .modules :
129
146
return False
@@ -135,21 +152,42 @@ def _is_gevent_monkey_patched():
135
152
return False
136
153
137
154
138
- # default to gevent when we are monkey patched with gevent, eventlet when
139
- # monkey patched with eventlet, otherwise if libev is available, use that as
140
- # the default because it's fastest. Otherwise, use asyncore.
141
- if _is_gevent_monkey_patched ():
142
- from cassandra . io . geventreactor import GeventConnection as DefaultConnection
143
- elif _is_eventlet_monkey_patched ():
144
- from cassandra . io . eventletreactor import EventletConnection as DefaultConnection
145
- else :
155
+ def _try_eventlet_import ():
156
+ if _is_eventlet_monkey_patched ():
157
+ from cassandra . io . eventletreactor import EventletConnection
158
+ return ( EventletConnection , None )
159
+ else :
160
+ return ( None , None )
161
+
162
+ def _try_libev_import () :
146
163
try :
147
- from cassandra .io .libevreactor import LibevConnection as DefaultConnection # NOQA
148
- except ImportError :
149
- try :
150
- from cassandra .io .asyncorereactor import AsyncoreConnection as DefaultConnection # NOQA
151
- except ImportError :
152
- from cassandra .io .asyncioreactor import AsyncioConnection as DefaultConnection # NOQA
164
+ from cassandra .io .libevreactor import LibevConnection
165
+ return (LibevConnection ,None )
166
+ except DependencyException as e :
167
+ return (None , e )
168
+
169
+ def _try_asyncore_import ():
170
+ try :
171
+ from cassandra .io .asyncorereactor import AsyncoreConnection
172
+ return (AsyncoreConnection ,None )
173
+ except DependencyException as e :
174
+ return (None , e )
175
+
176
+ def _connection_reduce_fn (val ,import_fn ):
177
+ (rv , excs ) = val
178
+ # If we've already found a workable Connection class return immediately
179
+ if rv :
180
+ return val
181
+ (import_result , exc ) = import_fn ()
182
+ if exc :
183
+ excs .append (exc )
184
+ return (rv or import_result , excs )
185
+
186
+ conn_fns = (_try_gevent_import , _try_eventlet_import , _try_libev_import , _try_asyncore_import )
187
+ (conn_class , excs ) = reduce (_connection_reduce_fn , conn_fns , (None ,[]))
188
+ if excs :
189
+ raise DependencyException ("Exception loading connection class dependencies" , excs )
190
+ DefaultConnection = conn_class
153
191
154
192
# Forces load of utf8 encoding module to avoid deadlock that occurs
155
193
# if code that is being imported tries to import the module in a seperate
0 commit comments