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

Introduce IShutdownManager which allows us to order the shutdown func… #31857

Merged
merged 2 commits into from
Jun 25, 2018

Conversation

DeepDiver1975
Copy link
Member

@DeepDiver1975 DeepDiver1975 commented Jun 21, 2018

…tions

Description

php's register_shutdown_function offers no capability to define an execution order.
The IShutdownManager allows this.

Related Issue

#31851 and #31758 require this

Motivation and Context

We need a way to define that some shutdown functions are executed before the cleanup routines are triggered.

How Has This Been Tested?

  • manually

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist:

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

Copy link
Contributor

@PVince81 PVince81 left a comment

Choose a reason for hiding this comment

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

Great idea.

I assume you grepped for every destruct call to find these ?

There's also the "fclose detection" wrapper which is likely unrelated to this and doesn't need touching.

}

public function run(): void {
foreach ($this->callbacks as $callbacks) {
Copy link
Member

Choose a reason for hiding this comment

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

This doesn't ensure a priority order according to the $priority variable:

php > $items = [];
php > $items[500] = 500;
php > $items[30] = 30;
php > $items[100] = 100;
php > foreach ($items as $item) { echo "$item\n";}
500
30
100

Copy link
Member Author

Choose a reason for hiding this comment

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

Damn ..... Thx

* @return void
* @since 11.0.0
*/
public function register(\Closure $callback, int $priority = self::LOW): void {
Copy link
Member

Choose a reason for hiding this comment

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

I'd prefer to use an interface instead of a closure. It should be easiear to test and also clarifies how tha callback should look like.

Copy link
Member Author

Choose a reason for hiding this comment

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

Interface handler {
Public function Run() : void;
}

I don't See much benefit tbh

Copy link
Member

Choose a reason for hiding this comment

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

For testing, it feels easier and cleaner to mock an interface even if you only need to check if the target method is being called. If you use a closure you'll need to create a custom implementation and use an external counter to test the same thing.

In addition, you'll need to document how the callback should be. You can use

function ($a = null, $b = null) {
  if ($a !== null) $a->doSomething();
  if ($b !== null) $b->doOtherThing();
}

That would be confusing on the long run because it seems to work, but it might not do what we expect.

Copy link
Contributor

Choose a reason for hiding this comment

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

from my understanding with a closure all you need to do for testing is passing a test function:

   $obj->register(function() use (&$called) { $called = true; });
   $obj->doYourThingWithAllClosures();
   $this->assertTrue($called);

*/
interface IShutdownManager {

public const LOW = 1000;
Copy link
Member

Choose a reason for hiding this comment

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

I'd prefer to define now some additional priorities to minimize the changes we'll need to do to the interface in the future.

lib/private/Shutdown/ShutDownManager.php Outdated Show resolved Hide resolved
@DeepDiver1975
Copy link
Member Author

I assume you grepped for every destruct call to find these ?

I only changed/grepped for usages of register_shutdown_function. destroy methods are called even later in the process from my understanding

@jvillafanez
Copy link
Member

Quoting official documentation:

The destructor method will be called as soon as there are no other references to a particular object, or in any order during the shutdown sequence.

We shouldn't need to care about the destructor code as long as it's properly coded. The purpose of the destructor is a bit different.

@DeepDiver1975 DeepDiver1975 force-pushed the feature/shutdown-handler branch from 3a437d5 to 2372c76 Compare June 22, 2018 11:16
@codecov
Copy link

codecov bot commented Jun 22, 2018

Codecov Report

Merging #31857 into master will increase coverage by 0.12%.
The diff coverage is 52.94%.

Impacted file tree graph

@@             Coverage Diff              @@
##             master   #31857      +/-   ##
============================================
+ Coverage     63.27%   63.39%   +0.12%     
+ Complexity    18479    18461      -18     
============================================
  Files          1161     1162       +1     
  Lines         69377    69252     -125     
  Branches       1261     1261              
============================================
+ Hits          43895    43904       +9     
+ Misses        25112    24978     -134     
  Partials        370      370
Flag Coverage Δ Complexity Δ
#javascript 52.47% <ø> (ø) 0 <ø> (ø) ⬇️
#phpunit 64.65% <52.94%> (+0.14%) 18461 <8> (-18) ⬇️
Impacted Files Coverage Δ Complexity Δ
lib/base.php 5.93% <ø> (+1.74%) 126 <0> (-26) ⬇️
lib/private/Log/ErrorHandler.php 6.06% <0%> (-0.4%) 13 <1> (+1)
lib/private/Server.php 84.9% <0%> (-0.21%) 251 <1> (+1)
lib/private/Log/Syslog.php 0% <0%> (ø) 7 <1> (+1) ⬆️
lib/private/Shutdown/ShutDownManager.php 100% <100%> (ø) 5 <5> (?)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 7549002...8e9b2e7. Read the comment docs.

@DeepDiver1975 DeepDiver1975 force-pushed the feature/shutdown-handler branch from 2372c76 to 7b3e9b7 Compare June 22, 2018 12:36
@jvillafanez
Copy link
Member

If we aren't going to use an interface shutdownManager registration, we should document what is the expected signature of the closure function, whether it is going to be function() : void or function(MyClass $obj) : void or function() : bool. I don't want to be forced to check how other people is using this.

We should also document that under the same priority, the tasks will be done in the same order they were registered.

@DeepDiver1975 DeepDiver1975 force-pushed the feature/shutdown-handler branch from 7b3e9b7 to f75e4e6 Compare June 22, 2018 14:12
@DeepDiver1975
Copy link
Member Author

@jvillafanez your objections have been addressed

@DeepDiver1975 DeepDiver1975 merged commit 0d64f54 into master Jun 25, 2018
@DeepDiver1975 DeepDiver1975 deleted the feature/shutdown-handler branch June 25, 2018 06:41
@lock lock bot locked as resolved and limited conversation to collaborators Sep 16, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants