wp-background-processing
wp-background-processing copied to clipboard
function handle() not firing
Hello!
Not sure if I'm missing something. I'm adding an item for an async request :
$example->example_request = new WP_Example_Request();
$example->example_request->data( array( 'value1' => 'the value 1', 'value2' => 'the value 2' ) );
$example->example_request->dispatch();
Then my class extension looks like this :
class WP_Example_Request extends WP_Async_Request {
/**
* @var string
*/
protected $action = 'example_request';
/**
* Handle
*
* Override this method to perform any actions required
* during the async request.
*/
protected function handle() {
error_log('test handle');
// Actions to perform
}
}
Not seeing "test handle" in the logs at all. So handle() is not firing at all. Any idea why? I must be missing something.
I'm experiencing a similar issue only that it's working fine on one server and not at all on another.
I'm getting the following response from handle() when logging it:
array (
'headers' =>
array (
),
'body' => '',
'response' =>
array (
'code' => false,
'message' => false,
),
'cookies' =>
array (
),
'http_response' => NULL,
)
Hi. I thought I had this problem as well using either Async or Background processing, but I tried running my background process anyway and it was producing the expected output file, but error_log was not outputting to the normal log file as defined in my nginx config. I used the php_ini_loaded_file() function to save the ini file path to the WordPress DB using update_user_option(). If I edit that ini file (in my case it was /etc/php5/fpm/php.ini) and set the error_log directive (i.e. error_log = syslog), then I could see the messages I was logging in /var/log/syslog. I am not sure if this is just because of how wp_remote_post() works, or just the way nginx/PHP-FPM work.
Semi-related -- another way I was testing initially was to use the sleep() function, but this seems to block the script, so it appeared that things weren't working correctly there as well. You can save yourself a lot of time by making sure you have PHP logging configured correctly and using a realistic function/process, rather than using sleep(), exec(), or any other blocking function for testing.
Thought I was doing something wrong... But it seemed Wordpress was logging to PHP error log, outside of Wordpress dir. Not what I expected.
So I changed
error_log($message);
to:
file_put_contents(WP_PLUGIN_DIR . '/my_plugin/logs/my.log', '['.date(DATE_RFC2822).'] '.$message.PHP_EOL , FILE_APPEND | LOCK_EX);
Now I got the result I wanted.
This may be related to the problem mentioned by @NiklasHogefjord. It's pretty obvious in hindsight, but easily overlooked. The server hosting the site needs to be able to resolve the hostname of your site. This plugin uses wp_remote_post().
I had setup a site on a linux server, and created a HOSTS entry on my development workstation, but not on the server. It took a bit to figure out that things were not working because wp_remote_post() was not able to connect to the site by hostname.
Same issue here. Not working at all.
Maybe mine is a little different, but my handle in single processing does not fire everytime. I did a count check and it only fires every other time or not at all for 3-5 dispatches... I hope that made sense? lol
I was also having the same problem but the problem was that I was initializing the WP_Async_Request on the wrong place. This class initializes the ajax actions, so it needs to be on the right place.
I added my solution here: #35
@kevinnivek Not sure if this helps in your situation (it doesn't in mine), but I noticed something when looking at your code. According to documentation the last line should look like $example->example_request->save()->dispatch();
... Looks like in your above logic the save()
method was omitted. Maybe it helps!
Ok, I just spent a day and a half debugging this same issue and finally got it working.
Like @NiklasHogefjord, my code was working fine on other servers except my beloved WP Engine site. To throw more confusion into the mix, it was only happening intermittently. Sometimes the batches would all finish sans errors, but sometimes they would just halt and seemingly timeout.
While debugging, I found that the batch itself was indeed being saved to the options table. This meant that the save()
function was working properly. I eventually traced the problem to the wp_remote_post()
function within the dispatch()
method of the parent Async class.
I tried logging the results of wp_remote_post()
but always received an empty array (even for successful batches) that looked exactly liked:
array (
'headers' =>
array (
),
'body' => '',
'response' =>
array (
'code' => false,
'message' => false,
),
'cookies' =>
array (
),
'http_response' => NULL,
)
To get an actual response from wp_remote_post()
, I had to remove the blocking
argument from the get_post_args()
method of the parent Async class. Whether this should be removed permanently is unclear to me, but it did finally give me a response to work with. Now I was able to actually see that I was getting a cURL error for those batches that were not working.
The specific error was: "cURL error 28: Operation timed out after 1000 milliseconds with 0 bytes received". I spent another 3-5 hours trying to figure this out. I eventually traced the issue to the timeout
argument located within the same get_post_args()
method as above. The default value here is 0.01
, which I instead set to 5 seconds.
The timeout
property here is interesting. According to the Codex it sets "the time in seconds, before the connection is dropped and an error is returned". https://codex.wordpress.org/HTTP_API#Other_Arguments So in other words, for whatever reason, the wp_ajax post to handle the batch process was being dropped immediately for certain batches, and giving it a bit more time to wait seems to have fixed the issue for me.
@A5hleyRich can you elaborate on why setting the timeout to a low value like 0.01
is needed? I don't seem to be encountering any performance degradations now either. Then again, in my case I have 7 different classes which all instantiate their own instances of the WP_Background_Process so perhaps that's why?
Anyway, hope this helps someone!
Thank you dbeja, you saved me! Hope I don't run into other issues as cited in this thread when I port my project to another server. Thanks to everyone who is posting here.
Thanks @arobbins! you saved my day. I spent hours on this issue, wasn't clear why I was receiving always an empty array. Now I was able to get the real issue (Domain name not found in my case).
Anyway having blocking
false and timeout
supershort will provide higher performance,
for example if the request to the server itself take too long for some reason, having timeout almost zero let the request immediately return but it isn't canceled (so the async action is performed).
There's subtle limitation of the package.
It useswp_ajax_...
action to trigger your handle
function.
The problem is due to the order that the actions got triggered.
I believe in your code where you created the WP_Example_Request
, it's already too late and already past the time for triggering wp_ajax_...
action. Therefore, your handle
function never gets a chance to run.
I came to the same problem trying to create the async request inside rest_api_init
action.
correct usage
create the request instance in action init
or plugins_loaded
(anything executed before wp_ajax...
is fine)
then use the request instance anywhere you desire.
It might be something to do with the server not being able to reach your domain?
On your Ubuntu server, check your /etc/hosts
file:
e.g.
127.0.0.1 somehostname localhost yourdomain.com www.yourdoamin.com
Closing ancient issue. :smile: (but in general we see this kind of issue if the server does not know itself by the domain of the site or security software is dropping local requests without responding)