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

fix: Propagate span when copying scope #2952

Merged
merged 5 commits into from
May 2, 2023

Conversation

kabiroberai
Copy link
Contributor

@kabiroberai kabiroberai commented Apr 24, 2023

📜 Description

This PR updates the SentryScope copy constructor to copy over the parent's span.

💡 Motivation and Context

Previously, copied scopes (such as those created in -[SentrySDK captureEvent:withScopeBlock:]) did not inherit the original scope's span. This resulted in emitted events not linking back to the relevant span. Other SDKs do copy over the parent span/transaction (for example here's the equivalent code in sentry-java).

💚 How did you test it?

I tested these changes in a production iOS app, ensuring that spans now propagate as expected.

📝 Checklist

You have to check all boxes before merging:

  • I reviewed the submitted code.
  • I added tests to verify the changes.
  • No new PII added or SDK only sends newly added PII if sendDefaultPII is enabled.
  • I updated the docs if needed.
  • Review from the native team if needed.
  • No breaking change or entry added to the changelog.
  • No breaking change for hybrid SDKs or communicated to hybrid SDKs.

@@ -108,6 +108,36 @@ class SentryScopeSwiftTests: XCTestCase {
XCTAssertNil(actual["transaction"])
XCTAssertNotNil(actual["breadcrumbs"])
}

func testInitWithScope() {
Copy link
Contributor Author

@kabiroberai kabiroberai Apr 24, 2023

Choose a reason for hiding this comment

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

this test is mostly a direct translation of the ObjC version, but with the addition of a check that calling cloned.applyTo has the same effect as calling it on the original scope. The new check would have failed without the change to the copy constructor.

Copy link
Member

Choose a reason for hiding this comment

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

Please add some validation for assigning self.span = scope.span in the initWithScope. So basically if I remove self.span = scope.span from initWithScope this test should fail.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oops, this was what the Event comparison was supposed to validate, but I forgot to assign a span to the scope. Removing that line goes from green -> red as expected now.

@kabiroberai kabiroberai changed the title Scope propagation improvements feat: scope propagation improvements Apr 24, 2023
@philipphofmann
Copy link
Member

Thanks for the PR, @kabiroberai. We didn't get to this today, but we'll have a look tomorrow.

Copy link
Member

@philipphofmann philipphofmann left a comment

Choose a reason for hiding this comment

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

Thanks for the PR @kabiroberai. Could you please split this PR up into two PRs? One for fixing the copy and another one for startWithOptions:andScope. Those are two independent changes, and they should have extra Changelog entries, PR titles etc.

Before you open the PR for startWithOptions:andScope, we still need to clarify if we want to add this method to the SDK cause it's not part of our unified API, and maybe we want to add it to all of our SDKs with a static API. I will get back to you.

@philipphofmann
Copy link
Member

philipphofmann commented Apr 26, 2023

@kabiroberai, could you elaborate on the race condition you experience between start and configureScope? Does your app do heavy work in the background already when you start the SDK?

@kabiroberai kabiroberai force-pushed the kabir/default-scope branch from 57f55f3 to bc83334 Compare April 27, 2023 19:15
@kabiroberai
Copy link
Contributor Author

👍 moved the startWithOptions:andScope: changes out of this PR. The race condition is speculative/us being extra cautious so it's possible that it doesn't actually get triggered, though I can stress-test to double check. Our main use case for passing our own scope is that we can replace the hub's scope with a subclass — to that end a +[SentrySDK setScope:] method would achieve the same goal. Unfortunately configureScope doesn't do the trick because we can't replace the scope instance entirely, only modify its properties.

Taking a step back, the reason we need to subclass Scope is because we're using Swift's @TaskLocal to allow different (concurrent) Tasks to have different "current" scopes. IIUC other Sentry SDKs achieve a similar goal through the use of thread-local hubs, but I don't see a way to do such a thing in the Cocoa SDK yet. I'd be happy to discuss alternative approaches here — maybe on Discord?

@kabiroberai kabiroberai changed the title feat: scope propagation improvements fix: propagate spans when copying scopes Apr 27, 2023
@philipphofmann
Copy link
Member

@kabiroberai, JavaScript the concept of the initialScope on the options. We could do the same on Cocoa. I guess that would work for you.

through the use of thread-local hubs

At some point, we should implement thread-local hubs, but if initialScope solves your problem, I would like to delay that a bit, as initialScope is also useful for other users.

@philipphofmann philipphofmann changed the title fix: propagate spans when copying scopes fix: Propagate span when copying scope Apr 28, 2023
Copy link
Member

@philipphofmann philipphofmann left a comment

Choose a reason for hiding this comment

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

Thanks for doing this @kabiroberai 👏

Please add an entry to the changelog under a section Fixed with Propagate span when copying scope. CI fails for the benchmarks and release builds, cause that doesn't work for contributors yet. Just focus on the lints and unit tests. FYI, our unit test are a bit flaky at the moment. We did several fixes on the main branch, so merging main into this PR should help.

@@ -108,6 +108,36 @@ class SentryScopeSwiftTests: XCTestCase {
XCTAssertNil(actual["transaction"])
XCTAssertNotNil(actual["breadcrumbs"])
}

func testInitWithScope() {
Copy link
Member

Choose a reason for hiding this comment

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

Please add some validation for assigning self.span = scope.span in the initWithScope. So basically if I remove self.span = scope.span from initWithScope this test should fail.

@philipphofmann philipphofmann self-assigned this Apr 28, 2023
@kabiroberai kabiroberai requested a review from philipphofmann May 1, 2023 16:39
Copy link
Contributor

@brustolin brustolin left a comment

Choose a reason for hiding this comment

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

Thanks @kabiroberai !!

This looks good to me.

Copy link
Member

@philipphofmann philipphofmann left a comment

Choose a reason for hiding this comment

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

Thanks, @kabiroberai 💯; LGTM. Just waiting for CI to be green.

@philipphofmann
Copy link
Member

I will fix the Changelog entry so that we can merge this PR.

@philipphofmann philipphofmann merged commit 9454d5d into getsentry:main May 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

4 participants