Scheduler: automatically step up capacity on new task
WorkForce scales down automatically after 2 seconds when workers fall idle; thus we need to step up automatically with each new task. Later we'll also add some capacity management to both the LoadController and the Job-Planning, but for now this rather crude approach should suffice. NOTE: most of the cases in SchedulerService_test verify parts of the component integration and thus need to bypass this automatism, because the test code wants to invoke the work-Function directly (without any interference from running workers)
This commit is contained in:
parent
3c3d31dd40
commit
0ed7dba641
3 changed files with 75 additions and 43 deletions
|
|
@ -319,6 +319,7 @@ namespace gear {
|
|||
private:
|
||||
void handleDutyCycle (Time now);
|
||||
void handleWorkerTermination (bool isFailure);
|
||||
void maybeScaleWorkForce();
|
||||
|
||||
void triggerEmergency();
|
||||
|
||||
|
|
@ -500,6 +501,7 @@ namespace gear {
|
|||
inline void
|
||||
Scheduler::postChain (ActivationEvent actEvent)
|
||||
{
|
||||
maybeScaleWorkForce();
|
||||
ExecutionCtx ctx{*this, actEvent};
|
||||
layer2_.postDispatch (actEvent, ctx, layer1_);
|
||||
}
|
||||
|
|
@ -673,6 +675,23 @@ namespace gear {
|
|||
loadControl_.markWorkerExit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook invoked whenever a new task is passed in.
|
||||
* Ensures that the Scheduler is in running state and
|
||||
* possibly steps up the WorkForce if not yet running at
|
||||
* full computation power.
|
||||
* @note the capacity scales down automatically when some
|
||||
* workers fall idle for extended time (> 2sec).
|
||||
*/
|
||||
inline void
|
||||
Scheduler::maybeScaleWorkForce()
|
||||
{
|
||||
if (empty())
|
||||
ignite();
|
||||
else
|
||||
workForce_.incScale();
|
||||
}
|
||||
|
||||
/**
|
||||
* Trip the emergency brake and unwind processing while retaining all state.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -80,10 +80,10 @@ namespace test {
|
|||
virtual void
|
||||
run (Arg)
|
||||
{
|
||||
// simpleUsage();
|
||||
// verify_StartStop();
|
||||
// verify_LoadFactor();
|
||||
// invokeWorkFunction();
|
||||
simpleUsage();
|
||||
verify_StartStop();
|
||||
verify_LoadFactor();
|
||||
invokeWorkFunction();
|
||||
scheduleRenderJob();
|
||||
walkingDeadline();
|
||||
}
|
||||
|
|
@ -101,6 +101,21 @@ namespace test {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* @internal helper to inject a new task into the Scheduler,
|
||||
* without also activating WorkForce and load control.
|
||||
* @remark this class is declared friend by the Scheduler to grant
|
||||
* this kind of »implementation backdoor« access; the function
|
||||
* defined there does essentially the same than Scheduler::postChain()
|
||||
*/
|
||||
void
|
||||
postNewTask (Scheduler& scheduler, Activity& chain, Time start)
|
||||
{
|
||||
ActivationEvent actEvent{chain, start};
|
||||
Scheduler::ExecutionCtx ctx{scheduler, actEvent};
|
||||
scheduler.layer2_.postDispatch (actEvent, ctx, scheduler.layer1_);
|
||||
}
|
||||
|
||||
|
||||
/** @test get the scheduler into running state
|
||||
* @todo WIP 10/23 ✔ define ⟶ ✔ implement
|
||||
|
|
@ -114,7 +129,7 @@ namespace test {
|
|||
CHECK (isnil (scheduler));
|
||||
|
||||
Activity dummy{Activity::FEED};
|
||||
auto postIt = [&] { scheduler.postChain (ActivationEvent{dummy, RealClock::now()+t200us}); };
|
||||
auto postIt = [&] { postNewTask (scheduler, dummy, RealClock::now()+t200us); };
|
||||
|
||||
scheduler.ignite();
|
||||
CHECK (isnil (scheduler)); // no start without any post()
|
||||
|
|
@ -169,7 +184,7 @@ namespace test {
|
|||
auto createLoad = [&](Offset start, uint cnt)
|
||||
{ // use internal API (this test is declared as friend)
|
||||
for (uint i=0; i<cnt; ++i) // flood the queue
|
||||
scheduler.postChain (ActivationEvent{dummy, anchor + start + TimeValue{i}});
|
||||
postNewTask (scheduler, dummy, anchor + start + TimeValue{i});
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -316,7 +331,7 @@ namespace test {
|
|||
auto post = [&](Time start)
|
||||
{ // this test class is declared friend to get a backdoor into Scheduler internals...
|
||||
scheduler.layer2_.acquireGoomingToken();
|
||||
scheduler.postChain(ActivationEvent{probe, start});
|
||||
postNewTask (scheduler, probe, start);
|
||||
};
|
||||
|
||||
auto pullWork = [&] {
|
||||
|
|
|
|||
|
|
@ -82118,17 +82118,27 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<linktarget COLOR="#a9b4c1" DESTINATION="ID_1964298619" ENDARROW="Default" ENDINCLINATION="27;865;" ID="Arrow_ID_900145073" SOURCE="ID_760916314" STARTARROW="Default" STARTINCLINATION="-554;-36;"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1699325172901" ID="ID_1435123962" MODIFIED="1699325566562" TEXT="muß Kapazität prüfen / Hochskalieren">
|
||||
<node COLOR="#338800" CREATED="1699325172901" ID="ID_1435123962" MODIFIED="1699372410733" TEXT="muß Kapazität prüfen / Hochskalieren">
|
||||
<arrowlink COLOR="#57496c" DESTINATION="ID_745204926" ENDARROW="Default" ENDINCLINATION="249;-377;" ID="Arrow_ID_55492946" STARTARROW="None" STARTINCLINATION="668;346;"/>
|
||||
<linktarget COLOR="#662136" DESTINATION="ID_1435123962" ENDARROW="Default" ENDINCLINATION="304;54;" ID="Arrow_ID_928822414" SOURCE="ID_1792556883" STARTARROW="None" STARTINCLINATION="-206;16;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1699329348003" ID="ID_396553511" MODIFIED="1699368192260" TEXT="Parameter zur WorkForce-Stärke berücksichtigen">
|
||||
<linktarget COLOR="#7f4745" DESTINATION="ID_396553511" ENDARROW="Default" ENDINCLINATION="486;26;" ID="Arrow_ID_329496296" SOURCE="ID_651840656" STARTARROW="None" STARTINCLINATION="728;32;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<linktarget COLOR="#373a76" DESTINATION="ID_1435123962" ENDARROW="Default" ENDINCLINATION="304;54;" ID="Arrow_ID_928822414" SOURCE="ID_1792556883" STARTARROW="None" STARTINCLINATION="-255;13;"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#338800" CREATED="1699329348003" ID="ID_396553511" MODIFIED="1699372243603" TEXT="Parameter zur WorkForce-Stärke wird berücksichtigt">
|
||||
<linktarget COLOR="#45647f" DESTINATION="ID_396553511" ENDARROW="Default" ENDINCLINATION="486;26;" ID="Arrow_ID_329496296" SOURCE="ID_651840656" STARTARROW="None" STARTINCLINATION="728;32;"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1699329449911" ID="ID_1960065591" MODIFIED="1699372221033" TEXT="wenn....">
|
||||
<node COLOR="#435e98" CREATED="1699329454534" ID="ID_258337881" MODIFIED="1699372224340" TEXT="Scheduler läuft nicht ⟹ ignite()"/>
|
||||
<node COLOR="#435e98" CREATED="1699329466069" ID="ID_1149902545" MODIFIED="1699372224340" TEXT="nicht volle Stärke ⟹ step"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1699372253576" ID="ID_869013268" MODIFIED="1699372262575" TEXT="Implementierung in postChain eingehängt">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#435e98" CREATED="1699372263855" ID="ID_1329492790" MODIFIED="1699372374425" TEXT="damit stets wirksam, wenn etwas in den Scheduler geht">
|
||||
<arrowlink COLOR="#5184bf" DESTINATION="ID_660894370" ENDARROW="Default" ENDINCLINATION="-622;-30;" ID="Arrow_ID_841520455" STARTARROW="None" STARTINCLINATION="1037;52;"/>
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1699372349395" ID="ID_1120366594" MODIFIED="1699372369723" TEXT="Neben-Hintertür für den SchedulerService_test geschaffen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node CREATED="1699329449911" ID="ID_1960065591" MODIFIED="1699329453611" TEXT="wenn....">
|
||||
<node CREATED="1699329454534" ID="ID_258337881" MODIFIED="1699329465057" TEXT="Scheduler läuft nicht ⟹ ignite()"/>
|
||||
<node CREATED="1699329466069" ID="ID_1149902545" MODIFIED="1699329477423" TEXT="nicht volle Stärke ⟹ step"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1699245611846" ID="ID_788545423" MODIFIED="1699307283267" TEXT="Definitions-Struktur und Code-Anordnung klären">
|
||||
|
|
@ -82694,21 +82704,18 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</node>
|
||||
<node CREATED="1699368212285" ID="ID_855305118" MODIFIED="1699368213601" TEXT="wird von WorkForce und LoadController als Referenz verwendet"/>
|
||||
<node COLOR="#338800" CREATED="1699329306877" ID="ID_651840656" MODIFIED="1699368342608" TEXT="dieser Parameter ist nun explizit änderbar (nicht mehr const)">
|
||||
<arrowlink COLOR="#7f4745" DESTINATION="ID_396553511" ENDARROW="Default" ENDINCLINATION="486;26;" ID="Arrow_ID_329496296" STARTARROW="None" STARTINCLINATION="728;32;"/>
|
||||
<arrowlink COLOR="#45647f" DESTINATION="ID_396553511" ENDARROW="Default" ENDINCLINATION="486;26;" ID="Arrow_ID_329496296" STARTARROW="None" STARTINCLINATION="728;32;"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1699368246481" ID="ID_817072584" MODIFIED="1699368325222" TEXT="wird aber wie eine Konstante behandelt">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
....also kein Locking etc; allerdings greift der LoadController jetzt per Lambda darauf zu.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1699368298187" ID="ID_1401898380" MODIFIED="1699368321811" TEXT="sollte man also bei stehendem Scheduler ändern">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
|
|
@ -82948,6 +82955,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<linktarget COLOR="#5184bf" DESTINATION="ID_660894370" ENDARROW="Default" ENDINCLINATION="-622;-30;" ID="Arrow_ID_841520455" SOURCE="ID_1329492790" STARTARROW="None" STARTINCLINATION="1037;52;"/>
|
||||
<font BOLD="true" NAME="SansSerif" SIZE="12"/>
|
||||
<icon BUILTIN="idea"/>
|
||||
<node COLOR="#594398" CREATED="1699068463527" ID="ID_82378192" MODIFIED="1699068489999" TEXT="gefühlsmäßig... jetzt sortiert sich das Design doch noch">
|
||||
|
|
@ -82974,16 +82982,13 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<icon BUILTIN="clanbomber"/>
|
||||
<node CREATED="1699314936837" ID="ID_1589318425" MODIFIED="1699315051503" TEXT="die pre-Dispatch-Kapazitätssteuerung will das (bisher) nicht machen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...im Lastbetrieb möchte man das eigentlich auch nicht: ein ankommender Thread soll gemäß aktueller Situation klassifiziert werden, aber nicht erst mal um das Grooming-Token konkurrieren
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1699315054445" ID="ID_1061745270" MODIFIED="1699315073575" TEXT="diese Situation dürfte im Regelbetrieb nicht auftreten">
|
||||
<node CREATED="1699315075175" ID="ID_1648796415" MODIFIED="1699315087836" TEXT="denn dort wird aus einem Managment-Job heraus weiter geplant"/>
|
||||
|
|
@ -83005,19 +83010,17 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<arrowlink COLOR="#751420" DESTINATION="ID_179251569" ENDARROW="Default" ENDINCLINATION="-787;-76;" ID="Arrow_ID_272593119" STARTARROW="None" STARTINCLINATION="1260;101;"/>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
<node CREATED="1699325057420" ID="ID_1792556883" MODIFIED="1699325504658" TEXT="Hochskalieren fehlt ebenfalls">
|
||||
<node COLOR="#338800" CREATED="1699325057420" ID="ID_1792556883" MODIFIED="1699372417701" TEXT="Hochskalieren muß auch noch eingebaut werden">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
....und das würde in dem Fall das Problem durch den ersten »Tick« nebenbei beheben — aber nicht, falls der Scheduler bereits läuft und leer gefallen ist
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<arrowlink COLOR="#662136" DESTINATION="ID_1435123962" ENDARROW="Default" ENDINCLINATION="304;54;" ID="Arrow_ID_928822414" STARTARROW="None" STARTINCLINATION="-206;16;"/>
|
||||
</html></richcontent>
|
||||
<arrowlink COLOR="#373a76" DESTINATION="ID_1435123962" ENDARROW="Default" ENDINCLINATION="304;54;" ID="Arrow_ID_928822414" STARTARROW="None" STARTINCLINATION="-255;13;"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -84276,22 +84279,19 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1699325295132" ID="ID_745204926" MODIFIED="1699325566562" TEXT="WorkForce hochfahren">
|
||||
<linktarget COLOR="#533354" DESTINATION="ID_745204926" ENDARROW="Default" ENDINCLINATION="-41;67;" ID="Arrow_ID_204394164" SOURCE="ID_1772549848" STARTARROW="None" STARTINCLINATION="-125;-5;"/>
|
||||
<linktarget COLOR="#57496c" DESTINATION="ID_745204926" ENDARROW="Default" ENDINCLINATION="249;-377;" ID="Arrow_ID_55492946" SOURCE="ID_1435123962" STARTARROW="None" STARTINCLINATION="668;346;"/>
|
||||
<linktarget COLOR="#533354" DESTINATION="ID_745204926" ENDARROW="Default" ENDINCLINATION="-41;67;" ID="Arrow_ID_204394164" SOURCE="ID_1772549848" STARTARROW="None" STARTINCLINATION="-125;-5;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1699325589332" ID="ID_25430169" MODIFIED="1699325606390" TEXT="WorkForce regelt sich selber herunter bei Leerlauf"/>
|
||||
<node CREATED="1699325607274" ID="ID_718145429" MODIFIED="1699325631062">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
daher muß für einen neuen Job ein <i>step up</i> erfolgen
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
<node CREATED="1699325634014" ID="ID_1493688459" MODIFIED="1699325647951" TEXT="bei Bedarf: ignite()"/>
|
||||
|
|
@ -92419,9 +92419,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</node>
|
||||
<node CREATED="1699328515692" ID="ID_649427536" MODIFIED="1699328747184" TEXT="das ist problematisch">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Aus Sicht des Testaufbaues wäre es sehr wünschenswert. Aber da das Scheduler-API high-Level ist, sehe ich keine einfache Möglichkeit, für einen Test dazwischen zu gehen. Ein Mocking / Austauschen des Scheduler wäre hier nicht zielführend (weil es genau auf die Interaktion mit der integrierten Scheduler-Implementierung ankommt).
|
||||
|
|
|
|||
Loading…
Reference in a new issue