-
Notifications
You must be signed in to change notification settings - Fork 178
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
gergo/web 2158 previews module multi region #3492
Changes from all commits
885826a
dab4b3a
d55296a
0e78c27
05f8bec
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,29 +1,74 @@ | ||
import { knexLogger as logger } from '@/observability/logging.js' | ||
import { getPostgresConnectionString, getPostgresMaxConnections } from '@/utils/env.js' | ||
import * as knex from 'knex' | ||
import { get } from 'lodash-es' | ||
|
||
// CJS interop (types are off) | ||
const knexBuilder = (get(knex, 'default') || | ||
get(knex, 'knex')) as unknown as typeof knex.knex | ||
|
||
export const db = knexBuilder({ | ||
client: 'pg', | ||
connection: { | ||
// eslint-disable-next-line camelcase | ||
application_name: 'speckle_preview_service', | ||
connectionString: getPostgresConnectionString() | ||
}, | ||
pool: { | ||
min: 0, | ||
max: getPostgresMaxConnections(), | ||
acquireTimeoutMillis: 16000, //allows for 3x creation attempts plus idle time between attempts | ||
createTimeoutMillis: 5000 | ||
}, | ||
log: { | ||
warn: (message) => logger.warn(message), | ||
error: (message) => logger.error(message), | ||
debug: (message) => logger.debug(message) | ||
import Environment from '@speckle/shared/dist/commonjs/environment/index.js' | ||
import { | ||
loadMultiRegionsConfig, | ||
configureKnexClient | ||
} from '@speckle/shared/dist/commonjs/environment/multiRegionConfig.js' | ||
import { Knex } from 'knex' | ||
|
||
const { FF_WORKSPACES_MULTI_REGION_ENABLED } = Environment.getFeatureFlags() | ||
|
||
type ConfiguredKnexClient = ReturnType<typeof configureKnexClient> | ||
export type DbClients = Record<'main', ConfiguredKnexClient> & | ||
Record<string, ConfiguredKnexClient> | ||
let dbClients: DbClients | ||
|
||
const isDevEnv = process.env.NODE_ENV === 'development' | ||
|
||
export const getDbClients = async () => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is already better than it was, but in the future we can probably even extract a lot of this DB querying/"repository" logic that is common between these BG services into shared as well There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think in future, preview service should be given a short-lived API token and call the API on the server instead of duplicating the objects stuff. |
||
if (dbClients) return dbClients | ||
const maxConnections = getPostgresMaxConnections() | ||
|
||
const configArgs = { | ||
migrationDirs: [], | ||
isTestEnv: isDevEnv, | ||
isDevOrTestEnv: isDevEnv, | ||
logger, | ||
maxConnections, | ||
applicationName: 'speckle_fileimport_service' | ||
} | ||
if (!FF_WORKSPACES_MULTI_REGION_ENABLED) { | ||
const mainClient = configureKnexClient( | ||
{ | ||
postgres: { | ||
connectionUri: getPostgresConnectionString() | ||
} | ||
}, | ||
configArgs | ||
) | ||
dbClients = { main: mainClient } | ||
} else { | ||
const configPath = process.env.MULTI_REGION_CONFIG_PATH || 'multiregion.json' | ||
const config = await loadMultiRegionsConfig({ path: configPath }) | ||
const clients = [['main', configureKnexClient(config.main, configArgs)]] | ||
Object.entries(config.regions).map(([key, config]) => { | ||
clients.push([key, configureKnexClient(config, configArgs)]) | ||
}) | ||
dbClients = Object.fromEntries(clients) as DbClients | ||
} | ||
// migrations are managed in the server package | ||
}) | ||
return dbClients | ||
} | ||
|
||
export const getProjectDbClient = async ({ | ||
projectId | ||
}: { | ||
projectId: string | ||
}): Promise<Knex> => { | ||
const dbClients = await getDbClients() | ||
const mainDb = dbClients.main.public | ||
if (!FF_WORKSPACES_MULTI_REGION_ENABLED) return mainDb | ||
|
||
const projectRegion = await mainDb<{ id: string; regionKey: string }>('streams') | ||
.select('id', 'regionKey') | ||
.where({ id: projectId }) | ||
.first() | ||
|
||
if (!projectRegion) return mainDb | ||
|
||
const regionDb = dbClients[projectRegion.regionKey] | ||
if (!regionDb) | ||
throw new Error(`Project region client not found for ${projectRegion.regionKey}`) | ||
|
||
return regionDb.public | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the .then()/.catch() bits are redundant