private void createInstance()

in src/main/java/com/amazonaws/services/neptune/cluster/AddCloneTask.java [363:441]


    private void createInstance(String name,
                                NeptuneClient neptune,
                                NeptuneClusterMetadata sourceClusterMetadata,
                                InstanceType instanceType,
                                DBParameterGroup dbParameterGroup,
                                DBCluster targetDbCluster) {

        System.err.println("Creating target " + name + " instance...");

        CreateDbInstanceRequest.Builder requestBuilder = CreateDbInstanceRequest.builder()
                .dbInstanceClass(instanceType.value())
                .dbInstanceIdentifier(String.format("neptune-export-%s-%s", name, UUID.randomUUID().toString().substring(0, 5)))
                .dbClusterIdentifier(targetDbCluster.dbClusterIdentifier())
                .dbParameterGroupName(dbParameterGroup.dbParameterGroupName())
                .engine("neptune")
                .tags(getTags(sourceClusterMetadata.clusterId()))
                ;

        if (StringUtils.isNotEmpty(engineVersion)) {
            requestBuilder = requestBuilder.engineVersion(engineVersion);
        }

        // Retry configuration
        int maxRetries = 3;
        long initialBackoffMillis = 1000; // 1 second
        DBInstance targetDbInstance = null;
        CreateDbInstanceRequest request = requestBuilder.build();
        
        // Retry loop with exponential backoff
        for (int attempt = 0; attempt <= maxRetries; attempt++) {
            try {
                targetDbInstance = neptune.createDBInstance(request).dbInstance();
                // If we get here, the request was successful
                break;
            } catch (NeptuneException e) {
                // Check if we've exhausted our retries
                if (attempt == maxRetries) {
                    logger.error("Failed to create {} instance after {} attempts, with error {}", name, maxRetries, e.getMessage());
                    return;
                }


                
                // Calculate backoff time with exponential increase and some jitter
                long backoffMillis = initialBackoffMillis * (long) Math.pow(2, attempt);
                long jitterMillis = (long) (backoffMillis * 0.2 * Math.random()); // 20% jitter
                long totalBackoffMillis = backoffMillis + jitterMillis;

                logger.debug("Failed to create {} instance (attempt {} of {}): {}. Retrying...", name, attempt + 1, maxRetries, e.getMessage());
                
                try {
                    Thread.sleep(totalBackoffMillis);
                } catch (InterruptedException ie) {
                    Thread.currentThread().interrupt();
                    throw new RuntimeException("Instance creation interrupted", ie);
                }
            }
        }
        
        if (targetDbInstance == null) {
            logger.warn("Failed to create DB instance {} after exhausting all retries", name);
            return;
        }

        String instanceStatus = targetDbInstance.dbInstanceStatus();

        while (instanceStatus.equals("creating")) {
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            instanceStatus = neptune.describeDBInstances(DescribeDbInstancesRequest.builder()
                            .dbInstanceIdentifier(targetDbInstance.dbInstanceIdentifier()).build())
                    .dbInstances()
                    .get(0)
                    .dbInstanceStatus();
        }
    }