r1993 - in trunk: wao-services/src/main/java/fr/ifremer/wao/services/service wao-web/src/main/java/fr/ifremer/wao/web
Author: bleny Date: 2014-06-04 16:29:43 +0200 (Wed, 04 Jun 2014) New Revision: 1993 Url: http://forge.codelutin.com/projects/wao/repository/revisions/1993 Log: introduce CacheInvalidationTopiaEntityListener Added: trunk/wao-web/src/main/java/fr/ifremer/wao/web/CacheInvalidationTopiaEntityListener.java Modified: trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/BoatsFilterValues.java trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/ObsMerSamplingPlan.java trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/ObsMerSamplingPlanBuilder.java trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/ObsMerSamplingPlanService.java trunk/wao-web/src/main/java/fr/ifremer/wao/web/DefaultWaoApplicationContext.java Modified: trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/BoatsFilterValues.java =================================================================== --- trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/BoatsFilterValues.java 2014-06-04 08:12:57 UTC (rev 1992) +++ trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/BoatsFilterValues.java 2014-06-04 14:29:43 UTC (rev 1993) @@ -31,7 +31,9 @@ import fr.ifremer.wao.entity.ShipOwner; import fr.ifremer.wao.entity.TerrestrialLocation; +import java.util.HashSet; import java.util.Locale; +import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; @@ -58,6 +60,8 @@ protected SortedSet<FilterOption> boats = new TreeSet<>(); + protected Set<String> boatIds = new HashSet<>(); + public BoatsFilterValues(Locale locale, ObsProgram obsProgram, Optional<String> optionalCompanyId) { super(locale); this.elligibleForSampleRowsFilterValues = new SampleRowsFilterValues(locale, obsProgram, optionalCompanyId); @@ -100,6 +104,8 @@ elligibleForSampleRowsFilterValues.addSampleRow(sampleRow); } } + + boatIds.add(boat.getTopiaId()); } public SampleRowsFilterValues getElligibleForSampleRowsFilterValues() { @@ -156,4 +162,8 @@ copyProperty(copy, propertyName); return copy; } + + public Set<String> getBoatIds() { + return boatIds; + } } Modified: trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/ObsMerSamplingPlan.java =================================================================== --- trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/ObsMerSamplingPlan.java 2014-06-04 08:12:57 UTC (rev 1992) +++ trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/ObsMerSamplingPlan.java 2014-06-04 14:29:43 UTC (rev 1993) @@ -42,6 +42,7 @@ import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Set; public class ObsMerSamplingPlan implements Iterable<ObsMerSamplingPlan.ObsMerSamplingPlanFacadePart>, Serializable { @@ -93,6 +94,11 @@ */ protected SampleRowsFilterValues filterValues; + /** + * Ids of all the sample rows included in this sampling plan. + */ + protected Set<String> sampleRowIds; + public ObsMerSamplingPlan(List<Date> months, Collection<ObsMerSamplingPlanFacadePart> facadeParts, Map<Date, ObsMerSamplingPlanStatistics> totalsPerMonth, @@ -100,7 +106,8 @@ Double observationTimesInDaysTotalExpected, Long observationTimesInDaysTotalReal, Long observationTimesInDaysTotalEstimated, - SampleRowsFilterValues filterValues) { + SampleRowsFilterValues filterValues, + Set<String> sampleRowIds) { this.months = months; this.facades = facadeParts; this.totalsPerMonth = totalsPerMonth; @@ -109,8 +116,13 @@ this.observationTimesInDaysTotalReal = observationTimesInDaysTotalReal; this.observationTimesInDaysTotalEstimated = observationTimesInDaysTotalEstimated; this.filterValues = filterValues; + this.sampleRowIds = sampleRowIds; } + public Set<String> getSampleRowIds() { + return sampleRowIds; + } + @Override public Iterator<ObsMerSamplingPlanFacadePart> iterator() { return facades.iterator(); Modified: trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/ObsMerSamplingPlanBuilder.java =================================================================== --- trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/ObsMerSamplingPlanBuilder.java 2014-06-04 08:12:57 UTC (rev 1992) +++ trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/ObsMerSamplingPlanBuilder.java 2014-06-04 14:29:43 UTC (rev 1993) @@ -36,9 +36,11 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Date; +import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Set; import java.util.TreeMap; /** @@ -63,6 +65,11 @@ protected SampleRowsFilterValues sampleRowsFilterValues; /** + * Ids of all the sample rows included in this sampling plan. + */ + protected Set<String> sampleRowIds; + + /** * List of month computed from the filter. */ protected List<Date> months; @@ -140,6 +147,7 @@ SampleRowsFilter sampleRowsFilter) { this.sampleRowsFilter = sampleRowsFilter; this.sampleRowsFilterValues = new SampleRowsFilterValues(locale, ObsProgram.OBSMER, optionalCompanyId); + this.sampleRowIds = new HashSet<>(); this.facadeMap = new TreeMap<>(); this.observationTimesInDaysTotalExpected = new MutableDouble(); this.observationTimesInDaysTotalReal = new MutableLong(); @@ -191,6 +199,8 @@ sampleRowsFilterValues.addSampleRow(sampleRow); + sampleRowIds.add(sampleRow.getTopiaId()); + return this; } @@ -233,7 +243,8 @@ observationTimesInDaysTotalExpected.toDouble(), observationTimesInDaysTotalReal.toLong(), observationTimesInDaysTotalEstimated.toLong(), - sampleRowsFilterValues); + sampleRowsFilterValues, + sampleRowIds); return result; } Modified: trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/ObsMerSamplingPlanService.java =================================================================== --- trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/ObsMerSamplingPlanService.java 2014-06-04 08:12:57 UTC (rev 1992) +++ trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/ObsMerSamplingPlanService.java 2014-06-04 14:29:43 UTC (rev 1993) @@ -364,28 +364,8 @@ } commit(); - if (updateSampleRowCommand.isCreation()) { - invalidateCachesForAllSampleRows(); - } else { - invalidateCachesForSampleRow(sampleRow); - } - } - protected void invalidateCachesForAllSampleRows() { - serviceContext.getSamplingPlansCache().invalidateAll(); - } - - protected void invalidateCachesForSampleRow(SampleRow sampleRow) { - Set<SamplingPlanCacheKey> toInvalidate = new HashSet<>(); - Cache<SamplingPlanCacheKey, ObsMerSamplingPlan> samplingPlansCache = serviceContext.getSamplingPlansCache(); - for (Map.Entry<SamplingPlanCacheKey, ObsMerSamplingPlan> entry : samplingPlansCache.asMap().entrySet()) { - entry.getValue().getFilterValues().getSampleRowCodes().contains(sampleRow.getCode()); - toInvalidate.add(entry.getKey()); - } - samplingPlansCache.invalidateAll(); - } - public SampleRow getSampleRow(String sampleRowId) { SampleRow sampleRow = getSampleRowDao().findByTopiaId(sampleRowId); @@ -407,8 +387,6 @@ commit(); - invalidateCachesForSampleRow(sampleRow); - } public List<SampleRow> getSamplingPlanRows(SampleRowsFilter sampleRowsFilter) { @@ -572,8 +550,6 @@ commit(); - invalidateCachesForAllSampleRows(); - } protected ImportModel<SampleRow> newSamplingPlanImportModel(AuthenticatedWaoUser authenticatedWaoUser) { @@ -822,8 +798,6 @@ } } - invalidateCachesForSampleRow(sampleRow); - } public List<SampleRow> getUnfinishedSampleRows(AuthenticatedWaoUser authenticatedWaoUser, String companyId) { Added: trunk/wao-web/src/main/java/fr/ifremer/wao/web/CacheInvalidationTopiaEntityListener.java =================================================================== --- trunk/wao-web/src/main/java/fr/ifremer/wao/web/CacheInvalidationTopiaEntityListener.java (rev 0) +++ trunk/wao-web/src/main/java/fr/ifremer/wao/web/CacheInvalidationTopiaEntityListener.java 2014-06-04 14:29:43 UTC (rev 1993) @@ -0,0 +1,141 @@ +package fr.ifremer.wao.web; + +import com.google.common.cache.Cache; +import fr.ifremer.wao.entity.Boat; +import fr.ifremer.wao.entity.Contact; +import fr.ifremer.wao.entity.ElligibleBoat; +import fr.ifremer.wao.entity.SampleRow; +import fr.ifremer.wao.services.service.BoatsFilterValues; +import fr.ifremer.wao.services.service.BoatsFilterValuesCacheKey; +import fr.ifremer.wao.services.service.ObsMerSamplingPlan; +import fr.ifremer.wao.services.service.SamplingPlanCacheKey; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.topia.persistence.TopiaEntity; +import org.nuiton.topia.persistence.event.TopiaEntityEvent; +import org.nuiton.topia.persistence.event.TopiaEntityListener; +import org.nuiton.topia.persistence.event.TopiaTransactionEvent; +import org.nuiton.topia.persistence.event.TopiaTransactionListener; + +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +/** + * Avec ce listener, on scrute ce qu'il se passe sur l'application pour invalider les caches + * qu'il faut. + */ +public class CacheInvalidationTopiaEntityListener implements TopiaEntityListener, TopiaTransactionListener { + + private static final Log log = LogFactory.getLog(CacheInvalidationTopiaEntityListener.class); + + protected Cache<SamplingPlanCacheKey, ObsMerSamplingPlan> samplingPlansCache; + + protected Cache<BoatsFilterValuesCacheKey, BoatsFilterValues> boatsFilterValuesCache; + + protected Set<String> dirtySampleRowIds = new HashSet<>(); + + protected Set<String> dirtyBoatIds = new HashSet<>(); + + protected boolean invalidateAllSampleRows = false; + + protected boolean invalidateAllBoats = false; + + public CacheInvalidationTopiaEntityListener( + Cache<SamplingPlanCacheKey, ObsMerSamplingPlan> samplingPlansCache, + Cache<BoatsFilterValuesCacheKey, BoatsFilterValues> boatsFilterValuesCache) { + this.samplingPlansCache = samplingPlansCache; + this.boatsFilterValuesCache = boatsFilterValuesCache; + } + + @Override + public void create(TopiaEntityEvent event) { + TopiaEntity entity = event.getEntity(); + if (entity instanceof SampleRow) { + invalidateAllSampleRows = true; + } else if (entity instanceof ElligibleBoat) { + ElligibleBoat elligibleBoat = (ElligibleBoat) entity; + dirtyBoatIds.add(elligibleBoat.getBoat().getTopiaId()); + } else if (entity instanceof Boat) { + invalidateAllBoats = true; + } else if (entity instanceof Contact) { + Contact contact = (Contact) entity; + dirtyBoatIds.add(contact.getBoat().getTopiaId()); + dirtySampleRowIds.add(contact.getSampleRow().getTopiaId()); + } + } + + @Override + public void load(TopiaEntityEvent event) { + + } + + @Override + public void update(TopiaEntityEvent event) { + TopiaEntity entity = event.getEntity(); + if (entity instanceof SampleRow) { + dirtySampleRowIds.add(entity.getTopiaId()); + } else if (entity instanceof Boat) { + dirtyBoatIds.add(entity.getTopiaId()); + } else if (entity instanceof Contact) { + Contact contact = (Contact) entity; + dirtyBoatIds.add(contact.getBoat().getTopiaId()); + dirtySampleRowIds.add(contact.getSampleRow().getTopiaId()); + } + } + + @Override + public void delete(TopiaEntityEvent event) { + TopiaEntity entity = event.getEntity(); + if (entity instanceof SampleRow) { + samplingPlansCache.invalidateAll(); + } else if (entity instanceof Contact) { + Contact contact = (Contact) entity; + dirtyBoatIds.add(contact.getBoat().getTopiaId()); + dirtySampleRowIds.add(contact.getSampleRow().getTopiaId()); + } + } + + @Override + public void commit(TopiaTransactionEvent event) { + if (log.isTraceEnabled()) { + log.trace("will commit for entities " + event.getEntities()); + } + if (invalidateAllSampleRows || dirtySampleRowIds.size() > 20) { + samplingPlansCache.invalidateAll(); + } else { + Set<SamplingPlanCacheKey> samplingPlansCacheKeysToInvalidate = new HashSet<>(); + for (Map.Entry<SamplingPlanCacheKey, ObsMerSamplingPlan> entry : samplingPlansCache.asMap().entrySet()) { + if (CollectionUtils.containsAny(entry.getValue().getSampleRowIds(), dirtySampleRowIds)) { + samplingPlansCacheKeysToInvalidate.add(entry.getKey()); + } + } + samplingPlansCache.invalidateAll(samplingPlansCacheKeysToInvalidate); + } + if (invalidateAllBoats || dirtyBoatIds.size() > 20) { + boatsFilterValuesCache.invalidateAll(); + } else { + Set<BoatsFilterValuesCacheKey> boatsFilterValuesCacheKeysToInvalidate = new HashSet<>(); + for (Map.Entry<BoatsFilterValuesCacheKey, BoatsFilterValues> entry : boatsFilterValuesCache.asMap().entrySet()) { + if (CollectionUtils.containsAny(entry.getValue().getBoatIds(), dirtyBoatIds)) { + boatsFilterValuesCacheKeysToInvalidate.add(entry.getKey()); + } + } + boatsFilterValuesCache.invalidateAll(boatsFilterValuesCacheKeysToInvalidate); + } + clear(); + } + + @Override + public void rollback(TopiaTransactionEvent event) { + clear(); + } + + protected void clear() { + dirtySampleRowIds.clear(); + dirtyBoatIds.clear(); + invalidateAllSampleRows = false; + invalidateAllBoats = false; + } +} Modified: trunk/wao-web/src/main/java/fr/ifremer/wao/web/DefaultWaoApplicationContext.java =================================================================== --- trunk/wao-web/src/main/java/fr/ifremer/wao/web/DefaultWaoApplicationContext.java 2014-06-04 08:12:57 UTC (rev 1992) +++ trunk/wao-web/src/main/java/fr/ifremer/wao/web/DefaultWaoApplicationContext.java 2014-06-04 14:29:43 UTC (rev 1993) @@ -141,6 +141,12 @@ WaoTopiaPersistenceContext persistenceContext = getTopiaApplicationContext().newPersistenceContext(); + CacheInvalidationTopiaEntityListener cacheInvalidationTopiaEntityListener = + new CacheInvalidationTopiaEntityListener(getSamplingPlansCache(), getBoatsFilterValuesCache()); + + persistenceContext.getTopiaFiresSupport().addTopiaEntityListener(cacheInvalidationTopiaEntityListener); + persistenceContext.getTopiaFiresSupport().addTopiaTransactionListener(cacheInvalidationTopiaEntityListener); + return persistenceContext; }
participants (1)
-
bleny@users.forge.codelutin.com