Skip to content

Commit 9a53a64

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

13 files changed

Lines changed: 248 additions & 160 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: 45 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,15 @@ 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:
4142
if environment is not None or rest_host is not None or realtime_host is not None:
4243
raise ValueError('endpoint is incompatible with any of environment, rest_host or realtime_host')
@@ -70,16 +71,25 @@ def __init__(self, client_id=None, log_level=0, tls=True, rest_host=None, realti
7071
idempotent_rest_publishing = api_version >= '1.2'
7172

7273
if environment is not None and endpoint is None:
74+
log.warning("environment client option is deprecated, please use endpoint instead")
7375
endpoint = environment
7476

77+
# REC1d: restHost or realtimeHost option
78+
# REC1d1: restHost takes precedence over realtimeHost
79+
if rest_host is not None and endpoint is None:
80+
log.warning("rest_host client option is deprecated, please use endpoint instead")
81+
endpoint = rest_host
82+
elif realtime_host is not None and endpoint is None:
83+
# REC1d2: realtimeHost if restHost not specified
84+
log.warning("realtime_host client option is deprecated, please use endpoint instead")
85+
endpoint = realtime_host
86+
7587
if endpoint is None:
7688
endpoint = Defaults.endpoint
7789

7890
self.__client_id = client_id
7991
self.__log_level = log_level
8092
self.__tls = tls
81-
self.__rest_host = rest_host
82-
self.__realtime_host = realtime_host
8393
self.__port = port
8494
self.__tls_port = tls_port
8595
self.__use_binary_protocol = use_binary_protocol
@@ -91,6 +101,8 @@ def __init__(self, client_id=None, log_level=0, tls=True, rest_host=None, realti
91101
self.__realtime_request_timeout = realtime_request_timeout
92102
self.__http_max_retry_count = http_max_retry_count
93103
self.__http_max_retry_duration = http_max_retry_duration
104+
# Field for internal use only
105+
self.__fallback_host = None
94106
self.__fallback_hosts = fallback_hosts
95107
self.__fallback_retry_timeout = fallback_retry_timeout
96108
self.__disconnected_retry_timeout = disconnected_retry_timeout
@@ -101,13 +113,10 @@ def __init__(self, client_id=None, log_level=0, tls=True, rest_host=None, realti
101113
self.__connection_state_ttl = connection_state_ttl
102114
self.__suspended_retry_timeout = suspended_retry_timeout
103115
self.__connectivity_check_url = connectivity_check_url
104-
self.__fallback_realtime_host = None
105116
self.__add_request_ids = add_request_ids
106117
self.__vcdiff_decoder = vcdiff_decoder
107118
self.__transport_params = transport_params or {}
108-
109-
self.__rest_hosts = self.__get_rest_hosts()
110-
self.__realtime_hosts = self.__get_realtime_hosts()
119+
self.__hosts = self.__get_hosts()
111120

112121
@property
113122
def client_id(self):
@@ -133,23 +142,6 @@ def tls(self):
133142
def tls(self, value):
134143
self.__tls = value
135144

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-
153145
@property
154146
def port(self):
155147
return self.__port
@@ -276,12 +268,18 @@ def connectivity_check_url(self):
276268
return self.__connectivity_check_url
277269

278270
@property
279-
def fallback_realtime_host(self):
280-
return self.__fallback_realtime_host
271+
def fallback_host(self):
272+
"""
273+
For internal use only, can be deleted in future
274+
"""
275+
return self.__fallback_host
281276

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

286284
@property
287285
def add_request_ids(self):
@@ -295,29 +293,20 @@ def vcdiff_decoder(self):
295293
def transport_params(self):
296294
return self.__transport_params
297295

298-
def __get_rest_hosts(self):
296+
def __get_hosts(self):
299297
"""
300298
Return the list of hosts as they should be tried. First comes the main
301299
host. Then the fallback hosts in random order.
302300
The returned list will have a length of up to http_max_retry_count.
303301
"""
304-
# Defaults
305-
host = self.rest_host
306-
if host is None:
307-
host = Defaults.get_hostname(self.endpoint)
302+
host = Defaults.get_hostname(self.endpoint)
303+
# REC2: Determine fallback hosts
304+
fallback_hosts = self.get_fallback_hosts()
308305

309306
http_max_retry_count = self.http_max_retry_count
310307
if http_max_retry_count is None:
311308
http_max_retry_count = Defaults.http_max_retry_count
312309

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-
321310
# Shuffle
322311
fallback_hosts = list(fallback_hosts)
323312
random.shuffle(fallback_hosts)
@@ -328,28 +317,19 @@ def __get_rest_hosts(self):
328317
hosts = hosts[:http_max_retry_count]
329318
return hosts
330319

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]
344-
345-
def get_realtime_hosts(self):
346-
return self.__realtime_hosts
320+
def get_hosts(self):
321+
return self.__hosts
347322

348-
def get_realtime_host(self):
349-
return self.__realtime_hosts[0]
323+
def get_host(self):
324+
return self.__hosts[0]
350325

351-
def get_fallback_rest_hosts(self):
352-
return self.__rest_hosts[1:]
326+
# REC2: Various client options collectively determine a set of fallback domains
327+
def get_fallback_hosts(self):
328+
# REC2a: If the fallbackHosts client option is specified
329+
if self.__fallback_hosts is not None:
330+
# REC2a2: the set of fallback domains is given by the value of the fallbackHosts option
331+
return self.__fallback_hosts
353332

354-
def get_fallback_realtime_hosts(self):
355-
return self.__realtime_hosts[1:]
333+
# REC2c: Otherwise, the set of fallback domains is defined implicitly by the options
334+
# used to define the primary domain as specified in (REC1)
335+
return Defaults.get_fallback_hosts(self.endpoint)

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)