Troubles

A common use case in single-purpose devices is the ability to notify users of error conditions. For example, a failed network connection may display a message or icon on a user interface or even change the color of an indicator light, which should clear when the connection is established. A device may need daily maintenance, requiring a reminder to the user that is triggered at a particular time of day. There may be a need to record when hardware experiences errors or when a device is offline because firmware is being installed. These are all examples of creating and recording conditions. Some may be stateful and automatically clear when conditions change, while others need to be logged. KOS provides standard infrastructure for these use cases in the form of troubles.

What is a trouble?

A trouble is simply an instance of any class that extends Trouble. Troubles are managed by adding them to TroubleService, which handles logging, lifecycle events, and notifications. The trouble service in KOS is unique because it doesn’t allow duplicate troubles to be added. As this is based on object equality, it is possible to have many troubles of the same type but not two troubles that are equal. This avoids the accumulation of troubles that represent the same error. This also tends to simplify trouble creation logic as there is no need to check if a trouble exists before adding a new one.

While troubles are just objects and can contain any relevant data, KOS provides support for a number of standard access patterns to make using troubles very simple:

Impacted objects

It is a common need to check if a trouble is related to another object. For example, consider inserting an expired ingredient in a beverage dispenser. When the expired ingredient is detected, a trouble can be created to indicate that it expired. In this example, the trouble is said to impact the ingredient so that the ingredient object can be placed into the impacted list of the trouble. Not only does this create a relationship between the trouble and the objects it impacts, but since the impact list is part of trouble equality, trouble service will automatically allow troubles of the same type with different impact lists. For example, inserting another expired ingredient will generate another trouble which is not equal to the original trouble as the ingredient objects are different.

When it comes time to remove the expired ingredient, the associated trouble should also be removed. In fact, when removing an ingredient, all troubles related to the ingredient should be removed as the ingredient no longer exists. KOS makes this very easy by providing a way to remove all troubles that contain the impacted object.

Linked objects

Consider a trouble that indicates an ingredient is sold out. This trouble may be created by more than one service. For example, one service may check the expiration date and create a sold-out trouble, while another detects that the ingredient is empty and creates the same trouble. If the expiration date check was disabled, there might be a requirement to remove all troubles generated by the service while not removing the sold-outs created by the empty check. If the service that created the trouble were added to the impact list, it would be easy to simply remove all troubles associated with the service, but then troubles for the same ingredient from the two services would no longer be equal, and there may be two sold outs for the same ingredient. To solve this, troubles also contain a list of linked objects. This list has all the same functionality as the impacted list, except that it’s not part of trouble equality so that it won’t result in multiple troubles.

Tags

While impacted and linked lists can contain arbitrary objects, this prevents them from being used to convey information to external systems, such as a UI running in a web browser. There is no attempt to serialize these objects as they are marker objects, not data. In cases where there is a need to use a marker that can also be visible to external systems, the tag list can be used. Just as with linked and impacted lists, tags have all the same api support, but as tags are strings, tags can be accessed via endpoints.

Resolving Troubles

While some troubles are simply indications of a failure, it is very common for troubles to represent an action that needs to be performed or a problem that has a potential remedy. In KOS, these are called resolvable troubles.

Consider the case where an ingredient is replaced in a dispenser, and it requires the pump to be primed. Since this is a physical action, a person must confirm the action. One approach is to ask the user to confirm the prime and then run the prime api. This approach requires a mechanism to indicate the prime needs to be performed as well as knowledge of which api is required to trigger the action. It also requires error handling logic in the event that the prime failed and the action needs to be performed again.

This can all be avoided by simply using a resolvable trouble. When the ingredient is inserted, and the need for a prime is detected, a resolvable prime trouble is created. Since troubles already have notification support, detecting the existence of the trouble is straightforward. Since the trouble understands the underlying problem and the action that needs to be performed, the action can be triggered by code in the resolve method of the trouble. This means that external code doesn’t need any knowledge about how to trigger a prime as it simply needs to call the resolve api for the trouble. Once called, the trouble will start the action and verify that it is completed correctly. If not, the trouble remains, and resolve can be called again to retry. Once successful, the trouble is automatically removed.

Following this pattern, virtually any action can be linked to trouble and integrated into external systems, such as a web UI, without understanding what the resolve action does.

Troubles are a key building block for virtually any device, and KOS provides a broad set of capabilities for both distributing trouble-related events and efficiently utilizing troubles for control logic.