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

fix(client): Fix cleanup of Client._waiters dict #129

Merged
merged 1 commit into from
Oct 2, 2023

Conversation

qweeze
Copy link
Collaborator

@qweeze qweeze commented Sep 21, 2023

fixes #125

@qweeze qweeze mentioned this pull request Sep 21, 2023
Copy link
Collaborator

@DanielePalaia DanielePalaia left a comment

Choose a reason for hiding this comment

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

Thanks!

@garvenlee
Copy link

In addition, function wait_frame also causes this bug.

@qweeze
Copy link
Collaborator Author

qweeze commented Sep 21, 2023

In addition, function wait_frame also causes this bug.

Do you mean creating a set in self._waiters[_key].add(fut) ? But this is intentional - this keys will either be deleted from _waiters in _listener, or the future will time out, and an exception will be raised.

@garvenlee
Copy link

garvenlee commented Sep 21, 2023

If the waiter is timeout, its callback will discard itself from self._waiters[key], but the underlaying set still exists?

And I don’t understand why self._waiters has to be a defautdict(set)? Each frame has a unique correlation_id, so the waiter_key is also unique.

@qweeze
Copy link
Collaborator Author

qweeze commented Sep 24, 2023

but the underlaying set still exists?

Yes, but I didn't consider it a big issue because it only happens when the app crashes, and recovery would require re-instantiating Client anyway, so at this point we don't care about memory. But I see your point now, and I agree it's better to not to leave any dangling references anyway

Each frame has a unique correlation_id, so the waiter_key is also unique

According to protocol, one-way messages (commands, i.e. Deliver) don't have correlation_id. So basically storing waiters in a set allows having multiple concurrent calls to wait_frame for a single command.

But as I can see, currently this is not used in the project. So I think we can simplify this structure, get rid of sets altogether and make it a plain dict[key, Future] But only if we're sure that we won't need this "multiple waiters" functionality - perhaps @Gsantomaggio and @DanielePalaia can confirm that is redundant

@garvenlee
Copy link

garvenlee commented Sep 24, 2023

it only happens when the app crashes, and recovery would require re-instantiating Client anyway

Yes, it is.

storing waiters in a set allows having multiple concurrent calls to wait_frame

Note that _waiters is only used in sync_request, where corr_id_seq is used to guarantee the uniqueness. This supports concurrency with different corr_id, so it’s fine to make _waiters a plain dict, and it’s also possible to simplify _handlers as here.

@qweeze qweeze force-pushed the fix/waiters-memory-leak branch from 69e8945 to f04c033 Compare September 26, 2023 23:54
@qweeze
Copy link
Collaborator Author

qweeze commented Sep 26, 2023

Ok, made waiters a plain dict

it’s also possible to simplify _handlers

I suggest to work on this in a next PR

@qweeze qweeze force-pushed the fix/waiters-memory-leak branch from f04c033 to 2e9e532 Compare September 27, 2023 09:14
@qweeze
Copy link
Collaborator Author

qweeze commented Oct 1, 2023

@Gsantomaggio do you mind if I merge this?

@Gsantomaggio
Copy link
Member

it is ok with me! thank you @qweeze

@qweeze qweeze merged commit 9fa8828 into master Oct 2, 2023
1 check passed
@Gsantomaggio Gsantomaggio deleted the fix/waiters-memory-leak branch October 2, 2023 12:40
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.

Memory Leak in Client
4 participants