14.1.5. How to make it work

14.1.5.1. Representing state in instances

State holds for particular instances. How to represent it? First, we must ask ourselves whether state should be persistently stored. Should state be recomputed on each new session, or should it survive the end of a session?

Ending a session does itself not change the state of a context or role or property as we have defined it here. Hence, there is no need to recompute it on session start. Because we want to be able to present the user with a list of notifications that have a certain duration (a notification can be valid for some time) and the user can switch off his computer in the meantime, it would mean we would have to recompute state for all context instances on startup. That is clearly undesirable. Hence, state must be persisted.

At first sight, we have two opportunities to represent (and persist) context instance state:

  1. as an external property (holding a list of strings representing the state types);

  2. as a new member of the context representation.

When we represent state as properties, it will be automatically shared between those who play a role in the context (assuming every user role will have a perspective on the state of the context). Is that what we want? Let’s explore some examples.

Consider a medical examination related to a serious disease, having a physician, a laboratory technician and a patient. Suppose a blood test is involved. At some point, the test results are available and the physician should interpret them. The physician should be notified of this state, but the patient should only receive a notification after the interpretation has been added to the test results.

Consider a financial transaction system involving two business parties and an intermediate party. The latter should perform fraud checks. The situation is modelled such that some broad checks are performed automatically on behalf of the intermediate party. When alarm bells go off, manual intervention is required before further action is taken. Obviously, the alarm bells should not ring for the two business parties before the human audit.

We conclude that indiscriminately sharing state would leak information that we’ve carefully kept away from some roles, using perspectives. Notice we’re not talking about actual notification, as we can choose to not notify some user roles of some state changes. However, these changes would be sent to their computer and this opens up, in principle, a way for the receiver to get access to it.

In other words: state should not be shared among participants; each should recompute state given the information available according to his perspective (in other words, users do not have an implicit perspective on the state condition).

This analysis allows us to decide on state representation in terms of a new internal member of the context instance representation, rather than as external properties.

We add to the context instance representation an Array of the current states that instance is in (and do a similar thing to role representation).

14.1.5.2. Working with Properties and Verbs

We provide an API function that returns, for a given role instance, an Array of Property-Verb combinations given the state(s) of the role and context and the type of the role the owning user plays in the context. As with other queries, we support the functional reactive programming pattern for these functions. This means that on state change, the user interface program is notified by an invocation of the callback that it provided on requesting the Property-Verb combinations.

This makes it very easy to adapt our user interfaces automatically to changing state, as the visual representation of each Perspective is built on Properties and Verbs.

The underlying mechanism is the same as for ordinary queries: based on dependencies. However, the computation of Property-Verb combinations depends on the states of a role and its context. Hence we record a new type of dependency, the ‘state-dependency’.

When that state changes (see below) we record the correlation identifier of the API request for the Property-Verb combinations in the current Transaction in Perspectives State. On subsequently running that transaction, we look up the corresponding effects and apply them (recomputing the combinations using the new states and sending them to the client).

14.1.5.3. Applying the inverted-query pattern to state queries

But how does state change? As a state definition consists of a boolean query, we can invert it and thereby make sure that relevant assignments lead to re-evaluation of such queries (just as we do with the previous Bot Action implementation). Actually, this is a two-phase mechanism. On changing some context, role or property, we follow inverted queries to the contexts (or roles) where they are state queries and record these in the current Transaction in Perspectives State.

Then, when we run that Transaction, we re-evaluate the state queries for each context or role that is affected. Whenever a state query evaluates to true, but the associated state label is not in the current states of the context or role instance, we add the label. Conversely, we remove the label if the query evaluates to false. On doing so, we record the correlation identifiers whose computation depends on those states, in the current Transaction.

In a way, a state query is like a rule whose right hand side adds or removes a state label (and also executes entry- and exit automatic actions, see the next paragraph and also the last).

When we then later re-evaluate queries that came in through the API, the relevant state-dependent requests are re-computed.

14.1.5.4. Automatic actions on entering and exiting states

When we re-evaluate a state query and add a label (or conversely remove it), we also look up all entry automatic actions for the newly added state (or the exit actions when it was removed instead) for the role played by the owning user. These will be executed, triggering state change that may lead to a new round of evaluation of state queries.

14.1.5.5. Notification

We want to notify the user about some roles and contexts when they enter (or exit) designated states. Being in a ‘notified state’ is, in some cases, a phenomenon that should persist for some time (see next paragraph). For that reason we record those roles and contexts in specific role types in sys:PerspectivesSystem (thus, this becomes Perspectives State and survives individual sessions).

If the modeller specified, say, state entry notification for state S of context type C, at level L, for user role U, an instance I of C that enters S when the owning user is in role U will be added to the role ContextNotification of MySystem, with property Level having value L.

In other words: we keep a list of contexts annotated with notification level (and another for roles). A client program can request these role instances through normal API calls; so when I is added to ContextNotification, the client will be updated.

It is up to the end user program to determine how to actually alert the end user. It may throw up a screen alert, for example. Handling notifications is part of the framework provided by MyContexts; it is not the responsibility of the screen programmer of a particular app (model).

14.1.5.6. Notification life cycle

What happens to a notification when it has been shown to the end user? For some notifications, just showing it once may be good enough. This may suffice for notifying the end user that a chat partner has entered a context. This means that the PDR does not remember contexts that entered the triggering state; after the end user program has received updates, they are discarded.

But for others it might be better to keep them in a list the end user can choose to inspect, until he actively dismisses them. This may be appropriate for reminders to reply to an email; indeed, the very idea of a to-do list is modelled this way. Such notifications should survive the end of a session with MyContexts.

So, for notifications we have two dimensions:

  • How urgent a notification is brought to the end users’ attention;

  • Whether it is dismissed automatically, or by hand (or after some time, etc.).

We must research whether these two dimensions can be collapsed into a single set of categories, or need separate representation.