Skip to content

FabMo Configuration Refactor

Ryan Sturmer edited this page Aug 30, 2016 · 4 revisions

The purpose of this document is to describe a restructure of the configuration tree in FabMo, an essential feature that has some issues and feature shortfalls that should be correctable without too much rip-up and restructure.

New Concepts

​Several new concepts have been described, which will be detailed below. ​

Config Manifest

​The configuration will be described in a manifest, which will replace the current default configuration files. The manifest will be structured the same way that the current configuration is structured, but leaf nodes will describe the configuration entries more completely, providing fields such as name, description, validation info, default value, visibility to the user, and permission class (for a future, as-yet-to-be-described permissions system) - Not clear whether the manifest should be a single file for the whole tree, or be composed of fragments that are assembled, but in the case of dynamic components like runtimes and drivers, there needs to be at least a part of the tree that allows for dynamic fragment loading.

Manifest Concepts

Configuration manifests can be complex for a number of reasons, listed below:

  1. Default values can vary depending on context. Example: The control/data port for the G2 driver "default" values are best chosen on a platform by platform basis. A configuration manifest that says the default control port is COM3 is missing the opportunity to make that port /dev/ttyACM0 on a linux host, etc. A method, therefore for specifying a way of generating default values in situations where that is appropriate (without making it cumbersome to define fixed values elsewhere) should be used.
  2. A similar argument can be made for defining ranges. The ranges of some configuration entries are fixed, and some are dynamic. The position of a limit switch, for instance, can be anywhere that's within the bounds of the table's physical limits. The tables physical limits might be yet another configuration entry, so a system is needed whereby a configuration manifest entry can either refer to other configuration entries, or more probably, leave limit checking to a handler written for that purpose (to allow for maximum flexibility in specifying complex relationships between entries) - here again, we don't want to require a limit checking function for every single entry, especially those that could otherwise be satisfied by simple bounds checks, but provide an opportunity to do custom checking, only where appropriate.
  3. Some configuration entries will provoke activity on the system, for instance, a change of preferred units will change unit settings in the driver, runtimes, etc. There needs to be a way to specify these handlers in a way that is clear and concise, (or to omit them if no action is necessary after a change)
  4. If configuration entry order provokes activity on the system to commit the changes, then there's a possibility that the order of application matters, too. The manifest should be order-preserving, so that if a collection of configuration entries is provided that the order in which those entries are applied is well defined.
  5. There needs to be a way to overlay manifests with changes based on vendor default configuration values. An example of this is the machine configuration which might have different table size defaults, toolhead configuration, etc based on different models of tools.

Some manifest leaf node entries:

  • name (key)
  • defaultValue
  • type
  • description
  • visibility
  • permissionClass

​User vs. Global Tree

One configuration complication is that configuration values really should travel with the user - when user A logs in to the tool, he should see his own values in the configuration, but the tool has a notion of global settings (jerk values, unit values, etc are all tool specific, and not expected to be changed or set by the user very frequently) - the solution is a dual config-tree system. The global tree is one-per-machine and stores the authoritative machine values for all of the configuration. The user tree is one-per-user and is essentially a copy of the global tree, but can be a sparse copy, containing only the values that the user has customized. A user is not necessarily allowed to customize all or even any values, but when a user does so, the customized value is stored in the user tree. The client never sees the trees as separate, there is only a coalesced view of both trees. From the perspective of an app developer, it is a single configuration tree that is accessed by reading/writing the configuration endpoint. Visibility in the tree, as well as permissions to access are all specified in the manifest, and accessible to the client. In order to allow for editing of the global tree, the admin account has no user tree, and so configuration changes are global.

Configuration Backup/Restore

The existing system of backup and restore can be enhanced by the manifest, which can encode global features of the tree, such as engine version, etc. When a configuration backup is restored, it can be compared against the existing manifest to resolve inconsistencies.

Mapping of Functionality to Configuration Entries

Configuration entries need to be backed in many cases by real engine functions that must execute when configuration values change. A system should be put in place where these handlers are registered against the manifest, and the current system where this is all hard-coded done away with. The dynamic, clearly specified behavior of a system that actually registers functions against configuration keys, will be easier to maintain than the current hard-coded configuration tree.

Clone this wiki locally