Skip to content

Conversation

@AbhiPrasad
Copy link
Member

@AbhiPrasad AbhiPrasad commented Feb 13, 2023

ref #44225

Building on the work from #44346, this PR adds dynamicSdkLoaderOptions, a dictionary of options for the new dynamic SDK loader.

The dynamicSdkLoaderOptions live on the data JSONField on the ProjectKey model, as the there is a dynamic loader unique to each DSN.

dynamicSdkLoaderOptions is also a dictionary, for ease of use, with 3 keys:

  1. hasReplay: If the loader should include the replay sdk in the bundle
  2. hasPerformance: If the loader should include the tracing sdk in the bundle
  3. hasDebug: If the loader should load the debug bundle

In the future we could migrate this onto the model directly (as a BitField or something), but for now for iteration speed and fluid schema, adding it as a JSON is good enough.

To validate we are using the correct fields, dynamicSdkLoaderOptions
is validated in the ProjectKeySerializer via a custom serializer.

These new options are used by the _get_bundle_kind_modifier method in the JavaScriptSdkDynamicLoader view, but for now are not used since the templates are not added (we render a no-op template instead). In the next PR we will add templates for the loader view, alongside tests to validate this all together.

@AbhiPrasad AbhiPrasad requested review from a team and HazAT February 13, 2023 13:52
@AbhiPrasad AbhiPrasad requested a review from a team as a code owner February 13, 2023 13:52
@github-actions github-actions bot added the Scope: Backend Automatically applied to PRs that change backend components label Feb 13, 2023
assert key.label == "hello world"
assert key.status == ProjectKeyStatus.INACTIVE

def test_default_browser_sdk_version(self):
Copy link
Member Author

Choose a reason for hiding this comment

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

Added some tests for browserSdkVersion since I drove by and refactored the code in src/sentry/api/endpoints/project_key_details.py around this (but unrelated to the dynamicSdkLoaderOptions work in this PR).

@mydea
Copy link
Member

mydea commented Feb 14, 2023

Very much logaf-l: Just a thought, but what about instead of having:

{ 
  hasReplay: boolean,
  hasPerformance: boolean
}

we make this an array of keys, like:

{ 
  include: ['replay', 'performance']
}

Not sure, maybe this doesn't even make sense, I generally try to avoid boolean flags for settings where possible, but I guess the ones you picked are also rather straightforward, so... 🤷

@AbhiPrasad
Copy link
Member Author

we make this an array of keys, like:

This is a great suggestion. I initially had something like this but changed to the explicit keys so that we left ourselves open to adding non-boolean fields in the future.

Perhaps this is un-needed optimization though, not sure 🤔

"""Validates dynamicSdkLoaderOptions to make sure it only contains valid keys"""

def to_internal_value(self, data):
if set(data.keys()) != {o.value for o in DynamicSdkLoaderOption}:
Copy link
Member

Choose a reason for hiding this comment

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

This will reject any additional keys, which can make forwards/backwards compatibility harder. Do you need to validate the values of these keys or is any datatype acceptable?

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah great point - we must have forwards compatibility here. Let me rework this, thanks for pointing it out.


response = render_to_response(tmpl, context, content_type="text/javascript")

response["Access-Control-Allow-Origin"] = "*"
Copy link
Member

Choose a reason for hiding this comment

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

Do you also want to set Cross-Origin-Resource-Policy for more restrictive cross-origin policy sites?

Copy link
Member Author

@AbhiPrasad AbhiPrasad Feb 15, 2023

Choose a reason for hiding this comment

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

We want the cross-origin policy to be as broad as possible, we want any site to be able to load the loader javascript.

Copy link
Member

Choose a reason for hiding this comment

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

That's what I thought, you'll want Cross-Origin-Resource-Policy: cross-origin then.

def test_noop(self):
settings.JS_SDK_LOADER_DEFAULT_SDK_URL = ""
resp = self.client.get(
reverse("sentry-js-sdk-dynamic-loader", args=[self.projectkey.public_key])
Copy link
Member

Choose a reason for hiding this comment

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

Is this ok to become a region specific endpoint in the the future? With only a project key parameter, we'd have to eventually use URLs like https://us.sentry.io/api/0/.* style URLs.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes this should be fine since this case is only there for self-hosted users. In the production getsentry case, we are using a Fastly CDN (hence the configurable URL).

@AbhiPrasad
Copy link
Member Author

As per feedback I updated the project key serializer to be forwards compatible in ec7ea1c.

To do this I overrided the to_internal_value method, and formed an allow list of keys to be checked. The test_dynamic_sdk_loader_options was re-written to show different scenarios of what to do.

Copy link
Member

@markstory markstory left a comment

Choose a reason for hiding this comment

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

API endpoint semantics look good to me.

@AbhiPrasad AbhiPrasad merged commit 4c46196 into master Feb 16, 2023
@AbhiPrasad AbhiPrasad deleted the abhi-sdk-dynamic-loader-options branch February 16, 2023 09:43
wmak pushed a commit that referenced this pull request Feb 16, 2023
ref #44225

Building on the work from
#44346, this PR adds
`dynamicSdkLoaderOptions`, a dictionary of options for the new dynamic
SDK loader.

The `dynamicSdkLoaderOptions` live on the data `JSONField` on the
`ProjectKey` model, as the there is a dynamic loader unique to each DSN.

`dynamicSdkLoaderOptions` is also a dictionary, for ease of use, with 3
keys:

1. `hasReplay`: If the loader should include the replay sdk in the
bundle
2. `hasPerformance`: If the loader should include the tracing sdk in the
bundle
3. `hasDebug`: If the loader should load the debug bundle

In the future we could migrate this onto the model directly (as a
`BitField` or something), but for now for iteration speed and fluid
schema, adding it as a JSON is good enough.

To validate we are using the correct fields, `dynamicSdkLoaderOptions`
is validated in the `ProjectKeySerializer` via a custom serializer.

These new options are used by the `_get_bundle_kind_modifier` method in
the `JavaScriptSdkDynamicLoader` view, but for now are not used since
the templates are not added (we render a no-op template instead). In the
next PR we will add templates for the loader view, alongside tests to
validate this all together.
@github-actions github-actions bot locked and limited conversation to collaborators Mar 3, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Scope: Backend Automatically applied to PRs that change backend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants