Resilient
Classes | Typedefs | Functions
Detector

Detectors are the classes used by Resilient to determine whether a function failed or not. More...

Classes

class  resilient::Always
 A detector which always detects failure. More...
 
class  resilient::Any< Detectors >
 Combine a group of detector, detecting a failure if any of them detect a failure. More...
 
struct  resilient::StatelessDetector< Detector >
 An helper base detector to simplify writing stateless detectors. More...
 
struct  resilient::FailureDetectorTag< FailureTypes >
 Helper struct which defines the required types for the detector concept. More...
 
class  resilient::ICallResult< T >
 Interface to represent the result of calling a detected function. More...
 
class  resilient::Never
 A detector which never detects failure. More...
 
class  resilient::Returns< T >
 A detector which detect whether a function returns a specific value. More...
 
class  resilient::Throws< T >
 A detector which detect whether a function throws an exception of a given type. More...
 

Typedefs

template<typename... FailureTypes>
using resilient::returned_failure_t = typename detail::returned_failure< FailureTypes... >::type
 Type alias to the Variant containing either NoFailure or the failure types. More...
 

Functions

template<typename Failure , if_is_variant< Failure > = nullptr>
bool resilient::holds_failure (Failure &&failure)
 Whether a failure contains a failure or not. More...
 

Detailed Description

Detectors are the classes used by Resilient to determine whether a function failed or not.

Description

There must be a way for the library for detecting when a function has failed.

Common ways are to return a specific error code, throw an exception, and many other. In order to allow you to define the failure conditions appropriate for your use case Resilient uses Detectors.

A detector is a class which is able to determine how a function behaved, and can return a different type depending on the type of the failure.

Glossary

A function which the return value will be used to detect a failure is called the detected function.

The Concept

Any class can be used as a detector as long as it implements the expected concept.

A detector must define the types:

A detector must define the methods:

Deriving from FailureDetectorTag<MyFailure1, MyFailure2, ...> defines the failure_types for you.

preRun() is called before the detected function is called. The returned type State can be any type, and it will be moved back into the postRun() method when invoked. The State type can be used to store some state the detector needs to keep between calls to preRun and postRun.

postRun() is called after the detected function is called. The type returned by preRun() is moved into it as first argument and an instance of ICallResult with the type returned by the detected function is passed as a second argument. T is the type returned by the detected function. Failure needs to be a variant which containes either NoFailure if no failure was detected or one of the types used in failure_types if a failure was detected.

ICallResult can be used to determine whether the function returned normally or threw an exception and can also return a const reference to the value returned by the function or to the threw exception.

The detector can also "consume" an exception, which means that the exception should be considered handled.

Resources

The Detector is not required to be stateless, but being stateless heavily simplify writing a detector as it prevents problems with multi-threading, it can be invoked multiple times and it can also be used in different tasks.

To make this simple the preRun() function can return an object of any type, which will be moved back into the postRun() function.

The detector can initialize any resource it needs inside the preRun() method and store it into the state. The postRun() method can then make use of the resources initialized by preRun() and release them at the end of the method.

If the state object is the owner of the resources and RAII is used then the code has no clean-up to do.

If a Detector requires no state a NoState type can be used as return type.

Typedef Documentation

template<typename... FailureTypes>
using resilient::returned_failure_t = typedef typename detail::returned_failure<FailureTypes...>::type

Type alias to the Variant containing either NoFailure or the failure types.

Template Parameters
FailureTypes...The failure types that can be returned. If it's a single tuple then the content of the tuple is used instead.

Function Documentation

template<typename Failure , if_is_variant< Failure > = nullptr>
bool resilient::holds_failure ( Failure &&  failure)

Whether a failure contains a failure or not.

Template Parameters
FailureThe type of the Failure returned by the detector.
nullptrSFINAE out if it's not a Variant.
Parameters
failureThe Failure returned by the detector.
Returns
true A failure was detected.
false A failure was not detected.