Skip to content

Dependency Injection and Context

Michael Dombrowski edited this page Sep 25, 2023 · 1 revision

Overview

Greengrass has custom dependency injection which is implemented in Context. Context will automatically create instances of objects if they have no-argument constructors or constructors annotated with @Inject and all the constructor parameters exist in the Context already, or they are recursively created and injected. After creating an object, Context will execute preInject on the instance, then inject any fields annotated with @Inject and then execute postInject on the instance.

If an object cannot be created automatically, you can insert it into the Context manually using put. See Kernel for an example of this. This enables simple mocking for unit/integration testing as you're able to insert your own custom implementation of classes which would then be used when creating new objects via the Context.

The publish thread is also used for all service lifecycle state changes. Nucleus (and plugin) code can register state changes listeners which will execute on the publish thread whenever any service is moving from one state to another. This is used most often during tests, but also for services to react to their dependencies changing state.

Because the publish thread is important for service lifecycle, configuration, and deployments it is critically important that any code executed by the publish thread does not block. If code blocks, it may lead to deadlocks or just poor performance for super important tasks (like allowing a service to transition to a different state). It is always important to know what thread will execute your code and if you are allowed to block or not. If you do not know, then assume you're not allowed to block and then use futures or a separate threadpool to execute blocking/async tasks.

Publish thread

Context, beyond dependency injection, also has a "publish thread". The publish thread is intended to execute code serially to ensure ordering and without multithreading. The publish thread is used critically for all Configuration changes, specifically when changing a configuration value the value is changed immediately and the fact that it changed will run any and all subscribers on the publish thread. The publish thread is also used during deployments to ensure that all configuration values are changed before the configuration subscribers execute. Without the publish thread there, the configuration subscribers may execute without seeing all the configuration changes which may result in various race conditions and inconsistent state.

Clone this wiki locally