Scheduler: providing the execution-context
The Activity-Language can be defined by abstracting away some crucial implementation functionality as part of an generic »ExecutionCtx«, which in the end will be provided by the Scheduler. But how actually? We want to avoid unnecessary indirections, and ideally we also want a concise formulation in-code. Here I'm exploring the idea to let the scheduler itself provide the ExecutionCtx-operations as member functions, employing some kind of "compile-time duck-typing" This seems to work, but breaks the poor-man's preliminary "Concept" check...
This commit is contained in:
parent
26b2e6f1bd
commit
0d2d8c3413
4 changed files with 184 additions and 9 deletions
|
|
@ -604,7 +604,7 @@ namespace gear {
|
|||
activity::Proc
|
||||
Activity::activate (Time now, EXE& executionCtx)
|
||||
{
|
||||
activity::_verify_usable_as_ExecutionContext<EXE>();
|
||||
// activity::_verify_usable_as_ExecutionContext<EXE>();
|
||||
|
||||
switch (verb_) {
|
||||
case INVOKE:
|
||||
|
|
@ -651,7 +651,7 @@ namespace gear {
|
|||
activity::Proc
|
||||
Activity::dispatch (Time now, EXE& executionCtx)
|
||||
{
|
||||
activity::_verify_usable_as_ExecutionContext<EXE>();
|
||||
// activity::_verify_usable_as_ExecutionContext<EXE>();
|
||||
|
||||
switch (verb_) {
|
||||
case NOTIFY:
|
||||
|
|
@ -681,7 +681,7 @@ namespace gear {
|
|||
activity::Proc
|
||||
Activity::notify (Time now, EXE& executionCtx)
|
||||
{
|
||||
activity::_verify_usable_as_ExecutionContext<EXE>();
|
||||
// activity::_verify_usable_as_ExecutionContext<EXE>();
|
||||
|
||||
switch (verb_) {
|
||||
case GATE:
|
||||
|
|
|
|||
|
|
@ -65,8 +65,9 @@ namespace gear {
|
|||
|
||||
namespace { // Scheduler default config
|
||||
|
||||
const auto IDLE_WAIT = 20ms;
|
||||
const size_t DISMISS_CYCLES = 100;
|
||||
const auto IDLE_WAIT = 20ms; ///< sleep-recheck cycle for workers deemed _idle_
|
||||
const size_t DISMISS_CYCLES = 100; ///< number of wait cycles before an idle worker terminates completely
|
||||
Offset POLL_WAIT_DELAY{FSecs(1,1000)}; ///< delay until re-evaluating a condition previously found unsatisfied
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -166,9 +167,73 @@ namespace gear {
|
|||
{
|
||||
UNIMPLEMENTED("die harder");
|
||||
}
|
||||
|
||||
|
||||
/** @internal expose a binding for Activity execution */
|
||||
class ExecutionCtx;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @remark when due, the scheduled Activities are performed within the
|
||||
* [Activity-Language execution environment](\ref ActivityLang::dispatchChain());
|
||||
* some aspects of Activity _activation_ however require external functionality,
|
||||
* which — for the purpose of language definition — was abstracted as _Execution-context._
|
||||
* The implementation of these binding functions fills in relevant external effects and
|
||||
* is in fact supplied by the implementation internals of the scheduler itself.
|
||||
*/
|
||||
class Scheduler::ExecutionCtx
|
||||
: private Scheduler
|
||||
{
|
||||
public:
|
||||
static ExecutionCtx&
|
||||
from (Scheduler& self)
|
||||
{
|
||||
return static_cast<ExecutionCtx&> (self);
|
||||
}
|
||||
|
||||
/* ==== Implementation of the Concept ExecutionCtx ==== */
|
||||
|
||||
/** λ-post: */
|
||||
activity::Proc
|
||||
post (Time when, Activity& chain, ExecutionCtx& ctx)
|
||||
{
|
||||
return layer2_.postDispatch (&chain, when, ctx, layer1_);
|
||||
}
|
||||
|
||||
void
|
||||
work (Time, size_t)
|
||||
{
|
||||
UNIMPLEMENTED ("λ-work");
|
||||
}
|
||||
|
||||
void
|
||||
done (Time, size_t)
|
||||
{
|
||||
UNIMPLEMENTED ("λ-done");
|
||||
}
|
||||
|
||||
activity::Proc
|
||||
tick (Time)
|
||||
{
|
||||
UNIMPLEMENTED ("λ-tick");
|
||||
}
|
||||
|
||||
Offset
|
||||
getWaitDelay()
|
||||
{
|
||||
return POLL_WAIT_DELAY;
|
||||
}
|
||||
|
||||
Time
|
||||
getSchedTime()
|
||||
{
|
||||
UNIMPLEMENTED ("access scheduler Time");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
}} // namespace vault::gear
|
||||
#endif /*SRC_VAULT_GEAR_SCHEDULER_H_*/
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ namespace test {
|
|||
const string CTX_DONE{"CTX-done"};
|
||||
const string CTX_TICK{"CTX-tick"};
|
||||
|
||||
Offset POLL_DELAY{FSecs(1)};
|
||||
Offset POLL_WAIT_DELAY{FSecs(1)};
|
||||
Time SCHED_TIME_MARKER{555,5}; ///< marker value for "current scheduler time" used in tests
|
||||
}
|
||||
|
||||
|
|
@ -563,7 +563,7 @@ namespace test {
|
|||
_DiagnosticFun<SIG_done>::Type done;
|
||||
_DiagnosticFun<SIG_tick>::Type tick;
|
||||
|
||||
function<Offset()> getWaitDelay = [] { return POLL_DELAY; };
|
||||
function<Offset()> getWaitDelay = [] { return POLL_WAIT_DELAY; };
|
||||
function<Time()> getSchedTime = [this]{ return SCHED_TIME_MARKER;};
|
||||
|
||||
FakeExecutionCtx (ActivityDetector& detector)
|
||||
|
|
|
|||
|
|
@ -80285,9 +80285,55 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<node COLOR="#338800" CREATED="1690490297125" ID="ID_1766901032" MODIFIED="1690490313350" TEXT="Vorgriff auf Concepts: Signaturen statisch prüfen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1697849524591" ID="ID_747589769" MODIFIED="1697849564995" TEXT="statische Prüfung schwierig">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1697849570913" ID="ID_155562107" MODIFIED="1697849610947" TEXT="ging gut solange ich stets Functor-Objekte verwendet hatte">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
...also solange ich nur mit Unit-Tests gearbeitet habe
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1690068793535" ID="ID_1906823317" MODIFIED="1697844595733" TEXT="ist tatsächlich implementiert durch den Scheduler selber">
|
||||
<arrowlink COLOR="#e6ffa8" DESTINATION="ID_1020998473" ENDARROW="Default" ENDINCLINATION="-1456;-96;" ID="Arrow_ID_1485027520" STARTARROW="None" STARTINCLINATION="-811;38;"/>
|
||||
<icon BUILTIN="idea"/>
|
||||
<node CREATED="1697844218566" ID="ID_290060192" MODIFIED="1697844248833" TEXT="die entscheidenden externen Effekte"/>
|
||||
<node CREATED="1697844230190" ID="ID_1228967510" MODIFIED="1697844240670" TEXT="(mal abgesehen vom JobFunctor)"/>
|
||||
<node CREATED="1697844259176" ID="ID_142974884" MODIFIED="1697844537005">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
im Besonderen <b>λ-post</b> ist im Grunde
|
||||
</p>
|
||||
<p>
|
||||
der Scheduler-Service <i>überhaupt</i>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
...nämlich die Fähigkeit, einen Activity-chain zu einem geplanten Zeitpunkt oder auf Signal hin auszuführen — und diese Fähigkeit muß selbstverständlich der Sprache selber zu Gebote stehen, damit sie komplexe Aktionsmuster flexibel ausdrücken kann
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1690068793535" ID="ID_1906823317" MODIFIED="1692286273670" TEXT="ist implementiert durch die ActivityLang selber">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1692286145852" ID="ID_596906210" MODIFIED="1692370174170" TEXT="Fake-Setup für Tests (ActivityDetector)">
|
||||
<arrowlink COLOR="#433d62" DESTINATION="ID_902152915" ENDARROW="Default" ENDINCLINATION="656;-38;" ID="Arrow_ID_644734597" STARTARROW="None" STARTINCLINATION="1154;77;"/>
|
||||
|
|
@ -81817,6 +81863,67 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1697758577471" ID="ID_805214343" MODIFIED="1697758585886" TEXT="dagegen BlockFlow ist eine externe Komponente"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1697844012851" ID="ID_1020998473" MODIFIED="1697844595733" TEXT="Execution-Context tatsächlich bereitstellen">
|
||||
<linktarget COLOR="#e6ffa8" DESTINATION="ID_1020998473" ENDARROW="Default" ENDINCLINATION="-1456;-96;" ID="Arrow_ID_1485027520" SOURCE="ID_1906823317" STARTARROW="None" STARTINCLINATION="-811;38;"/>
|
||||
<icon BUILTIN="forward"/>
|
||||
<node CREATED="1697844618383" ID="ID_988917685" MODIFIED="1697844647556" TEXT="für den Test wurde der stets nur gemockt">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
es genügte, an diesen Stellen die Ausführung der abstrahierten Aktionen zu loggen
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1697844649091" ID="ID_939726274" MODIFIED="1697844696080" TEXT="als Abstraktion wurde (bewußt) ein Template-Parameter gewählt"/>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1697844697092" ID="ID_766922475" MODIFIED="1697845768002" TEXT="kokretes Funktions-Binding">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node CREATED="1697844724057" ID="ID_1038347556" MODIFIED="1697844734323" TEXT="wieder ein ähnliches Problem wie bei der WorkForce-Config"/>
|
||||
<node CREATED="1697844740488" ID="ID_1999540950" MODIFIED="1697844761716" TEXT="hier aber einfacher: es wird stets nur eine Referenz benötigt">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node CREATED="1697844763748" ID="ID_1789360174" MODIFIED="1697845607548">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
⟹ <i>der Scheduler selber</i> kann diese Rolle <b>generisch</b> übernehmen
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1697845608675" ID="ID_610860781" MODIFIED="1697845760326" TEXT="noch sauberer: ein Sub-Interface-Mapping">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<ul>
|
||||
<li>
|
||||
eine Subklasse, die aber <b>private</b> vom Scheduler erbt
|
||||
</li>
|
||||
<li>
|
||||
sie bietet selber eine Downcast-Accessor-Funktion
|
||||
</li>
|
||||
<li>
|
||||
eigene Datenfelder sind nicht erlaubt (Slicing)
|
||||
</li>
|
||||
<li>
|
||||
aber beliebige Member-Funktionen, die sich frei aus dem (protected)-Scope des Schedulers bedienen können
|
||||
</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1697763699242" ID="ID_272943268" MODIFIED="1697763810547" TEXT="EngineObserver-Schnittstelle">
|
||||
<arrowlink COLOR="#4f3156" DESTINATION="ID_1642973256" ENDARROW="Default" ENDINCLINATION="-628;-472;" ID="Arrow_ID_1213898118" STARTARROW="None" STARTINCLINATION="-1771;162;"/>
|
||||
|
|
@ -86787,6 +86894,9 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<node CREATED="1697758391611" ID="ID_124711923" MODIFIED="1697758397083" TEXT="Fälle">
|
||||
<node CREATED="1697758425500" ID="ID_1450418166" MODIFIED="1697758430911" TEXT="simpleUsage">
|
||||
<node CREATED="1697758440737" ID="ID_1211803424" MODIFIED="1697758454084" TEXT="zeigt hier vor allem was man braucht"/>
|
||||
<node COLOR="#338800" CREATED="1697842432420" ID="ID_1052962927" MODIFIED="1697842447753" TEXT="Scheduler läßt sich instantiieren">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
|
|||
Loading…
Reference in a new issue