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 delayed diagnostics / job ordering #1417

Merged
merged 3 commits into from
Sep 26, 2023
Merged
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
126 changes: 67 additions & 59 deletions internal/indexer/document_change.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,15 @@ func (idx *Indexer) DocumentChanged(ctx context.Context, modHandle document.DirH
func (idx *Indexer) decodeModule(ctx context.Context, modHandle document.DirHandle, dependsOn job.IDs, ignoreState bool) (job.IDs, error) {
ids := make(job.IDs, 0)

// Changes to a setting currently requires a LS restart, so the LS
// setting context cannot change during the execution of a job. That's
// why we can extract it here and use it in Defer.
// See https://github.com/hashicorp/terraform-ls/issues/1008
validationOptions, err := lsctx.ValidationOptions(ctx)
if err != nil {
return ids, err
}

metaId, err := idx.jobStore.EnqueueJob(ctx, job.Job{
Dir: modHandle,
Func: func(ctx context.Context) error {
Expand All @@ -97,10 +106,10 @@ func (idx *Indexer) decodeModule(ctx context.Context, modHandle document.DirHand
Type: op.OpTypeLoadModuleMetadata.String(),
DependsOn: dependsOn,
IgnoreState: ignoreState,
Defer: func(ctx context.Context, jobErr error) (jobIds job.IDs, err error) {
Defer: func(ctx context.Context, jobErr error) (job.IDs, error) {
ids := make(job.IDs, 0)
if jobErr != nil {
err = jobErr
return
return ids, jobErr
}
modCalls, mcErr := idx.decodeDeclaredModuleCalls(ctx, modHandle, ignoreState)
if mcErr != nil {
Expand All @@ -115,14 +124,42 @@ func (idx *Indexer) decodeModule(ctx context.Context, modHandle document.DirHand
Func: func(ctx context.Context) error {
return module.PreloadEmbeddedSchema(ctx, idx.logger, schemas.FS, idx.modStore, idx.schemaStore, modHandle.Path())
},
DependsOn: modCalls,
Type: op.OpTypePreloadEmbeddedSchema.String(),
IgnoreState: ignoreState,
})
if err != nil {
return
return ids, err
}
ids = append(ids, eSchemaId)

if validationOptions.EarlyValidation {
_, err = idx.jobStore.EnqueueJob(ctx, job.Job{
Dir: modHandle,
Func: func(ctx context.Context) error {
return module.SchemaModuleValidation(ctx, idx.modStore, idx.schemaStore, modHandle.Path())
},
Type: op.OpTypeSchemaModuleValidation.String(),
DependsOn: append(modCalls, eSchemaId),
IgnoreState: ignoreState,
})
if err != nil {
return ids, err
}
}

refTargetsId, err := idx.jobStore.EnqueueJob(ctx, job.Job{
Dir: modHandle,
Func: func(ctx context.Context) error {
return module.DecodeReferenceTargets(ctx, idx.modStore, idx.schemaStore, modHandle.Path())
},
Type: op.OpTypeDecodeReferenceTargets.String(),
DependsOn: job.IDs{eSchemaId},
IgnoreState: ignoreState,
})
if err != nil {
return ids, err
}
jobIds = append(jobIds, eSchemaId)
ids = append(ids, refTargetsId)

refOriginsId, err := idx.jobStore.EnqueueJob(ctx, job.Job{
Dir: modHandle,
Expand All @@ -133,63 +170,33 @@ func (idx *Indexer) decodeModule(ctx context.Context, modHandle document.DirHand
DependsOn: append(modCalls, eSchemaId),
IgnoreState: ignoreState,
})
jobIds = append(jobIds, refOriginsId)
return
},
})
if err != nil {
return ids, err
}
ids = append(ids, metaId)

validationOptions, err := lsctx.ValidationOptions(ctx)
if err != nil {
return ids, err
}

if validationOptions.EarlyValidation {
_, err = idx.jobStore.EnqueueJob(ctx, job.Job{
Dir: modHandle,
Func: func(ctx context.Context) error {
return module.SchemaModuleValidation(ctx, idx.modStore, idx.schemaStore, modHandle.Path())
},
Type: op.OpTypeSchemaModuleValidation.String(),
DependsOn: job.IDs{metaId},
IgnoreState: ignoreState,
})
if err != nil {
return ids, err
}
}
if err != nil {
return ids, err
}
ids = append(ids, refOriginsId)

if validationOptions.EarlyValidation {
_, err = idx.jobStore.EnqueueJob(ctx, job.Job{
Dir: modHandle,
Func: func(ctx context.Context) error {
return module.ReferenceValidation(ctx, idx.modStore, idx.schemaStore, modHandle.Path())
},
Type: op.OpTypeReferenceValidation.String(),
DependsOn: job.IDs{refOriginsId, refTargetsId},
IgnoreState: ignoreState,
})
if err != nil {
return ids, err
}
}

refTargetsId, err := idx.jobStore.EnqueueJob(ctx, job.Job{
Dir: modHandle,
Func: func(ctx context.Context) error {
return module.DecodeReferenceTargets(ctx, idx.modStore, idx.schemaStore, modHandle.Path())
return ids, nil
},
Type: op.OpTypeDecodeReferenceTargets.String(),
DependsOn: job.IDs{metaId},
IgnoreState: ignoreState,
})
if err != nil {
return ids, err
}
ids = append(ids, refTargetsId)

if validationOptions.EarlyValidation {
_, err = idx.jobStore.EnqueueJob(ctx, job.Job{
Dir: modHandle,
Func: func(ctx context.Context) error {
return module.ReferenceValidation(ctx, idx.modStore, idx.schemaStore, modHandle.Path())
},
Type: op.OpTypeReferenceValidation.String(),
DependsOn: job.IDs{metaId, refTargetsId},
IgnoreState: ignoreState,
})
if err != nil {
return ids, err
}
}
ids = append(ids, metaId)

// This job may make an HTTP request, and we schedule it in
// the low-priority queue, so we don't want to wait for it.
Expand All @@ -199,8 +206,9 @@ func (idx *Indexer) decodeModule(ctx context.Context, modHandle document.DirHand
return module.GetModuleDataFromRegistry(ctx, idx.registryClient,
idx.modStore, idx.registryModStore, modHandle.Path())
},
Priority: job.LowPriority,
Type: op.OpTypeGetModuleDataFromRegistry.String(),
Priority: job.LowPriority,
DependsOn: job.IDs{metaId},
Type: op.OpTypeGetModuleDataFromRegistry.String(),
})
if err != nil {
return ids, err
Expand Down