reduced duplicate insert errors of portals, still present because of two players disovering the same portal at the same time, other changes to inventory

This commit is contained in:
erik 2025-09-22 18:21:04 +00:00
parent e7ca39318f
commit 6c646719dd
6 changed files with 1093 additions and 232 deletions

60
main.py
View file

@ -1985,16 +1985,16 @@ async def ws_receive_snapshots(
ew = float(ew)
z = float(z)
# Round coordinates for comparison (0.01 tolerance)
ns_rounded = round(ns, 2)
ew_rounded = round(ew, 2)
# Round coordinates for comparison (0.1 tolerance to match DB constraint)
ns_rounded = round(ns, 1)
ew_rounded = round(ew, 1)
# Check if portal exists at these coordinates
existing_portal = await database.fetch_one(
"""
SELECT id FROM portals
WHERE ROUND(ns::numeric, 2) = :ns_rounded
AND ROUND(ew::numeric, 2) = :ew_rounded
WHERE ROUND(ns::numeric, 1) = :ns_rounded
AND ROUND(ew::numeric, 1) = :ew_rounded
LIMIT 1
""",
{
@ -2004,26 +2004,48 @@ async def ws_receive_snapshots(
)
if not existing_portal:
# Store new portal in database
await database.execute(
portals.insert().values(
portal_name=portal_name,
ns=ns,
ew=ew,
z=z,
discovered_at=timestamp,
discovered_by=character_name
# Store new portal in database with ON CONFLICT handling
# This prevents race conditions and duplicate key errors
try:
await database.execute(
portals.insert().values(
portal_name=portal_name,
ns=ns,
ew=ew,
z=z,
discovered_at=timestamp,
discovered_by=character_name
)
)
)
logger.info(f"New portal discovered: {portal_name} at {ns_rounded}, {ew_rounded} by {character_name}")
logger.info(f"New portal discovered: {portal_name} at {ns_rounded}, {ew_rounded} by {character_name}")
except Exception as insert_error:
# If insert fails due to duplicate, update the existing portal
if "duplicate key" in str(insert_error).lower():
await database.execute(
"""
UPDATE portals
SET discovered_at = :timestamp, discovered_by = :character_name
WHERE ROUND(ns::numeric, 1) = :ns_rounded
AND ROUND(ew::numeric, 1) = :ew_rounded
""",
{
"timestamp": timestamp,
"character_name": character_name,
"ns_rounded": ns_rounded,
"ew_rounded": ew_rounded
}
)
logger.debug(f"Portal already exists (race condition), updated: {portal_name} at {ns_rounded}, {ew_rounded}")
else:
raise
else:
# Update timestamp for existing portal to keep it alive
await database.execute(
"""
UPDATE portals
UPDATE portals
SET discovered_at = :timestamp, discovered_by = :character_name
WHERE ROUND(ns::numeric, 2) = :ns_rounded
AND ROUND(ew::numeric, 2) = :ew_rounded
WHERE ROUND(ns::numeric, 1) = :ns_rounded
AND ROUND(ew::numeric, 1) = :ew_rounded
""",
{
"timestamp": timestamp,