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

ref(profiling): Normalize all profiles #1250

Merged
merged 13 commits into from
May 9, 2022

Conversation

phacops
Copy link
Contributor

@phacops phacops commented Apr 29, 2022

This PR aims to normalize all profiles and will reject invalid profiles with not enough samples or the wrong platform.

queue_address: Option<String>,

#[serde(deserialize_with = "deserialize_number_from_string")]
relative_timestamp_ns: u64,
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't you also serialize that type as string to allow for roundtrips?

It also looks like this is the only use of the serde_aux crate, so maybe you could vendor the implementation in? There's two ways to do this:

  • define your own functions/module to do the serialization and deserialization
  • create a named newtype

Note that in other places of the event payload we currently use floating point timestamps.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What do you mean by roundtrips? I don't serialize as string since I want to pass it as an integer downstream. Python supports decoding a uint64 from a JSON object even if it's not in the standard.

I think I'd rather deserialize as an integer pass it downstream than use a float. This seems simpler as we're not going to have anymore type conversion.

Copy link
Member

Choose a reason for hiding this comment

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

@phacops assuming this is in envelopes, our protocol has to roundtrip. so if you want to serialize this as integer, you have to be able to deserialize it as such. you can always be more lenient on deserialization than serialization, but not the other way around

example: customer relay forwards profiles to us. or pop relays forward profiles to internal relays

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK, I understand. The deserialization function I'm using now supports deserializing from string or number now.

Copy link
Member

Choose a reason for hiding this comment

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

ok you're right. I think I'm fine with this then.

}

#[derive(Debug, Serialize, Deserialize)]
struct Image {
Copy link
Member

Choose a reason for hiding this comment

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

This and other types are very similar to the existing types in the event protocol. Depending on how much you still want to refactor this, it would be good if we start looking into sharing the definitions.

The main challenge with this is that we base most of our protocol on the Annotated, which requires its own serializing and deserializing implementation. It's notably slower than plain serde, and we've been long looking to re-align it with serde.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm willing to refactor things to make them more cohesive. I think we should still ship that though because it sounds like a way larger effort that should really be done on its own as opposed to doing it on top of another change.

Copy link
Member

Choose a reason for hiding this comment

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

I'm fine with not aligning for now, unless we're planning to write this struct back into the event in some sort of capacity.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This won't be written back anywhere. I'll use in for symbolication later and then discard it.

Copy link
Member

@untitaker untitaker May 5, 2022

Choose a reason for hiding this comment

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

If this goes through symbolicator we should find a way to make those structs align and fail compilation if they don't. For the time being I would add yet another roundtrip test that ensures this: profiling image <-> big json string <-> event image

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I made a test for that but there's a few caveats. The iOS SDK is using a function get generate debug meta that was already part of the SDK and this function gets us apple debug images. Two problems from there:

  • It seems the Symbolicator wants Macho now, and that's why we have to rename the uuid field to debug_id, but then the image would be more of type macho.
  • It doesn't provide some fields that seems required when building an apple debug image (cpu_type, cpu_subtype and arch). I added those fields in our image struct for now.

So, we're investigating to see how to generate macho images and then I'll make this test a little bit less weird and will also likely remove the need to rename the uuid field to debug_id.

@phacops phacops force-pushed the pierre/profiling-normalize-profiles-all-platform branch from 2ea8176 to d07ebb6 Compare April 29, 2022 23:03
@phacops phacops force-pushed the pierre/profiling-normalize-profiles-all-platform branch from e242c24 to 828ae4f Compare May 4, 2022 15:07
Copy link
Member

@untitaker untitaker left a comment

Choose a reason for hiding this comment

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

I think this is conceptually fine, but serde annotations are easy to mess up. I would add roundtrip and snapshot tests for serialization and deserialization behavior. You can use insta to make test assertions a little easier


#[derive(Debug, Serialize, Deserialize)]
struct ThreadMetadata {
#[serde(skip_serializing_if = "Option::is_none")]
Copy link
Member

Choose a reason for hiding this comment

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

This won't roundtrip: name: null is required, but not serialized

I think there are more like this. Can you add roundtrip tests?

@phacops phacops requested a review from jan-auer May 6, 2022 15:59
@phacops phacops requested a review from untitaker May 6, 2022 18:01
Copy link
Member

@jan-auer jan-auer left a comment

Choose a reason for hiding this comment

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

Looks good to me now, thanks for incorporating the suggestions.

Before merging this, could you please move the large test payloads to a test fixture? We do not have reusable test fixtures in our Rust tests yet, but you can just create a file, for instance in <crate>/tests/fixtures like we did in relay-general.

pub struct ParseNativeImagePathError;

impl FromStr for NativeImagePath {
type Err = ParseNativeImagePathError;
Copy link
Member

Choose a reason for hiding this comment

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

Since this never fails, you can use std::convert::Infallible.

@@ -75,6 +94,8 @@ impl ProcessValue for NativeImagePath {
}
}

relay_common::impl_str_serde!(NativeImagePath, "a native image path");
Copy link
Member

Choose a reason for hiding this comment

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

As discussed offline, feel free to derive Deserialize, Serialize directly.

@phacops phacops enabled auto-merge (squash) May 9, 2022 23:14
@phacops phacops merged commit 7d0dc11 into master May 9, 2022
@phacops phacops deleted the pierre/profiling-normalize-profiles-all-platform branch May 9, 2022 23:18
jan-auer added a commit that referenced this pull request May 13, 2022
* master:
  feat(sampling): Support custom tags and more contexts (#1268)
  deps: Update symbolic to pull in Unreal parser fixes (#1266)
  Bring in CLA Lite (#1257)
  release: 0.8.11
  ref(profiling): Normalize all profiles (#1250)
  feat(profiling): Add a profile data category and count profiles in an envelope to apply rate limits (#1259)
  fix: Raise a new InvalidCompression Outcome for invalid Unreal compression (#1237)
  chore: Update logo for dark or light theme (#1262)
  ref: Use Duration to compute breakdowns and span durations (#1260)
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

3 participants