I'm trying to use xautoload to load Pimple classes with the pimple_container module. I've modified pimple_container to load classes via xautoload:

  'xautoload' => function ($adapter) {
    /**
     * @var \Drupal\xautoload\Adapter\LocalDirectoryAdapter $adapter
     *   An adapter object that can register stuff into the class loader.
     */
    $adapter->add('Pimple\\', 'src');
  },

but I get:

Exception: Serialization of 'Closure' is not allowed in serialize() (line 450 of /Users/luca/Sites/drupal-7.26/includes/cache.inc).

because libraries module caches the libraries_info array.

There is a solution here but I don't understand what xautoload_InjectedAPI_hookXautoload_LibInfoTransform do.

Any ideas?

Thanks

Comments

lussoluca’s picture

lussoluca’s picture

Issue summary: View changes
donquixote’s picture

Looking at it.

donquixote’s picture

I think the solution you mentioned was never implemented.
So far I lacked the information about whether libraries info will ever be cached and serialized.
See also #1809254: Do you ever plan to serialize (cache) libraries_get_info()

Where does the serialization happen?

The class you mention is something I made up, not even sure now what it was supposed to do. But I guess it was meant to restore the callback when the placeholder object is unserialized.

One could ask if the entire hijacking of hook_libraries_info() was a good idea or not. It certainly feels hacky, now that I think about it.
But we can't really go back from there to not break BC.

Options:
1. Entirely remove the callback in hook_libraries_info_alter(). Use something else to retrieve it when needed, because it won't be in libraries_info().
2. Use hook_libraries_info_alter() to replace the callback with something that can be serialized, and that can restore the callback on unserialize. I think this was the idea in the link you mentioned.

Both of these options imply that you cannot use hook_libraries_info_alter() to register a callback.

donquixote’s picture

I think the solution will be (option 2) to introduce a class like Drupal\xautoload\ClosureOnIce or FrozenClosure or SerializableClosureWrapper.
Restoring the closure will be done by calling the implementation of hook_libraries_info() that created the closure.

donquixote’s picture

Version: 7.x-4.5 » 7.x-5.x-dev

And we should fix this in 7.x-5.x, which will become the recommended branch soon.

donquixote’s picture

lussoluca’s picture

Where does the serialization happen?

in libraries.module on line 636:

$library = libraries_detect($name);
cache_set($name, $library, 'cache_libraries');

I'm following this way because pimple_container uses libraries module to load the old non-PSR version of Pimple, I'll switch my code to use hook_xautoload while waiting for 7.x-5.x :-)

Thanks

donquixote’s picture

Looking at libraries_load().
It seems that a library is only supposed to be loaded once someone actively calls libraries_load($name).
So, xautoload, by registering every library for class loading during every request, is doing it wrong!

Instead, xautoload could register a callback on the library, that would be executed when the library loads.

donquixote’s picture

But I don't quite get the point with the versions and variants..
See libraries_traverse_library()

donquixote’s picture

Instead, xautoload could register a callback on the library, that would be executed when the library loads.

Maybe not a good idea, for BC reasons.

What I want to avoid is hook_libraries_info() being called on every request.
(if the xautoload cache is not active, or cache misses caused by classes not known to xautoload)

donquixote’s picture

The latest 7.x-5.x should fix all of this. Can you try?

donquixote’s picture

Status: Active » Needs review
donquixote’s picture

Category: Support request » Bug report
Status: Needs review » Fixed

This is/was in fact a bug report.
Changing to "Fixed", but feel free to reopen.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.