11import logging
2- import random
32from abc import ABC , abstractmethod
43
54from ably .transport .defaults import Defaults
@@ -29,17 +28,21 @@ def __init__(self, client_id=None, log_level=0, tls=True, rest_host=None, realti
2928 tls_port = 0 , use_binary_protocol = True , queue_messages = True , recover = False , endpoint = None ,
3029 environment = None , http_open_timeout = None , http_request_timeout = None ,
3130 realtime_request_timeout = None , http_max_retry_count = None , http_max_retry_duration = None ,
32- fallback_hosts = None , fallback_retry_timeout = None , disconnected_retry_timeout = None ,
33- idempotent_rest_publishing = None , loop = None , auto_connect = True ,
31+ fallback_hosts = None , fallback_hosts_use_default = None , fallback_retry_timeout = None ,
32+ disconnected_retry_timeout = None , idempotent_rest_publishing = None , loop = None , auto_connect = True ,
3433 suspended_retry_timeout = None , connectivity_check_url = None ,
3534 channel_retry_timeout = Defaults .channel_retry_timeout , add_request_ids = False ,
3635 vcdiff_decoder : VCDiffDecoder = None , transport_params = None , ** kwargs ):
3736
3837 super ().__init__ (** kwargs )
3938
39+ # REC1b1: endpoint is incompatible with deprecated options
4040 if endpoint is not None :
41- if environment is not None or rest_host is not None or realtime_host is not None :
42- raise ValueError ('endpoint is incompatible with any of environment, rest_host or realtime_host' )
41+ if (environment is not None or rest_host is not None or
42+ realtime_host is not None or fallback_hosts_use_default is not None ):
43+ raise ValueError (
44+ 'endpoint is incompatible with any of environment, rest_host, '
45+ 'realtime_host or fallback_hosts_use_default' )
4346
4447 # TODO check these defaults
4548 if fallback_retry_timeout is None :
@@ -65,21 +68,34 @@ def __init__(self, client_id=None, log_level=0, tls=True, rest_host=None, realti
6568 if environment is not None and realtime_host is not None :
6669 raise ValueError ('specify realtime_host or environment, not both' )
6770
71+ # REC2a1: fallback_hosts is incompatible with fallback_hosts_use_default
72+ if fallback_hosts is not None and fallback_hosts_use_default is not None :
73+ raise ValueError ('fallback_hosts is incompatible with fallback_hosts_use_default' )
74+
6875 if idempotent_rest_publishing is None :
6976 from ably import api_version
7077 idempotent_rest_publishing = api_version >= '1.2'
7178
7279 if environment is not None and endpoint is None :
80+ log .warning ("environment client option is deprecated, please use endpoint instead" )
7381 endpoint = environment
7482
83+ # REC1d: restHost or realtimeHost option
84+ # REC1d1: restHost takes precedence over realtimeHost
85+ if rest_host is not None and endpoint is None :
86+ log .warning ("rest_host client option is deprecated, please use endpoint instead" )
87+ endpoint = rest_host
88+ elif realtime_host is not None and endpoint is None :
89+ # REC1d2: realtimeHost if restHost not specified
90+ log .warning ("realtime_host client option is deprecated, please use endpoint instead" )
91+ endpoint = realtime_host
92+
7593 if endpoint is None :
7694 endpoint = Defaults .endpoint
7795
7896 self .__client_id = client_id
7997 self .__log_level = log_level
8098 self .__tls = tls
81- self .__rest_host = rest_host
82- self .__realtime_host = realtime_host
8399 self .__port = port
84100 self .__tls_port = tls_port
85101 self .__use_binary_protocol = use_binary_protocol
@@ -92,6 +108,7 @@ def __init__(self, client_id=None, log_level=0, tls=True, rest_host=None, realti
92108 self .__http_max_retry_count = http_max_retry_count
93109 self .__http_max_retry_duration = http_max_retry_duration
94110 self .__fallback_hosts = fallback_hosts
111+ self .__fallback_hosts_use_default = fallback_hosts_use_default
95112 self .__fallback_retry_timeout = fallback_retry_timeout
96113 self .__disconnected_retry_timeout = disconnected_retry_timeout
97114 self .__channel_retry_timeout = channel_retry_timeout
@@ -101,13 +118,10 @@ def __init__(self, client_id=None, log_level=0, tls=True, rest_host=None, realti
101118 self .__connection_state_ttl = connection_state_ttl
102119 self .__suspended_retry_timeout = suspended_retry_timeout
103120 self .__connectivity_check_url = connectivity_check_url
104- self .__fallback_realtime_host = None
105121 self .__add_request_ids = add_request_ids
106122 self .__vcdiff_decoder = vcdiff_decoder
107123 self .__transport_params = transport_params or {}
108-
109- self .__rest_hosts = self .__get_rest_hosts ()
110- self .__realtime_hosts = self .__get_realtime_hosts ()
124+ self .__hosts = self .__get_hosts ()
111125
112126 @property
113127 def client_id (self ):
@@ -133,23 +147,6 @@ def tls(self):
133147 def tls (self , value ):
134148 self .__tls = value
135149
136- @property
137- def rest_host (self ):
138- return self .__rest_host
139-
140- @rest_host .setter
141- def rest_host (self , value ):
142- self .__rest_host = value
143-
144- # RTC1d
145- @property
146- def realtime_host (self ):
147- return self .__realtime_host
148-
149- @realtime_host .setter
150- def realtime_host (self , value ):
151- self .__realtime_host = value
152-
153150 @property
154151 def port (self ):
155152 return self .__port
@@ -275,14 +272,6 @@ def suspended_retry_timeout(self):
275272 def connectivity_check_url (self ):
276273 return self .__connectivity_check_url
277274
278- @property
279- def fallback_realtime_host (self ):
280- return self .__fallback_realtime_host
281-
282- @fallback_realtime_host .setter
283- def fallback_realtime_host (self , value ):
284- self .__fallback_realtime_host = value
285-
286275 @property
287276 def add_request_ids (self ):
288277 return self .__add_request_ids
@@ -295,61 +284,33 @@ def vcdiff_decoder(self):
295284 def transport_params (self ):
296285 return self .__transport_params
297286
298- def __get_rest_hosts (self ):
299- """
300- Return the list of hosts as they should be tried. First comes the main
301- host. Then the fallback hosts in random order.
302- The returned list will have a length of up to http_max_retry_count.
303- """
304- # Defaults
305- host = self .rest_host
306- if host is None :
307- host = Defaults .get_hostname (self .endpoint )
308-
309- http_max_retry_count = self .http_max_retry_count
310- if http_max_retry_count is None :
311- http_max_retry_count = Defaults .http_max_retry_count
312-
313- # Fallback hosts
314- fallback_hosts = self .fallback_hosts
315- if fallback_hosts is None :
316- if self .rest_host is not None :
317- fallback_hosts = []
318- else :
319- fallback_hosts = Defaults .get_fallback_hosts (self .endpoint )
320-
321- # Shuffle
322- fallback_hosts = list (fallback_hosts )
323- random .shuffle (fallback_hosts )
324- self .__fallback_hosts = fallback_hosts
325-
326- # First main host
327- hosts = [host ] + fallback_hosts
328- hosts = hosts [:http_max_retry_count ]
329- return hosts
330-
331- def __get_realtime_hosts (self ):
332- if self .realtime_host is not None :
333- host = self .realtime_host
334- return [host ]
335-
287+ def __get_hosts (self ):
336288 host = Defaults .get_hostname (self .endpoint )
337- return [host ] + self .__fallback_hosts
289+ # REC2: Determine fallback hosts
290+ fallback_hosts = self .get_fallback_hosts ()
291+ return [host ] + fallback_hosts
338292
339- def get_rest_hosts (self ):
340- return self .__rest_hosts
293+ def get_hosts (self ):
294+ return self .__hosts
341295
342- def get_rest_host (self ):
343- return self .__rest_hosts [0 ]
296+ def get_host (self ):
297+ return self .__hosts [0 ]
344298
345- def get_realtime_hosts (self ):
346- return self .__realtime_hosts
299+ # REC2: Various client options collectively determine a set of fallback domains
300+ def get_fallback_hosts (self ):
301+ # REC2a: If the fallbackHosts client option is specified
302+ if self .__fallback_hosts is not None :
303+ # REC2a2: the set of fallback domains is given by the value of the fallbackHosts option
304+ return self .__fallback_hosts
347305
348- def get_realtime_host (self ):
349- return self .__realtime_hosts [0 ]
306+ # REC2b: Otherwise, if the deprecated fallbackHostsUseDefault option is specified
307+ if self .__fallback_hosts_use_default is not None and self .__fallback_hosts_use_default :
308+ # REC2b: then the set of fallback domains is the default set defined in (REC2c1)
309+ return Defaults .get_fallback_hosts ("main" )
350310
351- def get_fallback_rest_hosts (self ):
352- return self .__rest_hosts [1 :]
311+ # REC2c: Otherwise, the set of fallback domains is defined implicitly by the options
312+ # used to define the primary domain as specified in (REC1)
313+ return Defaults .get_fallback_hosts (self .endpoint )
353314
354315 def get_fallback_realtime_hosts (self ):
355- return self .__realtime_hosts [ 1 :]
316+ return self .get_fallback_hosts ()
0 commit comments