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

fix: optimised the artifacts listing query and added query versioned support #4375

Merged
merged 2 commits into from
Dec 8, 2023
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
6 changes: 6 additions & 0 deletions api/bean/ValuesOverrideRequest.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,9 @@ type ArtifactsListFilterOptions struct {
PipelineId int
StageType WorkflowType

// CiPipelineId is id of ci-pipeline present in the same app-workflow of PipelineId
CiPipelineId int

//parent satge data
ParentCdId int
ParentId int
Expand All @@ -126,4 +129,7 @@ type ArtifactsListFilterOptions struct {

//pluginStage
PluginStage string

// UseCdStageQueryV2 is to set query version
UseCdStageQueryV2 bool
}
11 changes: 10 additions & 1 deletion internal/sql/repository/CiArtifactRepository.go
Original file line number Diff line number Diff line change
Expand Up @@ -713,13 +713,22 @@ func (impl CiArtifactRepositoryImpl) GetArtifactsByParentCiWorkflowId(parentCiWo
func (impl CiArtifactRepositoryImpl) FindArtifactByListFilter(listingFilterOptions *bean.ArtifactsListFilterOptions) ([]CiArtifact, int, error) {

var ciArtifactsResp []CiArtifactWithExtraData
var ciArtifacts []CiArtifact
ciArtifacts := make([]CiArtifact, 0)
totalCount := 0
finalQuery := BuildQueryForArtifactsForCdStage(*listingFilterOptions)
_, err := impl.dbConnection.Query(&ciArtifactsResp, finalQuery)
if err == pg.ErrNoRows || len(ciArtifactsResp) == 0 {
return ciArtifacts, totalCount, nil
}

if listingFilterOptions.UseCdStageQueryV2 {
for _, cia := range ciArtifactsResp {
totalCount = cia.TotalCount
ciArtifacts = append(ciArtifacts, cia.CiArtifact)
}
return ciArtifacts, totalCount, err
}

artifactIds := make([]int, len(ciArtifactsResp))
for i, af := range ciArtifactsResp {
artifactIds[i] = af.Id
Expand Down
34 changes: 34 additions & 0 deletions internal/sql/repository/CiArtifactsListingQueryBuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ func BuildQueryForArtifactsForCdStage(listingFilterOptions bean.ArtifactsListFil
// expected result -> will fetch all successfully deployed artifacts ar parent stage plus its own stage. Along with this it will
// also fetch all artifacts generated by plugin at pre_cd or post_cd process (will use data_source in ci artifact table for this)

if listingFilterOptions.UseCdStageQueryV2 {
return buildQueryForArtifactsForCdStageV2(listingFilterOptions)
}

commonQuery := " from ci_artifact LEFT JOIN cd_workflow ON ci_artifact.id = cd_workflow.ci_artifact_id" +
" LEFT JOIN cd_workflow_runner ON cd_workflow_runner.cd_workflow_id=cd_workflow.id " +
" Where (((cd_workflow_runner.id in (select MAX(cd_workflow_runner.id) OVER (PARTITION BY cd_workflow.ci_artifact_id) FROM cd_workflow_runner inner join cd_workflow on cd_workflow.id=cd_workflow_runner.cd_workflow_id))" +
Expand All @@ -72,6 +76,36 @@ func BuildQueryForArtifactsForCdStage(listingFilterOptions bean.ArtifactsListFil
return finalQuery
}

func buildQueryForArtifactsForCdStageV2(listingFilterOptions bean.ArtifactsListFilterOptions) string {
whereCondition := fmt.Sprintf(" WHERE (id IN ("+
" SELECT DISTINCT(cd_workflow.ci_artifact_id) as ci_artifact_id "+
" FROM cd_workflow_runner"+
" INNER JOIN cd_workflow ON cd_workflow.id = cd_workflow_runner.cd_workflow_id "+
" AND (cd_workflow.pipeline_id = %d OR cd_workflow.pipeline_id = %d)"+
" WHERE ("+
" (cd_workflow.pipeline_id = %d AND cd_workflow_runner.workflow_type = '%s')"+
" OR"+
" (cd_workflow.pipeline_id = %d"+
" AND cd_workflow_runner.workflow_type = '%s'"+
" AND cd_workflow_runner.status IN ('Healthy','Succeeded')"+
" )"+
" ) ) ", listingFilterOptions.PipelineId, listingFilterOptions.ParentId, listingFilterOptions.PipelineId, listingFilterOptions.StageType, listingFilterOptions.ParentId, listingFilterOptions.ParentStageType)

whereCondition = fmt.Sprintf(" %s OR (ci_artifact.component_id = %d AND ci_artifact.data_source= '%s' ))", whereCondition, listingFilterOptions.ParentId, listingFilterOptions.PluginStage)
if listingFilterOptions.SearchString != EmptyLikeRegex {
whereCondition = whereCondition + fmt.Sprintf(" AND ci_artifact.image LIKE '%s' ", listingFilterOptions.SearchString)
}
if len(listingFilterOptions.ExcludeArtifactIds) > 0 {
whereCondition = whereCondition + fmt.Sprintf(" AND ( ci_artifact.id NOT IN (%s))", helper.GetCommaSepratedString(listingFilterOptions.ExcludeArtifactIds))
}

selectQuery := fmt.Sprintf(" SELECT ci_artifact.* ,COUNT(id) OVER() AS total_count " +
" FROM ci_artifact")
ordeyByAndPaginated := fmt.Sprintf(" ORDER BY id DESC LIMIT %d OFFSET %d ", listingFilterOptions.Limit, listingFilterOptions.Offset)
finalQuery := selectQuery + whereCondition + ordeyByAndPaginated
return finalQuery
}

func BuildQueryForArtifactsForRollback(listingFilterOptions bean.ArtifactsListFilterOptions) string {
commonQuery := " FROM cd_workflow_runner cdwr " +
" INNER JOIN cd_workflow cdw ON cdw.id=cdwr.cd_workflow_id " +
Expand Down
11 changes: 10 additions & 1 deletion pkg/pipeline/AppArtifactManager.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/devtron-labs/devtron/internal/sql/repository/pipelineConfig"
bean2 "github.com/devtron-labs/devtron/pkg/bean"
repository2 "github.com/devtron-labs/devtron/pkg/pipeline/repository"
"github.com/devtron-labs/devtron/pkg/pipeline/types"
"github.com/devtron-labs/devtron/pkg/user"
"github.com/go-pg/pg"
"go.uber.org/zap"
Expand Down Expand Up @@ -56,6 +57,7 @@ type AppArtifactManagerImpl struct {
ciArtifactRepository repository.CiArtifactRepository
ciWorkflowRepository pipelineConfig.CiWorkflowRepository
pipelineStageService PipelineStageService
config *types.CdConfig
cdPipelineConfigService CdPipelineConfigService
dockerArtifactRegistry dockerArtifactStoreRegistry.DockerArtifactStoreRepository
CiPipelineRepository pipelineConfig.CiPipelineRepository
Expand All @@ -74,7 +76,10 @@ func NewAppArtifactManagerImpl(
dockerArtifactRegistry dockerArtifactStoreRegistry.DockerArtifactStoreRepository,
CiPipelineRepository pipelineConfig.CiPipelineRepository,
ciTemplateService CiTemplateService) *AppArtifactManagerImpl {

cdConfig, err := types.GetCdConfig()
if err != nil {
return nil
}
return &AppArtifactManagerImpl{
logger: logger,
cdWorkflowRepository: cdWorkflowRepository,
Expand All @@ -84,6 +89,7 @@ func NewAppArtifactManagerImpl(
ciWorkflowRepository: ciWorkflowRepository,
cdPipelineConfigService: cdPipelineConfigService,
pipelineStageService: pipelineStageService,
config: cdConfig,
dockerArtifactRegistry: dockerArtifactRegistry,
CiPipelineRepository: CiPipelineRepository,
ciTemplateService: ciTemplateService,
Expand Down Expand Up @@ -606,11 +612,14 @@ func (impl *AppArtifactManagerImpl) RetrieveArtifactsByCDPipelineV2(pipeline *pi
ciArtifactsResponse := &bean2.CiArtifactResponse{}

artifactListingFilterOpts.PipelineId = pipeline.Id
// this will be 0 for external-ci cases, note: do not refer this for external-ci cases
artifactListingFilterOpts.CiPipelineId = pipeline.CiPipelineId
artifactListingFilterOpts.ParentId = parentId
artifactListingFilterOpts.ParentCdId = parentCdId
artifactListingFilterOpts.ParentStageType = parentType
artifactListingFilterOpts.StageType = stage
artifactListingFilterOpts.SearchString = "%" + artifactListingFilterOpts.SearchString + "%"
artifactListingFilterOpts.UseCdStageQueryV2 = impl.config.UseArtifactListingQueryV2
ciArtifactsRefs, latestWfArtifactId, latestWfArtifactStatus, totalCount, err := impl.BuildArtifactsList(artifactListingFilterOpts)
if err != nil && err != pg.ErrNoRows {
impl.logger.Errorw("error in getting artifacts for child cd stage", "err", err, "stage", stage)
Expand Down
1 change: 1 addition & 0 deletions pkg/pipeline/types/CiCdConfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ type CiCdConfig struct {
BuildxProvenanceMode string `env:"BUILDX_PROVENANCE_MODE" envDefault:""` //provenance is set to false if this flag is not set
ExtBlobStorageCmName string `env:"EXTERNAL_BLOB_STORAGE_CM_NAME" envDefault:"blob-storage-cm"`
ExtBlobStorageSecretName string `env:"EXTERNAL_BLOB_STORAGE_SECRET_NAME" envDefault:"blob-storage-secret"`
UseArtifactListingQueryV2 bool `env:"USE_ARTIFACT_LISTING_QUERY_V2" envDefault:"true"`
}

type CiConfig struct {
Expand Down
Loading