Skip to content

Commit 7383719

Browse files
committed
feat: get rid of rest_host, realtime_host internally unified everything under host
1 parent 761c421 commit 7383719

13 files changed

Lines changed: 249 additions & 155 deletions

ably/http/http.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -140,9 +140,9 @@ def dump_body(self, body):
140140
else:
141141
return json.dumps(body, separators=(',', ':'))
142142

143-
def get_rest_hosts(self):
144-
hosts = self.options.get_rest_hosts()
145-
host = self.__host or self.options.fallback_realtime_host
143+
def get_hosts(self):
144+
hosts = self.options.get_hosts()
145+
host = self.__host or self.options.fallback_host
146146
if host is None:
147147
return hosts
148148

@@ -186,7 +186,7 @@ async def make_request(self, method, path, version=None, headers=None, body=None
186186
http_max_retry_duration = self.http_max_retry_duration
187187
requested_at = time.time()
188188

189-
hosts = self.get_rest_hosts()
189+
hosts = self.get_hosts()
190190
for retry_count, host in enumerate(hosts):
191191
def should_stop_retrying(retry_count=retry_count):
192192
time_passed = time.time() - requested_at
@@ -229,7 +229,7 @@ def should_stop_retrying(retry_count=retry_count):
229229
continue
230230

231231
# Keep fallback host for later (RSC15f)
232-
if retry_count > 0 and host != self.options.get_rest_host():
232+
if retry_count > 0 and host != self.options.get_host():
233233
self.__host = host
234234
self.__host_expires = time.time() + (self.options.fallback_retry_timeout / 1000.0)
235235

@@ -277,7 +277,7 @@ def options(self):
277277

278278
@property
279279
def preferred_host(self):
280-
return self.options.get_rest_host()
280+
return self.options.get_host()
281281

282282
@property
283283
def preferred_port(self):

ably/realtime/connectionmanager.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ def __init__(self, realtime: AblyRealtime, initial_state):
122122
self.retry_timer: Timer | None = None
123123
self.connect_base_task: asyncio.Task | None = None
124124
self.disconnect_transport_task: asyncio.Task | None = None
125-
self.__fallback_hosts: list[str] = self.options.get_fallback_realtime_hosts()
125+
self.__fallback_hosts: list[str] = self.options.get_fallback_hosts()
126126
self.queued_messages: deque[PendingMessage] = deque()
127127
self.__error_reason: AblyException | None = None
128128
self.msg_serial: int = 0
@@ -532,7 +532,7 @@ async def connect_with_fallback_hosts(self, fallback_hosts: list) -> Exception |
532532

533533
async def connect_base(self) -> None:
534534
fallback_hosts = self.__fallback_hosts
535-
primary_host = self.options.get_realtime_host()
535+
primary_host = self.options.get_host()
536536
try:
537537
await self.try_host(primary_host)
538538
return

ably/transport/websockettransport.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,8 @@ async def on_protocol_message(self, msg):
142142
self.max_idle_interval = max_idle_interval + self.options.realtime_request_timeout
143143
self.on_activity()
144144
self.is_connected = True
145-
if self.host != self.options.get_realtime_host(): # RTN17e
146-
self.options.fallback_realtime_host = self.host
145+
if self.host != self.options.get_host(): # RTN17e
146+
self.options.fallback_host = self.host
147147
self.connection_manager.on_connected(connection_details, connection_id, reason=exception)
148148
elif action == ProtocolMessageAction.DISCONNECTED:
149149
error = msg.get('error')

ably/types/options.py

Lines changed: 51 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,21 @@ def __init__(self, client_id=None, log_level=0, tls=True, rest_host=None, realti
2929
tls_port=0, use_binary_protocol=True, queue_messages=True, recover=False, endpoint=None,
3030
environment=None, http_open_timeout=None, http_request_timeout=None,
3131
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,
32+
fallback_hosts=None, fallback_retry_timeout=None,
33+
disconnected_retry_timeout=None, idempotent_rest_publishing=None, loop=None, auto_connect=True,
3434
suspended_retry_timeout=None, connectivity_check_url=None,
3535
channel_retry_timeout=Defaults.channel_retry_timeout, add_request_ids=False,
3636
vcdiff_decoder: VCDiffDecoder = None, transport_params=None, **kwargs):
3737

3838
super().__init__(**kwargs)
3939

40+
# REC1b1: endpoint is incompatible with deprecated options
4041
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')
42+
if (environment is not None or rest_host is not None or
43+
realtime_host is not None):
44+
raise ValueError(
45+
'endpoint is incompatible with any of environment, rest_host, '
46+
'realtime_host')
4347

4448
# TODO check these defaults
4549
if fallback_retry_timeout is None:
@@ -70,16 +74,25 @@ def __init__(self, client_id=None, log_level=0, tls=True, rest_host=None, realti
7074
idempotent_rest_publishing = api_version >= '1.2'
7175

7276
if environment is not None and endpoint is None:
77+
log.warning("environment client option is deprecated, please use endpoint instead")
7378
endpoint = environment
7479

80+
# REC1d: restHost or realtimeHost option
81+
# REC1d1: restHost takes precedence over realtimeHost
82+
if rest_host is not None and endpoint is None:
83+
log.warning("rest_host client option is deprecated, please use endpoint instead")
84+
endpoint = rest_host
85+
elif realtime_host is not None and endpoint is None:
86+
# REC1d2: realtimeHost if restHost not specified
87+
log.warning("realtime_host client option is deprecated, please use endpoint instead")
88+
endpoint = realtime_host
89+
7590
if endpoint is None:
7691
endpoint = Defaults.endpoint
7792

7893
self.__client_id = client_id
7994
self.__log_level = log_level
8095
self.__tls = tls
81-
self.__rest_host = rest_host
82-
self.__realtime_host = realtime_host
8396
self.__port = port
8497
self.__tls_port = tls_port
8598
self.__use_binary_protocol = use_binary_protocol
@@ -91,6 +104,8 @@ def __init__(self, client_id=None, log_level=0, tls=True, rest_host=None, realti
91104
self.__realtime_request_timeout = realtime_request_timeout
92105
self.__http_max_retry_count = http_max_retry_count
93106
self.__http_max_retry_duration = http_max_retry_duration
107+
# Field for internal use only
108+
self.__fallback_host = None
94109
self.__fallback_hosts = fallback_hosts
95110
self.__fallback_retry_timeout = fallback_retry_timeout
96111
self.__disconnected_retry_timeout = disconnected_retry_timeout
@@ -101,13 +116,10 @@ def __init__(self, client_id=None, log_level=0, tls=True, rest_host=None, realti
101116
self.__connection_state_ttl = connection_state_ttl
102117
self.__suspended_retry_timeout = suspended_retry_timeout
103118
self.__connectivity_check_url = connectivity_check_url
104-
self.__fallback_realtime_host = None
105119
self.__add_request_ids = add_request_ids
106120
self.__vcdiff_decoder = vcdiff_decoder
107121
self.__transport_params = transport_params or {}
108-
109-
self.__rest_hosts = self.__get_rest_hosts()
110-
self.__realtime_hosts = self.__get_realtime_hosts()
122+
self.__hosts = self.__get_hosts()
111123

112124
@property
113125
def client_id(self):
@@ -133,23 +145,6 @@ def tls(self):
133145
def tls(self, value):
134146
self.__tls = value
135147

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-
153148
@property
154149
def port(self):
155150
return self.__port
@@ -276,12 +271,18 @@ def connectivity_check_url(self):
276271
return self.__connectivity_check_url
277272

278273
@property
279-
def fallback_realtime_host(self):
280-
return self.__fallback_realtime_host
274+
def fallback_host(self):
275+
"""
276+
For internal use only, can be deleted in future
277+
"""
278+
return self.__fallback_host
281279

282-
@fallback_realtime_host.setter
283-
def fallback_realtime_host(self, value):
284-
self.__fallback_realtime_host = value
280+
@fallback_host.setter
281+
def fallback_host(self, value):
282+
"""
283+
For internal use only, can be deleted in future
284+
"""
285+
self.__fallback_host = value
285286

286287
@property
287288
def add_request_ids(self):
@@ -295,29 +296,20 @@ def vcdiff_decoder(self):
295296
def transport_params(self):
296297
return self.__transport_params
297298

298-
def __get_rest_hosts(self):
299+
def __get_hosts(self):
299300
"""
300301
Return the list of hosts as they should be tried. First comes the main
301302
host. Then the fallback hosts in random order.
302303
The returned list will have a length of up to http_max_retry_count.
303304
"""
304-
# Defaults
305-
host = self.rest_host
306-
if host is None:
307-
host = Defaults.get_hostname(self.endpoint)
305+
host = Defaults.get_hostname(self.endpoint)
306+
# REC2: Determine fallback hosts
307+
fallback_hosts = self.get_fallback_hosts()
308308

309309
http_max_retry_count = self.http_max_retry_count
310310
if http_max_retry_count is None:
311311
http_max_retry_count = Defaults.http_max_retry_count
312312

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-
321313
# Shuffle
322314
fallback_hosts = list(fallback_hosts)
323315
random.shuffle(fallback_hosts)
@@ -328,28 +320,22 @@ def __get_rest_hosts(self):
328320
hosts = hosts[:http_max_retry_count]
329321
return hosts
330322

331-
def __get_realtime_hosts(self):
332-
if self.realtime_host is not None:
333-
host = self.realtime_host
334-
return [host]
335-
336-
host = Defaults.get_hostname(self.endpoint)
337-
return [host] + self.__fallback_hosts
338-
339-
def get_rest_hosts(self):
340-
return self.__rest_hosts
341-
342-
def get_rest_host(self):
343-
return self.__rest_hosts[0]
323+
def get_hosts(self):
324+
return self.__hosts
344325

345-
def get_realtime_hosts(self):
346-
return self.__realtime_hosts
326+
def get_host(self):
327+
return self.__hosts[0]
347328

348-
def get_realtime_host(self):
349-
return self.__realtime_hosts[0]
329+
# REC2: Various client options collectively determine a set of fallback domains
330+
def get_fallback_hosts(self):
331+
# REC2a: If the fallbackHosts client option is specified
332+
if self.__fallback_hosts is not None:
333+
# REC2a2: the set of fallback domains is given by the value of the fallbackHosts option
334+
return self.__fallback_hosts
350335

351-
def get_fallback_rest_hosts(self):
352-
return self.__rest_hosts[1:]
336+
# REC2c: Otherwise, the set of fallback domains is defined implicitly by the options
337+
# used to define the primary domain as specified in (REC1)
338+
return Defaults.get_fallback_hosts(self.endpoint)
353339

354340
def get_fallback_realtime_hosts(self):
355-
return self.__realtime_hosts[1:]
341+
return self.get_fallback_hosts()

test/ably/realtime/realtimeconnection_test.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ async def test_connectivity_check_bad_status(self):
187187
assert ably.connection.connection_manager.check_connection() is False
188188

189189
async def test_unroutable_host(self):
190-
ably = await TestApp.get_ably_realtime(realtime_host="10.255.255.1", realtime_request_timeout=3000)
190+
ably = await TestApp.get_ably_realtime(endpoint="10.255.255.1", realtime_request_timeout=3000)
191191
state_change = await ably.connection.once_async()
192192
assert state_change.reason
193193
assert state_change.reason.code == 50003
@@ -197,7 +197,7 @@ async def test_unroutable_host(self):
197197
await ably.close()
198198

199199
async def test_invalid_host(self):
200-
ably = await TestApp.get_ably_realtime(realtime_host="iamnotahost")
200+
ably = await TestApp.get_ably_realtime(endpoint="iamnotahost")
201201
state_change = await ably.connection.once_async()
202202
assert state_change.reason
203203
assert state_change.reason.code == 40000
@@ -299,8 +299,8 @@ async def test_fallback_host(self):
299299

300300
await asyncio.wait_for(ably.connection.once_async(ConnectionState.CONNECTED), timeout=5)
301301

302-
assert ably.connection.connection_manager.transport.host != self.test_vars["realtime_host"]
303-
assert ably.options.fallback_realtime_host != self.test_vars["realtime_host"]
302+
assert ably.connection.connection_manager.transport.host != self.test_vars["endpoint"]
303+
assert ably.options.fallback_host != self.test_vars["endpoint"]
304304
await ably.close()
305305

306306
async def test_fallback_host_no_connection(self):
@@ -325,7 +325,7 @@ def check_connection():
325325

326326
await ably.connection.once_async(ConnectionState.DISCONNECTED)
327327

328-
assert ably.options.fallback_realtime_host is None
328+
assert ably.options.fallback_host is None
329329
await ably.close()
330330

331331
async def test_fallback_host_disconnected_protocol_msg(self):
@@ -344,8 +344,8 @@ async def test_fallback_host_disconnected_protocol_msg(self):
344344

345345
await asyncio.wait_for(ably.connection.once_async(ConnectionState.CONNECTED), timeout=5)
346346

347-
assert ably.connection.connection_manager.transport.host != self.test_vars["realtime_host"]
348-
assert ably.options.fallback_realtime_host != self.test_vars["realtime_host"]
347+
assert ably.connection.connection_manager.transport.host != self.test_vars["endpoint"]
348+
assert ably.options.fallback_host != self.test_vars["endpoint"]
349349
await ably.close()
350350

351351
# RTN2d

test/ably/rest/restauth_test.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,7 @@ class TestRenewToken(BaseAsyncTestCase):
486486
async def setup(self):
487487
self.test_vars = await TestApp.get_test_vars()
488488
self.host = 'fake-host.ably.io'
489-
self.ably = await TestApp.get_ably_rest(use_binary_protocol=False, rest_host=self.host)
489+
self.ably = await TestApp.get_ably_rest(use_binary_protocol=False, endpoint=self.host)
490490
# with headers
491491
self.publish_attempts = 0
492492
self.channel = uuid.uuid4().hex
@@ -549,7 +549,7 @@ async def test_when_not_renewable(self):
549549

550550
self.ably = await TestApp.get_ably_rest(
551551
key=None,
552-
rest_host=self.host,
552+
endpoint=self.host,
553553
token='token ID cannot be used to create a new token',
554554
use_binary_protocol=False)
555555
await self.ably.channels[self.channel].publish('evt', 'msg')
@@ -568,7 +568,7 @@ async def test_when_not_renewable_with_token_details(self):
568568
token_details = TokenDetails(token='a_dummy_token')
569569
self.ably = await TestApp.get_ably_rest(
570570
key=None,
571-
rest_host=self.host,
571+
endpoint=self.host,
572572
token_details=token_details,
573573
use_binary_protocol=False)
574574
await self.ably.channels[self.channel].publish('evt', 'msg')
@@ -638,7 +638,7 @@ def cb_publish(request):
638638

639639
# RSA4b1
640640
async def test_query_time_false(self):
641-
ably = await TestApp.get_ably_rest(rest_host=self.host)
641+
ably = await TestApp.get_ably_rest(endpoint=self.host)
642642
await ably.auth.authorize()
643643
self.publish_fail = True
644644
await ably.channels[self.channel].publish('evt', 'msg')
@@ -647,7 +647,7 @@ async def test_query_time_false(self):
647647

648648
# RSA4b1
649649
async def test_query_time_true(self):
650-
ably = await TestApp.get_ably_rest(query_time=True, rest_host=self.host)
650+
ably = await TestApp.get_ably_rest(query_time=True, endpoint=self.host)
651651
await ably.auth.authorize()
652652
self.publish_fail = False
653653
await ably.channels[self.channel].publish('evt', 'msg')

0 commit comments

Comments
 (0)