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

[sdk/*] Add support for resource source positions #13449

Merged
merged 1 commit into from Jul 14, 2023

Conversation

pgavlin
Copy link
Member

@pgavlin pgavlin commented Jul 10, 2023

Add support to the core SDKs for reporting resource source positions.

In each SDK, this is implemented by crawling the stack when a resource
is registered in order to determine the position of the user code that
registered the resource.

This is somewhat brittle in that it expects a call stack of the form:

  • Resource class constructor
  • abstract Resource subclass constructor
  • concrete Resource subclass constructor
  • user code

This stack reflects the expected class hierarchy of "cloud resource / component resource < customresource/componentresource < resource".

For example, consider the AWS S3 Bucket resource. When user code instantiates a Bucket, the stack will look like
this in NodeJS:

new Resource (/path/to/resource.ts:123:45)
new CustomResource (/path/to/resource.ts:678:90)
new Bucket (/path/to/bucket.ts:987:65)
<user code> (/path/to/index.ts:4:3)

In order to determine the source position, we locate the fourth frame (the <user code> frame).

@pulumi-bot
Copy link
Contributor

pulumi-bot commented Jul 10, 2023

Changelog

[uncommitted] (2023-07-13)

Features

  • [sdk/{go,nodejs,python}] Add support for reporting resource source positions
    #13449

@pgavlin pgavlin force-pushed the pgavlin/source-position-sdks branch 2 times, most recently from de1cf9d to fe93795 Compare July 12, 2023 20:48
@pgavlin
Copy link
Member Author

pgavlin commented Jul 12, 2023

Updated the CHANGELOG.

I've structured these changes s.t. the changes to each SDK are in separate commits. Hopefully this makes it easier to review.

@pgavlin pgavlin requested a review from Frassle July 12, 2023 23:14
Copy link
Member

@justinvp justinvp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM otherwise

sdk/nodejs/runtime/resource.ts Show resolved Hide resolved
sdk/go/pulumi/context_test.go Show resolved Hide resolved
Comment on lines +1581 to +1589
assert.strictEqual(sourcePosition.line, 2);
break;
case "component":
assert.strictEqual(sourcePosition.line, 2);
break;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are these line 2? Isn't it 16 and 17?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am confused by this as well. I've had correct results from Typescript files but I haven't tried JS outside of the test harness. I'm wondering if this is related to the harness or if we'll always see this for JS.

@justinvp
Copy link
Member

One question, that I didn't get a chance to ask on #13437. From reading the changes in #13437, when a user is creating an MLC, it looks like we won't record the position of where the user created the MLC, but rather, the position where the component is created inside the MLC provider. Is that correct? If so, should we consider making it so that it records the position of where the user is instantiating the MLC instead?

@pgavlin
Copy link
Member Author

pgavlin commented Jul 13, 2023

it looks like we won't record the position of where the user created the MLC, but rather, the position where the component is created inside the MLC provider. Is that correct? If so, should we consider making it so that it records the position of where the user is instantiating the MLC instead?

Ooooh, that is an excellent catch--I believe you're correct about that. Offhand it seems like we could either include the original source position in the construct request and leave it up to the MLC or we could inform the resource monitor about the actual source position and let it handle things. The latter is probably moderately more complex to implement in the engine, but seems like it is likely to be simpler and less error prone overall. Thoughts? cc @Frassle as well.

@justinvp
Copy link
Member

Offhand it seems like we could either include the original source position in the construct request and leave it up to the MLC or we could inform the resource monitor about the actual source position and let it handle things. The latter is probably moderately more complex to implement in the engine, but seems like it is likely to be simpler and less error prone overall.

The latter approach would be my preference, if we can make it all work in the engine. That way we don't have to go through all the hassle of propagating the value through the construct request and having to update each SDK (that has APIs for defining MLC providers) to handle it.

@Frassle
Copy link
Member

Frassle commented Jul 13, 2023

Agree with Justin.
There's been quite a few scenarios where it's looked like it would be beneficial to spawn a new resource monitor for MCL construct requests so that we can override data on the responses with contextual information. This feels like another case of that.

If when doing a Construct we spawn a new resource monitor that just overrides the SourcePosition of any RegisterResourceRequests that come through it before propagating to the original resource monitor then this is purely an engine side change and MLCs in every language will just work.
That lets us override the Component to say it's SourcePosition is what's in the user program, but also gives us a place to override all other Resources to say their SourcePositions are in the MLC package.

@pgavlin pgavlin force-pushed the pgavlin/source-position-sdks branch from 31a7c5a to 556a2b5 Compare July 13, 2023 16:58
@pgavlin
Copy link
Member Author

pgavlin commented Jul 13, 2023

If when doing a Construct we spawn a new resource monitor that just overrides the SourcePosition of any RegisterResourceRequests that come through it before propagating to the original resource monitor then this is purely an engine side change and MLCs in every language will just work.
That lets us override the Component to say it's SourcePosition is what's in the user program, but also gives us a place to override all other Resources to say their SourcePositions are in the MLC package.

I like the idea of spawning new resource monitors. I'm not sure about overriding all child resources of a remote component. I think that there's value in deep linking into component sources, especially if we can go from a component source position to the component's package to its sources. I think we can start with your suggestion, though, and implement the rest later.

@pgavlin
Copy link
Member Author

pgavlin commented Jul 13, 2023

(I'll follow up MLC bits in another PR)

@pgavlin
Copy link
Member Author

pgavlin commented Jul 13, 2023

bors merge

bors bot added a commit that referenced this pull request Jul 13, 2023
13449: [sdk/*] Add support for resource source positions r=pgavlin a=pgavlin

Add support to the core SDKs for reporting resource source positions.

In each SDK, this is implemented by crawling the stack when a resource
is registered in order to determine the position of the user code that
registered the resource.

This is somewhat brittle in that it expects a call stack of the form:
- Resource class constructor
- abstract Resource subclass constructor
- concrete Resource subclass constructor
- user code

This stack reflects the expected class hierarchy of "cloud resource / component resource < customresource/componentresource < resource".

For example, consider the AWS S3 Bucket resource. When user code instantiates a Bucket, the stack will look like
this in NodeJS:

    new Resource (/path/to/resource.ts:123:45)
    new CustomResource (/path/to/resource.ts:678:90)
    new Bucket (/path/to/bucket.ts:987:65)
    <user code> (/path/to/index.ts:4:3)

In order to determine the source position, we locate the fourth frame (the `<user code>` frame).

Co-authored-by: Pat Gavlin <pat@pulumi.com>
@pgavlin pgavlin force-pushed the pgavlin/source-position-sdks branch from 556a2b5 to f950465 Compare July 13, 2023 19:15
@bors
Copy link
Contributor

bors bot commented Jul 13, 2023

Canceled.

@Frassle
Copy link
Member

Frassle commented Jul 13, 2023

I think that there's value in deep linking into component sources, especially if we can go from a component source position to the component's package to its sources.

That was my intent. Not to totally override the sub-resources SourcePositions but just to fix them up to be "package://" style.

@pgavlin pgavlin force-pushed the pgavlin/source-position-sdks branch 4 times, most recently from f548229 to b504e55 Compare July 13, 2023 23:28
Add support to the core SDKs for reporting resource source positions.

In each SDK, this is implemented by crawling the stack when a resource
is registered in order to determine the position of the user code that
registered the resource.

This is somewhat brittle in that it expects a call stack of the form:
- Resource class constructor
- abstract Resource subclass constructor
- concrete Resource subclass constructor
- user code

This stack reflects the expected class hierarchy of "cloud resource /
component resource < customresource/componentresource < resource".

For example, consider the AWS S3 Bucket resource. When user code
instantiates a Bucket, the stack will look like
this in NodeJS:

    new Resource (/path/to/resource.ts:123:45)
    new CustomResource (/path/to/resource.ts:678:90)
    new Bucket (/path/to/bucket.ts:987:65)
    <user code> (/path/to/index.ts:4:3)

In order to determine the source position, we locate the fourth frame
(the `<user code>` frame).
@pgavlin pgavlin force-pushed the pgavlin/source-position-sdks branch from b504e55 to 248f78b Compare July 13, 2023 23:46
@pgavlin
Copy link
Member Author

pgavlin commented Jul 14, 2023

bors merge

@bors
Copy link
Contributor

bors bot commented Jul 14, 2023

Build succeeded!

The publicly hosted instance of bors-ng is deprecated and will go away soon.

If you want to self-host your own instance, instructions are here.
For more help, visit the forum.

If you want to switch to GitHub's built-in merge queue, visit their help page.

  • bors-ok

@bors bors bot merged commit ca041c9 into master Jul 14, 2023
48 of 50 checks passed
@bors bors bot deleted the pgavlin/source-position-sdks branch July 14, 2023 01:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants