-
Notifications
You must be signed in to change notification settings - Fork 47
Dependency Injection and Context
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.
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.