microsoft / microsoft/DacFx

Late initialization of ModelTypeClasses (at least) such as PrimaryKeyConstraint.TypeClass??

Open
#394 1 comment 0 reactions 0 assignees View on GitHub
bug
Dominant language
C#
Stars
460
Forks
29
Avg merge
4d 9h
Merged PRs (30d)
7

Description

I'm experimenting with a SSDT DeploymentPlanModifier C# project that, for now, enumerates various constraints being dropped and re-added - this is being loaded by the `SqlPackage.exe` command-line utility with the `/Properties:AdditionalDeploymentContributors= Mine.MyContributor` switch.

I'm able to repeatedly able to demonstrate a frustrating condition of what I guess is a late initialization of some of the DacFX internals. `PrimaryKeyConstraint.TypeClass` is `null`, as is `PrimaryKeyConstraint.Columns`, when the following code is run at full speed:

[ExportDeploymentPlanModifier("Mine.MyContributor", "1.0.0.0")]
public class MyContributor: DeploymentPlanModifier
{
protected override void OnExecute(DeploymentPlanContributorContext context)
{
// PrimaryKeyConstraint
PublishMessage(new ExtensibilityError($"PrimaryKeyConstraints", Severity.Message));
ProcessConstraints(context, PrimaryKeyConstraint.TypeClass, PrimaryKeyConstraint.Columns);
}
}

If I set a breakpoint in Visual Studio before the `ProcessConstraints()` call, the debugger breaks there correctly and the Autos show that both `PrimaryKeyConstraint.TypeClass` and `PrimaryKeyConstraint.Columns` are `null`! Adding an explicit Watch shows the same. Eventually (a minute? though not necessarily time-based), and without allowing the execution to Continue, the Autos eventually change to the non-null, expected values! I'm kind of baffled by this - with the debugger paused, I don't think it's possible for some background thread responsible for populating this value to complete its work - so it must be based on some side-effect of me probing the various values through the IDE. If I wait until after these values are populated to Continue execution, the program runs correctly and gives the expected output. If I don't wait, I can step-into `ProcessConstraints()` with the debugger showing that `null` was passed in - and this gives unexpectedly blank behavior.

I'm not doing any threading or async operations in `ProcessConstraints()` (nor anywhere else). Is there some initialization of the DacFX, or `Ready` event that I must wait for?

Note: I am debugging by having deployed the latest assemblies to `C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\Extensions\Microsoft\SQLDB\DAC\130\Extensions\MyContributor` and running the correlating version of SqlPackage `C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\Extensions\Microsoft\SQLDB\DAC\130\SqlPackage.exe` and not using the Visual Studio Hosting process (not that I know that it's interfering with anything).

The code for `ProcessConstraints()` is uninteresting for this problem, I think. It goes wrong at the very beginning, since typeClass is clearly being passed in as `null`:

private void ProcessConstraints(DeploymentPlanContributorContext context, ModelTypeClass typeClass, ModelRelationshipClass relationshipClass)
{
var droppedPKConstraints =
context.ComparisonResult.ElementsToDrop
.Where(ele => ele.ObjectType == typeClass)
...

Contributor guide

Open the contributing guide

Research direction

Start at the DeploymentPlanModifier.OnExecute entry point and the PrimaryKeyConstraint.TypeClass and PrimaryKeyConstraint.Columns accesses, reproducing through SqlPackage.exe with the AdditionalDeploymentContributors switch. Trace when these values become non-null relative to ProcessConstraints; done means the contributor no longer receives null values during normal execution, or the required initialization/readiness step is identified.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp, sql
Domain
database
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.