From 91c2763fa4879d08ba253da9404a6b6e6edda086 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Tue, 1 Jun 2010 05:59:34 +0200 Subject: [PATCH] WIP considering how to manage default / fallback advice --- src/lib/advice.hpp | 8 ++++++-- wiki/renderengine.html | 14 +++++++++++++- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/lib/advice.hpp b/src/lib/advice.hpp index 3281c7de2..b04096036 100644 --- a/src/lib/advice.hpp +++ b/src/lib/advice.hpp @@ -254,6 +254,10 @@ namespace advice { * and is placed into the internal storage buffer; the * advice index keeps a (type erased) pointer to serve * any requests which happen to match the binding. + * + * @note the ptr-to-solution in the inherited PointOfAdvice + * is currently (5/10) not used, because this \em is + * already the solution. */ template class ActiveProvision @@ -273,7 +277,7 @@ namespace advice { : PointOfAdvice(refPoint) , theAdvice_(advice_given) { - setSolution (this, this); + setSolution (this, this); // not used currently (5/10) } friend class Provision; @@ -310,7 +314,7 @@ namespace advice { /* == policy definitions == */ ////TODO: extract into policy classes - AD const& handleMissingSolution() const { return AD(); } /////////////////////TODO either return value or build a registry of defaults + AD const& handleMissingSolution() const { return AD(); } /////////////////////TODO singleton or registry for default advice. See TiddlyWiki for discussion public: diff --git a/wiki/renderengine.html b/wiki/renderengine.html index 9643f5c49..80b45c3ed 100644 --- a/wiki/renderengine.html +++ b/wiki/renderengine.html @@ -540,7 +540,7 @@ In a more elaborate scheme, the advised entity could provide a signal to be invo → AdviceImplementation -
+
[<img[Advice solution|uml/fig141573.png]]
 
 
@@ -581,6 +581,18 @@ Aside from the index, handling of the advice provisions turns out to be tricky.
 * an attempt to reduce this considerable overhead would be to use an back-link from the provision as added to the system to the original source (the ~AdviceProvision owned by the advisor). On modification, this original source would be notified and thus detached. Of course this is tricky to implement correctly, and also requires locking.
 The decision for the initial implementation is to use the first variant and just accept the slightly imprecise semantics.
 
+!!!lifecycle considerations
+Behind the scenes, hidden within the {{{advice.cpp}}} implementation file, the ~AdviceSystem is maintained as singleton. According to a general lifecycle policy within Lumiera, no significant logic is allowed to execute in the shutdown phase of the application, once the {{{main()}}} has exited. Thus, any advice related operations might throw {{{error::Logic}}} after that point. The {{{~AdviceSystem()}}} also is a good place to free any buffers holding incorporated advice data, after having freed the index datastructure referring to these buffer storage, of course.
+
+!!!!handling of default advice
+Basically, the behaviour when requesting non-existing advice may be configured by policy. But the default policy is to return ref to a default constructed instance of the advice type in that case. Just the (implementation related) problem is that we return advice by {{{const&}}}, not by value, so we're bound to create and manage this piece of default advice during the lifetime of the ~AdviceSystem. The way the ~AdviceSystem is accessed (only through the frontend of {{{advice::Request}}} and {{{advice::Provision}}} objects, in conjunction with the desire to control this behaviour by policy, creates a tricky implementation situation. Here we might also consider to use some separate kind of singleton bundle just for these default advice data (e.g. a templated version of //Meyer's Singleton...//), but this would create yet another difficult to define relation between the lifecycle of the ~AdviceSystem and such a singleton bundle.
+<<<
+{{red{WIP ... solution idea}}}: //let the handling-function for missing advice create an {{{advice::Provision<AD>}}}, with the same binding as the current request,//
+i.e. fabricate the missing solution on-the-fly, setting a default constructed piece of advice data.
+__pro__: simple to implement, avoids to re-create for this special case some of the functionality the index already provides
+__con__: difficult to check and verify, loads additional data into the index table, the first request failure gets as expensive as an advice provision, how to fabricate a reliably matching solution is not obvious in case we allow variables in the binding pattern.
+<<<
+
 !!!index datastructure
 It is clear by now that the implementation datastrucutre has to serve as a kind of //reference count.// Within this datastructure, any constructed advice solution needs to be reflected somehow, to prevent us from discarding an advice provision still accessible. Allowing lock-free access to the advice solution (planned feature) adds an special twist, because in this case we can't even tell for sure if an overwritten old solution is actually gone (or if its still referred from some thread's cached memeory). This could be addressed with an transactional approach (which might be good anyway) &mdash; but I tend to leave this special concern asside for now.