/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package com.smartitengineering.user.service.impl.cache; import com.google.inject.Inject; import com.google.inject.name.Named; import com.smartitengineering.dao.common.cache.CacheServiceProvider; import com.smartitengineering.dao.common.cache.Lock; import com.smartitengineering.dao.common.cache.Mutex; import com.smartitengineering.dao.common.cache.impl.CacheAPIFactory; import com.smartitengineering.user.domain.Person; import com.smartitengineering.user.filter.PersonFilter; import com.smartitengineering.user.service.PersonService; import java.util.Collection; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * * @author imyousuf */ public class PersonServiceCacheImpl implements PersonService { @Inject @Named("primaryService") private PersonService primaryService; @Inject private CacheServiceProvider<Long, Person> cacheProvider; @Inject private CacheServiceProvider<String, Long> nameCacheProvider; private transient final Logger logger = LoggerFactory.getLogger(getClass()); private final Mutex<Long> mutex = CacheAPIFactory.<Long>getMutex(); @Override public void save(Person person) { //Simply delegate primaryService.save(person); } @Override public void update(Person person) { //First update then delete if update successful! try { primaryService.update(person); expireFromCache(person); } catch (RuntimeException exception) { logger.info("Could not update thus invalidate cache!", exception); throw exception; } } @Override public void delete(Person person) { //First update then delete if update successful! try { primaryService.delete(person); expireFromCache(person); } catch (RuntimeException exception) { logger.info("Could not update thus invalidate cache!", exception); throw exception; } } @Override public Person getById(Long id) { //Check cache first Person person = cacheProvider.retrieveFromCache(id); if (person != null) { return person; } else { try { Lock<Long> lock = mutex.acquire(id); person = cacheProvider.retrieveFromCache(id); if (person != null) { return person; } person = primaryService.getById(id); if (person != null) { putToCache(person); } mutex.release(lock); } catch (Exception ex) { logger.warn("Could not do cache lookup!", ex); } return person; } } @Override public Person getPersonByEmail(String email) { Long id = nameCacheProvider.retrieveFromCache(getNameCacheKey(email)); if (id != null) { Person person = getById(id); if (person != null) { return person; } } return primaryService.getPersonByEmail(email); } @Override public Collection<Person> search(PersonFilter filter) { return primaryService.search(filter); } @Override public Collection<Person> getAllPerson() { return primaryService.getAllPerson(); } @Override public void validatePerson(Person person) { primaryService.validatePerson(person); } private String getNameCacheKey(Person person) { final String email = person.getPrimaryEmail(); return getNameCacheKey(email); } protected String getNameCacheKey(final String email) { return new StringBuilder("person:").append(email).toString(); } private void putToCache(Person person) { cacheProvider.putToCache(person.getId(), person); nameCacheProvider.putToCache(getNameCacheKey(person), person.getId()); } private void expireFromCache(Person person) { if (cacheProvider.containsKey(person.getId())) { Person oldPerson = getById(person.getId()); if (oldPerson != null) { nameCacheProvider.expireFromCache(getNameCacheKey(oldPerson)); } cacheProvider.expireFromCache(person.getId()); } } }