Clearing a specific MODX item from the cache (or learning I don't have to)

I have a chunk which is updated programatically by a cron job. Then I’ve found historically I need to clear the cache which I do using $modx->getCacheManager()->clearCache() - but that’s dumping the whole cache.

Should I need to be doing this?
If I’m loading the MODX object in my script, setting the content then using $object->save() and the chunk has “clear cache on save” checked, should I need to do this specifically or should be be done

Is there a better way
If I need to be using cache manager, I see docs about wielding the cache for my own benefit, but is there a way to specifically target just that specific chunk? Browsing the cache files for myself it looks like chunks don’t appear for themselves but rather as fields in the resource cache. Does that sound right and if so, is the best thing to target the resources that contain that chunk in their page output? And if so, is there a neat programmatic way to do that or do I just target the files in their predicable locations in the /cache/resources branch of the filesystem?

$modx->getCacheManager()->clearCache() is very old - that’s been deprecated since v2.1 and should instead be $modx->getCacheManager()->refresh().

Yep!

If you can reliably predict which resources use that chunk, you can indeed try clearing just the specific resources with code like this:

$cacheManager->delete('specific/path/for/resource', [xPDO::OPT_CACHE_KEY => 'resource']);

Because it’s so hard to predict where something may be used, it is pretty typical to refresh the entire cache:

$cacheManager->refresh();

or you can refresh the resource cache partition with specific contexts:

$cacheManager->refresh([
    'resource' => ['contexts' => ['web', 'context2']],
]);

Perfect - thank you Mark!

You don’t say what you’re doing with the chunk. If it’s pulled in with a chunk tag, you can just call it uncached:

[[!$ChunkName]]

IIRC, if you’re calling $modx->getObject(), you can do this to get an uncached version:

$chunk = $modx->getObject('modChunk', 
    array('name => 'ChunkName'), false);

The slight drawback is that both methods will give you a slightly slower page load for every request compared to clearing the cache in the cron job, which will only give you the slow page load for the first request. My guess is that the difference would be trivial, though.

If you’re using $modx->getChunk() because you need to fill placeholders in code, there’s no way I know of to get an uncached version, so clearing the clearing the cache would make sense.

Thanks Bob - that’s helpful!

I was calling the chunk uncached ([[!$chunkName]] in the template), but that didn’t seem to be doing the job for whatever reason.

I’ve gone with the cache clear for now because then it rebuilds for the first call on that page every hour and is running optimised for the rest of the time.

That sounds like a good solution, though I can’t think of any possible way that calling the chunk uncached wouldn’t work, unless there’s a bug in the tag processing. It would be worth reporting if you can verify it.

Nah - I can’t think of a good reason a cached version would have stuck either.

I inherited this site many years ago and there’s a completely over-engineered system behind the templating which has about 4-5 nested calls before it’s putting in template.

It sniffs like someone who was translating an existing mechanism/paradigm into MODX but who didn’t understand MODX at the time.

This over-engineering is flagged for replacement at the next full site makeover. Until then I won’t stress about any in-depth testing to find edge cases because it could be hidden in weird details or could just be an artefact of many moons of upgrades. Were similar behaviour to show up in a newer site I’d definitely pursue it to the pointy end.

That makes sense. I’ve seen heavily nested calls go haywire before, especially when some are cached and some aren’t.

There’s also a side-effect of calling things uncached, which is that their processing is delayed. Nested, uncached tags may not be processed at the time they’re used by the outer tag so you get things like a raw tag being sent as an parameter to a snippet.

It still caches the chunk contents in the resource cache when using the uncached chunk tag, it’ll only process it every single request.