TimerData Aggregator

Requirements

Create a CMR component that will be able to aggregate TimerData objects that are coming from the Agent (both in and outside an invocation) and persists only aggregated data to the database. The aggregation period should be specified in the configuration.

Approach

The Aggregator should hold limited number of aggregation objects, where every aggregation object is created as a copy of original TimerData object and a modified time stamp. If the aggregation period is for example 10s, for each method ident, a aggregation objects should have the time stamps like 12:50:10, 12:50:20, etc, so in the 10 seconds difference. When the new TimerData comes to the Aggregator, the Aggregator checks if the aggregation object for the arriving TimerData is already created. If yes, it simply adds the information from incoming TimerData to the aggregation objects, otherwise, it creates a new aggregation object as described above.

The persistence of objects is done in two ways. First is when the number of aggregation objects is higher than Aggregator's limit, by creating a persistence list from oldest objects and persisting set of "old" objects at the same time. Second is when there is no activity for a specified time period, thus assuming that there is no data coming from the agent any more, Aggregator should persist all aggregation objects that are currently present.

Realization

The implementation is done in class info.novatec.inspectit.cmr.dao.impl.TimerDataAggregator. This class is initialized by Spring with three property values:

Property

Description

aggregationPeriod

Time in milliseconds that defines the aggregation period.

maxElements

Maximum of aggregated objects that should be kept by Aggregator.

cacheCleanSleepingPeriod

Time in milliseconds that thread that is cleaning the Aggregator's cache should sleep.

The Aggregator has three concurrent collections:

1. ConcurrentHashMap for caching the aggregation objects by time stamp and method ident hash combination, and it's fast retrieval.
2. ConcurrentLinkedQueue to keep FIFO order of aggregation objects, so when the number of elements reaches maximum, First In object can be drooped out from both cache map and this list.
3. ConcurrentLinkedQueue (2) for keeping the aggregation objects that are drooped out from Aggregator and are ready for persistence.

The persistence is done by a inner Thread class CacheCleaner. This thread runs occasionally (sleep is defined by cacheCleanSleepingPeriod property) and checks if there was some activity in Aggregator (if new TimerData objects where coming for aggregation). If not, it will persist all the objects in the Aggregator. Furthermore, in every run it will anyway persist all objects that are in persist list.

Testing

Testing of Aggregator is performed in class info.novatec.inspectit.cmr.dao.test.TimerDataAggregatorTest with following tests:

Test

Description

testAggregation

Tests for the validity of aggregation.

testNoSetterInteractions

Verifies the zero interactions with setters of TimerData object passed to the Aggregator.