Using Dynamic Rule Reactors

Dynamic Rule Reactors are used to automatically generate or remove dynamic rules when there are changes to other dynamic rules. These actions are controlled by rules, and therefore have access to all rules in the model at that time. Reactors are a host-independent feature, and work the same way in all hosts, including server-based implementations.

Certain Dynamic Rule operations trigger Reactors . This makes Reactors a capability useful in a "runtime" context, in an end-user session. These dynamic-rule-related operations are exactly those which an end-user will be initiating, usually through a custom user interface (UI). For testing purposes, you can use the development environment to simulate this process. But the main idea is that Reactors allow you-as-developer to provide a rule-based way of augmenting end-user-initiated changes to the model.

For each kind of change to a Dynamic Rule , such as creation, change, or deletion, you can define "reactor" methods, which tell Intent to perform additional actions at the specified times. The reactor methods are ordinary Intent methods, most which return a list of action lists. The reactor methods can examine the model at the time of the change, can reference other rules to build part or all of the action lists, and have few restrictions in scope. If the reactor returns the empty list, { }, then no actions are taken.

Reactors are always used in conjunction with a custom UI of some kind, as opposed to being used from the developer UI (except for testing purposes). Using rule-based Reactors has several advantages over simply hard coding the behavior into the UI:
  • The rules are a “complete package”, and you can change to a different UI and your rules will still control a complete and accurate model.
  • The UI can be extensible – different types of objects can respond differently, and they can be changed/added without touching the UI code itself.
  • Since the Reactor is in the rules, it’s “closer” to the changes that need to be made, and so sometimes it’s easier to do because it is in the same context.

Notes

  • All of the Reactor rules are methods that take no arguments. This may seem unusual but was a deliberate design decision. Reactors have to be uncached, in order to be re-invoked on each change. But we quickly found that users (including ourselves!) often forgot the 'uncached' flag, and the Reactor would mysteriously not fire on the second and subsequent change. By forcing all of the Reactors to be methods, we avoid this problem.
  • Dynamic Rules created by event-handlers do not have a dependency upon the Reactor method itself, nor, therefore upon anything that the Reactor depends upon.