2525from collections .abc import Mapping
2626from concurrent .futures import ThreadPoolExecutor , FIRST_COMPLETED , wait as wait_futures
2727from copy import copy
28- from functools import partial , wraps
28+ from functools import partial , reduce , wraps
2929from itertools import groupby , count , chain
3030import json
3131import logging
4545from cassandra import (ConsistencyLevel , AuthenticationFailed , InvalidRequest ,
4646 OperationTimedOut , UnsupportedOperation ,
4747 SchemaTargetType , DriverException , ProtocolVersion ,
48- UnresolvableContactPoints )
48+ UnresolvableContactPoints , DependencyException )
4949from cassandra .auth import _proxy_execute_key , PlainTextAuthProvider
5050from cassandra .connection import (ConnectionException , ConnectionShutdown ,
5151 ConnectionHeartbeat , ProtocolVersionUnsupported ,
113113except ImportError :
114114 from cassandra .util import WeakSet # NOQA
115115
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+
116132def _is_eventlet_monkey_patched ():
117133 if 'eventlet.patcher' not in sys .modules :
118134 return False
@@ -124,6 +140,7 @@ def _is_eventlet_monkey_patched():
124140 # TODO: remove it when eventlet issue would be fixed
125141 return False
126142
143+
127144def _is_gevent_monkey_patched ():
128145 if 'gevent.monkey' not in sys .modules :
129146 return False
@@ -135,21 +152,42 @@ def _is_gevent_monkey_patched():
135152 return False
136153
137154
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 () :
146163 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
153191
154192# Forces load of utf8 encoding module to avoid deadlock that occurs
155193# if code that is being imported tries to import the module in a seperate
0 commit comments