Skip to content
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

chore(server): various useful multiregion changes from comments pr #3499

Merged
merged 8 commits into from
Nov 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -595,13 +595,13 @@ jobs:
POSTGRES_DB: speckle2_test
POSTGRES_PASSWORD: speckle
POSTGRES_USER: speckle
command: -c 'max_connections=1000'
command: -c 'max_connections=1000' -c 'wal_level=logical'
- image: 'speckle/speckle-postgres'
environment:
POSTGRES_DB: speckle2_test
POSTGRES_PASSWORD: speckle
POSTGRES_USER: speckle
command: -c 'max_connections=1000' -c 'port=5433'
command: -c 'max_connections=1000' -c 'port=5433' -c 'wal_level=logical'
- image: 'minio/minio'
command: server /data --console-address ":9001"
environment:
Expand All @@ -623,8 +623,10 @@ jobs:
S3_REGION: '' # optional, defaults to 'us-east-1'
AUTOMATE_ENCRYPTION_KEYS_PATH: 'test/assets/automate/encryptionKeys.json'
FF_BILLING_INTEGRATION_ENABLED: 'true'
# These are the only 2 different env keys:
# These are the only different env keys:
MULTI_REGION_CONFIG_PATH: '../../.circleci/multiregion.test-ci.json'
FF_WORKSPACES_MODULE_ENABLED: 'true'
FF_WORKSPACES_MULTI_REGION_ENABLED: 'true'
RUN_TESTS_IN_MULTIREGION_MODE: true

test-frontend-2:
Expand Down
10 changes: 5 additions & 5 deletions packages/frontend-2/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,11 @@
"@babel/preset-typescript": "^7.18.6",
"@datadog/datadog-ci": "^2.37.0",
"@eslint/config-inspector": "^0.4.10",
"@graphql-codegen/cli": "^5.0.2",
"@graphql-codegen/client-preset": "^4.3.0",
"@graphql-codegen/plugin-helpers": "^5.0.4",
"@graphql-codegen/typescript": "^4.0.9",
"@graphql-codegen/visitor-plugin-common": "5.3.1",
"@graphql-codegen/cli": "^5.0.3",
"@graphql-codegen/client-preset": "^4.5.0",
"@graphql-codegen/plugin-helpers": "^5.1.0",
"@graphql-codegen/typescript": "^4.1.1",
"@graphql-codegen/visitor-plugin-common": "5.5.0",
"@nuxt/devtools": "^1.3.9",
"@nuxt/eslint": "^0.3.13",
"@nuxt/image": "^1.8.1",
Expand Down
3 changes: 2 additions & 1 deletion packages/server/db/knex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export default knexInstance
export {
knexInstance as db,
knexInstance as knex,
knexInstance as knexInstance,
knexInstance as mainDb,
knexInstance,
config
}
13 changes: 13 additions & 0 deletions packages/server/modules/cli/commands/workspaces.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { noop } from 'lodash'
import { CommandModule } from 'yargs'

const command: CommandModule = {
command: 'workspaces',
describe: 'Various workspace related actions',
builder(yargs) {
return yargs.commandDir('workspaces', { extensions: ['js', 'ts'] }).demandCommand()
},
handler: noop
}

export = command
67 changes: 67 additions & 0 deletions packages/server/modules/cli/commands/workspaces/set-plan.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { CommandModule } from 'yargs'
import { cliLogger } from '@/logging/logging'
import { getWorkspaceBySlugOrIdFactory } from '@/modules/workspaces/repositories/workspaces'
import { db } from '@/db/knex'
import {
PaidWorkspacePlanStatuses,
PlanStatuses
} from '@/modules/gatekeeper/domain/billing'
import { upsertPaidWorkspacePlanFactory } from '@/modules/gatekeeper/repositories/billing'
import { PaidWorkspacePlans } from '@/modules/gatekeeper/domain/workspacePricing'

const command: CommandModule<
unknown,
{
workspaceSlugOrId: string
status: PlanStatuses
plan: PaidWorkspacePlans
}
> = {
command: 'set-plan <workspaceSlugOrId> [plan] [status]',
describe: 'Set a plan for a workspace.',
builder: {
workspaceSlugOrId: {
describe: 'Workspace ID or slug',
type: 'string'
},
plan: {
describe: 'Plan to set the status for',
type: 'string',
default: 'business',
choices: ['business', 'team', 'pro']
},
status: {
describe: 'Status to set for the workspace plan',
type: 'string',
default: 'valid',
choices: [
'valid',
'trial',
'expired',
'paymentFailed',
'cancelationScheduled',
'canceled'
]
}
},
handler: async (args) => {
cliLogger.info(
`Setting plan for workspace '${args.workspaceSlugOrId}' to '${args.plan}' with status '${args.status}'`
)
const workspace = await getWorkspaceBySlugOrIdFactory({ db })(args)
if (!workspace) {
throw new Error(`Workspace w/ slug or id '${args.workspaceSlugOrId}' not found`)
}

await upsertPaidWorkspacePlanFactory({ db })({
workspacePlan: {
workspaceId: workspace.id,
name: args.plan,
status: args.status as PaidWorkspacePlanStatuses
}
})
cliLogger.info(`Plan set!`)
}
}

export = command
13 changes: 9 additions & 4 deletions packages/server/modules/comments/repositories/comments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ export const getPaginatedCommitCommentsTotalCountFactory =
(deps: { db: Knex }): GetPaginatedCommitCommentsTotalCount =>
async (params: Omit<PaginatedCommitCommentsParams, 'limit' | 'cursor'>) => {
const baseQ = getPaginatedCommitCommentsBaseQueryFactory(deps)(params)
const q = knex.count<{ count: string }[]>().from(baseQ.as('sq1'))
const q = deps.db.count<{ count: string }[]>().from(baseQ.as('sq1'))
const [row] = await q

return parseInt(row.count || '0')
Expand Down Expand Up @@ -476,7 +476,7 @@ export const getPaginatedBranchCommentsTotalCountFactory =
(deps: { db: Knex }) =>
async (params: Omit<PaginatedBranchCommentsParams, 'limit' | 'cursor'>) => {
const baseQ = getPaginatedBranchCommentsBaseQueryFactory(deps)(params)
const q = knex.count<{ count: string }[]>().from(baseQ.as('sq1'))
const q = deps.db.count<{ count: string }[]>().from(baseQ.as('sq1'))
const [row] = await q

return parseInt(row.count || '0')
Expand Down Expand Up @@ -673,7 +673,7 @@ export const getPaginatedProjectCommentsTotalCountFactory =
params,
options
)
const q = knex.count<{ count: string }[]>().from(baseQuery.as('sq1'))
const q = deps.db.count<{ count: string }[]>().from(baseQuery.as('sq1'))
const [row] = await q

return parseInt(row.count || '0')
Expand Down Expand Up @@ -866,7 +866,12 @@ export const getCommentsLegacyFactory =
query.orderBy('createdAt', 'desc')
query.limit(limit || 1) // need at least 1 row to get totalCount

const rows = await query
const rows = (await query) as Array<
CommentRecord & {
total_count: string
resources: Array<{ resourceId: string; resourceType: string }>
}
>
const totalCount = rows && rows.length > 0 ? parseInt(rows[0].total_count) : 0
const nextCursor = rows && rows.length > 0 ? rows[rows.length - 1].createdAt : null

Expand Down
3 changes: 0 additions & 3 deletions packages/server/modules/core/graph/resolvers/versions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,6 @@ export = {
},
VersionMutations: {
async moveToModel(_parent, args, ctx) {
// TODO: how to get streamId here?
const projectId = args.input.projectId
const projectDb = await getProjectDbClient({ projectId })

Expand All @@ -121,7 +120,6 @@ export = {
return await batchMoveCommits(args.input, ctx.userId!)
},
async delete(_parent, args, ctx) {
// TODO: how to get streamId here?
const projectId = args.input.projectId
const projectDb = await getProjectDbClient({ projectId })

Expand All @@ -138,7 +136,6 @@ export = {
return true
},
async update(_parent, args, ctx) {
// TODO: how to get streamId here?
const projectId = args.input.projectId
const projectDb = await getProjectDbClient({ projectId })
const stream = await ctx.loaders
Expand Down
7 changes: 5 additions & 2 deletions packages/server/modules/core/helpers/graphTypes.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
CommitWithStreamBranchId,
CommitWithStreamId,
LegacyStreamCommit,
LegacyUserCommit
} from '@/modules/core/domain/commits/types'
Expand All @@ -12,7 +13,6 @@ import {
import { Roles, ServerRoles, StreamRoles } from '@/modules/core/helpers/mainConstants'
import {
BranchRecord,
CommitRecord,
ObjectRecord,
ServerInfo,
StreamRecord,
Expand All @@ -36,7 +36,10 @@ export type StreamGraphQLReturn = StreamRecord & {
role?: string | null
}

export type CommitGraphQLReturn = CommitRecord | LegacyStreamCommit | LegacyUserCommit
export type CommitGraphQLReturn =
| CommitWithStreamId
| LegacyStreamCommit
| LegacyUserCommit

export type BranchGraphQLReturn = BranchRecord

Expand Down
4 changes: 4 additions & 0 deletions packages/server/modules/core/loaders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ export async function buildRequestLoaders(
* Get dataloaders for specific region
*/
const forRegion = (deps: { db: Knex }) => {
if (deps.db === mainDb) {
return mainDbLoaders
}

if (!regionLoaders.has(deps.db)) {
regionLoaders.set(deps.db, createLoadersForRegion(deps))
}
Expand Down
2 changes: 1 addition & 1 deletion packages/server/modules/core/repositories/branches.ts
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,7 @@ export const getPaginatedProjectModelsTotalCountFactory =
}

const baseQ = getPaginatedProjectModelsBaseQueryFactory(deps)(projectId, params)
const q = knex.count<{ count: string }[]>().from(baseQ.as('sq1'))
const q = deps.db.count<{ count: string }[]>().from(baseQ.as('sq1'))

const [res] = await q
return parseInt(res?.count || '0')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ describe('FileUploads @fileuploads', () => {
.set('Authorization', `Bearer ${userOneToken}`)
.set('Accept', 'application/json')
.attach('test.ifc', require.resolve('@/readme.md'), 'test.ifc')
expect(response.statusCode).to.equal(500) //FIXME should be 404 (technically a 401, but we don't want to leak existence of stream so 404 is preferrable)
expect(response.statusCode).to.equal(404) //FIXME should be 404 (technically a 401, but we don't want to leak existence of stream so 404 is preferrable)
const gqlResponse = await sendRequest(userOneToken, {
query: `query ($streamId: String!) {
stream(id: $streamId) {
Expand Down
5 changes: 5 additions & 0 deletions packages/server/modules/gatekeeper/domain/billing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ export type PaidWorkspacePlanStatuses =

export type TrialWorkspacePlanStatuses = 'trial' | 'expired'

export type PlanStatuses =
| PaidWorkspacePlanStatuses
| TrialWorkspacePlanStatuses
| UnpaidWorkspacePlanStatuses

type BaseWorkspacePlan = {
workspaceId: string
}
Expand Down
8 changes: 5 additions & 3 deletions packages/server/modules/multiregion/regionConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@ import {
let multiRegionConfig: Optional<MultiRegionConfig> = undefined

const getMultiRegionConfig = async (): Promise<MultiRegionConfig> => {
const emptyReturn = () => ({ main: { postgres: { connectionUri: '' } }, regions: {} })

if (isDevOrTestEnv() && !isMultiRegionEnabled()) {
// this should throw somehow
return { main: { postgres: { connectionUri: '' } }, regions: {} }
return emptyReturn()
}

if (!multiRegionConfig) {
const relativePath = getMultiRegionConfigPath()
const relativePath = getMultiRegionConfigPath({ unsafe: isDevOrTestEnv() })
if (!relativePath) return emptyReturn()

const configPath = path.resolve(packageRoot, relativePath)

Expand Down
Loading