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

ManagesFailPointsTrait and always stop event listeners #1

Conversation

jmikola
Copy link

@jmikola jmikola commented Sep 20, 2024

@alcaeus: This is for mongodb#1427


trait ManagesFailPointsTrait
{
/** @var list<list{string, Server}> */
Copy link
Author

Choose a reason for hiding this comment

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

In your original PR you were storing the entire configureFailPoint command document. We only need the name of the fail point, so I've reduced this to a tuple like we originally had in FailPointObserver.

{
assertObjectHasAttribute('configureFailPoint', $failPoint);
assertIsString($failPoint->configureFailPoint);
assertObjectHasAttribute('mode', $failPoint);
Copy link
Author

Choose a reason for hiding this comment

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

A few assertions before we access object properties. I had these in for testing, but I suppose you can remove them if want to rely on the command succeeding.

$operation = new DatabaseCommand('admin', $failPoint);
$operation->execute($server);

if ($failPoint->mode !== 'off') {
Copy link
Author

Choose a reason for hiding this comment

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

I don't believe this is used in any tests, but it seemed reasonable to check for it since there's no point in disabling a fail point twice.

$context->stopEventObservers();
$context->stopEventCollectors();
} finally {
$this->disableFailPoints($context->getFailPoints());
$context->disableFailPoints();
Copy link
Author

Choose a reason for hiding this comment

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

Note that I moved stopEventObservers() and stopEventCollectors() within the finally block. That seemed correct given the following text from Executing a Test in the Unified Test Format spec:

For each element in test.operations, follow the process in Executing an Operation. If an unexpected error is encountered or an assertion fails, the test runner MUST consider this test to have failed.

If any event listeners were enabled on any client entities, the test runner MUST now disable those event listeners.

If any fail points were configured, the test runner MUST now disable those fail points (on the same server)...

It's possible that this could have resulted in memory leaks after failing tests. The subscriber would never get unregistered, and since they were registered globally they'd continue to accumulate in the process. Both EventCollector and EventObserver also hold a reference to a Context object, so those would also linger. I'm not sure if gc_collect_cycles() would have helped here, since it's PHPC itself that ultimately holds a reference to the subscriber(s) in its request-scoped HashTable.

I put this change in a separate commit, so if you think it deserves its own PHPLIB ticket for tracking feel free to create that and incorporate it into the message when merging this.

@alcaeus alcaeus merged commit 8921152 into alcaeus:phplib-1531-remove-getServer-failpoints Sep 20, 2024
@jmikola jmikola deleted the phplib-1531-remove-getServer-failpoints branch September 20, 2024 14:25
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.

2 participants