Skip to content

Commit 4efc337

Browse files
committed
add postgres get best node query and casts for posgres support with comment
1 parent 9d39a63 commit 4efc337

1 file changed

Lines changed: 41 additions & 5 deletions

File tree

tools/tokenserver/database.py

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,9 @@
180180
""")
181181

182182

183-
_GET_BEST_NODE = sqltext("""\
183+
# MySQL: log(0) returns NULL, and NULLs sort first with ASC — zero-load
184+
# nodes naturally win. Original query unchanged.
185+
_GET_BEST_NODE_MYSQL = sqltext("""\
184186
select
185187
id, node
186188
from
@@ -192,7 +194,26 @@
192194
and downed = 0
193195
and backoff = 0
194196
order by
195-
log(GREATEST(current_load, 1)) / log(capacity)
197+
log(current_load) / log(capacity)
198+
limit 1
199+
""")
200+
201+
# PostgreSQL: log(0) raises InvalidArgumentForLogarithm, so we use NULLIF
202+
# to convert zero to NULL explicitly. NULLS FIRST replicates MySQL's default
203+
# NULL-first ASC sort order, ensuring zero-load nodes are always preferred.
204+
_GET_BEST_NODE_POSTGRES = sqltext("""\
205+
select
206+
id, node
207+
from
208+
nodes
209+
where
210+
service = :service
211+
and available > 0
212+
and capacity > current_load
213+
and downed = 0
214+
and backoff = 0
215+
order by
216+
log(NULLIF(current_load, 0)) / log(capacity) NULLS FIRST
196217
limit 1
197218
""")
198219

@@ -656,8 +677,10 @@ def add_node(self, node, capacity, **kwds):
656677
capacity=capacity,
657678
available=available,
658679
current_load=kwds.get("current_load", 0),
659-
downed=kwds.get("downed", 0),
660-
backoff=kwds.get("backoff", 0),
680+
# Cast to int: optparse action="store_true" produces Python bools,
681+
# which postgres rejects for INTEGER columns (MySQL coerces silently).
682+
downed=int(kwds.get("downed", 0)),
683+
backoff=int(kwds.get("backoff", 0)),
661684
)
662685
res.close()
663686

@@ -679,6 +702,11 @@ def update_node(self, node, **kwds):
679702
query += """
680703
where service = :service and node = :node
681704
"""
705+
# Cast boolean fields to int: Python bools are rejected by postgres
706+
# INTEGER columns. MySQL coerces silently; postgres does not.
707+
for field in ("downed", "backoff"):
708+
if field in values:
709+
values[field] = int(values[field])
682710
values["service"] = self._get_service_id(SERVICE_NAME)
683711
values["node"] = node
684712
if kwds:
@@ -750,8 +778,16 @@ def get_best_node(self):
750778
# capacity. This loop allows a maximum of five retries before
751779
# bailing out.
752780
for _ in range(5):
781+
# Select the appropriate query variant — postgres requires
782+
# explicit NULL handling for log(0) and NULL sort order that
783+
# MySQL handles implicitly.
784+
best_node_query = (
785+
_GET_BEST_NODE_POSTGRES
786+
if self.db_mode == "postgresql"
787+
else _GET_BEST_NODE_MYSQL
788+
)
753789
res = self._execute_sql(
754-
_GET_BEST_NODE, service=self._get_service_id(SERVICE_NAME)
790+
best_node_query, service=self._get_service_id(SERVICE_NAME)
755791
)
756792
row = res.fetchone()
757793
res.close()

0 commit comments

Comments
 (0)