1

I run a site where I make an external API call. I want to have a failure case such that, if the API call fails, it will call wp_schedule_single_event() to re-try the API call in +4 hours.

If that next API call fails, it will schedule it try again in +4 hours.

I have things working such that the first wp_schedule_single_event for +4 hours runs just fine. But when it is called recursively, that is the wp_schedule_single_event calls wp_schedule_single_event with time() + 4 hours, the newest event does not schedule.

I believe I understand why this is happening. I believe it is because time() is returning the time for when the initial event was run. It is not re-running the time() call to get a new system time. As a result, it is essentially trying to call wp_schedule_single_event with a time in the past, causing it to fail.

Here is the code in question:

add_action('order_drip_followers_hook','order_drip_followers', 10, 2);
function order_drip_followers($workflow, $days)
{
    $link = 'https://www.instagram.com/';
    $order = $workflow->data_layer()->get_order();
    $ig_user = clean($order->get_meta('ig_username'));
    $forward_slash = '/';
    $profile_link = $link . $ig_user . $forward_slash;
    $customer = $workflow->data_layer()->get_customer();
    $customer_user_id = $customer->get_user_id();

        $postData = array(
        //removed for privacy
        );

        $request = curl_post_followers($postData);
        var_dump($request);

        $payload = json_decode($request,true);
        $order_status = $payload["status"];

        if($order_status == "ok") {
            //API Order Success
            $order_id = $payload["order"];
            update_user_meta($customer_user_id, "drip_followers_order_id", $order_id);
        } else {
            //API Order Failure
            //Schedule retry in 4 hours
            wp_schedule_single_event(time() + 3600*4, 'order_drip_followers_hook', array($workflow, $days));
        }
    }

How do I fix this issue?

2
  • 1
    Can you include your code to show exactly how you’re doing this? Aug 12, 2019 at 6:05
  • Done! Thanks for the reminder
    – Sam
    Aug 12, 2019 at 7:08

1 Answer 1

0

As I can understand from your code, you need to run the code only once to get the data, but if it failed, so run again once, untill you get the data then stop. according to this understanding we can think like the following:

  • We need to depend on wp_schedule_event to make sure the event will continue firing, untill it meets a condition (will be defined). so use it instead of wp_schedule_single_event

  • Create a flag that will be set to a value if the function returned the desired data..

  • This flag should be the condition the controls the code running.

  • If the condition is not met so we run the code, else we remove the hooked event

So we can write the code:

<?php
add_action('order_drip_followers_hook','order_drip_followers', 10, 2);
function order_drip_followers($workflow, $days)
{
if(!get_transient('user_meta_updated_'.get_current_user_id( )){


$link = 'https://www.instagram.com/';
$order = $workflow->data_layer()->get_order();
$ig_user = clean($order->get_meta('ig_username'));
$forward_slash = '/';
$profile_link = $link . $ig_user . $forward_slash;
$customer = $workflow->data_layer()->get_customer();
$customer_user_id = $customer->get_user_id();

    $postData = array(
    //removed for privacy
    );

    $request = curl_post_followers($postData);
    var_dump($request);

    $payload = json_decode($request,true);
    $order_status = $payload["status"];

    if($order_status == "ok") {
        //API Order Success
        $order_id = $payload["order"];
        update_user_meta($customer_user_id, "drip_followers_order_id", $order_id);
        set_transient('user_meta_updated_'.get_current_user_id( ), '1' );
   }
   }else{
    wp_clear_scheduled_hook( 'order_drip_followers_hook', array( $workflow, $day ) );
   }
}
 ?>

I didn't test the code, I hope you test and inform me what happens.

Note

If you just need the code run always for specific intervals so no need for the flag.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.