Runnable Components

Jivago provides a mechanism for running background tasks and exposes application initialization hooks. For both of those purposes, the Runnable interface is used.

from jivago.lang.annotations import Override
from jivago.lang.runnable import Runnable


class MyRunnableComponent(Runnable):

    @Override
    def run(self):
        print("hello!")

Background Workers

For running continuous tasks on a background thread, use the @BackgroundWorker annotation. These components will be started on separate threads when the app has started successfully. Components instantiated in this manner support all of the usual dependency injection features.

import time

from jivago.lang.annotations import Override, BackgroundWorker, Inject
from jivago.lang.runnable import Runnable


@BackgroundWorker
class MyBackgroundWorker(Runnable):

    @Inject
    def __init__(self, component: MyComponent):
        self.component = component

    @Override
    def run(self):
        while True:
            print("hello from the background")
            time.sleep(5)

Application Initialization Hooks

@PreInit, @Init and @PostInit hooks are provided for running one-off tasks at startup and are invoked identically to background workers. These are, however, required to exit before the application can start.

from jivago.config.startup_hooks import PreInit, Init, PostInit, PreShutdown
from jivago.lang.annotations import Override
from jivago.lang.runnable import Runnable


@PreInit
class FirstHook(Runnable):

    @Override
    def run(self):
        print("First!")


@Init
class SecondHook(Runnable):

    @Override
    def run(self):
        print("Second!")


@PostInit
class ThirdHook(Runnable):

    @Override
    def run(self):
        print("Third!")

@PreShutdown
class ShutdownHook(Runnable):

    @Override
    def run(self):
        print("Cleaning up before shutting down.")
  • PreInit is invoked right after the service locator and application properties are configured.

  • Init is invoked after initializing the routing table. At this stage, the application is in a coherent state.

  • PostInit is invoked after starting background workers and scheduled tasks. No further initialization task is left to be done.

  • PreShutdown is invoked upon receiving SIGINT/SIGTERM signals. Use for cleaning up resources and gracefully shutting down threads.

Scheduled Tasks

One-off background tasks can be scheduled over a longer period of time using scheduled tasks. The @Scheduled annotation takes either a “cron” or “every” parameter.

  • cron : Takes a cron-style string.

  • every: Takes a Duration enum. (Duration.SECOND, Duration.MINUTE, Duration.HOUR, Duration.DAY)

  • start : Optional. Specifies a start time before which the task will not be run.

from jivago.lang.annotations import Override
from jivago.lang.runnable import Runnable
from jivago.scheduling.annotations import Scheduled, Duration


@Scheduled(every=Duration.HOUR)
class ScheduledTask(Runnable):

    @Override
    def run(self):
        print("hello")