Blame SOURCES/0036-BE-Extend-be_ptask_create-with-control-when-to-sched.patch

d6181b
From 25b9f34fb2c7ea493c5e0fe83047703ec65fe60c Mon Sep 17 00:00:00 2001
d6181b
From: Jakub Hrozek <jhrozek@redhat.com>
d6181b
Date: Tue, 18 Jun 2019 20:49:00 +0200
d6181b
Subject: [PATCH 36/48] BE: Extend be_ptask_create() with control when to
d6181b
 schedule next run after success
d6181b
d6181b
Related: https://pagure.io/SSSD/sssd/issue/4012
d6181b
d6181b
be_ptask_create() used to always schedule the next periodical run
d6181b
"period" seconds after the previous run started. This is great for tasks
d6181b
that are short-lived like DNS updates because we know they will be
d6181b
executed really with the configured period.
d6181b
d6181b
But the background refresh task can potentially take a very long time in
d6181b
which case the next run could have been scheduled almost immediately and
d6181b
as a result sssd_be would always be quite busy. It is better to have the
d6181b
option to schedule the next task period seconds after the last run has
d6181b
finished. This can lead to some inconsistency, but we can warn the
d6181b
admin about that.
d6181b
d6181b
This patch so far does not change any of the existing calls to
d6181b
be_ptask_create(), just adds BE_PTASK_SCHEDULE_FROM_LAST as an
d6181b
additional parameter.
d6181b
d6181b
Reviewed-by: Sumit Bose <sbose@redhat.com>
d6181b
---
d6181b
 src/providers/ad/ad_dyndns.c             |  3 +-
d6181b
 src/providers/ad/ad_machine_pw_renewal.c |  4 +-
d6181b
 src/providers/ad/ad_subdomains.c         |  4 +-
d6181b
 src/providers/be_ptask.c                 | 10 ++--
d6181b
 src/providers/be_ptask.h                 | 24 ++++++++-
d6181b
 src/providers/be_ptask_private.h         |  1 +
d6181b
 src/providers/be_refresh.c               |  4 +-
d6181b
 src/providers/ipa/ipa_dyndns.c           |  5 +-
d6181b
 src/providers/ipa/ipa_subdomains.c       |  4 +-
d6181b
 src/providers/ldap/ldap_id_enum.c        |  1 +
d6181b
 src/providers/ldap/sdap_sudo_shared.c    |  8 ++-
d6181b
 src/tests/cmocka/test_be_ptask.c         | 62 ++++++++++++++++--------
d6181b
 12 files changed, 95 insertions(+), 35 deletions(-)
d6181b
d6181b
diff --git a/src/providers/ad/ad_dyndns.c b/src/providers/ad/ad_dyndns.c
d6181b
index 52a4e4d53..02ea7f24b 100644
d6181b
--- a/src/providers/ad/ad_dyndns.c
d6181b
+++ b/src/providers/ad/ad_dyndns.c
d6181b
@@ -97,8 +97,9 @@ errno_t ad_dyndns_init(struct be_ctx *be_ctx,
d6181b
               "dyndns_refresh_interval is 0\n");
d6181b
         return EINVAL;
d6181b
     }
d6181b
+
d6181b
     ret = be_ptask_create(ad_opts, be_ctx, period, ptask_first_delay, 0, 0, period,
d6181b
-                          BE_PTASK_OFFLINE_DISABLE, 0,
d6181b
+                          BE_PTASK_OFFLINE_DISABLE, BE_PTASK_SCHEDULE_FROM_LAST, 0,
d6181b
                           ad_dyndns_update_send, ad_dyndns_update_recv, ad_opts,
d6181b
                           "Dyndns update", NULL);
d6181b
 
d6181b
diff --git a/src/providers/ad/ad_machine_pw_renewal.c b/src/providers/ad/ad_machine_pw_renewal.c
d6181b
index 5b6ba26b7..47941dfbf 100644
d6181b
--- a/src/providers/ad/ad_machine_pw_renewal.c
d6181b
+++ b/src/providers/ad/ad_machine_pw_renewal.c
d6181b
@@ -382,7 +382,9 @@ errno_t ad_machine_account_password_renewal_init(struct be_ctx *be_ctx,
d6181b
     }
d6181b
 
d6181b
     ret = be_ptask_create(be_ctx, be_ctx, period, initial_delay, 0, 0, 60,
d6181b
-                          BE_PTASK_OFFLINE_DISABLE, 0,
d6181b
+                          BE_PTASK_OFFLINE_DISABLE,
d6181b
+                          BE_PTASK_SCHEDULE_FROM_LAST,
d6181b
+                          0,
d6181b
                           ad_machine_account_password_renewal_send,
d6181b
                           ad_machine_account_password_renewal_recv,
d6181b
                           renewal_data,
d6181b
diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c
d6181b
index c4ac23065..2510498da 100644
d6181b
--- a/src/providers/ad/ad_subdomains.c
d6181b
+++ b/src/providers/ad/ad_subdomains.c
d6181b
@@ -2066,7 +2066,9 @@ errno_t ad_subdomains_init(TALLOC_CTX *mem_ctx,
d6181b
 
d6181b
     period = be_ctx->domain->subdomain_refresh_interval;
d6181b
     ret = be_ptask_create(sd_ctx, be_ctx, period, 0, 0, 0, period,
d6181b
-                          BE_PTASK_OFFLINE_DISABLE, 0,
d6181b
+                          BE_PTASK_OFFLINE_DISABLE,
d6181b
+                          BE_PTASK_SCHEDULE_FROM_LAST,
d6181b
+                          0,
d6181b
                           ad_subdomains_ptask_send, ad_subdomains_ptask_recv, sd_ctx,
d6181b
                           "Subdomains Refresh", NULL);
d6181b
     if (ret != EOK) {
d6181b
diff --git a/src/providers/be_ptask.c b/src/providers/be_ptask.c
d6181b
index c43351755..32d9a03ce 100644
d6181b
--- a/src/providers/be_ptask.c
d6181b
+++ b/src/providers/be_ptask.c
d6181b
@@ -30,11 +30,6 @@
d6181b
 
d6181b
 #define backoff_allowed(ptask) (ptask->max_backoff != 0)
d6181b
 
d6181b
-enum be_ptask_schedule {
d6181b
-    BE_PTASK_SCHEDULE_FROM_NOW,
d6181b
-    BE_PTASK_SCHEDULE_FROM_LAST
d6181b
-};
d6181b
-
d6181b
 enum be_ptask_delay {
d6181b
     BE_PTASK_FIRST_DELAY,
d6181b
     BE_PTASK_ENABLED_DELAY,
d6181b
@@ -182,7 +177,7 @@ static void be_ptask_done(struct tevent_req *req)
d6181b
         DEBUG(SSSDBG_TRACE_FUNC, "Task [%s]: finished successfully\n",
d6181b
                                   task->name);
d6181b
 
d6181b
-        be_ptask_schedule(task, BE_PTASK_PERIOD, BE_PTASK_SCHEDULE_FROM_LAST);
d6181b
+        be_ptask_schedule(task, BE_PTASK_PERIOD, task->success_schedule_type);
d6181b
         break;
d6181b
     default:
d6181b
         DEBUG(SSSDBG_OP_FAILURE, "Task [%s]: failed with [%d]: %s\n",
d6181b
@@ -268,6 +263,7 @@ errno_t be_ptask_create(TALLOC_CTX *mem_ctx,
d6181b
                         time_t random_offset,
d6181b
                         time_t timeout,
d6181b
                         enum be_ptask_offline offline,
d6181b
+                        enum be_ptask_schedule success_schedule_type,
d6181b
                         time_t max_backoff,
d6181b
                         be_ptask_send_t send_fn,
d6181b
                         be_ptask_recv_t recv_fn,
d6181b
@@ -300,6 +296,7 @@ errno_t be_ptask_create(TALLOC_CTX *mem_ctx,
d6181b
     task->max_backoff = max_backoff;
d6181b
     task->timeout = timeout;
d6181b
     task->offline = offline;
d6181b
+    task->success_schedule_type = success_schedule_type;
d6181b
     task->send_fn = send_fn;
d6181b
     task->recv_fn = recv_fn;
d6181b
     task->pvt = pvt;
d6181b
@@ -470,6 +467,7 @@ errno_t be_ptask_create_sync(TALLOC_CTX *mem_ctx,
d6181b
 
d6181b
     ret = be_ptask_create(mem_ctx, be_ctx, period, first_delay,
d6181b
                           enabled_delay, random_offset, timeout, offline,
d6181b
+                          BE_PTASK_SCHEDULE_FROM_LAST,
d6181b
                           max_backoff, be_ptask_sync_send, be_ptask_sync_recv,
d6181b
                           ctx, name, _task);
d6181b
     if (ret != EOK) {
d6181b
diff --git a/src/providers/be_ptask.h b/src/providers/be_ptask.h
d6181b
index 3b9755361..c23278e88 100644
d6181b
--- a/src/providers/be_ptask.h
d6181b
+++ b/src/providers/be_ptask.h
d6181b
@@ -46,6 +46,19 @@ enum be_ptask_offline {
d6181b
     BE_PTASK_OFFLINE_EXECUTE
d6181b
 };
d6181b
 
d6181b
+/**
d6181b
+ * Defines the starting point for scheduling a task
d6181b
+ */
d6181b
+enum be_ptask_schedule {
d6181b
+    /* Schedule starting from now, typically this is used when scheduling
d6181b
+     * relative to the finish time
d6181b
+     */
d6181b
+    BE_PTASK_SCHEDULE_FROM_NOW,
d6181b
+    /* Schedule relative to the start time of the task
d6181b
+     */
d6181b
+    BE_PTASK_SCHEDULE_FROM_LAST
d6181b
+};
d6181b
+
d6181b
 typedef struct tevent_req *
d6181b
 (*be_ptask_send_t)(TALLOC_CTX *mem_ctx,
d6181b
                    struct tevent_context *ev,
d6181b
@@ -75,6 +88,14 @@ typedef errno_t
d6181b
  * The first execution is scheduled first_delay seconds after the task is
d6181b
  * created.
d6181b
  *
d6181b
+ * Subsequent runs will be scheduled depending on the value of the
d6181b
+ * success_schedule_type parameter:
d6181b
+ *  - BE_PTASK_SCHEDULE_FROM_NOW: period seconds from the finish time
d6181b
+ *  - BE_PTASK_SCHEDULE_FROM_LAST: period seconds from the last start time
d6181b
+ *
d6181b
+ * If the test fails, another run is always scheduled period seconds
d6181b
+ * from the finish time.
d6181b
+ *
d6181b
  * If request does not complete in timeout seconds, it will be
d6181b
  * cancelled and rescheduled to 'now + period'.
d6181b
  *
d6181b
@@ -83,7 +104,7 @@ typedef errno_t
d6181b
  *
d6181b
  * The random_offset is maximum number of seconds added to the
d6181b
  * expected delay. Set to 0 if no randomization is needed.
d6181b
-
d6181b
+ *
d6181b
  * If max_backoff is not 0 then the period is doubled
d6181b
  * every time the task is scheduled. The maximum value of
d6181b
  * period is max_backoff. The value of period will be reset to
d6181b
@@ -100,6 +121,7 @@ errno_t be_ptask_create(TALLOC_CTX *mem_ctx,
d6181b
                         time_t random_offset,
d6181b
                         time_t timeout,
d6181b
                         enum be_ptask_offline offline,
d6181b
+                        enum be_ptask_schedule success_schedule_type,
d6181b
                         time_t max_backoff,
d6181b
                         be_ptask_send_t send_fn,
d6181b
                         be_ptask_recv_t recv_fn,
d6181b
diff --git a/src/providers/be_ptask_private.h b/src/providers/be_ptask_private.h
d6181b
index 4144a3938..e89105f95 100644
d6181b
--- a/src/providers/be_ptask_private.h
d6181b
+++ b/src/providers/be_ptask_private.h
d6181b
@@ -32,6 +32,7 @@ struct be_ptask {
d6181b
     time_t timeout;
d6181b
     time_t max_backoff;
d6181b
     enum be_ptask_offline offline;
d6181b
+    enum be_ptask_schedule success_schedule_type;
d6181b
     be_ptask_send_t send_fn;
d6181b
     be_ptask_recv_t recv_fn;
d6181b
     void *pvt;
d6181b
diff --git a/src/providers/be_refresh.c b/src/providers/be_refresh.c
d6181b
index 5d86509bb..50b023c3d 100644
d6181b
--- a/src/providers/be_refresh.c
d6181b
+++ b/src/providers/be_refresh.c
d6181b
@@ -156,7 +156,9 @@ errno_t be_refresh_ctx_init(struct be_ctx *be_ctx,
d6181b
     refresh_interval = be_ctx->domain->refresh_expired_interval;
d6181b
     if (refresh_interval > 0) {
d6181b
         ret = be_ptask_create(be_ctx, be_ctx, refresh_interval, 30, 5, 0,
d6181b
-                              refresh_interval, BE_PTASK_OFFLINE_SKIP, 0,
d6181b
+                              refresh_interval, BE_PTASK_OFFLINE_SKIP,
d6181b
+                              BE_PTASK_SCHEDULE_FROM_LAST,
d6181b
+                              0,
d6181b
                               be_refresh_send, be_refresh_recv,
d6181b
                               ctx, "Refresh Records", NULL);
d6181b
         if (ret != EOK) {
d6181b
diff --git a/src/providers/ipa/ipa_dyndns.c b/src/providers/ipa/ipa_dyndns.c
d6181b
index a692b0d19..8e8ff5a4f 100644
d6181b
--- a/src/providers/ipa/ipa_dyndns.c
d6181b
+++ b/src/providers/ipa/ipa_dyndns.c
d6181b
@@ -72,8 +72,11 @@ errno_t ipa_dyndns_init(struct be_ctx *be_ctx,
d6181b
               "dyndns_refresh_interval is 0\n");
d6181b
         return EINVAL;
d6181b
     }
d6181b
+
d6181b
     ret = be_ptask_create(ctx, be_ctx, period, ptask_first_delay, 0, 0, period,
d6181b
-                          BE_PTASK_OFFLINE_DISABLE, 0,
d6181b
+                          BE_PTASK_OFFLINE_DISABLE,
d6181b
+                          BE_PTASK_SCHEDULE_FROM_LAST,
d6181b
+                          0,
d6181b
                           ipa_dyndns_update_send, ipa_dyndns_update_recv, ctx,
d6181b
                           "Dyndns update", NULL);
d6181b
     if (ret != EOK) {
d6181b
diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c
d6181b
index 94365aaca..3a17c851d 100644
d6181b
--- a/src/providers/ipa/ipa_subdomains.c
d6181b
+++ b/src/providers/ipa/ipa_subdomains.c
d6181b
@@ -3134,7 +3134,9 @@ errno_t ipa_subdomains_init(TALLOC_CTX *mem_ctx,
d6181b
 
d6181b
     period = be_ctx->domain->subdomain_refresh_interval;
d6181b
     ret = be_ptask_create(sd_ctx, be_ctx, period, ptask_first_delay, 0, 0, period,
d6181b
-                          BE_PTASK_OFFLINE_DISABLE, 0,
d6181b
+                          BE_PTASK_OFFLINE_DISABLE,
d6181b
+                          BE_PTASK_SCHEDULE_FROM_LAST,
d6181b
+                          0,
d6181b
                           ipa_subdomains_ptask_send, ipa_subdomains_ptask_recv, sd_ctx,
d6181b
                           "Subdomains Refresh", NULL);
d6181b
     if (ret != EOK) {
d6181b
diff --git a/src/providers/ldap/ldap_id_enum.c b/src/providers/ldap/ldap_id_enum.c
d6181b
index 8832eb558..062185c55 100644
d6181b
--- a/src/providers/ldap/ldap_id_enum.c
d6181b
+++ b/src/providers/ldap/ldap_id_enum.c
d6181b
@@ -99,6 +99,7 @@ errno_t ldap_setup_enumeration(struct be_ctx *be_ctx,
d6181b
                           0,                        /* random offset */
d6181b
                           period,                   /* timeout */
d6181b
                           BE_PTASK_OFFLINE_SKIP,
d6181b
+                          BE_PTASK_SCHEDULE_FROM_LAST,
d6181b
                           0,                        /* max_backoff */
d6181b
                           send_fn, recv_fn,
d6181b
                           ectx, "enumeration", &sdom->enum_task);
d6181b
diff --git a/src/providers/ldap/sdap_sudo_shared.c b/src/providers/ldap/sdap_sudo_shared.c
d6181b
index d2f24ed6e..a00d8e6a9 100644
d6181b
--- a/src/providers/ldap/sdap_sudo_shared.c
d6181b
+++ b/src/providers/ldap/sdap_sudo_shared.c
d6181b
@@ -90,7 +90,9 @@ sdap_sudo_ptask_setup_generic(struct be_ctx *be_ctx,
d6181b
      * when offline. */
d6181b
     if (full > 0) {
d6181b
         ret = be_ptask_create(be_ctx, be_ctx, full, delay, 0, 0, full,
d6181b
-                              BE_PTASK_OFFLINE_DISABLE, 0,
d6181b
+                              BE_PTASK_OFFLINE_DISABLE,
d6181b
+                              BE_PTASK_SCHEDULE_FROM_LAST,
d6181b
+                              0,
d6181b
                               full_send_fn, full_recv_fn, pvt,
d6181b
                               "SUDO Full Refresh", NULL);
d6181b
         if (ret != EOK) {
d6181b
@@ -107,7 +109,9 @@ sdap_sudo_ptask_setup_generic(struct be_ctx *be_ctx,
d6181b
      * when offline. */
d6181b
     if (smart > 0) {
d6181b
         ret = be_ptask_create(be_ctx, be_ctx, smart, delay + smart, smart, 0,
d6181b
-                              smart, BE_PTASK_OFFLINE_DISABLE, 0,
d6181b
+                              smart, BE_PTASK_OFFLINE_DISABLE,
d6181b
+                              BE_PTASK_SCHEDULE_FROM_LAST,
d6181b
+                              0,
d6181b
                               smart_send_fn, smart_recv_fn, pvt,
d6181b
                               "SUDO Smart Refresh", NULL);
d6181b
         if (ret != EOK) {
d6181b
diff --git a/src/tests/cmocka/test_be_ptask.c b/src/tests/cmocka/test_be_ptask.c
d6181b
index 356d9f9e2..03b1165bb 100644
d6181b
--- a/src/tests/cmocka/test_be_ptask.c
d6181b
+++ b/src/tests/cmocka/test_be_ptask.c
d6181b
@@ -304,7 +304,8 @@ void test_be_ptask_create_einval_be(void **state)
d6181b
     errno_t ret;
d6181b
 
d6181b
     ret = be_ptask_create(test_ctx, NULL, PERIOD, 0, 0, 0, 0,
d6181b
-                          BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send,
d6181b
+                          BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST,
d6181b
+                          0, test_be_ptask_send,
d6181b
                           test_be_ptask_recv, NULL, "Test ptask", &ptask);
d6181b
     assert_int_equal(ret, EINVAL);
d6181b
     assert_null(ptask);
d6181b
@@ -317,7 +318,8 @@ void test_be_ptask_create_einval_period(void **state)
d6181b
     errno_t ret;
d6181b
 
d6181b
     ret = be_ptask_create(test_ctx, test_ctx->be_ctx, 0, 0, 0, 0, 0,
d6181b
-                          BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send,
d6181b
+                          BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST,
d6181b
+                          0, test_be_ptask_send,
d6181b
                           test_be_ptask_recv, NULL, "Test ptask", &ptask);
d6181b
     assert_int_equal(ret, EINVAL);
d6181b
     assert_null(ptask);
d6181b
@@ -330,7 +332,8 @@ void test_be_ptask_create_einval_send(void **state)
d6181b
     errno_t ret;
d6181b
 
d6181b
     ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0,
d6181b
-                          BE_PTASK_OFFLINE_SKIP, 0, NULL,
d6181b
+                          BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST,
d6181b
+                          0, NULL,
d6181b
                           test_be_ptask_recv, NULL, "Test ptask", &ptask);
d6181b
     assert_int_equal(ret, EINVAL);
d6181b
     assert_null(ptask);
d6181b
@@ -343,7 +346,8 @@ void test_be_ptask_create_einval_recv(void **state)
d6181b
     errno_t ret;
d6181b
 
d6181b
     ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0,
d6181b
-                          BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send,
d6181b
+                          BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST,
d6181b
+                          0, test_be_ptask_send,
d6181b
                           NULL, NULL, "Test ptask", &ptask);
d6181b
     assert_int_equal(ret, EINVAL);
d6181b
     assert_null(ptask);
d6181b
@@ -356,7 +360,8 @@ void test_be_ptask_create_einval_name(void **state)
d6181b
     errno_t ret;
d6181b
 
d6181b
     ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0,
d6181b
-                          BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send,
d6181b
+                          BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST,
d6181b
+                          0, test_be_ptask_send,
d6181b
                           test_be_ptask_recv, NULL, NULL, &ptask);
d6181b
     assert_int_equal(ret, EINVAL);
d6181b
     assert_null(ptask);
d6181b
@@ -371,7 +376,8 @@ void test_be_ptask_create_no_delay(void **state)
d6181b
 
d6181b
     now = get_current_time();
d6181b
     ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0,
d6181b
-                          BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send,
d6181b
+                          BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST,
d6181b
+                          0, test_be_ptask_send,
d6181b
                           test_be_ptask_recv, test_ctx, "Test ptask", &ptask);
d6181b
     assert_int_equal(ret, ERR_OK);
d6181b
     assert_non_null(ptask);
d6181b
@@ -398,7 +404,8 @@ void test_be_ptask_create_first_delay(void **state)
d6181b
 
d6181b
     now = get_current_time();
d6181b
     ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, DELAY, 0, 0, 0,
d6181b
-                          BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send,
d6181b
+                          BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST,
d6181b
+                          0, test_be_ptask_send,
d6181b
                           test_be_ptask_recv, test_ctx, "Test ptask", &ptask);
d6181b
     assert_int_equal(ret, ERR_OK);
d6181b
     assert_non_null(ptask);
d6181b
@@ -423,7 +430,8 @@ void test_be_ptask_disable(void **state)
d6181b
     errno_t ret;
d6181b
 
d6181b
     ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0,
d6181b
-                          BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send,
d6181b
+                          BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST,
d6181b
+                          0, test_be_ptask_send,
d6181b
                           test_be_ptask_recv, test_ctx, "Test ptask", &ptask);
d6181b
     assert_int_equal(ret, ERR_OK);
d6181b
     assert_non_null(ptask);
d6181b
@@ -447,7 +455,8 @@ void test_be_ptask_enable(void **state)
d6181b
 
d6181b
     now = get_current_time();
d6181b
     ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0,
d6181b
-                          BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send,
d6181b
+                          BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST,
d6181b
+                          0, test_be_ptask_send,
d6181b
                           test_be_ptask_recv, test_ctx, "Test ptask", &ptask);
d6181b
     assert_int_equal(ret, ERR_OK);
d6181b
     assert_non_null(ptask);
d6181b
@@ -479,7 +488,8 @@ void test_be_ptask_enable_delay(void **state)
d6181b
     errno_t ret;
d6181b
 
d6181b
     ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, DELAY, 0, 0,
d6181b
-                          BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send,
d6181b
+                          BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST,
d6181b
+                          0, test_be_ptask_send,
d6181b
                           test_be_ptask_recv, test_ctx, "Test ptask", &ptask);
d6181b
     assert_int_equal(ret, ERR_OK);
d6181b
     assert_non_null(ptask);
d6181b
@@ -518,7 +528,8 @@ void test_be_ptask_offline_skip(void **state)
d6181b
 
d6181b
     now = get_current_time();
d6181b
     ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0,
d6181b
-                          BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send,
d6181b
+                          BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST,
d6181b
+                          0, test_be_ptask_send,
d6181b
                           test_be_ptask_recv, test_ctx, "Test ptask", &ptask);
d6181b
     assert_int_equal(ret, ERR_OK);
d6181b
     assert_non_null(ptask);
d6181b
@@ -551,7 +562,9 @@ void test_be_ptask_offline_disable(void **state)
d6181b
     will_return(be_add_offline_cb, test_ctx);
d6181b
 
d6181b
     ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0,
d6181b
-                          BE_PTASK_OFFLINE_DISABLE, 0, test_be_ptask_send,
d6181b
+                          BE_PTASK_OFFLINE_DISABLE,
d6181b
+                          BE_PTASK_SCHEDULE_FROM_LAST,
d6181b
+                          0, test_be_ptask_send,
d6181b
                           test_be_ptask_recv, test_ctx, "Test ptask", &ptask);
d6181b
     assert_int_equal(ret, ERR_OK);
d6181b
     assert_non_null(ptask);
d6181b
@@ -581,7 +594,9 @@ void test_be_ptask_offline_execute(void **state)
d6181b
     mark_offline(test_ctx);
d6181b
 
d6181b
     ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0,
d6181b
-                          BE_PTASK_OFFLINE_EXECUTE, 0, test_be_ptask_send,
d6181b
+                          BE_PTASK_OFFLINE_EXECUTE,
d6181b
+                          BE_PTASK_SCHEDULE_FROM_LAST,
d6181b
+                          0, test_be_ptask_send,
d6181b
                           test_be_ptask_recv, test_ctx, "Test ptask", &ptask);
d6181b
     assert_int_equal(ret, ERR_OK);
d6181b
     assert_non_null(ptask);
d6181b
@@ -608,7 +623,8 @@ void test_be_ptask_reschedule_ok(void **state)
d6181b
 
d6181b
     now = get_current_time();
d6181b
     ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0,
d6181b
-                          BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send,
d6181b
+                          BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST,
d6181b
+                          0, test_be_ptask_send,
d6181b
                           test_be_ptask_recv, test_ctx, "Test ptask", &ptask);
d6181b
     assert_int_equal(ret, ERR_OK);
d6181b
     assert_non_null(ptask);
d6181b
@@ -639,7 +655,8 @@ void test_be_ptask_reschedule_null(void **state)
d6181b
     errno_t ret;
d6181b
 
d6181b
     ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0,
d6181b
-                          BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_null_send,
d6181b
+                          BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST,
d6181b
+                          0, test_be_ptask_null_send,
d6181b
                           test_be_ptask_recv, test_ctx, "Test ptask",
d6181b
                           &ptask);
d6181b
     assert_int_equal(ret, ERR_OK);
d6181b
@@ -666,7 +683,8 @@ void test_be_ptask_reschedule_error(void **state)
d6181b
     errno_t ret;
d6181b
 
d6181b
     ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0,
d6181b
-                          BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send,
d6181b
+                          BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST,
d6181b
+                          0, test_be_ptask_send,
d6181b
                           test_be_ptask_error_recv, test_ctx, "Test ptask",
d6181b
                           &ptask);
d6181b
     assert_int_equal(ret, ERR_OK);
d6181b
@@ -693,7 +711,8 @@ void test_be_ptask_reschedule_timeout(void **state)
d6181b
     errno_t ret;
d6181b
 
d6181b
     ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 1,
d6181b
-                          BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_timeout_send,
d6181b
+                          BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST,
d6181b
+                          0, test_be_ptask_timeout_send,
d6181b
                           test_be_ptask_error_recv, test_ctx, "Test ptask",
d6181b
                           &ptask);
d6181b
     assert_int_equal(ret, ERR_OK);
d6181b
@@ -730,7 +749,8 @@ void test_be_ptask_reschedule_backoff(void **state)
d6181b
 
d6181b
     now_first = get_current_time();
d6181b
     ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0,
d6181b
-                          BE_PTASK_OFFLINE_SKIP, PERIOD*2, test_be_ptask_send,
d6181b
+                          BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST,
d6181b
+                          PERIOD*2, test_be_ptask_send,
d6181b
                           test_be_ptask_recv, test_ctx, "Test ptask", &ptask);
d6181b
     assert_int_equal(ret, ERR_OK);
d6181b
     assert_non_null(ptask);
d6181b
@@ -784,7 +804,8 @@ void test_be_ptask_get_period(void **state)
d6181b
     errno_t ret;
d6181b
 
d6181b
     ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0,
d6181b
-                          BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send,
d6181b
+                          BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST,
d6181b
+                          0, test_be_ptask_send,
d6181b
                           test_be_ptask_recv, test_ctx, "Test ptask", &ptask);
d6181b
     assert_int_equal(ret, ERR_OK);
d6181b
     assert_non_null(ptask);
d6181b
@@ -804,7 +825,8 @@ void test_be_ptask_get_timeout(void **state)
d6181b
     errno_t ret;
d6181b
 
d6181b
     ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, TIMEOUT,
d6181b
-                          BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send,
d6181b
+                          BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST,
d6181b
+                          0, test_be_ptask_send,
d6181b
                           test_be_ptask_recv, test_ctx, "Test ptask", &ptask);
d6181b
     assert_int_equal(ret, ERR_OK);
d6181b
     assert_non_null(ptask);
d6181b
-- 
d6181b
2.20.1
d6181b