package fr.openwide.core.jpa.externallinkchecker.business.service; import java.util.Collection; import java.util.Map; import java.util.concurrent.Callable; import org.hibernate.FlushMode; import org.hibernate.Session; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.TransactionCallback; import org.springframework.transaction.support.TransactionTemplate; import fr.openwide.core.jpa.exception.SecurityServiceException; import fr.openwide.core.jpa.exception.ServiceException; import fr.openwide.core.jpa.externallinkchecker.business.model.ExternalLinkWrapper; import fr.openwide.core.jpa.util.EntityManagerUtils; import fr.openwide.core.spring.util.SpringBeanUtils; public class ExternalLinkCheckByDomainTask implements Callable<Void> { private static final Logger LOGGER = LoggerFactory.getLogger(ExternalLinkCheckByDomainTask.class); private static final int SESSION_LIMIT = 1000; @Autowired private IExternalLinkCheckerService linkCheckerService; @Autowired private PlatformTransactionManager transactionManager; @Autowired private EntityManagerUtils entityManagerUtils; @Autowired private IExternalLinkWrapperService externalLinkWrapperService; private Map<io.mola.galimatias.URL, Collection<Long>> urlToIdsMap; public ExternalLinkCheckByDomainTask(ApplicationContext applicationContext, Map<io.mola.galimatias.URL, Collection<Long>> urlToIdsMap) { this.urlToIdsMap = urlToIdsMap; SpringBeanUtils.autowireBean(applicationContext, this); } @Override public Void call() throws Exception { TransactionTemplate template = new TransactionTemplate(transactionManager); return template.execute(new TransactionCallback<Void>() { @Override public Void doInTransaction(TransactionStatus status) { Session session = entityManagerUtils.getEntityManager().unwrap(Session.class); session.setFlushMode(FlushMode.COMMIT); int count = 0; for (Map.Entry<io.mola.galimatias.URL, Collection<Long>> urlToIdsEntry : urlToIdsMap.entrySet()) { // We flush the session to avoid a memory overhead if there is a huge amount of links within the same domain if (count >= SESSION_LIMIT) { session.flush(); session.clear(); count = 0; } io.mola.galimatias.URL url = urlToIdsEntry.getKey(); try { Collection<ExternalLinkWrapper> links = externalLinkWrapperService.listByIds(urlToIdsEntry.getValue()); linkCheckerService.checkLinksWithSameUrl(url, links); count += links.size(); } catch (RuntimeException | ServiceException | SecurityServiceException e) { LOGGER.error("An error occurred while checking links", e); } } return null; } }); } }