Sentry – how to make use of the interfaces

In today’s post, I’ll describe what kind of interfaces have been defined in the Sentry project, and how you can take advantage of this knowledge, e.g. in order to create the custom metrics.
I’ve tried to keep these interfaces as simple as possible, yet some of them require an explanation, mostly due to the fact, that even though the library itself is rather simple to use (I want to believe that it’s also what you think), it does not mean that the main methods when being executed, will return for example, a single boolean value that doesn’t really say much about what just happened.


At first, let’s start with the core interface (actually, all of them are defined in the Core namespace):

Quite simple, start, pause and stop the Sentry, nothing more than that. The only difference between the PauseAsync() and StopAsync() is that similarly to the remote controller, the pause does not reset the current iteration number (ordinal will not be set to 1) and executes the hook OnPause() whereas stopping the Sentry will set that number to 1, and execute the hook OnStop() (and of course the async versions of these hooks). And do not forget that once you start the Sentry it will keep running forever (unless you define the limited number of iterations or stop/kill it). It’s the ISentry job to execute the check, determine what happened and push this information (including additional data such as date & time of execution etc.) to the listeners via hooks (callbacks). And how it does that? Before we move on, I need to describe the two simplistic interfaces, that are implemented in a few places:

The first one helps to determine whether some operation has executed successfully (or not), while the second one holds the dates and times of these executions. And now, the things will start to get a little more interesting:

Not too complicated either, every watcher has it’s name (you can name it whatever you like), and the ExecuteAsync() method that actually does the job. So what is that special result type? Here it goes:

Why two separate interfaces? Well, the former is used only for the hook called OnStart(), while the latter for everthing else (not literally of course). And what’s great about it is that every watcher has it’s own implementation of that interface (which adds much more useful data). All you need to do is to cast that interface into the specific result type, for example like the one below:

And this is how you can gather much more data, as long as you need it for any kind of anaylitcs, metrics etc. Otherwise, you can only check the IsValid property and perform some action based upon this knowledge (e.g. send an email to the system administrator). You may ask, what the heck is that ISentryCheckResult? Basically, it holds the result of the watcher check along with the dates and times of its execution. Keep in mind, that the only responsibility of the watcher, is to perform a check on a given resource – it is not aware about the iteration thingy.
In short, you may either use the watcher hooks to listen for the specific callbacks directly (that will receive IWatcherCheck), but it’s also possible to gather all of the results from a single iteration:

You can get that object by defining the hook for the OnIterationCompleted()it’s up to you whether you wish to perform an action once the particular watcher check is finished or after the whole iteration (all of the defined checks) is completed. Finally, there’s one special configuration option for the Sentry:

As the name says, it is responsible for performing the iteration. And if you’d like to provide your custom iteration processor (e.g. the parallel one), just implement that interface on your own and pass it via the Sentry configuration:

And that’s all. Surely, I’m not saying that all of these interfaces will remain the same in the final version, as there’s always a room for improvement. I just hope that it does not look too scary.

1 Comment Sentry – how to make use of the interfaces

  1. Pingback:

Leave A Comment

Your email address will not be published. Required fields are marked *