Replies: 3 comments 5 replies
-
|
Bump |
Beta Was this translation helpful? Give feedback.
-
|
Since there might be many people relying on the current behaviour, I'm going to leave things as they are for now. |
Beta Was this translation helpful? Give feedback.
-
|
came across similar myself today. Perhaps it's a good idea to note this in the documentation? or add a flag/extra function? although with once coming natively to Laravel 11, this might be a change you want also to be adopted there. As a workaround, people can add the following to a Function helper file in their projects. The body is the same as the use Spatie\Once\Backtrace;
use Spatie\Once\Cache;
if (!function_exists('only_once')) {
function only_once(callable $callback): mixed
{
$trace = debug_backtrace(
DEBUG_BACKTRACE_PROVIDE_OBJECT, 2
);
$backtrace = new Backtrace($trace);
if ($backtrace->getFunctionName() === 'eval') {
return call_user_func($callback);
}
$object = $backtrace->getObject();
$cache = Cache::getInstance();
if (is_string($object)) {
$object = $cache;
}
if (!$cache->isEnabled()) {
return call_user_func($callback, $backtrace->getArguments());
}
$hash = md5(
spl_object_hash($object)
. $backtrace->getObjectName()
. $backtrace->getFunctionName()
);
if (!$cache->has($object, $hash)) {
$result = call_user_func($callback, $backtrace->getArguments());
$cache->set($object, $hash, $result);
}
return $cache->get($object, $hash);
}
} |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Hi @freekmurze,
I love the once package.
It really helped me on some performance issues in a legacy and spaghetti codebase.
But I noticed, that in some circumstances, once is not working as I was expecting it to do.
Let's take a look at the following example:
I thought I was fine with this, but then I saw, that once is creating the once-per-combination key by the arguments provided to the outer function. That means, if I call the
processSomethingHeavyon 10000 users, of which a high percentage may have the same foo_relation_id, but all of them for sure have a different user_id, the cache will not work, cause the once-per-combination key gets generated by the outer function parameters. With this I would drastically lose performance here!Since PHP 8.1 you can dynamically get the parameters passed to a callback like this:
With that code we could generate the once-per-combination key from the parameters passed to the closure, which I think is much more intuitive and also as shown above would lead to a better cache hit and performance!
Cause I needed it fast, I wrote a own small memoization package.
But if you think about implementing this approach, I would definitly use the once package again!
Beta Was this translation helpful? Give feedback.
All reactions