mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-14 17:02:49 +03:00
console: fix neon DB connection error due to env var propagation delay
PR-URL: https://github.com/hasura/graphql-engine-mono/pull/9430 Co-authored-by: Rikin Kachhia <54616969+rikinsk@users.noreply.github.com> GitOrigin-RevId: ea407dae924ef2e88c4cb27b2207f52dc0fdf125
This commit is contained in:
parent
aeb8bc4c7a
commit
d3fd27d9db
@ -59,7 +59,8 @@ const DBCreation: React.FC<Props> = ({
|
||||
const dbName = allDataSources.length ? `herokuapp-${appName}` : 'default';
|
||||
setIsSettingEnvVar(true);
|
||||
setDBURLInEnvVars(dbURL)
|
||||
.then(envVar => {
|
||||
.then(data => {
|
||||
const { envVar } = data;
|
||||
setIsSettingEnvVar(false);
|
||||
setCreatedEnvVar(envVar);
|
||||
dispatch(
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { useState, useCallback } from 'react';
|
||||
import { useCallback, useState } from 'react';
|
||||
import { programmaticallyTraceError } from '../../../../../../features/Analytics';
|
||||
import { Dispatch } from '../../../../../../types';
|
||||
import {
|
||||
@ -12,6 +12,11 @@ import {
|
||||
connectionTypes,
|
||||
getDefaultState,
|
||||
} from '../../../DataSources/state';
|
||||
import Globals from '../../../../../../Globals';
|
||||
import {
|
||||
controlPlaneClient,
|
||||
FETCH_CONFIG_STATUS,
|
||||
} from '../../../../../../features/ControlPlane';
|
||||
|
||||
type HasuraDBCreationPayload = {
|
||||
envVar: string;
|
||||
@ -105,7 +110,8 @@ export function useCreateHasuraCloudDatasource(
|
||||
|
||||
// This sets the database URL of the given Hasura project as an env var in Hasura Cloud project
|
||||
setDBURLInEnvVars(dbUrl)
|
||||
.then(envVar => {
|
||||
.then(data => {
|
||||
const { envVar, oldConfigHash } = data;
|
||||
setState({
|
||||
status: 'adding-data-source',
|
||||
payload: {
|
||||
@ -113,38 +119,19 @@ export function useCreateHasuraCloudDatasource(
|
||||
dataSourceName,
|
||||
},
|
||||
});
|
||||
/*
|
||||
There's a downtime after env var updation.
|
||||
So we verify the project health and attempt connecting datasource only after project is up
|
||||
We start verifying the project health after a timeout of 5000 seconds,
|
||||
because it could 2-3 seconds for the project to go down after the environment variable update
|
||||
*/
|
||||
setTimeout(() => {
|
||||
verifyProjectHealthAndConnectDataSource(
|
||||
|
||||
const successCallback = () => {
|
||||
executeConnect(
|
||||
envVar,
|
||||
// set success status when the data source gets added successfully
|
||||
() => {
|
||||
executeConnect(
|
||||
envVar,
|
||||
// set success status when the data source gets added successfully
|
||||
() => {
|
||||
setState({
|
||||
status: 'success',
|
||||
payload: {
|
||||
envVar,
|
||||
dataSourceName,
|
||||
},
|
||||
});
|
||||
setState({
|
||||
status: 'success',
|
||||
payload: {
|
||||
envVar,
|
||||
dataSourceName,
|
||||
},
|
||||
// set error status when the data source gets added successfully
|
||||
() => {
|
||||
setState({
|
||||
status: 'adding-data-source-failed',
|
||||
payload: {
|
||||
envVar,
|
||||
dataSourceName,
|
||||
},
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
},
|
||||
// set error status if creating env var failed
|
||||
() => {
|
||||
@ -157,7 +144,61 @@ export function useCreateHasuraCloudDatasource(
|
||||
});
|
||||
}
|
||||
);
|
||||
}, 5000);
|
||||
};
|
||||
const errorCallback = () => {
|
||||
setState({
|
||||
status: 'adding-data-source-failed',
|
||||
payload: {
|
||||
envVar,
|
||||
dataSourceName,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Getting a success response on adding an env var for a tenant on lux does not
|
||||
* mean that the change has propagated to all workers of that tenant.
|
||||
*
|
||||
* If the change has not propagated to a worker to which the `pg_add_source` request is routed to,
|
||||
* the server would throw an `inconsistent_object` error as the new env var will not be found.
|
||||
*
|
||||
* To handle this, we wait for the changes to be propagated to all
|
||||
* workers of a tenant before attempting to connect the DB.
|
||||
*
|
||||
* We do that by verifying that the new config hash has been set
|
||||
* for all workers of the tenant using the `config_status` table.
|
||||
*
|
||||
* Additionally add a timeout interval with retries as an additional
|
||||
* redundancy since it throws CORS error locally
|
||||
*/
|
||||
const { unsubscribe } = controlPlaneClient.subscribe(
|
||||
FETCH_CONFIG_STATUS,
|
||||
{
|
||||
tenantId: Globals.hasuraCloudTenantId,
|
||||
},
|
||||
data => {
|
||||
if (
|
||||
// check if all workers are successfully configured with the new hash
|
||||
data.config_status.every(
|
||||
(config: { hash: string; message: string }) =>
|
||||
config.message === 'Service configured successfully' &&
|
||||
config.hash !== oldConfigHash
|
||||
)
|
||||
) {
|
||||
setTimeout(() => {
|
||||
verifyProjectHealthAndConnectDataSource(
|
||||
successCallback,
|
||||
errorCallback
|
||||
);
|
||||
}, 1000);
|
||||
unsubscribe();
|
||||
}
|
||||
},
|
||||
error => {
|
||||
errorCallback();
|
||||
unsubscribe();
|
||||
}
|
||||
);
|
||||
})
|
||||
.catch(error => {
|
||||
// if adding env var fails unexpectedly, set the error state
|
||||
@ -189,7 +230,7 @@ export function useCreateHasuraCloudDatasource(
|
||||
});
|
||||
});
|
||||
}
|
||||
}, [dbUrl, dataSourceName, state]);
|
||||
}, [dbUrl, dataSourceName, executeConnect]);
|
||||
|
||||
return {
|
||||
state,
|
||||
|
@ -129,7 +129,7 @@ export const setDBURLInEnvVars = (dbURL: string) => {
|
||||
value: dbURL,
|
||||
},
|
||||
]).then(() => {
|
||||
return emptyEnvVar;
|
||||
return { envVar: emptyEnvVar, oldConfigHash: hash };
|
||||
});
|
||||
})
|
||||
.catch(e => {
|
||||
|
@ -263,3 +263,17 @@ export const ADD_SCHEMA_REGISTRY_FEATURE_REQUEST = gql(`
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
||||
export const FETCH_CONFIG_STATUS = gql(`
|
||||
subscription FetchConfigStatus($tenantId: uuid!) {
|
||||
config_status(
|
||||
where: {
|
||||
tenant_id: { _eq: $tenantId }
|
||||
is_active: { _eq: true }
|
||||
}
|
||||
) {
|
||||
hash
|
||||
message
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
Loading…
Reference in New Issue
Block a user