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

subscriber: fix missing on_layer for Box/Arc layer impls #1576

Merged
merged 5 commits into from
Sep 17, 2021

Conversation

hawkw
Copy link
Member

@hawkw hawkw commented Sep 17, 2021

The Layer::on_layer method on Layer was added in PR #1523. PR #1536,
which added Layer implementations to Box<dyn Layer<...> + ...> and
Arc<dyn Layer<...> + ...>, merged prior to #1523. However, when
merging #1523, I didn't think to update the Layer impl for Boxed and
Arced layers to forward on_layer to the inner Layer. This means
that when a Layer is wrapped in an Arc or a Box, the on_layer
method never gets called.

When per-layer filters are in use, the on_layer method is necessary to
ensure the filter is registered with the inner subscriber and has a
valid ID. This bug means that when per-layer filters are wrapped in a
Box or Arc, they won't be registered, and per-layer filtering
breaks.

This PR fixes the bug by adding on_layer implementations to the
Layer impls for Arced and Boxed layers. I also added some tests
--- thanks to @Noah-Kennedy for the original repro that these were based
on (#1563 (comment)).

I also added a nicer debug assertion to Filtered for cases where
Layer impls don't call on_layer, so that this fails less
confusingly in the future.

this is a minimization of #1563 (comment)

Signed-off-by: Eliza Weisman <eliza@buoyant.io>
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
The `Layer::on_layer` method on `Layer` was added in PR #1523. PR #1536,
which added `Layer` implementations to `Box<dyn Layer<...> + ...>` and
`Arc<dyn Layer<...> + ...>`, merged prior to #1523. However, when
merging #1523, I didn't think to update the `Layer` impl for `Box`ed and
`Arc`ed layers to forward `on_layer` to the inner `Layer`. This means
that when a `Layer` is wrapped in an `Arc` or a `Box`, the `on_layer`
method never gets called.

When per-layer filters are in use, the `on_layer` method is necessary to
ensure the filter is registered with the inner subscriber and has a
valid ID. This bug means that when per-layer filters are wrapped in a
`Box` or `Arc`, they won't be registered, and per-layer filtering
breaks.

This PR fixes the bug by adding `on_layer` implementations to the
`Layer` impls for `Arc`ed and `Box`ed layers. I also added some tests
--- thanks to @Noah-Kennedy for the original repro that these were based
on (#1563 (comment)).

Signed-off-by: Eliza Weisman <eliza@buoyant.io>
this would help if this ever happened again

Signed-off-by: Eliza Weisman <eliza@buoyant.io>
@hawkw hawkw requested a review from a team as a code owner September 17, 2021 20:19
@hawkw hawkw self-assigned this Sep 17, 2021
@hawkw hawkw merged commit e597953 into v0.1.x Sep 17, 2021
@hawkw hawkw deleted the eliza/more-fun-panics branch September 17, 2021 21:25
Comment on lines +1169 to +1171
// XXX(eliza): this may behave weird if another `Arc` clone of this
// layer is layered onto a _different_ subscriber...but there's no
// good solution for that...
Copy link
Contributor

@jsgf jsgf Sep 18, 2021

Choose a reason for hiding this comment

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

I don't understand this comment. Arc::get_mut will only return a value if there are no other aliases so if it gets here there can't be a different subscriber. So the weird behaviour will be if there are multiple references to the Layer then this won't get called.

It seems like Arc<Layer> and on_layer are intrinsically incompatible. If having on_layer(&mut self, ... is useful, then maybe there shouldn't be Arc after all?

Copy link
Member Author

Choose a reason for hiding this comment

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

Arc::get_mut will only return a value if there are no other aliases so if it gets here there can't be a different subscriber.

was thinking about a situation where the Arc is cloned after on_layer is called. But, in practice, that will never happen, because on_layer is only called when layering, and layering moves the layer by value. However, there's nothing stopping user code from just arbitrarily calling on_layer.

It seems like Arc<Layer> and on_layer are intrinsically incompatible. If having on_layer(&mut self, ... is useful, then maybe there shouldn't be Arc after all?

Yes, I'm thinking that as well --- I regret not thinking through the potential implications of the Arc impl w.r.t having an on_layer callback. We may want to deprecate the Arc impls...which doesn't feel great, since we just added 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.

...ugh, i've been once again reminded that you can't deprecate a trait impl for a type:
image

so, I guess the only real solution for this is a big warning in the docs and removing it in the next breaking change. Gah!

Copy link
Contributor

Choose a reason for hiding this comment

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

Better to deprecate a bad idea earlier than later. And if Arc isn't actually usable, then presumably that will dissuade people from using it.

hawkw added a commit that referenced this pull request Sep 19, 2021
# 0.2.24 (September 19, 2021)

This release contains a number of bug fixes, including a fix for
`tracing-subscriber` failing to compile on the minimum supported Rust
version of 1.42.0. It also adds `IntoIterator` implementations for the
`Targets` type.

### Fixed

- Fixed compilation on Rust 1.42.0 ([#1580], [#1581])
- **registry**: Ensure per-layer filter `enabled` state is cleared when
  a global filter short-circuits filter evaluation ([#1575])
- **layer**: Fixed `Layer::on_layer` not being called for `Box`ed
  `Layer`s, which broke  per-layer filtering ([#1576])

### Added

- **filter**: Added `Targets::iter`, returning an iterator over the set
  of target-level pairs enabled by a `Targets` filter ([#1574])
- **filter**:  Added `IntoIterator` implementations for `Targets` and
  `&Targets` ([#1574])

Thanks to new contributor @connec for contributing to this release!

[#1580]: #1580
[#1581]: #1581
[#1575]: #1575
[#1576]: #1576
[#1574]: #1574
hawkw added a commit that referenced this pull request Sep 20, 2021
# 0.2.24 (September 19, 2021)

This release contains a number of bug fixes, including a fix for
`tracing-subscriber` failing to compile on the minimum supported Rust
version of 1.42.0. It also adds `IntoIterator` implementations for the
`Targets` type.

### Fixed

- Fixed compilation on Rust 1.42.0 ([#1580], [#1581])
- **registry**: Ensure per-layer filter `enabled` state is cleared when
  a global filter short-circuits filter evaluation ([#1575])
- **layer**: Fixed `Layer::on_layer` not being called for `Box`ed
  `Layer`s, which broke  per-layer filtering ([#1576])

### Added

- **filter**: Added `Targets::iter`, returning an iterator over the set
  of target-level pairs enabled by a `Targets` filter ([#1574])
- **filter**:  Added `IntoIterator` implementations for `Targets` and
  `&Targets` ([#1574])

Thanks to new contributor @connec for contributing to this release!

[#1580]: #1580
[#1581]: #1581
[#1575]: #1575
[#1576]: #1576
[#1574]: #1574
hawkw added a commit that referenced this pull request Oct 19, 2021
Implementing `Subscribe` for `Arc`s, which are immutable, breaks the
ability to implement `Subscribe::on_layer` with a mutable reference.
This is necessary for per-layer filtering. See
#1576 (comment) for
details. Therefore, the `Layer` impls for `Arc`s should not be used.

In 0.3, we have the opportunity to remove these APIs. Therefore, this PR
removes them.
hawkw added a commit that referenced this pull request Oct 19, 2021
Implementing `Subscribe` for `Arc`s, which are immutable, breaks the
ability to implement `Subscribe::on_layer` with a mutable reference.
This is necessary for per-layer filtering. See
#1576 (comment) for
details. Therefore, the `Layer` impls for `Arc`s should not be used.

In 0.3, we have the opportunity to remove these APIs. Therefore, this PR
removes them.
hawkw added a commit that referenced this pull request Oct 21, 2021
Implementing `Layer` for `Arc`s, which are immutable, breaks the
ability to implement `Layer::on_layer` with a mutable reference.
This is necessary for per-layer filtering. See
#1576 (comment) for
details. Therefore, the `Layer` impls for `Arc`s should not be used.

In 0.3, we have the opportunity to remove these APIs. Therefore, this PR
removes them.
hawkw added a commit that referenced this pull request Oct 21, 2021
Implementing `Layer` for `Arc`s, which are immutable, breaks the
ability to implement `Layer::on_layer` with a mutable reference.
This is necessary for per-layer filtering. See
#1576 (comment) for
details. Therefore, the `Layer` impls for `Arc`s should not be used.

In 0.3, we have the opportunity to remove these APIs. Therefore, this PR
removes them.
davidbarsky added a commit that referenced this pull request Mar 18, 2022
Implementing `Layer` for `Arc`s, which are immutable, breaks the
ability to implement `Layer::on_layer` with a mutable reference.
This is necessary for per-layer filtering. See
#1576 (comment) for
details. Therefore, the `Layer` impls for `Arc`s should not be used.

In 0.3, we have the opportunity to remove these APIs. Therefore, this PR
removes them.
hawkw pushed a commit that referenced this pull request Mar 23, 2022
Implementing `Layer` for `Arc`s, which are immutable, breaks the
ability to implement `Layer::on_layer` with a mutable reference.
This is necessary for per-layer filtering. See
#1576 (comment) for
details. Therefore, the `Layer` impls for `Arc`s should not be used.

In 0.3, we have the opportunity to remove these APIs. Therefore, this PR
removes them.
kaffarell pushed a commit to kaffarell/tracing that referenced this pull request May 22, 2024
…-rs#1576)

The `Layer::on_layer` method on `Layer` was added in PR tokio-rs#1523. PR tokio-rs#1536,
which added `Layer` implementations to `Box<dyn Layer<...> + ...>` and
`Arc<dyn Layer<...> + ...>`, merged prior to tokio-rs#1523. However, when
merging tokio-rs#1523, I didn't think to update the `Layer` impl for `Box`ed and
`Arc`ed layers to forward `on_layer` to the inner `Layer`. This means
that when a `Layer` is wrapped in an `Arc` or a `Box`, the `on_layer`
method never gets called.

When per-layer filters are in use, the `on_layer` method is necessary to
ensure the filter is registered with the inner subscriber and has a
valid ID. This bug means that when per-layer filters are wrapped in a
`Box` or `Arc`, they won't be registered, and per-layer filtering
breaks.

This PR fixes the bug by adding `on_layer` implementations to the
`Layer` impls for `Arc`ed and `Box`ed layers. I also added some tests
--- thanks to @Noah-Kennedy for the original repro that these were based
on (tokio-rs#1563 (comment)).

I also added a nicer debug assertion to `Filtered` for cases where
`Layer` impls don't call `on_layer`, so that this fails less confusingly
in the future.

Signed-off-by: Eliza Weisman <eliza@buoyant.io>
kaffarell pushed a commit to kaffarell/tracing that referenced this pull request May 22, 2024
# 0.2.24 (September 19, 2021)

This release contains a number of bug fixes, including a fix for
`tracing-subscriber` failing to compile on the minimum supported Rust
version of 1.42.0. It also adds `IntoIterator` implementations for the
`Targets` type.

### Fixed

- Fixed compilation on Rust 1.42.0 ([tokio-rs#1580], [tokio-rs#1581])
- **registry**: Ensure per-layer filter `enabled` state is cleared when
  a global filter short-circuits filter evaluation ([tokio-rs#1575])
- **layer**: Fixed `Layer::on_layer` not being called for `Box`ed
  `Layer`s, which broke  per-layer filtering ([tokio-rs#1576])

### Added

- **filter**: Added `Targets::iter`, returning an iterator over the set
  of target-level pairs enabled by a `Targets` filter ([tokio-rs#1574])
- **filter**:  Added `IntoIterator` implementations for `Targets` and
  `&Targets` ([tokio-rs#1574])

Thanks to new contributor @connec for contributing to this release!

[tokio-rs#1580]: tokio-rs#1580
[tokio-rs#1581]: tokio-rs#1581
[tokio-rs#1575]: tokio-rs#1575
[tokio-rs#1576]: tokio-rs#1576
[tokio-rs#1574]: tokio-rs#1574
kaffarell pushed a commit to kaffarell/tracing that referenced this pull request May 22, 2024
Implementing `Layer` for `Arc`s, which are immutable, breaks the
ability to implement `Layer::on_layer` with a mutable reference.
This is necessary for per-layer filtering. See
tokio-rs#1576 (comment) for
details. Therefore, the `Layer` impls for `Arc`s should not be used.

In 0.3, we have the opportunity to remove these APIs. Therefore, this PR
removes them.
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.

3 participants