Compare commits

...

1 commit

Author SHA1 Message Date
Anton Tayanovskyy f223ba0295 WIP: initialize earlier 2021-11-24 16:28:42 -05:00
3 changed files with 21 additions and 17 deletions

View file

@ -22,17 +22,9 @@ namespace Pulumi
// finished. Otherwise, we might actually read and get the result back *prior* to the
// object finishing initializing. Note: this is not a speculative concern. This is
// something that does happen and has to be accounted for.
//
// IMPORTANT! We have to make sure we run 'OutputCompletionSource.InitializeOutputs'
// synchronously directly when `resource`'s constructor runs since this will set all of
// the `[Output(...)] Output<T>` properties. We need those properties assigned by the
// time the base 'Resource' constructor finishes so that both derived classes and
// external consumers can use the Output properties of `resource`.
var completionSources = OutputCompletionSource.InitializeOutputs(resource);
_runner.RegisterTask(
$"{nameof(IDeploymentInternal.ReadOrRegisterResource)}: {resource.GetResourceType()}-{resource.GetResourceName()}",
CompleteResourceAsync(resource, remote, newDependency, args, options, completionSources));
CompleteResourceAsync(resource, remote, newDependency, args, options, resource.CompletionSources));
}
private async Task<(string urn, string id, Struct data, ImmutableDictionary<string, ImmutableHashSet<Resource>> dependencies)> ReadOrRegisterResourceAsync(

View file

@ -103,6 +103,8 @@ namespace Pulumi
/// </summary>
internal readonly string? _version;
internal readonly ImmutableDictionary<string,IOutputCompletionSource> CompletionSources;
/// <summary>
/// Creates and registers a new resource object. <paramref name="type"/> is the fully
/// qualified type token and <paramref name="name"/> is the "name" part to use in creating a
@ -128,6 +130,7 @@ namespace Pulumi
_name = "";
_protect = false;
_providers = ImmutableDictionary<string, ProviderResource>.Empty;
CompletionSources = ImmutableDictionary<string, IOutputCompletionSource>.Empty;
return;
}
@ -137,6 +140,13 @@ namespace Pulumi
if (string.IsNullOrEmpty(name))
throw new ArgumentException("'name' cannot be null or empty.", nameof(name));
// Initialize all Output properties crucially including
// `Urn` to non-nil Output values, record
// `CompletionSources`. This needs to happen before
// partially initialized `this` is exposed to other
// threads via `parentResource.ChildResources`.
CompletionSources = OutputCompletionSource.InitializeOutputs(this);
// Before anything else - if there are transformations registered, invoke them in order
// to transform the properties and options assigned to this resource.
var parent = type == Stack._rootPulumiStackTypeName

View file

@ -72,13 +72,15 @@ namespace Pulumi.Serialization
if (!propType.IsConstructedGenericType ||
propType.GetGenericTypeDefinition() != typeof(Output<>))
{
throw new InvalidOperationException($"{propFullName} was not an Output<T>");
continue;
// throw new InvalidOperationException($"{propFullName} was not an Output<T>");
}
var setMethod = prop.DeclaringType!.GetMethod("set_" + prop.Name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
if (setMethod == null)
{
throw new InvalidOperationException($"{propFullName} did not have a 'set' method");
continue;
//throw new InvalidOperationException($"{propFullName} did not have a 'set' method");
}
var outputTypeArg = propType.GenericTypeArguments.Single();