Skip to content
Jonathan Samples edited this page Mar 25, 2016 · 2 revisions

Dependency Injection

The sync engine uses the dependency injection (or inversion of control) pattern to structure it's code and runtime dependencies. We use the Spring framework to facilitate service (bean) creation and dependency resolution.

Because DI is so central to how the sync engine is built any other design patterns found in the code are either offshoots or adaptations of DI patterns.

Registry

Supplementing DI, we use the provider pattern. The provider pattern is where there is a provider registry for a particular type of interface, that gets injected at startup time by all of the available implementations of that interface. Then at runtime the particular provider gets chosen by the registry depending on the type of processing that needs to occur. For example, we use this for authentication because a particular ActiveStack implementation may have more than one auth provider and we need to be able to handle both kinds. The specific auth implementation to be used will be chosen by the the providerId attribute of the message that gets received by the active service when authentication occurs. Another example, is the DAODataProvider.

Factory

The factory pattern is used when we want to instantiate objects at runtime rather than at startup time. For example, with database connections we don't want a single point in time when connection objects are created. We want to create them as needed. For this we use a connection factory (which is still just a bean) that gets injected with the connection configuration at startup that then creates connection objects for which ever process needs it. This has another benefit that it centralizes db configuration and pooling.

Reflection

Across the application we heavily rely on the meta data associated with model classes to instruct the sync engine how to do it's job. At startup we inspect all entity classes and cache the meta data about the class that is relevant. For example, we inspect an entity class's annotations and field declarations in order to discover how to build queries.

Aspect Oriented Programming

To a small degree the sync engine uses Aspect Oriented Programming (AOP). AOP describes that type of programming that breaks the single responsibility principal. In other words, you use AOP for things like logging, db transaction boundaries and the like. For these things we use annotations and factory classes to give us the instance objects we need or to simply create, commit and rollback database transactions.

Work Queue

The primary way that messages get passed from client to Active Service is via work queue. Messages from the client get enqueued onto the appropriate queue (via the gateway) and the Active Service acts like a works, popping the messages off of the queues and processing them one-by-one.

Timers

There are a variety of time-based processing that occurs in the sync engine. We use the Spring Framework to schedule and maintain the thread pool necessary for executing these tasks. An example, is the update table integration that kicks off every 5 seconds and polls the database for new updates.