On a Drupal 7 site, I am using the Batch API to perform operations on many entities, one at a time. During a typical operation, the D7 site uses Guzzle to make a POST call to a Drupal 8 site. The D7 Batch callback looks like this:
function example_operation($foo, &$context) {
// Login to Drupal 8.
// ...
// Make POST call to Drupal 8.
// ...
// Logout from Drupal 8.
// ...
}
The D7 client uses a Guzzle client and cookie jar to authenticate with the D8 server (REST+cookies), with no issues. Great!
Now imagine running this on 100K+ entities, that's an awful lot of logging in and out unnecessarily, wasting a whole bunch of time and resources. So I figure, let's login once on the first operation, retain that session for each operation, then logout when finished. Sounds reasonable.
I thought I'd use D7 Batch API's $context['results']
array to hang onto the cookie jar and D8 rest tokens, that way each operation would have access to them, no problem, or so I thought. Take a look at this attempt in the D7 Batch callbacks:
function example_operation($foo, &$context) {
$jar = NULL;
$csrfToken = NULL;
// Login to Drupal 8 (first time only)
if (!isset($context['results']['jar'])) {
// Login to Drupal 8.
// ...
// Set aside cookie jar and tokens.
$context['results']['jar'] = $jar;
$context['results']['csrf_token'] = $csrfToken;
$context['results']['logout_token'] = $logoutToken;
}
else {
// We've already logged in, grab the cookie jar and token.
$jar = $context['results']['jar'];
$csrfToken = $context['results']['csrf_token'];
}
// Make POST call to Drupal 8 (using cookie jar and token).
// ...
}
function example_finished($success, $results, $operations) {
// Pull out cookie jar and tokens.
$jar = $results['jar'];
$csrfToken = $results['csrf_token'];
$logoutToken = $results['logout_token'];
// Logout from Drupal 8 (using cookie jar and tokens)
// ...
}
This approach works fine on the first operation only. Then on the second operation, the tokens are available in $context['results']
as expected, but the cookie jar always comes through as a __PHP_Incomplete_Class Object, and then if I try using it with the Guzzle client a cookies must be an instance of GuzzleHttp\Cookie\CookieJarInterface
is thrown.
How do you retain a Guzzle session between batch operations in Drupal 7?
- Perhaps
$context['results']
cannot contain "complex" class/objects like a Guzzle cookie jar - I tried using the
cookies
request option when instantiating the Guzzle client, but that breaks any authenticated POST calls (including the first operation) - Maybe the way D7's batch http requests work, it starts confusing the client/cookies/etc