What's the point of calling `this.registerOutputs`...
# general
b
What's the point of calling
this.registerOutputs
(https://www.pulumi.com/docs/intro/concepts/resources/#registering-component-outputs)? Everything seems to work fine without it, and I don't see any immediate benefit.
b
if you're registering outputs from your component it's needed. If you're not it's best practice, and we may enforce it in future
b
b
So it is definitely a little confusing. But
registerOutputs
is how pulumi keeps track of pending asynchronous tasks. In your
create-an-s3-folder-component
example they are not providing the output to the
registerOutputs
call because functionally it is not necessary - functionally all that example is doing is forwarding the
bucketName
output from the
aws.s3.Bucket
to the parent
ComponentResource
. So this works because the
aws.s3.Bucket
has already registered that output and no additional tracking is necessary. The
registering-component-outputs
example also technically doesn't need to provide the output to the function because functionally it is just forwarding an output that was already registered by the component that owns it. But consider the following:
Copy code
var newOutput = bucket.Name.apply(bucketName => {
    // do some asynchronous work, make an API call
    return value;
});

this.output = newOutput;
this.registerOutputs();
In this scenario, since I did not provide
newOutput
to the
registerOutputs
call pulumi has no way of tracking the asynchronous work that I added. So you have introduced a race-condition, it is now possible for your
pulumi up
to finish before that asynchronous work has finished, and you might have leaky promises. Another thing to keep in mind is that
Output<T>
doesn't just convey asynchronous work, it also conveys dependency. So if you want your dependency tree to accurately reflect that consuming resources depend on the
ComponentResource
rather than the inner
aws.s3.Bucket
than you want to register it as a new output. Otherwise your dependency path will be
consumer -> aws.s3.Bucket
instead of
consumer -> componentResource -> aws.s3.Bucket
which conceptually breaks the logical grouping of your component resource. But this is less important because I can't think of scenario where the former dependency path would break anything, it just may not be a strictly accurate representation of your resources
b
Thanks a lot for the great explanation, makes way more sense now :)
🙌 1