Skip to content

Conversation

@HUAHUAI23
Copy link
Collaborator

No description provided.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds backward compatibility support for KubeBlock v5 MongoDB 5.0 clusters by calling an external upgrade API during horizontal scaling operations.

Key Changes:

  • Added new configuration constant KUBEBLOCK_V5_UPGRADE_URL for the external upgrade API endpoint
  • Integrated KubeBlock v5 upgrade API call into the horizontal scaling workflow with 3-second timeout
  • Implemented version detection logic to identify v5 MongoDB 5.0 clusters using cluster labels

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
server/src/constants.ts Added configuration for the v5 upgrade URL and timeout constant (3s)
server/src/database/dedicated-database/dedicated-database.service.ts Implemented v5 compatibility layer with manifest detection, API call handling, and response parsing for horizontal scaling operations

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +780 to +791
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
namespace,
database_name: clusterName,
replicas,
}),
signal: controller.signal,
})
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fetch API is being used directly without any visible import. While fetch is globally available in Node.js 18+, this codebase appears to use @nestjs/axios (HttpService) for HTTP requests elsewhere in the project (e.g., in http-interceptor.service.ts, wechat-pay.service.ts). For consistency and better error handling, consider using the injected HttpService instead of the global fetch API.

Using HttpService would provide:

  • Consistent error handling patterns across the codebase
  • Built-in timeout support via axios configuration
  • Better integration with NestJS ecosystem

Copilot uses AI. Check for mistakes.
Comment on lines +793 to +802
const responseData = await this.parseKubeBlockV5Response(response)

if (!response.ok) {
throw new Error(
`HTTP error! status: ${response.status}, statusText: ${
response.statusText
}, body: ${JSON.stringify(responseData)}`,
)
}

Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The response parsing happens before checking response.ok, which means the response body is consumed before the error check. If the response is not OK and has a large body, this could be inefficient. More importantly, if parseKubeBlockV5Response fails (e.g., malformed JSON), the error message won't include the HTTP status information.

Consider checking response.ok first, then parsing the response body only when needed:

if (!response.ok) {
  const errorBody = await this.parseKubeBlockV5Response(response)
  throw new Error(
    `HTTP error! status: ${response.status}, statusText: ${response.statusText}, body: ${JSON.stringify(errorBody)}`
  )
}

const responseData = await this.parseKubeBlockV5Response(response)
Suggested change
const responseData = await this.parseKubeBlockV5Response(response)
if (!response.ok) {
throw new Error(
`HTTP error! status: ${response.status}, statusText: ${
response.statusText
}, body: ${JSON.stringify(responseData)}`,
)
}
if (!response.ok) {
const errorBody = await this.parseKubeBlockV5Response(response)
throw new Error(
`HTTP error! status: ${response.status}, statusText: ${
response.statusText
}, body: ${JSON.stringify(errorBody)}`,
)
}
const responseData = await this.parseKubeBlockV5Response(response)

Copilot uses AI. Check for mistakes.
Comment on lines +741 to +743
this.logger.error(
`Failed to call KubeBlock v5 upgrade API for ${appid}: ${error.message}`,
)
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When the AbortController aborts the request due to timeout, it will throw an AbortError. However, this error is caught by the outer try-catch in handleKubeBlockV5Upgrade (line 740-745) which only logs error.message. For AbortError, the message might not clearly indicate it was a timeout.

Consider adding specific handling for timeout errors to provide clearer logging:

} catch (error) {
  if (error.name === 'AbortError') {
    this.logger.error(
      `KubeBlock v5 upgrade API timeout (${KUBEBLOCK_V5_UPGRADE_API_TIMEOUT}ms) for ${appid}`
    )
  } else {
    this.logger.error(
      `Failed to call KubeBlock v5 upgrade API for ${appid}: ${error.message}`
    )
  }
}
Suggested change
this.logger.error(
`Failed to call KubeBlock v5 upgrade API for ${appid}: ${error.message}`,
)
if (error.name === 'AbortError') {
this.logger.error(
`KubeBlock v5 upgrade API timeout (${KUBEBLOCK_V5_UPGRADE_API_TIMEOUT}ms) for ${appid}`
)
} else {
this.logger.error(
`Failed to call KubeBlock v5 upgrade API for ${appid}: ${error.message}`,
)
}

Copilot uses AI. Check for mistakes.
Comment on lines +769 to +770
const clusterName = manifest.metadata.name
const namespace = manifest.metadata.namespace
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing null/undefined safety checks for manifest.metadata.name and manifest.metadata.namespace. While the manifest is passed from the calling function and likely has these properties, adding defensive checks would prevent potential runtime errors and align with the defensive programming pattern used elsewhere in the method (e.g., line 727).

Consider adding validation:

const clusterName = manifest?.metadata?.name
const namespace = manifest?.metadata?.namespace

if (!clusterName || !namespace) {
  throw new Error('Invalid manifest: missing name or namespace')
}
Suggested change
const clusterName = manifest.metadata.name
const namespace = manifest.metadata.namespace
const clusterName = manifest?.metadata?.name
const namespace = manifest?.metadata?.namespace
if (!clusterName || !namespace) {
throw new Error('Invalid manifest: missing name or namespace')
}

Copilot uses AI. Check for mistakes.
@HUAHUAI23 HUAHUAI23 merged commit d7a1d25 into labring:main Dec 1, 2025
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant