You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 5 Next »

To be Reviewed By: August 20th, 2020

Authors: Patrick Johnson

Status: Draft | Discussion | Active | Dropped | Superseded

Superseded by: N/A

Related: ClassLoader Isolation

Problem

For the purposes of this document, a Geode component is any class/feature that, when created/started, adds to or changes the behavior of Geode, like Cache, Region, or LuceneIndex. Currently, Geode components can be created and shutdown directly using things like CacheFactory in the case of Cache or RegionFactory in the case of Region. After the completion of the work proposed by the  ClassLoader Isolation RFC, the sub-projects containing Cache, Region, and other Geode components will be loaded as separate modules with their own ClassLoaders, rendering these components inaccessible from outside the module framework. The below graphic shows the division between the system and the module ClassLoaders.

system-module-separation

The modules can access classes from the system ClassLoader, but code outside cannot directly reference classes defined in the modules and must instead use indirect methods, like service loading to access them.


Let's use Cache as an example; Cache is located in geode-core, which is loaded as a module, as shown above, and is inaccessible from the system ClassLoader. In order to access classes from modules, they must implement an interface that is accessible from the system ClassLoader and that doesn't reference any classes from inside the module system, so they can be services loaded. While Cache is an interface, it requires several other classes from geode-core making it difficult to decouple and move to a separate sub-project. This is the case for more components than just Cache and impacts more modules that just geode-core. Without an external interface to use to load the implementation from the relevant module, we have no way of creating or managing components.

Anti-Goals

this document is intended to solve the problem of creating, managing, and destroying Geode components within the module framework and is not concerned with...

  • The implementation of modules within Geode
  • Adding, removing, or modifying the behavior of any Geode components

Solution

The proposed solution is the creation of a ComponentManagementService interface. The interface will live in a sub-project accessible from the system ClassLoader, allowing it to be used for service loading. There will be an implementation of ComponentManagementService for each type of component (Cache, Region, LuceneIndex, etc.), that will reside in the same module as the component. The implementation will be able to access classes from inside the module system, such as CacheFactory and Cache, allowing it to create, manage, and destroy its associated component. Different types of components will be identified using a ComponentIdentifier class, which will primarily consist of a name (e.g. "Cache"). The ComponentManagementService interface will have the following methods:

  • A method to create the component and return a ComponentInstance.
  • A method to destroy the component.
  • A method that returns the created component.
  • A method that takes a ComponentIdentifier and determines whether or not the ComponentManagementService can create a specific type of component.

The list above makes reference to a ComponentInstance being returned when creating a component. The ComponentInstance class will contain a reference to the created component and the ComponentManagementService instance that created it, which can later be used to shut down the component. Holding the component in an object separate from ComponentManagementService allows for the creation of multiple components of the same type, for example, we need to be able to have more than one region.

The basic flow for creating a component using ComponentManagementService will be as follows:

  1. Start with a ComponentIdentifier representing the type of component to be created.
  2. Load all implementation of ComponentManagementService from the module system.
  3. Ask each implementation if it can create the type represented by the ComponentIdentifier until you find one that can.
  4. Ask the found ComponentManagementService to create the component.
  5. Store the returned ComponentInstance so it can be used later to access or destroy the created component.

***TODO: change parts about ComponentInstance***


Changes and Additions to Public Interfaces

Addition of ComponentManagementService and ComponentIdentifier. No changes to existing pubic interfaces.

Performance Impact

No anticipated performance impact.

Backwards Compatibility and Upgrade Path

No backward compatibility impact.

Prior Art

An alternative to this solution is to refactor every component to have an interface that doesn't depend on anything besides other interfaces and pulling all of the interfaces out of their current sub-projects into a sub-project specifically for interfaces to be used for service loading.

FAQ

Answers to questions you’ve commonly been asked after requesting comments for this proposal.

Errata

What are minor adjustments that had to be made to the proposal since it was approved?


  • No labels