Skip to content

Commit 65aa31d

Browse files
committed
feat: get rid of rest_host, realtime_host internally unified everything under host
1 parent f35fcce commit 65aa31d

File tree

13 files changed

+272
-164
lines changed

13 files changed

+272
-164
lines changed

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
@@ -136,7 +136,7 @@ def __init__(self, realtime: AblyRealtime, initial_state):
136136
self.retry_timer: Timer | None = None
137137
self.connect_base_task: asyncio.Task | None = None
138138
self.disconnect_transport_task: asyncio.Task | None = None
139-
self.__fallback_hosts: list[str] = self.options.get_fallback_realtime_hosts()
139+
self.__fallback_hosts: list[str] = self.options.get_fallback_hosts()
140140
self.queued_messages: deque[PendingMessage] = deque()
141141
self.__error_reason: AblyException | None = None
142142
self.msg_serial: int = 0
@@ -551,7 +551,7 @@ async def connect_with_fallback_hosts(self, fallback_hosts: list) -> Exception |
551551

552552
async def connect_base(self) -> None:
553553
fallback_hosts = self.__fallback_hosts
554-
primary_host = self.options.get_realtime_host()
554+
primary_host = self.options.get_host()
555555
try:
556556
await self.try_host(primary_host)
557557
return

ably/transport/websockettransport.py

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

ably/types/options.py

Lines changed: 59 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
from ably.transport.defaults import Defaults
66
from ably.types.authoptions import AuthOptions
7+
from ably.util.exceptions import AblyException
78

89
log = logging.getLogger(__name__)
910

@@ -37,9 +38,14 @@ def __init__(self, client_id=None, log_level=0, tls=True, rest_host=None, realti
3738

3839
super().__init__(**kwargs)
3940

41+
# REC1b1: endpoint is incompatible with deprecated options
4042
if endpoint is not None:
4143
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')
44+
raise AblyException(
45+
message='endpoint is incompatible with any of environment, rest_host or realtime_host',
46+
status_code=400,
47+
code=40106,
48+
)
4349

4450
# TODO check these defaults
4551
if fallback_retry_timeout is None:
@@ -60,26 +66,43 @@ def __init__(self, client_id=None, log_level=0, tls=True, rest_host=None, realti
6066
suspended_retry_timeout = Defaults.suspended_retry_timeout
6167

6268
if environment is not None and rest_host is not None:
63-
raise ValueError('specify rest_host or environment, not both')
69+
raise AblyException(
70+
message='specify rest_host or environment, not both',
71+
status_code=400,
72+
code=40106,
73+
)
6474

6575
if environment is not None and realtime_host is not None:
66-
raise ValueError('specify realtime_host or environment, not both')
76+
raise AblyException(
77+
message='specify realtime_host or environment, not both',
78+
status_code=400,
79+
code=40106,
80+
)
6781

6882
if idempotent_rest_publishing is None:
6983
from ably import api_version
7084
idempotent_rest_publishing = api_version >= '1.2'
7185

7286
if environment is not None and endpoint is None:
87+
log.warning("environment client option is deprecated, please use endpoint instead")
7388
endpoint = environment
7489

90+
# REC1d: restHost or realtimeHost option
91+
# REC1d1: restHost takes precedence over realtimeHost
92+
if rest_host is not None and endpoint is None:
93+
log.warning("rest_host client option is deprecated, please use endpoint instead")
94+
endpoint = rest_host
95+
elif realtime_host is not None and endpoint is None:
96+
# REC1d2: realtimeHost if restHost not specified
97+
log.warning("realtime_host client option is deprecated, please use endpoint instead")
98+
endpoint = realtime_host
99+
75100
if endpoint is None:
76101
endpoint = Defaults.endpoint
77102

78103
self.__client_id = client_id
79104
self.__log_level = log_level
80105
self.__tls = tls
81-
self.__rest_host = rest_host
82-
self.__realtime_host = realtime_host
83106
self.__port = port
84107
self.__tls_port = tls_port
85108
self.__use_binary_protocol = use_binary_protocol
@@ -91,6 +114,8 @@ def __init__(self, client_id=None, log_level=0, tls=True, rest_host=None, realti
91114
self.__realtime_request_timeout = realtime_request_timeout
92115
self.__http_max_retry_count = http_max_retry_count
93116
self.__http_max_retry_duration = http_max_retry_duration
117+
# Field for internal use only
118+
self.__fallback_host = None
94119
self.__fallback_hosts = fallback_hosts
95120
self.__fallback_retry_timeout = fallback_retry_timeout
96121
self.__disconnected_retry_timeout = disconnected_retry_timeout
@@ -101,13 +126,10 @@ def __init__(self, client_id=None, log_level=0, tls=True, rest_host=None, realti
101126
self.__connection_state_ttl = connection_state_ttl
102127
self.__suspended_retry_timeout = suspended_retry_timeout
103128
self.__connectivity_check_url = connectivity_check_url
104-
self.__fallback_realtime_host = None
105129
self.__add_request_ids = add_request_ids
106130
self.__vcdiff_decoder = vcdiff_decoder
107131
self.__transport_params = transport_params or {}
108-
109-
self.__rest_hosts = self.__get_rest_hosts()
110-
self.__realtime_hosts = self.__get_realtime_hosts()
132+
self.__hosts = self.__get_hosts()
111133

112134
@property
113135
def client_id(self):
@@ -133,23 +155,6 @@ def tls(self):
133155
def tls(self, value):
134156
self.__tls = value
135157

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-
153158
@property
154159
def port(self):
155160
return self.__port
@@ -276,12 +281,18 @@ def connectivity_check_url(self):
276281
return self.__connectivity_check_url
277282

278283
@property
279-
def fallback_realtime_host(self):
280-
return self.__fallback_realtime_host
284+
def fallback_host(self):
285+
"""
286+
For internal use only, can be deleted in future
287+
"""
288+
return self.__fallback_host
281289

282-
@fallback_realtime_host.setter
283-
def fallback_realtime_host(self, value):
284-
self.__fallback_realtime_host = value
290+
@fallback_host.setter
291+
def fallback_host(self, value):
292+
"""
293+
For internal use only, can be deleted in future
294+
"""
295+
self.__fallback_host = value
285296

286297
@property
287298
def add_request_ids(self):
@@ -295,29 +306,20 @@ def vcdiff_decoder(self):
295306
def transport_params(self):
296307
return self.__transport_params
297308

298-
def __get_rest_hosts(self):
309+
def __get_hosts(self):
299310
"""
300311
Return the list of hosts as they should be tried. First comes the main
301312
host. Then the fallback hosts in random order.
302313
The returned list will have a length of up to http_max_retry_count.
303314
"""
304-
# Defaults
305-
host = self.rest_host
306-
if host is None:
307-
host = Defaults.get_hostname(self.endpoint)
315+
host = Defaults.get_hostname(self.endpoint)
316+
# REC2: Determine fallback hosts
317+
fallback_hosts = self.get_fallback_hosts()
308318

309319
http_max_retry_count = self.http_max_retry_count
310320
if http_max_retry_count is None:
311321
http_max_retry_count = Defaults.http_max_retry_count
312322

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-
321323
# Shuffle
322324
fallback_hosts = list(fallback_hosts)
323325
random.shuffle(fallback_hosts)
@@ -328,28 +330,19 @@ def __get_rest_hosts(self):
328330
hosts = hosts[:http_max_retry_count]
329331
return hosts
330332

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
333+
def get_hosts(self):
334+
return self.__hosts
347335

348-
def get_realtime_host(self):
349-
return self.__realtime_hosts[0]
336+
def get_host(self):
337+
return self.__hosts[0]
350338

351-
def get_fallback_rest_hosts(self):
352-
return self.__rest_hosts[1:]
339+
# REC2: Various client options collectively determine a set of fallback domains
340+
def get_fallback_hosts(self):
341+
# REC2a: If the fallbackHosts client option is specified
342+
if self.__fallback_hosts is not None:
343+
# REC2a2: the set of fallback domains is given by the value of the fallbackHosts option
344+
return self.__fallback_hosts
353345

354-
def get_fallback_realtime_hosts(self):
355-
return self.__realtime_hosts[1:]
346+
# REC2c: Otherwise, the set of fallback domains is defined implicitly by the options
347+
# used to define the primary domain as specified in (REC1)
348+
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["host"]
303+
assert ably.options.fallback_host != self.test_vars["host"]
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["host"]
348+
assert ably.options.fallback_host != self.test_vars["host"]
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)