Commit graph

205 commits

Author SHA1 Message Date
5c5dc40f3f Scheduler: processing of peak loads works
This is the first kind of integration,
albeit still with a synthetic load.

- placed two excessive load peaks in the scheduling timeline
- verified load behaviour
- verified timings
- verified that the scheduler shuts down automatically when done
2023-11-01 04:24:44 +01:00
4937577557 (WIP) instrumentation for investigation of sleep-behaviour 2023-11-01 02:06:02 +01:00
9f7711d26b Scheduler: complete and cover load indicator
- sample distance to scheduler head whenever a worker asks for work
- moving average with N = worker-pool size and damp-factor 2
- multiply with the current concurrency fraction
2023-10-31 02:29:50 +01:00
a087e52ab1 Scheduler: draft a load indicator
...using a state fusion
based on both the threadpool size and the average distance
or lag to the next task to be scheduled.
2023-10-30 20:22:06 +01:00
6a7a2832bf Scheduler: simplify usage of microbenchmark helper
as an aside, the header lib/test/microbenchmark.hpp
turns out to be prolific for this kind of investigation.

However, it is somewhat obnoxious that the »test subject«
must expose the signature <size_t(size_t)>.

Thus, with some metaprogramming magic, an generic adaptor
can be built to accept a range of typical alternatives,
and even the quite obvious signature void(void).
Since all these will be wrapped directly into a lambda,
the optimiser will remove these adaptations altogether.
2023-10-30 20:17:16 +01:00
4fada4225c Scheduler: watch behaviour under load
- create a synthetic load peak while operating with full WorkForce
- Goal is to develop a load indicator
2023-10-30 05:09:41 +01:00
22b4a9e4b2 Scheduler: start and shutdown implemented and demonstrated in test
- An important step towards a complete »Scheduler Service«
- Correct timing pattern could be verified in detail by tracing
- Spurred some further concept and design work regarding Load-control
2023-10-29 20:06:41 +01:00
8505059476 Scheduler: consider how to maintain active state
- draft the duty cycle »tick«
- investigate corner cases of state updates and allocation managment
- implement start and forcible stop of the scheduler service
2023-10-29 04:22:42 +01:00
4e9d54e6f9 Scheduler: switch to steady-clock
Obviously the better choice and a perfect fit for our requirements;
while the system-clock may jump and even move backwards on time service
adjustments, the steady clock just counts the ticks since last boot.

In libStdC++ both are implemented as int64_t and use nanoseconds resolution
2023-10-28 20:58:37 +02:00
6166ab63f2 Scheduler: complete handling of the grooming-token
- Ensure the grooming-token (lock) is reliably dropped
- also explicitly drop it prior to trageted sleeps
- properly signal when not able to acquire the token before dispatch

- amend tests broken by changes since yesterday
2023-10-28 05:35:35 +02:00
552d8dec0e Scheduler: complete work-Function / conception work
Notably the work-function is now completely covered, by adding
this last test, and the detailed investigations yesterday
ultimately unveiled nothing of concern; the times sum up.

Further reflection regarding the overall concept led me
to a surprising solution for the problem with priority classes.
2023-10-28 05:34:56 +02:00
e26d251867 Scheduler: rationalise delay decision logic
...especially for the case »outgoing to sleep«

- reorganise switch-case to avoid falling through
- properly handle the tendedNext() predicate also in boundrary cases
- structure the decision logic clearer
- cover the new behaviour in test

Remark: when the queue falls empty, the scheduler now sends each
worker once into a targted re-shuffling delay, to ensure the
sleep-cycles are statistically evenly spaced
2023-10-28 05:34:56 +02:00
b5e9d67a79 Scheduler: wrap-up and comment test cases thus far
...up to now, Behaviour is as expected
- with some minor discrepancies still to be fixed
- and an effect due to the test-scaffolding
2023-10-27 03:37:24 +02:00
097001d16f Scheduler: investigate timings of dispatch()
...there seemed to be an anomaly of 50...100µs

==> conclusion: this is due to the instrumentation code
    - it largely caused by the EventLog, which was never meant
      to be used in performance-critical code, and does hefty
      heap allocations and string processing.
    - moreover, there clearly is a cache-effect, adding a Factor 2
      whenever some time passed since the last EventLog call

==> can be considered just an artifact of the test setup and
    will have no impact on the scheduler


remark: this commit adds a lot of instrumentation code
2023-10-27 02:53:34 +02:00
a90a5d9636 Scheduler: can demonstrate basic behaviour
- invoked right away
- pre-sleep to tend next
- post-sleep if next activity follows at a distance
2023-10-26 03:56:18 +02:00
a71bcaae43 Scheduler: shorthand notation for work-Function test
To cover the visible behaviour of the work-Function,
we have to check an amalgam of timing delays and time differences.

This kind of test tends to be problematic, since timings are always
random and also machine dependent, and thus we need to produce pronounced effects
2023-10-26 01:14:13 +02:00
5164ead929 Scheduler: access invocation time for test
...find a way to sneak out the "now" parameter passed on Invocation
...this is prerequisite to demonstrate expected behaviour of the work-Function
2023-10-25 23:40:47 +02:00
7da88b772f Scheduler: setup to verify the work-Function
...first steps to get anything to run with the Scheduler constructed thus far
...can now
 - enqueue
 - getWork -> invoke
2023-10-25 17:31:32 +02:00
a180d38ed9 Scheduler: integrate capacity handling with work-Function
...this integration becomes more and more challenging
...the high degree of inter-correlation between the scheduler components is concerning
2023-10-25 05:11:10 +02:00
d6c859fd3a Scheduler: implement and document capacity redirection 2023-10-25 02:13:18 +02:00
1d5b8c3e9c Scheduler: implement and verify random reshuffling of capacity
...using the current time itself as source for randomisation;
the test indicates this yields a smooth and even distribution.
2023-10-24 04:59:49 +02:00
3eaf623e98 Scheduler: develop scheme for capacity redirection
...to make that abundantly clear: we do not aim at precision timing,
rather the goal is to redistribute capacity currently not usable...

Basically we're telling the worker "nothing to do right now, sorry,
but check back in <timespan> because I may need you then"
2023-10-24 00:56:24 +02:00
08c13ed6fe Scheduler: consider wiring of Load-Controller
...and general questions of component design and coupling.
Decided to go for explicit configuration points by functor.
2023-10-23 21:51:16 +02:00
69fb77246e Scheduler: implement capacity redistribution scheme
wow... that was conceptually challenging, yet dead easy to implement
2023-10-23 18:48:02 +02:00
6ccb6540e6 Scheduler: implement the tended-next mark
...as KISS solution to put aside the next free capacity
whenever a new time point appears at scheduler head
2023-10-23 17:02:44 +02:00
84ca2460c1 Scheduler: fundamentals of capacity classification
Workers asking for the next task are classified as belonging
to some fraction of the free capacity, based on the distance
to the closest next Activity known to the scheduler
2023-10-23 04:07:38 +02:00
b61ca94ee5 Scheduler: rectify λ-post API
...to bring it more in line with all the other calls dealing with Activity*
...allows also to harmonise the ActivityLang::dispatchChain()
...and to compose the calls in Scheduler directly

NOTE: there is a twist: our string-formatting helper did not render
custom string conversions for objects passed as pointer. This was a
long standing problem, caused by ambiguous templates overloads;
now I've attempted to solve it one level more down, in util::StringConv.
This solution may turn out brittle, since we need to exclude any direct
string conversion, most notably the ones for C-Strings (const char*)

In case this solution turns out unsustainable, please feel free
to revert this API change, and return to passing Activity& in λ-post,
because in the end this is cosmetics.
2023-10-23 01:48:46 +02:00
a21057bdf2 Scheduler: control structure for the worker-functor 2023-10-22 23:25:35 +02:00
e5638119f5 Scheduler: devise scheme for load control
- organise by principles rather than implementing a mechanism
- keep the first version simple yet flexible
- conduct empiric research under synthetic load

Basic scheme:
- tend for next
- classify free capacity
- scattered targeted wait
2023-10-22 16:45:13 +02:00
0d2d8c3413 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...
2023-10-21 03:01:27 +02:00
74c97614b3 Scheduler: component wiring
The »Scheduler Service« will be assembled
from the components developed during the last months
- Layer-1
- Layer-2
- Activity-Language
- Block-Flow
- Work-Force
2023-10-20 04:36:07 +02:00
9db341bd8b Scheduler: plan for integration
identified three distinct tasks
- build the external API
- establish component integration
- performance testing
2023-10-20 00:59:50 +02:00
9ce3ad3d72 Scheduler: Layer-2 complete and tested (see #1326)
* the implementation logic of the Scheduler is essentially complete now
 * all functionality necessary for the worker-function has been demonstrated

As next step, the »Scheduler Service« can be assembled from the two
Implementation Layers, the Activity-Language and the `BlockFlow` allocator
This should then be verified by a multi-threaded integration test...
2023-10-19 01:49:08 +02:00
10a2c6908c Scheduler: Layer-2 integration scenario complete
could even rig the diagnostic Execution-Ctx
to drop the GroomingToken at the point when switching to work-mode
2023-10-18 23:02:29 +02:00
c2ddaed28e Scheduler: draft scenario for Layer-2 integration test
Idea: re-use the scenario and instrumentation from
SchedulerActivity_test::scenario_RenderJob()
2023-10-18 18:10:10 +02:00
ee09a2eff2 Scheduler: completed implementation of Layer-2
...some further checks
...one integration test case needs to be written
2023-10-18 17:29:41 +02:00
93fcebb331 Scheduler: implement and verify postDispatch 2023-10-18 16:39:08 +02:00
666546856f Scheduler: design the core API operation - postDispatch
This central operation sits at a crossroad and is used
- from external clients to fed new work to the Scheduler
- from Workers to engage into execution of the next Activity
- recursively from the execution of an Activity-chain

From these requirements the semantics of behaviour can be derived
regarding the GroomingToken and the result values, which indicate
when follow-up work should be processed
2023-10-18 15:50:11 +02:00
55967cd649 Scheduler: work retrieval implementation
- simple approach, delegating to Layer-1
- deliberately no error handling
- GroomingToken not dropped
2023-10-18 04:18:01 +02:00
b57503fb97 Scheduler: define expected behaviour for work retrieval
still not quite sure how to implement it,
but working down from first principles to define test scenarios first...
2023-10-18 02:59:58 +02:00
aa60869082 Scheduler: decision logic for actual dispatch of activities 2023-10-18 01:38:58 +02:00
fa391d1267 Scheduler: torture test the thread access logic
Ensure the GroomingToken mechanism indeed creates an
exclusive section protected against concurrent corruption:

Use a without / with-protection test and verify
the results are exact vs. grossly broken
2023-10-17 21:35:37 +02:00
1223772f14 Scheduler: implement thread access logic
T thread holding the »Grooming Token" is permitted to
manipulate scheduler internals and thus also to define new
activities; this logic is implemented as an Atomic lock,
based on the current thread's ID.
2023-10-17 20:37:32 +02:00
862933e809 Scheduler: define API for Layer-2
Notably both Layers are conceived as functionality providers;
only at Scheduler top-Level will functionality be combined with
external dependencies to create the actual service.
2023-10-17 19:20:53 +02:00
0431a14584 Scheduler: Layer-1 complete and tested 2023-10-17 04:35:58 +02:00
430f1af4c5 Scheduler: define water-level for prioritisation 2023-10-17 03:38:28 +02:00
152413589c Scheduler: clarify role of the Time parameter
At first sight, this seems confusing; there is a time window,
there is sometimes a `when` parameter, and mostly a `now` parameter
is passed through the activation chain.

However, taking the operational semantics into account, the existing
definitions seem to be (mostly) adequate already: The scheduler is
assumed to activate a chain only ''when'' the defined start time is reached.
2023-10-17 03:04:19 +02:00
c76e5488bd Scheduler: plot steps towards integration
(1) SchedulerInvocation_test
    »Layer-1« : Queue operation

(2) SchedulerCommutator_test
    »Layer-2« : Activity execution

(3) SchedulerUsage_test
    Component End-to-End
2023-10-16 23:57:22 +02:00
3af6a54219 Library/Application: complete technology switch (closes #1279)
As follow-up to the rework of thread-handling, likewise also
the implementation base for locking was switched over from direct
usage of POSIX primitives to the portable wrappers available in
the C++ standard library. All usages have been reviewed and
modernised to prefer λ-functions where possible.

With this series of changes, the old threadpool implementation
and a lot of further low-level support facilities are not used
any more and can be dismantled. Due to the integration efforts
spurred by the »Playback Vertical Slice«, several questions of
architecture could be decided over the last months. The design
of the Scheduler and Engine turned out different than previously
anticipated; notably the Scheduler now covers a wider array of
functionality, including some asynchronous messaging. This has
ramifications for the organisation of work tasks and threads,
and leads to a more deterministic memory management. Resource
management will be done on a higher level, partially superseding
some of the concepts from the early phase of the Lumiera project.
2023-10-16 01:44:04 +02:00
685be1b039 Library/Application: consolidate Monitor API and usage
This is Step-2 : change the API towards application

Notably all invocation variants to support member functions
or a reference to bool flags are retracted, since today a
λ-binding directly at usage site tends to be more readable.

The function names are harmonised with the C++ standard and
emergency shutdown in the Subsystem-Runner is rationalised.

The old thread-wrapper test is repurposed to demonstrate
the effectiveness of monitor based locking.
2023-10-15 20:42:55 +02:00
73737f2aee Library/Application: consolidate Monitor implementation
After the fundamental switch from POSIX to the C++14 wrappers
the existing implementation of the Monitor can now be drastically condensed,
removing several layers of indirection. Moreover, all signatures
shall be changed to blend in with the names and patterns established
by the C++ standard.

This is Step-1 : consolidate the Implementation.

(to ensure correctness, the existing API towards application code was retained)
2023-10-15 02:41:41 +02:00
1c4f605e8f Library/Application: switch WorkForce
The WorkForce (passive worker pool) has been coded just recently,
and -- in anticipation of this refactoring -- directly against std::thread
instead of using the old framework.

...the switch is straight-forward, using the default case
...add the ability to decorate the thread-IDs with a running counter
2023-10-12 22:00:55 +02:00
42eba8425a Library: now able to provide a self-managed thread
After quite some detours, with this take I'm finally able to
provide a stringent design to embody all the variants of thread start
encountered in practice in the Lumiera code base.

Especially the *self-managed* thread is now represented as a special-case
of a lifecycle-hook, and can be embodied into a builder front-end,
able to work with any client-provided thread-wrapper subclass.
2023-10-10 21:45:41 +02:00
332ad0e920 Testsuite: fix regression
FamilyMember::allocateNextMember() was actually a post-increment,
so (different than with TypedCounter) here no correction is necessary


As an asside, WorkForce_test is sometimes unstable immediately after a build.
Seemingly a headstart of 50µs is not enough to compensate for scheduler leeway
2023-10-05 00:39:29 +02:00
c183045dfa Library: switch Microbenchmark setup to C++17 threads
Over time, a collection of microbenchmark helper functions was
extracted from occasional use -- including a variant to perform
parallelised microbenchmarks. While not used beyond sporadic experiments yet,
this framework seems a perfect fit for measuring the SyncBarrier performance.

There is only one catch:
 - it uses the old Threadpool + POSIX thread support
 - these require the Threadpool service to be started...
 - which in turn prohibits using them for libary tests

And last but not least: this setup already requires a barrier.

==> switch the existing microbenchmark setup to c++17 threads preliminarily
    (until the thread-wrapper has been reworked).
==> also introduce the new SyncBarrier here immediately
==> use this as a validation test of the setup + SyncBarrier
2023-09-24 18:07:28 +02:00
416895b5b2 Library: prepare switch of Thread-wrapper to C++17
The investigation for #1279 leads to the following conclusions

- the features and the design of our custom thread-wrapper
  almost entirely matches the design chosen meanwhile by the C++ committee

- the implementation provided by the standard library however uses
  modern techniques (especially Atomics) and is more precisely worked out
  than our custom implementation was.

- we do not need an *active* threadpool with work-assignment,
  rather we'll use *active* workers and a *passive* pool,
  which was easy to implement based on C++17 features

==> decision to drop our POSIX based custom implementation
    and to retrofit the Thread-wrapper as a drop-in replacement

+++ start this refactoring by moving code into the Library
+++ create a copy of the Threadwrapper-code to build and test
    the refactorings while the application itself still uses
    existing code, until the transition is complete
2023-09-21 23:23:55 +02:00
997fc36c81 Workforce: implementation complete 2023-09-09 23:42:13 +02:00
397ded86df Workforce: verify error handling and wait on shutdown
...seemingly the implementation is complete now
2023-09-09 03:31:46 +02:00
9ccdfa24f7 Workforce: invoke a exit hook prior to worker termination
...essential for clean-up work, especially to drop
claimed resources reliably, even in case of error.
2023-09-09 02:31:16 +02:00
dd62240900 Workforce: terminate after excessive idle cycles
- count each consecutive idle cycle
- by default, terminate after 100 idle cycles (2 sec)
2023-09-09 01:47:15 +02:00
b493f15333 Workforce: configure and demonstrate idle-wait 2023-09-09 01:12:10 +02:00
67a3e87dbc Workforce: demonstrate controlled worker-stop
- workers can be controlled by the return-value from the work functor
- this test could be brittle, since it's based on timing and CPU speed
2023-09-08 14:32:37 +02:00
ef5365057a Workforce: demonstrate standard behaviour
- can activate / scale up
- work functor invoked repeatedly
2023-09-08 14:07:23 +02:00
81cab9a675 Workforce: emergency brake
While in principle it would be possible (and desirable)
to control worker behaviour exclusively through the Work-Functor's return code,
in practice we must concede that Exceptions can always happen from situations
beyond our control. And while it is necessary for the WorkForce-dtor to
join and block (we can not just pull away the resources from running threads),
the same destructor (when called out of order) must somehow be able
at least to ask the running threads to terminate.

Especially for unit tests this becomes an obnoxious problem -- otherwise
each test failure would cause the test runner to hang.

Thus adding an emergency halt, and also improve setup for tests
with a convenience function to inject a work-function-λ
2023-09-08 02:48:30 +02:00
b8e52d008c Workforce: configuration and initialisation of workers
- use a template parameter to allow for hook into local facilities (Scheduler)
- pass config initialisation down through constructors
2023-09-07 17:15:25 +02:00
38ab5a6aa9 Workforce: draft simple usage
...start with an oversimplified implementation...
2023-09-05 00:24:33 +02:00
70cd8af806 Workforce: requirement analysis 2023-09-05 00:22:17 +02:00
2e28f5d278 Activity-Lang: abstracted execution framework complete and tested (closes: #1319) 2023-09-03 01:50:50 +02:00
95ae12bba1 Activity-Lang: complete handling of IO activities 2023-09-03 00:40:37 +02:00
b3b6f7524c Activity-Lang: outline for wiring async IO activities
...relies on the same building pattern, with the notable difference
that the chain is severed, providing an additional NOTIFY as re-entrance point
2023-09-02 22:36:02 +02:00
73a67886f0 Activity-Lang: wiring for internal/planning job
...uses just the minimal wiring and is thus already implemented :-)
2023-09-02 03:35:02 +02:00
e6d233def2 Activity-Lang: instrumentation to make the complete call sequence visible
No new functionality, and implementation works as expected.

This test case covers an especially tricky setup, where a calculation
shall be triggered from an external event, while ensuring that the actual
processing can start only after also the regular time-bound scheduling
has taken place (this might be used to prevent an unexpectedly early
external signal to cause writing into an output buffer before the
defined window of data delivery)
2023-09-02 03:08:13 +02:00
6563688e07 Activity-Lang: now able to demonstrate the intended call sequence
...based on the new ability in the ActivityDetector, we can now assign
a custom λ, which deflects back the ctx.post() call into the ActivityLang
instance used for this test case.

While the previously seen behaviour was correct, it was not the call sequence
expected in the real implementation; with this change, on the main-chain
activation the post() now immediately dispatches the notification, which in turn
dispatches the rest of the chain, so that the JobFunctor is indeed
called in this second test case as expected
2023-09-02 01:48:25 +02:00
f3cf178388 Activity-Lang: ability to hook in a fake implementation
Up to now, the DiagnosticFun mock in ActivityDetector only
created an EventLog entry on invocation and was able to retunr
a canned result value. Yet for the job invocation scenario test,
it would be desirable to hook-in a λ with a fake implementation
into the ExecutionContext. As a further convenience, the
return value is now default initialised, instead of being
marked as uninitialised until invocation of "returning(val)"
2023-09-01 21:59:25 +02:00
fd8716d398 Activity-Lang: demonstrate multi-stage Gate
...seems to work, but not really happy with the test setup,
since in real usage the post()-calls would dispatch, while here,
using the ActivityDetector, these calls just log invoation,
and thus the activation is not passed on
2023-09-01 19:23:27 +02:00
44e840f27c Activity-Lang: implement optional notification builders 2023-09-01 19:03:37 +02:00
963dc38088 Activity-Lang: introduce some shorthand notation
...regarding the kind of activity (the verb),
and also for some special case access of payload data;
deliberately asserting the correct verb, but no mandatory check,
since this whole Activity-Language is conceived as cohesive
and essentially sealed (not meant to be extended)
2023-09-01 17:41:40 +02:00
789bcd72c2 Activity-Lang: better solution to demonstrate time access
...to show in test that indeed the actual time is retrieved on each activation,
we can assign a λ -- which is rigged to increase the time on each access
2023-09-01 17:18:32 +02:00
67c71725a4 Activity-Lang: access current scheduler time dynamically
It is not sufficient just to pass this "current time" as parameter
into the ActivityLang::dispatchChain(), since some Activities within
this chain will essentially be long-running (think rendering); thus
we need a real callback from within the chain. The obvious solution
is to make this part of the Execution Context, which is an abstraction
of the scheduler environment anyway
2023-09-01 02:44:29 +02:00
14effc2349 Activity-Lang: consider logic for dependency notification
...turns out there is still a lot of leeway in the possible implementation,
and seemingly it is too early to decide which case to consider the default.
Thus I'll proceed with the drafted preliminary solution...

- on primary-chain, an inhibited Gate dispatches itself into future for re-check
- on Notification, activation happens if and only if this very notification opens the Gate
- provide a specifically wired requireDirectActivation() to allow enforcing a minimal start time
2023-08-31 20:18:35 +02:00
07fcc89e6a Activity-Lang: complete execution of the basic CalculationJob scheme
...assembled from parts already implemented

TODO
 - need a way to access the »current scheduler time«
 - need builder extension points to connect notifications
2023-08-31 02:24:01 +02:00
32c08c0307 Activity-Lang: also dispatch notifications 2023-08-31 02:11:07 +02:00
900f46b1d5 Activity-Lang: framework to execute a chain of Activities
without and error or concurrency handling (which is the responsibility
of the Scheduler-Layer-2; just the sequencing of individual activations
2023-08-30 22:19:57 +02:00
2746743135 Activity-Lang: invoke the configured Job-Functor
...this completes the basic setup
- Term builder mechanism working properly
- Memory allocator behaves sane
- the simple default wiring allows to invoke a Job
2023-08-29 19:10:24 +02:00
cda1cdd975 Activity-Lang: verify memory allocation and connectivity 2023-08-29 18:46:37 +02:00
80a48abcf4 Activity-Lang: determine role of the time window parameters 2023-08-29 16:40:52 +02:00
ae89831275 Activity-Lang: wire Job invocation in the activity::Term builder 2023-08-29 04:19:19 +02:00
e98fe1e78b Activity-Lang: scaffolding to create a simple Term 2023-08-29 03:18:47 +02:00
568957b75d Activity-Lang: prevent spurious activations after notification
Solved by special treatment of a notification, which happens
to decrement the latch to zero: in this case, the chain is
dispatched, but also the Gate is locked permanently to block
any further activations scheduled or forwareded otherwise
2023-08-23 01:03:11 +02:00
2f042ce6c0 Activity-Lang: cover all cases of Gate-behaviour
TODO: while correct as implemented, the handling of the
notification seems questionable, since re-scheduling the chain immediately
may lead to multiple invocations of the chain, since it might have been "spinned"
and thus re-scheduled already, and we have no way to find out about that
2023-08-22 20:13:13 +02:00
f1a446d85c Activity-Lang: notification settled and covered 2023-08-22 18:57:25 +02:00
4fed0b8cd2 Activity-Lang: clarify and fix behaviour of POST
...can not take a shortcut here, since the timing information
embedded into the POST-Activity must somehow be transported
to the Scheduler; key point to note is that the chain will
be performed in »management mode« (single threaded)
2023-08-22 18:38:40 +02:00
4c0e58849a Activity-Lang: define test cases for basic Activities 2023-08-22 17:37:58 +02:00
4e6ee0ec9c Activity-Lang: notification to Gate now working
...also diagnostics helper now able to trace notifications
...and additionally the Gate now triggers as planned
2023-08-21 18:23:57 +02:00
108a5e7ca5 Activity-Lang: work out activation-dispatch-notification sequence
...attempt to get this intricate state machine sorted out

Notification turned out quite tricky, since it may emanate
from a concurrently executed phase and we try to avoid having
to protect the gate directly with a lock; rather we re-dispatch
the notification through the queue, which indirectly also ensures
that the worker de-queuing the NOTIFY-Activity operates in
management mode (single threaded, holding the GroomingToken)
2023-08-21 17:32:52 +02:00
abc29eaa31 Activity-Lang: complete implementation for Gate (conditional)
Decision how to handle a failed Gate-check
- spin forward (re-scheduler) by some time amount
- this spin-offset parameter is retrieved from the Execution Context
- thus it will be some kind of engine parameter

With these determinations and the framework for the Execution Context
it is now possible to code up the logic for Gate check, which in turn
can then be verified by the watchGate diagnostics
2023-08-20 02:39:57 +02:00
8a85e57235 Activity-Lang: setup to watch a Gate-Activity
ouch... this becomes kindof convoluted,
due to the lack of dynamic extension points
2023-08-20 01:35:14 +02:00
f0d71672d8 Activity-Lang: allow to inject the activation detector
...by prepending it into existing wiring
2023-08-20 00:59:47 +02:00
7debaaca48 Activity-Lang: adaptor to watch existing Activity's activation
due to technical limitations this requires to wire the adaptor
as replacement for the subject Activity, so that it can capture
and log the activation, and then pass it on to its watched subject
2023-08-19 19:06:44 +02:00
d9f2909b07 Activity-Lang: simple activation working 2023-08-19 17:48:38 +02:00