From 86b90fbf847770ae76ec420f401b619a4b652a43 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Mon, 6 Nov 2023 06:00:00 +0100 Subject: [PATCH] Scheduler: draft high-level API for building a Job schedule The invocation structure is effectively determined by the Activity-chain builder from the Activity-Language; but, taking into account the complexity of the Scheduler code developed thus far, it seems prudent to encapsulate the topic of "Activities" altogether and expose only a convenience builder-API towards the Job-Planning --- src/vault/gear/scheduler.hpp | 44 ++++++++++- src/vault/gear/work-force.hpp | 2 + .../vault/gear/scheduler-commutator-test.cpp | 4 +- tests/vault/gear/scheduler-service-test.cpp | 61 +++++++++++++-- wiki/thinkPad.ichthyo.mm | 78 +++++++++++++++++-- 5 files changed, 172 insertions(+), 17 deletions(-) diff --git a/src/vault/gear/scheduler.hpp b/src/vault/gear/scheduler.hpp index 3b49d1189..dc5125413 100644 --- a/src/vault/gear/scheduler.hpp +++ b/src/vault/gear/scheduler.hpp @@ -147,6 +147,46 @@ namespace gear { + class ScheduleSpec + { + Job job_; + + public: + ScheduleSpec (Job job) + : job_{job} + { } + + ScheduleSpec + startOffset (microseconds microTicks) + { + UNIMPLEMENTED ("start offset"); + return move(*this); + } + + ScheduleSpec + lifeWindow (microseconds microTicks) + { + UNIMPLEMENTED ("deadline relative to starts"); + return move(*this); + } + + ScheduleSpec + manifestation (ManifestationID manID) + { + UNIMPLEMENTED ("store manifestation-ID"); + return move(*this); + } + + ScheduleSpec + post() + { + UNIMPLEMENTED ("build chain and hand-over into queue"); + return move(*this); + } + }; + + + /******************************************************//** * »Scheduler-Service« : coordinate render activities. * @todo WIP-WIP 10/2023 @@ -248,8 +288,8 @@ namespace gear { /** * */ - void - buildJob() + ScheduleSpec + defineSchedule (Job job) { UNIMPLEMENTED("wrap the ActivityTerm"); } diff --git a/src/vault/gear/work-force.hpp b/src/vault/gear/work-force.hpp index 88debd675..9f7978a53 100644 --- a/src/vault/gear/work-force.hpp +++ b/src/vault/gear/work-force.hpp @@ -73,7 +73,9 @@ namespace gear { using std::atomic; using util::unConst; using std::chrono::milliseconds; + using std::chrono::microseconds; using std::chrono_literals::operator ""ms; + using std::chrono_literals::operator ""us; using std::this_thread::sleep_for; diff --git a/tests/vault/gear/scheduler-commutator-test.cpp b/tests/vault/gear/scheduler-commutator-test.cpp index 160056691..be1acc820 100644 --- a/tests/vault/gear/scheduler-commutator-test.cpp +++ b/tests/vault/gear/scheduler-commutator-test.cpp @@ -368,7 +368,7 @@ namespace test { Time t2{20,0}; Activity a2{2u,2u}; Time t3{30,0}; Activity a3{3u,3u}; Time t4{40,0}; Activity a4{4u,4u}; - + // start,deadline, manif.ID, isCompulsory queue.instruct ({a1, t1, t4, ManifestationID{5}}); queue.instruct ({a2, t2, t2}); queue.instruct ({a3, t3, t3, ManifestationID{23}, true}); @@ -497,7 +497,7 @@ namespace test { queue.feedPrioritisation(); CHECK (now == queue.headTime()); CHECK (isSameObject (activity, *sched.findWork(queue, now))); - CHECK (sched.holdsGroomingToken (myself)); + CHECK (sched.holdsGroomingToken (myself)); // findWork() acquired the token CHECK (future == queue.headTime()); CHECK (not queue.isDue(now)); CHECK ( queue.isDue(future)); diff --git a/tests/vault/gear/scheduler-service-test.cpp b/tests/vault/gear/scheduler-service-test.cpp index e16cb1589..69aa211af 100644 --- a/tests/vault/gear/scheduler-service-test.cpp +++ b/tests/vault/gear/scheduler-service-test.cpp @@ -80,10 +80,11 @@ namespace test { virtual void run (Arg) { -// simpleUsage(); -// verify_StartStop(); + simpleUsage(); + verify_StartStop(); verify_LoadFactor(); -// invokeWorkFunction(); + invokeWorkFunction(); + scheduleRenderJob(); walkingDeadline(); } @@ -137,7 +138,7 @@ namespace test { /** @test verify the scheduler processes scheduled events, * indicates current load and winds down automatically * when falling empty. - * - placing short bursts of single FEED-Activities + * - schedule short bursts of single FEED-Activities * - these actually do nothing and can be processed typically < 5µs * - placing them spaced by 1µs, so the scheduler will build up congestion * - since this Activity does not drop the »grooming-token«, actually only @@ -146,12 +147,14 @@ namespace test { * - when reaching the scheduler »tick«, the queue should be empty * and the scheduler will stop active processing * - the main thread (this test) polls every 50µs to observe the load + * - after 2 seconds of idle-sleeping, the WorkForce is disengaged * - verify the expected load pattern * @todo WIP 10/23 ✔ define ⟶ ✔ implement */ void verify_LoadFactor() { + MARK_TEST_FUN BlockFlowAlloc bFlow; EngineObserver watch; Scheduler scheduler{bFlow, watch}; @@ -284,19 +287,20 @@ namespace test { * + after dispatching an Activity in a situation with no follow-up work, * the work-function inserts a targeted sleep of random duration, * to re-shuffle the rhythm of sleep cycles - * + when the next planned Activity has already be »tended for« (by placing + * + when the next planned Activity was already »tended for« (by placing * another worker into a targeted sleep), further workers entering the * work-function will be re-targeted by a random sleep to focus capacity * into a time zone behind the next entry. - * @note Invoke the Activity probe itself can take 50..150µs, due to the EventLog, + * @note Invoking the Activity probe itself can take 50..150µs, due to the EventLog, * which is not meant to be used in performance critical paths but only for tests, * because it performs lots of heap allocations and string operations. Moreover, * we see additional cache effects after an extended sleep period. - * @todo WIP 10/23 🔁 define ⟶ implement + * @todo WIP 10/23 ✔ define ⟶ ✔ implement */ void invokeWorkFunction() { + MARK_TEST_FUN BlockFlowAlloc bFlow; EngineObserver watch; Scheduler scheduler{bFlow, watch}; @@ -310,7 +314,7 @@ namespace test { activity::Proc res; auto post = [&](Time start) - { // this test class is declared friend to get a backdoor to Scheduler internals... + { // this test class is declared friend to get a backdoor into Scheduler internals... scheduler.layer2_.acquireGoomingToken(); scheduler.postChain(ActivationEvent{probe, start}); }; @@ -436,6 +440,47 @@ namespace test { + /** @test TODO schedule a render job through the high-level Job-builder API. + * - use the mock Job-Functor provided by the ActivityDetector + * @todo WIP 11/23 ✔ define ⟶ 🔁 implement + */ + void + scheduleRenderJob() + { + MARK_TEST_FUN + BlockFlowAlloc bFlow; + EngineObserver watch; + Scheduler scheduler{bFlow, watch}; + + Time nominal{7,7}; + Time start{0,1}; + Time dead{0,10}; + + ActivityDetector detector; + Job testJob{detector.buildMockJob("testJob", nominal, 1337)}; + + CHECK (scheduler.empty()); + scheduler.defineSchedule(testJob) + .startOffset(200us) + .lifeWindow (1ms) + .manifestation(ManifestationID{55}) + .post(); + + CHECK (not scheduler.empty()); + CHECK (detector.ensureNoInvocation("testJob")); + + sleep_for(400us); + CHECK (detector.ensureNoInvocation("testJob")); + + CHECK (activity::PASS == scheduler.getWork()); + CHECK (scheduler.empty()); + + cout << detector.showLog()<

- ....das hat sich allerdings schon aus der Analyse des Pull-Processing im Node-Network so ergeben, denn dort geht man von der ExitNode rückwärts; damals konnte ich nicht vorhersehen, wie die Situation im Scheduler sich darstellen wird — möglicherweise verbirg sich eine tiefere, strukturelle Konvergenz dahinter, daß das jetzt so schön aufgeht + ....das hat sich allerdings schon aus der Analyse des Pull-Processing im Node-Network so ergeben, denn dort geht man von der ExitNode rückwärts; damals konnte ich nicht vorhersehen, wie die Situation im Scheduler sich darstellen wird — möglicherweise verbirgt sich eine tiefere, strukturelle Konvergenz dahinter, daß das jetzt so schön aufgeht

@@ -82029,6 +82029,14 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + + + @@ -82067,8 +82075,9 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - + + + @@ -82076,6 +82085,40 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -83199,7 +83242,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + + @@ -83222,6 +83266,15 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + + + +
@@ -84046,8 +84099,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -90046,6 +90099,12 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + @@ -92117,6 +92176,15 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + + + +