From b975b98cc70f193bf74c45f6981989cff66ddfc2 Mon Sep 17 00:00:00 2001 From: Kevin Carter Date: Wed, 19 Nov 2025 20:13:35 +0000 Subject: [PATCH] timing --- .../database/services/provisioning_service.py | 56 +++++++++++++++++-- 1 file changed, 50 insertions(+), 6 deletions(-) diff --git a/modules/database/services/provisioning_service.py b/modules/database/services/provisioning_service.py index b531915..189c14e 100644 --- a/modules/database/services/provisioning_service.py +++ b/modules/database/services/provisioning_service.py @@ -1,5 +1,6 @@ import json import os +import time from datetime import datetime, timedelta from typing import Dict, Optional, Tuple, List @@ -157,6 +158,31 @@ class ProvisioningService: self.neo4j_service.create_database(school_db) self.neo4j_service.create_database(curriculum_db) + # Wait for databases to be fully available (Neo4j needs time to make new databases accessible) + logger.info(f"Waiting for databases to be fully available...") + time.sleep(2) # Initial wait + + # Verify databases exist with retries + max_retries = 5 + retry_delay = 1 + for attempt in range(max_retries): + try: + # Check if school_db exists + check_result = self.neo4j_service.check_database_exists(school_db) + if check_result.get("exists", False): + logger.info(f"Database {school_db} is available") + break + else: + if attempt < max_retries - 1: + logger.info(f"Database {school_db} not yet available, retrying in {retry_delay}s... (attempt {attempt + 1}/{max_retries})") + time.sleep(retry_delay) + else: + logger.warning(f"Database {school_db} may not be fully available, proceeding anyway...") + except Exception as e: + logger.warning(f"Error checking database existence: {e}, proceeding anyway...") + if attempt < max_retries - 1: + time.sleep(retry_delay) + metadata = institute.get("metadata") or {} if isinstance(metadata, str): try: @@ -173,12 +199,30 @@ class ProvisioningService: website=institute.get("website", "https://example.com"), ) - neon.init_neontology_connection() - try: - create_or_merge_neontology_node(school_node, database=_CC_SCHOOLS_DB, operation='merge') - create_or_merge_neontology_node(school_node, database=school_db, operation='merge') - finally: - neon.close_neontology_connection() + # Retry node creation with exponential backoff + max_node_retries = 3 + for attempt in range(max_node_retries): + try: + neon.init_neontology_connection() + try: + create_or_merge_neontology_node(school_node, database=_CC_SCHOOLS_DB, operation='merge') + create_or_merge_neontology_node(school_node, database=school_db, operation='merge') + logger.info(f"Successfully created school nodes in databases") + break # Success, exit retry loop + finally: + neon.close_neontology_connection() + except Exception as e: + if "Database" in str(e) and "not found" in str(e): + if attempt < max_node_retries - 1: + wait_time = (attempt + 1) * 2 # Exponential backoff: 2s, 4s, 6s + logger.warning(f"Database not yet available, waiting {wait_time}s before retry (attempt {attempt + 1}/{max_node_retries}): {e}") + time.sleep(wait_time) + else: + logger.error(f"Failed to create school nodes after {max_node_retries} attempts: {e}") + raise + else: + # Different error, don't retry + raise # Try to persist database references back to Supabase (best effort) updates = {