Hello,

Cache backend management is a low-level critical functionallity, doing the Cache Backport module, I also added some code improvements into the D6 backport.

I think Drupal 7 could benefit those improvements, since they are API compatible and could avoid some crashes on misconfigured environments.

Basically, I do all of this:

  • Adding an interface for strongly environment related backends, backends that needs external libraries to run steamlessly should implement a new checkEnv() method in order for core to test if the environment if ready.
  • I added a dummy implementation of this method on the database backend, as a code sample.
  • I added a class_exists() call at cache backend instanciation time, if the current class does not exists, the backend gracefully downgrade to default.
  • Added the necessary checkEnv() calls while instanciating the backend class, and provide a graceful downgrade to default if it fails.
  • Added a bonus Null Object implementation of cache backend; this allows site administrators or developers to disable fully cache for one or more bins by configuration.

Using this interface improvements, it can be easy to implement administration screens (at least report screen) for various cache backends state, what I did in the D6 backport, and I could easily do for D7 if people are interested.

Cache backend being plugins is now being discussed for D8, so that's why I won't do a D8 patch until the solution to this problem comes up, until, this can still provide a nice consistency bugfix for D7 next release.

Comments

pounard’s picture

This makes the system more robust at the cost of less than (number of bins) * function calls. I needed it while I was iterating on development phases on some custom projects, and this code has proven to me to be working quite well. Well, on the D6 cache backport module it did, but this patch is basically almost the same code, with better Drupal code convention support and better documentation. I tested some use cases on a D7 instance even run some UNIT tests (well, not every of them because my box is dawn slow).

damien tournoud’s picture

Version: 7.x-dev » 8.x-dev
Status: Active » Needs work

Feature requests needs to go to D8 first, nonetheless.

About the patch:

* We try not to abbreviate, checkEnv() should be named checkEnvironment(), or most preferably something like isHealthy() because there could be more reasons for a cache not to be available then just missing libraries
* We already have a Null cache (DrupalFakeCache)

damien tournoud’s picture

Also, the final hardcoding of DrupalDatabaseCahe feels weird to me:

+    if ($instance instanceof DrupalEnvRelatedPlugin && !$instance->checkEnv()) {
+      $instance = new DrupalDatabaseCache($bin);
+    }

A better strategy would be to try the default cache implementation first, and if it fails fallback to the fake cache.

pounard’s picture

Category: feature » bug

@#2
Sounds right for the method naming. Doesn't really care about the name as soon as it express the purpose.
Didn't see the DrupalFakeCache, probably should it live in the cache.inc, I mean, is the cache-install.inc loaded on normal runtime?

@#3
I'll provide a clearer patch.

Since a misconfigured settings.php file can lead to WSOD with the actual cache.inc, I'm switching this down to bugfix, not feature request anymore.

pounard’s picture

DrupalFakeCache embeds specific code for install time (messes up with Database) what a real Dummy/Stumb/Null/Neutral object should not, maybe should it be renamed to DrupalInstallCache instead, and DrupalFakeCache should be my own implementation? Plus, a real Null Object implementation shouldn't rely on a base class that's a totally messed-up and broken design.

damien tournoud’s picture

I'm pretty sure it was named DrupalInstallCache at one point. We should try to track down where it changed. Agreed on the broken design, but it makes sense at install time.

pounard’s picture

Version: 8.x-dev » 7.x-dev

Yes, I'm rewriting the patch.

pounard’s picture

Status: Needs review » Needs work
StatusFileSize
new5.68 KB

Ok, here is a more complicated patch, implementing Damien suggestions:

  • Renamed legacy DrupalFakeCache as DrupalInstallCache, which should probably be better for code comprehension.
  • Patched install related files in order for them to use the DrupalInstallCache.
  • DrupalFakeCache is now defined in the cache.inc which makes more sense since it can be used voluntarely by site admins or developers to do testing. It is now a real Null Object implementation that does not extends the DrupalDatabaseCache anymore.
  • Rewrote _cache_get_object() with more checks. Default backend class is statically cached, if it fails once, the system downgrades to the null implementation instead. This means that misconfigured sites will suffer from performance problems, but won't WSOD anymore.
  • Renamed the checkEnv() method as isHealthy() as Damien suggested (it makes sense to me).

There are a few things to consider here, but I think this patch can work as-is without going further, nevertheless:

  • DrupalInstallCache is an insane and unnecessary code indirection, and should be definitely removed as the install-cache.inc file. It should use the real null implementation aKa DrupalFakeCache instead.

EDIT: Fixed some typo errors.

pounard’s picture

Status: Needs work » Needs review

Switching to needs review.

catch’s picture

There is an existing issue for a null cache backend at #1082328: Provide a proper no-op cache.inc, although no patch.

DrupalInstallCache is necessary due to ajax requests to the Drupal site during install (I think this is the clean URL check, not sure what else), it is a hack, but it can't be removed without dealing with the bugs it works around.

Why not put the health check in the catch section of a try/catch block? If get() returns something valid and no error then it is already healthy. #1167144: Make cache backends responsible for their own storage contains some discussion around this.

pounard’s picture

We related all of that, and my implementation actually keeps the installation backend, but renaming it, while it created a real fake implementation into a simpler version which is actually a real null object pattern implementation (that get the name of the older one, therefore keeping backward compatibility).

The try/catch implementation is not likely to be useful here because we cannot catch while instanciating based on the get() errors.

My whole patch is about not ending up with a WSOD (which with the actual code can happen) and keeping full API compatibility. It adds some new stuff but there are basically dormant if you don't use it and doesn't modify the actual API.

pounard’s picture

Status: Needs work » Needs review

Hello, waking up this issue since I'm actually developing cache backend, it's the right time for me to have a final answer about this issue.

@Damien Tournoud you made pertinent comments, now that I fulfilled every one of them, should be the right time for a go or a no go.

@catch I think this issue is not incompatible with the others being opened, and the isHealthy() method could be the right one were to implement the lazy table creation (or anything else depending on the backend).

damien tournoud’s picture

Version: 7.x-dev » 8.x-dev
Category: bug » feature
Status: Needs review » Needs work
Issue tags: +Needs backport to D7

Re-filling properly.

This should be easily backportable, but I suggest we fix the name of the interface and the documentation:

+/**
+ * Defines an strongly environment related plugin.
+ * 
+ * Every plugin that [...] 
+ * 
+ * @see DrupalDatabaseCache
+ *   For a functional plugin example.
+ * @see _cache_get_object
+ *   For a sample usage by core.
+ */
+interface DrupalCriticalBackendInterface {

There is no such thing as a "Plugin" in Drupal at this stage. This is not meant to be a generic implementation of a "strongly environment related plugin". This is just meant as a way for a cache implementation to declare if it is healthy or not.

If down the road we want to tackle the generic problem, we will. In the meantime I don't see this getting in without making it specific to the cache system.

pounard’s picture

Ok, I don't see any problems with that suggestion, let me redo the patch and we could then discuss it further.

EDIT: But I really don't see why loosing the generic aspect, when we look at this issue: #402896: Introduce DrupalCacheArray and use it for drupal_get_schema() the proposition is meant to give a generic solution (and a good candidate for backport) for potential modules or other core usage.

Maybe the terminology indeed can be changed, the plugin word can be confusing; But the generic aspect, even if not being used right now, is still a potential future benefit.

pounard’s picture

New patch attached, did on latest 7.x, should pass on 8.x as well.

Changes:

  • As required, removed all plugin word occurences, changed the interface name to DrupalCriticalCacheInterface.
  • Changed a bit documentation to fit this change.
  • Removed useless default sample implementation on DrupalDatabaseCache
  • Removed useless cache-install.inc file and make the install using the DrupalFakeCache backend instead.
pounard’s picture

Forgot the patch..

pounard’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, drupal-7.x-git-cache_backend_env_downgrade-3.patch, failed testing.

pounard’s picture

Status: Needs work » Needs review
StatusFileSize
new6.76 KB
dtwork’s picture

pounard’s picture

Wrong tab, forget it.

pounard’s picture

Status: Needs review » Needs work
Anonymous’s picture

subscribe.

pounard’s picture

Status: Needs work » Needs review
StatusFileSize
new7.2 KB

Attached patch following latest commit from catch API modifications.

pounard’s picture

This still includes the FakeCache correct implementation, sorry if it mixes up with the other related issue, but it's simpler this way.

pounard’s picture

Personal reminder: need to separate the null object cache implementation and put in the right issue: #1082328: Provide a proper no-op cache.inc

Done, and waiting for it to be commited to fix the patch here.

thedavidmeister’s picture

Status: Needs review » Needs work

The last submitted patch, drupal-8.x-git-cache_backend_env_downgrade-4.patch, failed testing.

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.2.x-dev

Drupal 8 is end-of-life as of November 17, 2021. There will not be further changes made to Drupal 8. Bugfixes are now made to the 9.3.x and higher branches only. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.15 was released on June 1st, 2022 and is the final full bugfix release for the Drupal 9.3.x series. Drupal 9.3.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.4.x-dev branch from now on, and new development or disruptive changes should be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.9 was released on December 7, 2022 and is the final full bugfix release for the Drupal 9.4.x series. Drupal 9.4.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.5.x-dev branch from now on, and new development or disruptive changes should be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

smustgrave’s picture

Status: Needs work » Postponed (maintainer needs more info)
Issue tags: +stale-issue-cleanup

Thank you for sharing your idea for improving Drupal.

We are working to decide if this proposal meets the Criteria for evaluating proposed changes. There hasn't been any discussion here for over 8 years which suggests that this has either been implemented or there is no community support. Your thoughts on this will allow a decision to be made.

Since we need more information to move forward with this issue, the status is now Postponed (maintainer needs more info). If we don't receive additional information to help with the issue, it may be closed after three months.

Thanks!

smustgrave’s picture

Status: Postponed (maintainer needs more info) » Closed (outdated)

Since there's been no follow up in 3 months going to close out, but don't worry if still valid it can be reopened. Thanks all!