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

Compare with Current View Page History

« Previous Version 15 Next »

 

The goal of this proposal is to define clear lines between modules of geode. The goal of is that each module should

  1. Be mockable - so that that other modules can write tests that don't depend on that module
  2. Be tested within the module. In other words, if WAN depends on the Region module, I should not need to run any WAN tests to test all of the Code in LocalRegion.

 

In order to accomplish these goals, each module needs to have a clear API for the rest of the system to use, and tests within that module that cover all of the features of the API. Each module should have at least it's own package(s), if not be in a separate gradle module. Anything that is not part of the API for that module should only not be accessible outside of the module.

 

Here's a start at listing the proposed modules and their dependencies. This is not the current state of these modules because currently there are several cyclical dependencies (eg Persistence dependencies on Regions, regions depend on persistence). Part of the effort here will be to break these cyclic dependencies by replacing hardcoded references to other modules with plugins and callbacks that are part of the well defined API for each module.

  Geode Package Dependency Graph WAN CacheServer Messaging Statistics Client FunctionService Regions Serialization OffHeap PDX Persistence Querying ResourceManager  

 

Below is a high level view of the interfaces for each module and some of the changes that need to be made to get to this point.

 

Messaging

Package:distributed.interna, distributed.internal.advisor

API interfaces/classes: InternalDistributedMember, DM, InternalDistributedSystem, MembershipListener, DistributionAdvisor, DistributionAdvisee

Required Changes: InternalDistributedMember and InternalDistributedSystem should be interfaces, not concrete classes. They should only have the methods that are required by the rest of the system. The concrete classes like DistributionManager, the old InternalDistributedSystem class, etc. should not be referenced outside this package.

TBD - The proposal here is that membership is another module that is hidden behind the messaging layer as far as the rest of the system is concerned. The membership layer has it's own interface that should hide its internals from the messaging layer. Advisors are lumped in here to reduce the complexity of the high level graph.

  Messaging Packages OtherComponents Regions WAN Messaging Advisors Membership  

Statistics

Package:internal.statistics

API interfaces/classes: Statistics, StatisticsFactory, StatisticsManager

Required changes: Move into a separate package. Pull the code out of InternalDistributedSystem (it currently implements StatisticsFactory) into a separate class

Persistence

Package: internal.cache.persistence

API interfaces/classes: InternalDiskStore, DiskStore, DiskRegionView, DiskId

Required Changes: InternalDiskStore is new interface for DiskStoreImpl.

 

Regions

Package: internal.cache.region

API interfaces/classes:  InternalRegionService, InternalRegion,

Required Changes:

InternalRegion is new interface for LocalRegion. RegionService is a new interface that has the functionality from GemfireCacheImpl to manage regions. LocalRegion, etc. should not be used outside this package.

Direct references to other modules, for example LocalRegion.notifyGatewaySender, should be turned into callbacks that other modules plug into the Region interface. Those callbacks should be tested within the region module.

This is still the big ball of string that needs to get untangled further. We need to split out expiration, eviction, conflict detection, GII, transactions. There's also the question of what package owns RegionEntry and EntryEvent, because those objects are passed everywhere.

WAN

Package: internal.cache.wan

API interfaces/classes: AsyncEventQueue, GatewaySender

Required Changes: Region code should be refactored to not have direct dependencies on this package. For example, AsyncEventQueues should be notified through a listener installed on the region. The listener interface will be part of the region package.

 

FunctionService

Package: internal.cache.execute

API interfaces/classes: FunctionService, Execution, Function

Required changes: Region code should be refactored to not have direct dependencies on this package. For example, LocalRegion should not have function execution code in it.

 

Server

Package:internal.cache.tier.sockets (change this?)

API interfaces/classes: CacheServer, CommandInitializer, BaseCommand

Required Changes: Commands (the server side code for a client-> server message) for other modules (eg WAN) should be moved to their respective packages and registered with CommandInitializer.

 

Client

Package: internal.cache.client

API interfaces/classes: AbstractOp, ExecutablePool

Required Changes: Operations (The client side code for client-> server messages) for other modules should be moved to their respective packages.

 

Questions/Issues

What to do with GemfireCacheImpl,Cache?

The Cache interface currently has dependencies on almost all of the modules of geode because it has methods like getQueryService, getGatewaySenders (WAN). Unfortunately, Cache, InternalCache, or GemfireCacheImpl is used as a context object that also passed to almost all modules of Geode.

We need to rework how we inject dependencies into all of these modules. If we want a context object, it should be something that is generic that does not pull in dependencies on all other services, something likes spring's BeanFactory.  But it might be better if the specific dependencies for each module were passed into that module.

Modularity in the public API

We've already started creating a few separate modules at the external level - for example the lucene integration or the auto rebalancer. We need to nail down how these extensions are accessed by the user. One option might be to add a method to Cache like Cache.getService(Class<T> serviceInterface). Maybe we should remove methods like Cache.getQueryService, Cache.getGatewaySenders, etc. in favor of not hardcoding all of the services on Cache?

 

  • No labels