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

Modify how nested resolutions get cached #10

Merged
merged 2 commits into from
Feb 23, 2022

Conversation

stevegrunwell
Copy link
Contributor

Previously, calling Container::get() would set Container::$cacheResolutions = true, run Container::make(), then restore Container::$cacheResolutions to its default value of false.

This worked well-enough for simple dependencies, but if the callable used to resolve a dependency used get() instead of make() then the resolution caching could be broken, resulting in warnings like the following:

PHP Warning: Undefined array key "some-abstract" in /path/to/Container.php

This PR fixes the issue in two ways:

  1. Replace the boolean Container::$cacheResolutions property with Container::$resolutionCacheDepth, an integer that gets incremented with each level of recursion
    • If this value is greater than 0, make() will automatically cache everything it resolves
  2. Explicitly set Container::$resolved[$abstract] upon calling get() instead of relying on make() to set it.

Previously, calling `Container::get()` would set `Container::$cacheResolutions = true`, run `Container::make()`, then restore `Container::$cacheResolutions` to its default value of `false`.

This worked well-enough for simple dependencies, but if the callable used to resolve a dependency used `get()` instead of `make()` then the resolution caching could be broken, resulting in warnings like the following:

> PHP Warning: Undefined array key "some-abstract" in /path/to/Container.php

This commit fixes the issue in two ways:

1. Replace the boolean `Container::$cacheResolutions` property with `Container::$resolutionCacheDepth`, an integer that gets incremented with each level of recursion
    * If this value is greater than 0, `make()` will automatically cache everything it resolves
2. Explicitly set `Container::$resolved[$abstract]` upon calling `get()` instead of relying on `make()` to set it.
@stevegrunwell stevegrunwell added the bug Something isn't working label Feb 23, 2022
Copy link
Contributor

@lkwdwrd lkwdwrd left a comment

Choose a reason for hiding this comment

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

This looks fine, but moves us a little further down this weird global state tracking path. If this ends up causing more problems in the future, let me know and I feel we should refactor to make this more thread-safe, which should also make weird edge cases less of a problem. Still this approach is faster than what I loosely have in mind, and if it's doing its job, we're only in a single threaded environment so there's no reason to refactor.

/**
* Whether or not resolutions should be cached.
*
* By default, this will be false but will be set to `true` when calling `get()`.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
* By default, this will be false but will be set to `true` when calling `get()`.
* By default, this will be `0` and will get incremented when calling `get()`.

@@ -214,11 +219,9 @@ public function make($abstract)
} else {
throw new ContainerException(sprintf('Unhandled definition type (%s)', gettype($config[$abstract])));
}
} catch (RecursiveDependencyException $e) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, this is much better. Good update.

@stevegrunwell
Copy link
Contributor Author

That's definitely a path I'd like to look into when we have some more time 👍

@stevegrunwell stevegrunwell merged commit 7cda04f into develop Feb 23, 2022
@stevegrunwell stevegrunwell deleted the fix/undefined-keys-in-resolved branch February 23, 2022 22:52
@stevegrunwell stevegrunwell mentioned this pull request Mar 22, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants