Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

In most applications ClassLoader isolation is not required, because all dependencies are well contained. In Geode’s case, the ClassLoader isolation would be perfect, as each module can be a self-contained component. In addition application code that is deployed into Geode can now include different versions of libraries used by Geode without conflict. .

After some research, it was found that JBoss-Modules addresses all the ClassLoader isolation and dependency isolation concerns.

...

JBoss-Modules is a standalone implementation of a modular (non-hierarchical) class loading and execution environment for Java. In other words, rather than a single class loader which loads all JARs into a flat class pathclasspath, each library becomes a module which only links against the exact modules it depends on, and nothing more. It implements a thread-safe, fast, and highly concurrent delegating class loader model, coupled to an extensible module resolution system, which combine combines to form a unique, simple and powerful system for application execution and distribution.

JBoss Modules is designed to work with any existing library or application without changes, and its . Its simple naming and resolution strategy is are what makes that possible. Unlike OSGi, JBoss Modules does not implement a container; rather, it is a thin bootstrap wrapper for executing an application in a modular environment. The moment your application takes control, the modular environment is ready to load and link modules as needed. Furthermore, modules are never loaded (not even for resolution purposes) until required by a dependency, meaning that the performance of a modular application depends only on the number of modules actually used (and when they are used), rather than the total number of modules in the system. And, they may be unloaded by the user at any time.” -- GitHub JBoss-module description

...

With the introduction of modularity, the notion of modular dependency management has been introduced. As each module can depend on other module(s), the management of loading these module(s) become critical. The system needs to be able to determine when to load modules, based on their dependency graphs. Without this capability, it is left to the user to determine the dependency graph.

Maven and Gradle are well-known tools in the library dependency management space. Both tools allow applications to specify required libraries without having to list all dependent libraries for the required libraries. This allows developers to use/upgrade libraries without any knowledge of the dependencies of libraries in question.

Modules need to behave to in the same manner. An A user/application needs to be able to list a module and version without the concern of loading and managing any dependencies other than their own.  

...

To keep this short, all the DI/CDI technologies will provide dependency injection. Given the goal of ClassLoader isolation, some the frameworks will not work. Both Spring and Google Guice, by design, neither implement nor support classloader isolation. This only leaves us with the CDI implementations. Which work well with JBoss-modules and its Classloader isolation.

The main CDI implementations would be Weld or Apache OpenWebBeans. At this stage, it is unclear which of these two implementations are to be used, as both as ASF2 licenced licensed and both are actively developed. At this stage, Weld is close to releasing v3.0 which will include the CDI 2.0 specification, whereas Apache OpenWebBeans only supports CDI v1.2.

...

CDI provides a mechanism to intercept method invocations using either an Interceptor or a Decorator. In essence, these two constructs are the same as both provide the capability to intercept method invocations and run an action. The difference between an Interceptor and a Decorator is: Interceptors are used for cross-cutting concerns over many classes , like logging and security and Decorators are type-safe and specific per type, usually to enhance some business logic for a type.

...

The module dependency manager (MDM) is responsible for the management of dependencies between modules. When managers start they register themselves with the MDM, providing their contextual path and the modules it depends on.

The MDM will build up a dependency model that is used in the starting and stopping instances. The MDM will use the dependency model to avoid dependency dependencies starting/stopping in the wrong order.


Manager

The manager is a an MBean and comprises of 4 pieces:

  • A list of parent managers with which it has a “depends-on” relationship, “injected” as part of the configuration lifecycle.

  • Configuration used to create an Instance

  • The reference to the “managed” instance

  • Operations, metrics and configuration methods

IMG_20170320_141347.jpg


A manager  will will provide a single API, via JMX, for the configuration and management of an instance. The configuration service will interact with the manager to add/change/update the configuration of the instance.

Each manager is responsible for the starting of its referenced instance (creating an instance) based upon the stored configuration. The manager will , interact with the MDM to, get a list of its direct dependents and request that they start themselves. Once all dependent modules have successfully started, it will create its managed instance based upon the stored configuration.

...

This proposal adds to Geode the concept of a manager. A manager should be seen as the owner of an instance. Managers and Instance have a 1:1 relationship. Every instance will have a Manager associated to with it. I.e RegionA will have a RegionManager containing all its configuration and RegionB will have its own RegionManager container all the configuration to instantiate RegionB. There are two managers, not 1 manager for 2 regions.

...

Managers are configured via the configuration service. (this can be in the form of XML, Spring, GFSH, REST,....)

In the case that a manager requires more managers to be createscreated, they will recursively be created at this step. E.g The Lucene modules requires its own regions to be created for internal management.

...

  1. Get the component Manager

  2. Determine is the Manager has dependent managers

    1. If there are dependents, iterate over dependent managers and recursively ask them to start themselves

    2. If no dependents exist, create an instance of the component using the configuration stored on the manager

  3. *Optional: After creating the instance, the instance can then be used and injected into the configuration of a “parent” manager, to be used for it’s its creation.


IMG_20170328_134243.jpg

A component is considered “started” when it has an instance and all its dependents have instances.

...

ModuleC → no dependencies


Well We'll assume that each module contains a single component, corresponding to the module name.

...

Manager A is asked to start, but it has 2 dependencies, Manager B + Manager C. Iterating over the dependencies, Manager B is then asked to start. It to too has a dependency, Manager C, which it then asked to start. Manager C does not have any dependencies and it starts C`. After starting C`, Manager C will request Manager B to add C` to its configuration.

...

With a more modular Geode, it now becomes possible to add/extend functionality. There are 2 types of additions in Geode that can be supported with this extensions option.

  1. A stand alone module with any dependency on Geode

  2. A module with dependency on events from Geode

The first options is option is the simplest. All that is required is to define the module, its components, and its configuration. This new module will then just be added to Geode by adding it to the classpath. The AppManager will process the relevant configuration and start the corresponding Managers and Instances. A good example for this option would be the Redis adapter for Geode, which is currently experimental. The Redis adapter module is completely stand-alone and requires events from the Geode system to function.

The second option is a little more complicated. A module or component requires to “hook - into” the current eventing the Geode provides. Current Geode events would include all events received by the CacheWriters, CacheListeners or AsyncQueues. The best way to describe this is per the example used in the Bootstrapping Lifecycle example. Upon the creation of the instance, the manager will then request the dependent manager to register/add the current instance to the configuration of the dependent manager.

...

  1. The configuration is parsed by the configuration service

  2. The ConfigurationService creates a CacheManager

  3. The ConfigurationService creates a RegionManager with a dependency on the CacheManager

  4. The ConfigurationService creates a LuceneManager with a dependency on the RegionManager created in Step2

  5. As part of the creation on the LuceneManager, the LuceneManager creates a LuceneAsyncEventQueueManager

  6. After creating the AsyncEventQueueManager (Step 5), the LuceneManager creates a LuceneRegionManager

  7. The system is requested to start. Using the steps described for bootstrapping the LuceneRegionManager is requested to start, thereby creating a LuceneRegion(s)

  8. The LuceneAsyncEventQueueManager then starts the LuceneAsyncEventQueue

  9. The LuceneAsyncEventQ is registered/added into the configuration of the RegionManager

  10. The RegionManager creates the Region with the LuceneAsyncEventQueue configured as a an AsyncEventQueue to the Region

  11. The CacheManager creates a Cache and completes the start-up cycle.

  12. Region sends events to LuceneAsyncEventQueue

...

Service Provider Interfaces provides the ability for 3rd party vendors to implement services to extend functionality or replace components. Geode will also have a an SPI that will be used to define and extend/implement the Geode services.

...