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

Feature/closeables weak ref #1443

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from
Open

Conversation

JerryShea
Copy link
Contributor

@JerryShea JerryShea commented Sep 26, 2023

WIP - do not merge

Fixes two problems:

  1. makes sure that tailers and appenders remove themselves from SingleChronicleQueue.closers
  2. makes closers a WeakReference so that the SCQ is no longer the only thing holding a reference to tailers & appenders after they would otherwise be candidates for GC

Second point above we should definitely discuss.

If we can reach consensus on this then after this change has been merged, it will be possible to set disable.discard.warning=false to register a finalizer for both appenders and tailers and ensure that if the finalizer is called, that they will warn and close themselves, thus releasing any resources. Backporting this to 23 will not be trivial as discard warnings/finalizers were different back then.

@JerryShea
Copy link
Contributor Author

JerryShea commented Sep 28, 2023

I reverted the first change (to call removeCloseListener from appender/tailer close methods) as a bunch of tests failed - will come back to.

The second change gives us some test flakiness with tests occasionally failed with exceptions were detected: Discarded without closing... and the tests that have shown this have tailers which are not explicitly closed and could go out of scope (and thus be GC'd) before the parent queue is closed. I have fixed a few of these tests to close tailers explicitly but there are a lot of them. We can
a) fix all these tests - it would be the ideal situation for our tests to demonstrate proper lifecycle management OR
b) ignoreException the "Discarded without closing" warning and create an issue to fix the tests

@@ -209,6 +209,7 @@ public void writeBytes(@NotNull final WriteBytesMarshallable marshallable) {

@Override
protected void performClose() {
// queue.removeCloseListener(this);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

see comments - will come back to

@sonarcloud
Copy link

sonarcloud bot commented Oct 15, 2023

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 5 Code Smells

64.3% 64.3% Coverage
0.0% 0.0% Duplication

@nicktindall
Copy link
Contributor

I reverted the first change (to call removeCloseListener from appender/tailer close methods) as a bunch of tests failed - will come back to.

The second change gives us some test flakiness with tests occasionally failed with exceptions were detected: Discarded without closing... and the tests that have shown this have tailers which are not explicitly closed and could go out of scope (and thus be GC'd) before the parent queue is closed. I have fixed a few of these tests to close tailers explicitly but there are a lot of them. We can a) fix all these tests - it would be the ideal situation for our tests to demonstrate proper lifecycle management OR b) ignoreException the "Discarded without closing" warning and create an issue to fix the tests

I vote definitely not b - unless it's done locally on the problematic tests, but if you're doing that you might as well fix them. "Creating an issue" no way guarantees it will ever get done, in the meantime, we are muting the thing we use to detect resource leaks so we will run the risk of introducing resource leaks. If it's not tested it's broken.

closers.add(key);
closers.removeIf(wrc -> {
final Closeable closeable = wrc.get();
return (closeable != null) ? closeable.isClosed() : true;
Copy link
Contributor

Choose a reason for hiding this comment

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

We don't need to keep empty weak references around do we?
return closeable == null || closeable.isClosed()

Copy link
Contributor

Choose a reason for hiding this comment

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

Sorry that's what it does, but perhaps refactor to less byzantine logic

// See https://github.com/OpenHFT/Chronicle-Queue/issues/1455. As many unit tests do not use try/finally
// to manage tailer or appender scope properly. we are ignoring this exception for now.
// TODO: remove the below line and run the tests many times to flush out the problematic tests (or else inspect the codebase)
ignoreException("Discarded without closing");
Copy link
Contributor

Choose a reason for hiding this comment

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

big one of these 👎

Copy link
Contributor

@nicktindall nicktindall left a comment

Choose a reason for hiding this comment

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

Don't silence leak detection

@@ -104,7 +105,7 @@
private final TimeProvider time;
@NotNull
private final BiFunction<RollingChronicleQueue, Wire, SingleChronicleQueueStore> storeFactory;
private final Set<Closeable> closers = Collections.newSetFromMap(new IdentityHashMap<>());
private final Set<WeakReference<Closeable>> closers = Collections.newSetFromMap(new IdentityHashMap<>());
Copy link
Member

Choose a reason for hiding this comment

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

Need to ensure these resources are closed if discarded, otherwise, the resources they reference won't be cleaned up except by further GCs, if they are closed on being discarded.

Copy link

sonarcloud bot commented Jan 27, 2024

Quality Gate Failed Quality Gate failed

Failed conditions

16.67% Condition Coverage on New Code (required ≥ 35%)

See analysis details on SonarCloud

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