Between the Start and Stop stages is Run. In this stage the kernel runs through each deployed service in deployment order and if that Service implements the Runnable interface then it's Run() function is invoked.

1type RunnableService interface {
2    Run() error

If that function returns an error then the kernel stops and enters the Stop stage. Otherwise, it continues with the next deployed service. When all services are checked it then enters the Stop stage.

Run patterns

There are two patterns for the use of this interface.

Command line tools

In this pattern you write the components of your tool as Service's with each component having dependencies to the various Service's it requires to perform some task.

Then, each one of those components implements the Run() function. It can then test to see if it should actually do something (e.g. a command line flag) and just return nil if it should not do anything, otherwise perform its task.

Once all Service's implementing Run() have done their task the tool can then shutdown.

An example of this is the tool that generates this actual document. It consists of a group of RunnableService's which perform various tasks:

  1. Generates any dynamic pages like indices,
  2. Run's hugo to generate the actual html site,
  3. Run's chromium in headless mode to generate each PDF document based on the site.


In the Daemon pattern only one Service implements RunnableService. When it's Run() function is called it never returns keeping the kernel and the application alive.

Dependent services might extend the Daemon service by calling a registration function in the Daemon from within their Start() function.

For example the daemon implements a webserver so the dependent services register handlers against specific paths within the website.

An example of this is the rest package included with the kernel. This implements a Webserver Service where you can register handlers against paths served by the server and implement REST actions which are provided by dependent Service's.