-
-
Notifications
You must be signed in to change notification settings - Fork 4.4k
chore(ts): Improve Starfish span metrics typing #53453
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
Conversation
It's pointless to pass a "partial" span, and use the `IndexedSpan` type.
This was a duplicate of a type defined elsewhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good change, feel free to use my review comments however you want.
We probably should add a validation step on initial query so we can validate if data is returned in the expected schema (can just send an error to Sentry), that way we can detect fe/be problems faster (validation can even happen in a useEffect
so it doesn't block).
queryFilters: SpanSummaryQueryFilters, | ||
yAxis: string[] = [], | ||
referrer = 'span-metrics-series' | ||
) => { | ||
const pageFilters = usePageFilters(); | ||
|
||
const eventView = span | ||
? getEventView(span, pageFilters.selection, yAxis, queryFilters) | ||
const eventView = group |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
m: How can group be undefined
here if it's defined as string
in useSpanMetricsSeries
? We can remove the Boolean(group)
cast too then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
True, but in Step 2 I'm going to move the group
parameter into queryFilters
, since it's just a filter like anything else, so this code isn't long for this world
@@ -26,6 +26,17 @@ export enum SpanMetricsFields { | |||
SPAN_SELF_TIME = 'span.self_time', | |||
} | |||
|
|||
export type SpanMetricsFieldTypes = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we want to prefer interfaces whenever possible due to https://github.com/microsoft/TypeScript/wiki/Performance#preferring-interfaces-over-intersections
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it completely whenever possible? I thought we were mostly using it for things like props that get extended. I'm happy to change in a future iteration, though!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've just been defaulting to interface
, but I think we can do this whenever
'time_spent_percentage()', | ||
'http_error_count()', | ||
], | ||
'api.starfish.span-summary-page-metrics' | ||
); | ||
|
||
const span = Object.assign({group: groupId}, spanMetrics as SpanMetrics & SpanMeta); | ||
const span = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
l: Isn't this more accurate?
const span = { | |
const span: SpanMetricsFieldTypes = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Neither is fully accurate unfortunately. Another down-the-road fix that I want is for API calls to correctly type their return values based on the fields that were passed in, but one thing at a time
'api.starfish.span-summary-page-metrics-chart' | ||
); | ||
|
||
useSynchronizeCharts([!areSpanMetricsSeriesLoading]); | ||
|
||
const spanMetricsThroughputSeries = { | ||
seriesName: span?.[SPAN_OP]?.startsWith('db') ? 'Queries' : 'Requests', | ||
seriesName: span?.[SpanMetricsFields.SPAN_OP]?.startsWith('db') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
seriesName: span?.[SpanMetricsFields.SPAN_OP]?.startsWith('db') | |
seriesName: span[SpanMetricsFields.SPAN_OP]?.startsWith('db') |
span should always be defined here right?
l: We can then think about extracting span[SpanMetricsFields.SPAN_OP] into it's own var.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, always defined! We sprinkled ?.
everywhere else in the file, so I didn't bother cleaning that up for now. I wonder if TypeScript can detect redundant optional lookups 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there is https://typescript-eslint.io/rules/no-unnecessary-condition/, perhaps we should turn it on
@@ -26,35 +25,33 @@ export type SpanTransactionMetrics = { | |||
}; | |||
|
|||
export const useSpanTransactionMetrics = ( | |||
span: Pick<IndexedSpan, 'group'>, | |||
group: string, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
m: should we rename to either group
or groupId
across the board?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should be group
everywhere, I just chose not to do it in this particular PR
@AbhiPrasad right on, thanks for the comments! Overall, all fair and I'll be addressing them all in some shape in upcoming PRs this week and next. Just trying to keep the changes isolated, so the PRs are abit "incomplete" while I look for manageable chunks to fix |
Small PRs best PRs |
Still a lot of cleanup to do, but this takes a few initial steps. 1. Remove unused `Span` type. Literally not used anywhere 2. Remove `IndexedSpan` type. This one was a little silly. It was used in a few places, mostly to pick off the `group` and `op` properties. Wrong for a bunch of reasons, but mostly wrong because `SpanIndexedFieldTypes` covers the same space but much better. 3. Improve `SpanIndexedFieldTypes` by adding a few missing fields 4. Add `SpanMetricsFieldTypes` to match the indexed version 5. Remove newly unused `useSpanMeta` hook Also, a bunch of places were accepting a `span`, but it's just an object with a group. I replaced it with a plain string parameter. In the future, I'll probably just merge it into `queryFilters`, since `group` is a filter like any other. Next up I'll probably consolidate some of these field names, and start looking at adding more descriptive, strict typing.
Still a lot of cleanup to do, but this takes a few initial steps.
Span
type. Literally not used anywhereIndexedSpan
type. This one was a little silly. It was used in a few places, mostly to pick off thegroup
andop
properties. Wrong for a bunch of reasons, but mostly wrong becauseSpanIndexedFieldTypes
covers the same space but much better.SpanIndexedFieldTypes
by adding a few missing fieldsSpanMetricsFieldTypes
to match the indexed versionuseSpanMeta
hookAlso, a bunch of places were accepting a
span
, but it's just an object with a group. I replaced it with a plain string parameter. In the future, I'll probably just merge it intoqueryFilters
, sincegroup
is a filter like any other.Next up I'll probably consolidate some of these field names, and start looking at adding more descriptive, strict typing.