Reputation: 7975
I've got some time-consuming code that processes the results of a series of HTTP requests that I'd like to run in the background. I'm using a Redis store for managing the queue. Here's what I've tried:
Queue::push( 'FetchUrls', [
'urls' => [ 'http://one.com', 'http://two.com', 'http://three.com' ],
'complete' => function( $response ) { /* process data returned by URL here */ },
'error' => function( $error ) { /* process HTTP errors here */ },
]);
What shows up in the Redis queue store is a JSON
serialization of the $data
parameter:
{
"job": "FetchUrls",
"data": {
"urls": [
"http:\/\/one.com",
"http:\/\/two.com",
"http:\/\/three.com"
],
"complete": [],
"error": []
},
"id": "aAlkNM0ySLXcczlLYho19TlWYs9hStzl",
"attempts": 1
}
As you can see, the callbacks just show up as empty arrays in the queue store. I've never used the Queue class before and so I may be approaching this problem in the wrong way. I'm looking for a suggestion for the best way to work around this. Thanks!
Upvotes: 1
Views: 1135
Reputation: 579
You could pass function names and invoke them with something like call_user_func()
.
Queue::push('FetchUrls', [
'urls' => ['http://one.com', 'http://two.com', 'http://three.com'],
'complete' => ['ResponseHandler', 'fetchComplete'],
'error' => ['ResponseHandler', 'fetchError'],
]);
class FetchUrls
{
public function fire($job, $data)
{
list($urls, $complete, $error) = $data;
foreach ($urls as $url) {
if ($response = $this->fetch($url)) {
$job->delete();
call_user_func($complete, $response);
} else {
$job->release();
call_user_func($error, $this->getError());
}
}
}
private function fetch($url)
{
// ...
}
private function getError()
{
// ...
}
}
class ResponseHandler
{
public static function fetchComplete($response)
{
// ...
}
public static function fetchError($error)
{
// ...
}
}
There's a not-class-based version of this approach, but this is relatively clean.
call_user_func()
with ['ResponseHandler', 'fetchComplete']
as the first parameter will invoke ResponseHandler::fetchComplete()
.
Upvotes: 2
Reputation: 22872
To be safe, you should push arrays only (since problems with serializations).
To answer your question - there is no workaround, you should rethink the logic.
Upvotes: 3