perf(deployment): staleness/comparison paths no longer Roslyn-compile every script — deploy gate remains the authoritative compile
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
This commit is contained in:
@@ -648,8 +648,12 @@ public class DeploymentService
|
||||
if (snapshot == null)
|
||||
return Result<DeploymentComparisonResult>.Failure("No deployed snapshot found for this instance.");
|
||||
|
||||
// Compute current template-derived config
|
||||
var currentResult = await _flatteningPipeline.FlattenAndValidateAsync(instanceId, cancellationToken);
|
||||
// Compute current template-derived config. This read-only comparison only needs
|
||||
// the revision hash (staleness) + the flattened config (structured diff) — NOT a
|
||||
// script compile — so skip the expensive Roslyn ValidateScriptCompilation stage.
|
||||
// The deploy gate remains the authoritative compile.
|
||||
var currentResult = await _flatteningPipeline.FlattenAndValidateAsync(
|
||||
instanceId, cancellationToken, validateScripts: false);
|
||||
if (currentResult.IsFailure)
|
||||
return Result<DeploymentComparisonResult>.Failure($"Cannot compute current config: {currentResult.Error}");
|
||||
|
||||
|
||||
@@ -54,7 +54,8 @@ public class FlatteningPipeline : IFlatteningPipeline
|
||||
/// <inheritdoc />
|
||||
public async Task<Result<FlatteningPipelineResult>> FlattenAndValidateAsync(
|
||||
int instanceId,
|
||||
CancellationToken cancellationToken = default)
|
||||
CancellationToken cancellationToken = default,
|
||||
bool validateScripts = true)
|
||||
{
|
||||
// Load instance with full graph
|
||||
var instance = await _templateRepo.GetInstanceByIdAsync(instanceId, cancellationToken);
|
||||
@@ -158,13 +159,19 @@ public class FlatteningPipeline : IFlatteningPipeline
|
||||
// on the site — blocks the deployment. (The template DESIGN-TIME validate path in
|
||||
// ManagementActor leaves this non-blocking by NOT enforcing, since bindings are
|
||||
// set later at instance/deploy time.)
|
||||
// validateScripts == false is the read-only staleness/comparison path: skip
|
||||
// only the expensive Roslyn ValidateScriptCompilation (which loads a
|
||||
// non-collectible InteractiveAssemblyLoader assembly per script). Structural
|
||||
// and semantic validation still run so a genuinely broken flatten is surfaced;
|
||||
// the deploy path (validateScripts: true) remains the authoritative compile gate.
|
||||
var validation = _validationService.Validate(
|
||||
config,
|
||||
resolvedSharedScripts,
|
||||
alarmCapableConnectionNames,
|
||||
enforceConnectionBindings: true,
|
||||
siteConnectionNames: siteConnectionNames,
|
||||
resolveSchemaRef: resolveSchemaRef);
|
||||
resolveSchemaRef: resolveSchemaRef,
|
||||
validateScriptCompilation: validateScripts);
|
||||
|
||||
// Compute revision hash
|
||||
var hash = _revisionHashService.ComputeHash(config);
|
||||
|
||||
@@ -15,10 +15,19 @@ public interface IFlatteningPipeline
|
||||
/// </summary>
|
||||
/// <param name="instanceId">Id of the instance to flatten and validate.</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
/// <param name="validateScripts">
|
||||
/// When <c>true</c> (the deploy default), the authoritative Roslyn script-compilation
|
||||
/// gate runs. When <c>false</c>, that compile step is skipped — used by the read-only
|
||||
/// staleness/comparison paths (Deployments comparison page,
|
||||
/// <see cref="ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Transport.IStaleInstanceProbe"/>)
|
||||
/// which need only the flattened config + revision hash, not a compile. Structural and
|
||||
/// semantic validation still run in both cases.
|
||||
/// </param>
|
||||
/// <returns>A task that resolves to the flattened configuration, revision hash, and validation result; or a failure result if flattening could not complete.</returns>
|
||||
Task<Result<FlatteningPipelineResult>> FlattenAndValidateAsync(
|
||||
int instanceId,
|
||||
CancellationToken cancellationToken = default);
|
||||
CancellationToken cancellationToken = default,
|
||||
bool validateScripts = true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -30,8 +30,11 @@ public sealed class StaleInstanceProbe : IStaleInstanceProbe
|
||||
// instance as "staleness indeterminate" and skips it. Flattening reuses
|
||||
// the scoped ITemplateEngineRepository, so it observes template rows the
|
||||
// in-flight import has staged on the shared change tracker.
|
||||
// Staleness only needs the revision hash — skip the expensive Roslyn
|
||||
// script-compilation stage (this probe is called per-instance across a whole
|
||||
// bundle import in BundleImporter.ComputeStaleInstanceIdsAsync).
|
||||
var result = await _flatteningPipeline
|
||||
.FlattenAndValidateAsync(instanceId, cancellationToken)
|
||||
.FlattenAndValidateAsync(instanceId, cancellationToken, validateScripts: false)
|
||||
.ConfigureAwait(false);
|
||||
return result.IsSuccess ? result.Value.RevisionHash : null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user