package org.cryptocoinpartners.module; import java.util.Map; import java.util.concurrent.BlockingQueue; import java.util.concurrent.Callable; import java.util.concurrent.DelayQueue; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingDeque; import javax.inject.Singleton; import javax.persistence.ElementCollection; import org.cryptocoinpartners.schema.EntityBase; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListeningExecutorService; import com.google.common.util.concurrent.MoreExecutors; import com.google.inject.Inject; import com.google.inject.persist.PersistService; @Singleton public class ApplicationInitializer implements Context.AttachListener { private Map<String, String> config; private static ListeningExecutorService insertPool = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(1)); protected static Logger log = LoggerFactory.getLogger("org.cryptocoinpartners.applicationInitalizer"); private static ExecutorService mergeService = Executors.newFixedThreadPool(1); private static ExecutorService deleteService = Executors.newFixedThreadPool(1); private static ExecutorService insertService = Executors.newFixedThreadPool(1); //private static BlockingQueue insertQueue = new DelayQueue(); //private static BlockingQueue mergeQueue = new DelayQueue(); private static LinkedBlockingDeque insertQueue = new LinkedBlockingDeque(); private static LinkedBlockingDeque mergeQueue = new LinkedBlockingDeque(); private static BlockingQueue deleteQueue = new DelayQueue(); // LinkedBlockingQueue<EntityBase[]>(); @Inject ApplicationInitializer(PersistService service) { service.start(); ListenableFuture<String> insertFuture = insertPool.submit(new persistRunnable(insertQueue)); // Future<Void> insertFuture = insertService.submit(new persistRunnable(insertQueue)); Future<Void> mergeFuture = mergeService.submit(new mergeRunnable(mergeQueue)); Future<Void> deleteFuture = deleteService.submit(new deleteRunnable(deleteQueue)); insertFuture.addListener(new insertMointorRunnable(insertFuture), MoreExecutors.sameThreadExecutor()); // try { // insertFuture.get(); //} catch (InterruptedException e) { // Thread.currentThread().interrupt(); // } catch (ExecutionException e) { // System.out.println("** RuntimeException from thread "); // e.getCause().printStackTrace(System.out); // } // insertService.submit(new persistRunnable(insertQueue)); // mergeService.submit(new mergeRunnable(mergeQueue)); // DaoJpa.mergeRunnable // At this point JPA is started and ready. // other application initializations if necessary } protected void setInsertQueue(LinkedBlockingDeque insertQueue) { this.insertQueue = insertQueue; } protected void setMergeQueue(LinkedBlockingDeque mergeQueue) { this.mergeQueue = mergeQueue; } protected void setDeleteQueue(LinkedBlockingDeque deleteQueue) { this.deleteQueue = deleteQueue; } public LinkedBlockingDeque getMergeQueue() { return mergeQueue; } public LinkedBlockingDeque getInsertQueue() { return insertQueue; } public BlockingQueue getDeleteQueue() { return deleteQueue; } public class insertMointorRunnable implements Runnable { private ListenableFuture<String> insertFuture; public insertMointorRunnable(ListenableFuture<String> insertFuture) { this.insertFuture = insertFuture; } @Override public void run() { while (true) try { insertFuture.get(); //...process web site contents } catch (InterruptedException e) { log.error(" " + this.getClass().getSimpleName() + ":run, full stack trace follows:", e); } catch (ExecutionException e) { insertFuture = insertPool.submit(new persistRunnable(insertQueue)); log.error(" " + this.getClass().getSimpleName() + ":run, full stack trace follows:", e); } } } public class persistRunnable implements Callable { private final LinkedBlockingDeque peristQueue; @Override public Void call() { while (true) { try { EntityBase entity = (EntityBase) peristQueue.take(); if (entity.getPeristanceAction() != null) { switch (entity.getPeristanceAction()) { // entity.getDao().persistEntities(entity); case NEW: entity.getDao().persistEntities(entity); break; case MERGE: entity.getDao().mergeEntities(entity); break; case DELETE: entity.getDao().deleteEntities(entity); break; default: entity.getDao().persistEntities(entity); break; } } else entity.getDao().persistEntities(entity); // EntityBase[] entities = peristQueue.take(); // for (EntityBase entity : entities) } catch (Exception | Error e) { log.error(" " + this.getClass().getSimpleName() + ":call, full stack trace follows:", e); // Thread.currentThread().interrupt(); // return null; // supposing there is no cleanup or other stuff to be done } } } public persistRunnable(LinkedBlockingDeque peristQueue) { this.peristQueue = peristQueue; } } public class mergeRunnable implements Callable { private final LinkedBlockingDeque mergeQueue; @Override public Void call() { while (true) { try { EntityBase entity = (EntityBase) mergeQueue.take(); if (entity.getPeristanceAction() != null) { switch (entity.getPeristanceAction()) { case NEW: entity.getDao().persistEntities(entity); break; case MERGE: entity.getDao().mergeEntities(entity); break; case DELETE: entity.getDao().deleteEntities(entity); break; default: entity.getDao().mergeEntities(entity); break; } } else entity.getDao().mergeEntities(entity); } catch (Exception | Error e) { log.error(" " + this.getClass().getSimpleName() + ":call, full stack trace follows:", e); } } } public mergeRunnable(LinkedBlockingDeque mergeQueue) { this.mergeQueue = mergeQueue; } } public class deleteRunnable implements Callable { private final BlockingQueue deleteQueue; @Override public Void call() { while (true) { try { EntityBase entity = (EntityBase) deleteQueue.take(); if (entity.getPeristanceAction() != null) { switch (entity.getPeristanceAction()) { case NEW: entity.getDao().persistEntities(entity); break; case MERGE: entity.getDao().mergeEntities(entity); break; case DELETE: entity.getDao().deleteEntities(entity); break; default: entity.getDao().deleteEntities(entity); break; } } else entity.getDao().deleteEntities(entity); // for (EntityBase entity : entities) // dao.mergeEntities(entities); } catch (Exception | Error e) { log.error(" " + this.getClass().getSimpleName() + ":call, full stack trace follows:", e); } } } public deleteRunnable(BlockingQueue deleteQueue) { this.deleteQueue = deleteQueue; } } @ElementCollection public Map<String, String> getConfig() { return config; } protected void setConfig(Map<String, String> config) { this.config = config; } @Override public void afterAttach(final Context context) { // attach the actual Strategy instead of this StrategyInstance // Set ourselves as the StrategyInstance // context.loadStatements("BasicPortfolioService"); // context.attach("BaseOrderService", new MapConfiguration(config), new Module() // { // @Override // public void configure(Binder binder) { // binder.install(new FactoryModuleBuilder().build(GeneralOrderFactory.class)); // binder.install(new FactoryModuleBuilder().build(SpecificOrderFactory.class)); // } //}); } }