Skip to content

Commit 69382de

Browse files
committed
Replace infinite loop with safer approach with a max number of retries and exponential backoff
1 parent 03b9eac commit 69382de

File tree

1 file changed

+60
-49
lines changed

1 file changed

+60
-49
lines changed

docs/performance/inserts/sequences.rst

Lines changed: 60 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -131,55 +131,66 @@ ID for the record we are inserting into the ``mytable`` table.
131131

132132
.. code:: python
133133
134-
# /// script
135-
# requires-python = ">=3.8"
136-
# dependencies = [
137-
# "records",
138-
# "sqlalchemy-cratedb",
139-
# ]
140-
# ///
141-
142-
import records
143-
144-
db = records.Database("crate://")
145-
sequence_name = "mysequence"
146-
147-
while True:
148-
select_query = """
149-
SELECT last_value,
150-
_seq_no,
151-
_primary_term
152-
FROM sequences
153-
WHERE name = :sequence_name;
154-
"""
155-
row = db.query(select_query, sequence_name=sequence_name).first()
156-
new_value = row.last_value + 1
157-
158-
update_query = """
159-
UPDATE sequences
160-
SET last_value = :new_value
161-
WHERE name = :sequence_name
162-
AND _seq_no = :seq_no
163-
AND _primary_term = :primary_term
164-
RETURNING last_value;
165-
"""
166-
if (
167-
str(
168-
db.query(
169-
update_query,
170-
new_value=new_value,
171-
sequence_name=sequence_name,
172-
seq_no=row._seq_no,
173-
primary_term=row._primary_term,
174-
).all()
175-
)
176-
!= "[]"
177-
):
178-
break
179-
180-
insert_query = "INSERT INTO mytable (id, field1) VALUES (:id, :field1)"
181-
db.query(insert_query, id=new_value, field1="abc")
182-
db.close()
134+
# /// script
135+
# requires-python = ">=3.8"
136+
# dependencies = [
137+
# "records",
138+
# "sqlalchemy-cratedb",
139+
# ]
140+
# ///
141+
142+
import time
143+
144+
import records
145+
146+
db = records.Database("crate://")
147+
sequence_name = "mysequence"
148+
149+
max_retries = 5
150+
base_delay = 0.1 # 100 milliseconds
151+
152+
for attempt in range(max_retries):
153+
select_query = """
154+
SELECT last_value,
155+
_seq_no,
156+
_primary_term
157+
FROM sequences
158+
WHERE name = :sequence_name;
159+
"""
160+
row = db.query(select_query, sequence_name=sequence_name).first()
161+
new_value = row.last_value + 1
162+
163+
update_query = """
164+
UPDATE sequences
165+
SET last_value = :new_value
166+
WHERE name = :sequence_name
167+
AND _seq_no = :seq_no
168+
AND _primary_term = :primary_term
169+
RETURNING last_value;
170+
"""
171+
if (
172+
str(
173+
db.query(
174+
update_query,
175+
new_value=new_value,
176+
sequence_name=sequence_name,
177+
seq_no=row._seq_no,
178+
primary_term=row._primary_term,
179+
).all()
180+
)
181+
!= "[]"
182+
):
183+
break
184+
185+
delay = base_delay * (2**attempt)
186+
print(f"Attempt {attempt + 1} failed. Retrying in {delay:.1f} seconds...")
187+
time.sleep(delay)
188+
else:
189+
raise Exception(f"Failed after {max_retries} retries with exponential backoff")
190+
191+
insert_query = "INSERT INTO mytable (id, field1) VALUES (:id, :field1)"
192+
db.query(insert_query, id=new_value, field1="abc")
193+
db.close()
183194
184195
.. _extremely fast ingestion speeds: https://cratedb.com/blog/how-we-scaled-ingestion-to-one-million-rows-per-second
185196

0 commit comments

Comments
 (0)