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

river/encoding: fix issue where interface capsules were downcasted to empty objects #2437

Merged
merged 2 commits into from
Oct 27, 2022

Conversation

rfratto
Copy link
Member

@rfratto rfratto commented Oct 26, 2022

This change is similar to the fix introduced in #2369, where calling the Interface() method on River values forced a type change from an interface-based capsule to an any-type capsule. This caused the UI to crash when displaying an otelcol component (see #2361).

The new value.FromRaw method allows constructing a River value from a reflect.Value directly, avoiding the need to convert to interface{}.

As part of this change, a !reflect.Value.IsZero() check has been added for safety; this shouldn't happen in most circumstances unless a value.Null is trying to be encoded.

The CHANGELOG wasn't updated because this behavior only occurs when a component exports a capsule type, which was first introduced in the otelcol.* components which have yet to be released.

Fixes #2361.

… empty objects

This change is similar to the change introduced in grafana#2369, where calling
the `Interface()` method on River values forced a type change from an
interface-based capsule to an any-type capsule.

The new `value.FromRaw` method allows constructing a River value from a
reflect.Value directly, avoiding the need to convert to interface{}.

As part of this change, a `!reflect.Value.IsZero()` check has been added
for safety; this shouldn't happen in most circumstances unless a
value.Null is trying to be encoded.

Fixes grafana#2361.
@rfratto rfratto requested a review from mattdurham October 26, 2022 23:21
Comment on lines +109 to +113
// FromRaw converts a reflect.Value into a River Value. It is useful to prevent
// downcasting a interface into an any.
func FromRaw(v reflect.Value) Value {
return makeValue(v)
}
Copy link
Member Author

@rfratto rfratto Oct 27, 2022

Choose a reason for hiding this comment

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

The need to do this is probably the start of a wider discussion around whether interface types should be capsules. It's fairly hard to reason about in the internal code, and there's still some edge cases where a capsule can be downcasted like when providing it to a vm.Scope.

The alternative would be to stop magically trying to determine if specific types of interfaces can be capsules and require the marker interface instead (but channels could still default to capsules). This would be more work on component developers, but it's probably easier to reason about and harder to get wrong in the River implementation.

There could also be a registry of capsule types like we used to have, but I'm not a big fan of that solution.

cc @grafana/databases-agent

Copy link
Collaborator

Choose a reason for hiding this comment

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

When you say marker interface, do you mean interfaces would need to have the Capsule interface on them?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, I mean to change the rules so that:

  1. Go interfaces are deferenced into their underlying type.
  2. Types which implement river.Capsule are forced capsule types.
  3. Go types which have no River mapping (like channels) default to capsule types.

The only new rule here is the first one; currently interface types with at least one method are treated as capsules, though it's too easy for that information to be lost.

Copy link
Member Author

Choose a reason for hiding this comment

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

Either way, I think making these changes should be something we do later, we still need this bug fix for now, especially since #2431 probably makes it happen for even more components.

Copy link
Collaborator

@mattdurham mattdurham left a comment

Choose a reason for hiding this comment

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

LGTM

@rfratto rfratto merged commit 6dafed1 into grafana:main Oct 27, 2022
@rfratto rfratto deleted the flow-api-fix-otelcol-components branch October 27, 2022 14:56
@github-actions github-actions bot added the frozen-due-to-age Locked due to a period of inactivity. Please open new issues or PRs if more discussion is needed. label Mar 16, 2024
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 16, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
frozen-due-to-age Locked due to a period of inactivity. Please open new issues or PRs if more discussion is needed.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Flow UI: Panic when viewing otelcol.exporter.otlp component
2 participants