From 419329cf782a5e5c3d6f967f61ef7165dfa3a323 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julius=20Zhang=20=E5=BC=A0=E7=80=9A=E5=A0=83?= Date: Mon, 17 Jul 2023 17:14:14 +0800 Subject: [PATCH] Implements delay-publish-to archive logic. capture scp messages draft remove extra white space clean up header impl moved delay publish logic to ledger manager rm delay timer from herder impl and add delay-publish-to-archive criterion add delay publish to archive config option preliminary changes for delay publish to archive logic in history manager impl Remove delay publish to archive logic from herder and ledger manager. Change delay-publish-to-archive work to ConditionalWork. update xdr make publish to archive delay configurable fix format fix format and work naming Make default publish-to-archive delay to 0 --- src/history/HistoryManagerImpl.cpp | 19 +++++++++++++++++-- src/main/Config.cpp | 6 ++++++ src/main/Config.h | 3 +++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/history/HistoryManagerImpl.cpp b/src/history/HistoryManagerImpl.cpp index e130c66dda..08448f5042 100644 --- a/src/history/HistoryManagerImpl.cpp +++ b/src/history/HistoryManagerImpl.cpp @@ -33,6 +33,7 @@ #include "util/Math.h" #include "util/StatusManager.h" #include "util/TmpDir.h" +#include "work/ConditionalWork.h" #include "work/WorkScheduler.h" #include "xdrpp/marshal.h" #include @@ -278,14 +279,28 @@ HistoryManagerImpl::takeSnapshotAndPublish(HistoryArchiveState const& has) std::vector> seq{resolveFutures, writeSnap, putSnap}; + + auto start = mApp.getClock().now(); + ConditionFn delayTimeout = [start](Application& app) { + auto delayDuration = app.getConfig().PUBLISH_TO_ARCHIVE_DELAY; + + auto time = app.getClock().now(); + auto dur = time - start; + return std::chrono::duration_cast(dur) >= + delayDuration; + }; + // Pass in all bucket hashes from HAS. We cannot rely on StateSnapshot // buckets here, because its buckets might have some futures resolved by // now, differing from the state of the bucketlist during queueing. // // NB: if WorkScheduler is aborting this returns nullptr, but that // which means we don't "really" start publishing. - mPublishWork = mApp.getWorkScheduler().scheduleWork( - snap, seq, allBucketsFromHAS); + auto publishWork = + std::make_shared(mApp, snap, seq, allBucketsFromHAS); + + mPublishWork = mApp.getWorkScheduler().scheduleWork( + "delay-publishing-to-archive", delayTimeout, publishWork); } size_t diff --git a/src/main/Config.cpp b/src/main/Config.cpp index 67b3d586fb..ac6ce04c84 100644 --- a/src/main/Config.cpp +++ b/src/main/Config.cpp @@ -142,6 +142,7 @@ Config::Config() : NODE_SEED(SecretKey::random()) EXPERIMENTAL_BUCKETLIST_DB_INDEX_PAGE_SIZE_EXPONENT = 14; // 2^14 == 16 kb EXPERIMENTAL_BUCKETLIST_DB_INDEX_CUTOFF = 20; // 20 mb EXPERIMENTAL_BUCKETLIST_DB_PERSIST_INDEX = true; + PUBLISH_TO_ARCHIVE_DELAY = std::chrono::seconds{0}; // automatic maintenance settings: // short and prime with 1 hour which will cause automatic maintenance to // rarely conflict with any other scheduled tasks on a machine (that tend to @@ -1121,6 +1122,11 @@ Config::processConfig(std::shared_ptr t) { ALLOW_LOCALHOST_FOR_TESTING = readBool(item); } + else if (item.first == "PUBLISH_TO_ARCHIVE_DELAY") + { + PUBLISH_TO_ARCHIVE_DELAY = + std::chrono::seconds(readInt(item)); + } else if (item.first == "AUTOMATIC_MAINTENANCE_PERIOD") { AUTOMATIC_MAINTENANCE_PERIOD = diff --git a/src/main/Config.h b/src/main/Config.h index 2c0c5a7be4..97cd10d89e 100644 --- a/src/main/Config.h +++ b/src/main/Config.h @@ -210,6 +210,9 @@ class Config : public std::enable_shared_from_this // This config should only be enabled when testing. std::chrono::microseconds ARTIFICIALLY_SLEEP_MAIN_THREAD_FOR_TESTING; + // Timeout before publishing externalized values to archive + std::chrono::seconds PUBLISH_TO_ARCHIVE_DELAY; + // Config parameters that force transaction application during ledger // close to sleep for a certain amount of time. // The probability that it sleeps for