Skip to content

Modify how nested resolutions get cached#10

Merged
stevegrunwell merged 2 commits intodevelopfrom
fix/undefined-keys-in-resolved
Feb 23, 2022
Merged

Modify how nested resolutions get cached#10
stevegrunwell merged 2 commits intodevelopfrom
fix/undefined-keys-in-resolved

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()`.

} 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