package net.ion.bleujin; import java.util.Date; import java.util.concurrent.Callable; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import junit.framework.TestCase; import net.ion.craken.node.ReadNode; import net.ion.craken.node.ReadSession; import net.ion.craken.node.TransactionJob; import net.ion.craken.node.WriteSession; import net.ion.craken.node.crud.Craken; import net.ion.framework.util.Debug; import net.ion.framework.util.ObjectId; import net.ion.framework.util.RandomUtil; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; public class TestConcurrent extends TestCase { private Craken icraken; @Override protected void setUp() throws Exception { super.setUp(); this.icraken = Craken.inmemoryCreateWithTest() ; } @Override protected void tearDown() throws Exception { icraken.stop(); super.tearDown(); } public void testCDDConcurrent() throws Exception { ExecutorService es = Executors.newCachedThreadPool(); // Executors.newSingleThreadExecutor() ; // ReadSession rsession = icraken.login("test"); Cache<String, FakeTask> tasks = CacheBuilder.newBuilder().maximumSize(100).build(); // rsession.workspace().cddm().add(new CDDHandler() { // @Override // public String pathPattern() { // return "/thoth/{taskid}"; // } // // @Override // public TransactionJob<Void> modified(Map<String, String> rmap, CDDModifiedEvent mevent) { // final String taskId = rmap.get("taskid"); // if (!"cancel".equals(mevent.property("action").asString())) // return null; // try { // Thread.sleep(700 + RandomUtil.nextInt(100)); // } catch (InterruptedException e) { // } // return null; // } // // @Override // public TransactionJob<Void> deleted(Map<String, String> map, CDDRemovedEvent cddremovedevent) { // return null; // } // }); final CountDownLatch cd = new CountDownLatch(30) ; for (int i = 0; i < 30; i++) { final String taskId = i+ "" ; // new ObjectId().toString(); final FakeTask task = new FakeTask(taskId, this); tasks.put(taskId, task); rsession.tran(new TransactionJob<Void>() { @Override public Void handle(WriteSession wsession) throws Exception { wsession.pathBy("/thoth/" + taskId).property("name", "bleujin").property("startdate", new Date().getTime()); return null; } }); es.submit(new Callable<Void>() { public Void call() throws Exception { task.run(); cd.countDown(); return null; } }); } cd.await(20, TimeUnit.SECONDS) ; Debug.line(); icraken.login("test").ghostBy("/thoth").children().debugPrint(); } public void endTask(final String taskId) { try { final ReadSession rsession = icraken.login("test"); // rsession.tranSync(new TransactionJob<Void>() { // @Override // public Void handle(WriteSession wsession) throws Exception { // wsession.pathBy("/thoth/" + taskId).property("action", "cancel"); // return null; // } // }); rsession.tranSync(new TransactionJob<Void>() { @Override public Void handle(WriteSession wsession) throws Exception { boolean removed = wsession.pathBy("/thoth").removeChild(taskId); return null; } }); // rsession.tran(new TransactionJob<Void>() { // @Override // public Void handle(WriteSession wsession) throws Exception { // boolean removed = wsession.pathBy("/thoth").removeChild(taskId); // return null; // } // }); } catch (Exception e) { e.printStackTrace(); } } } class FakeTask implements Runnable { private TestConcurrent parent; private String taskId; public FakeTask(String taskId, TestConcurrent parent) { this.taskId = taskId; this.parent = parent; } @Override public void run() { for (int i = 0; i < RandomUtil.nextInt(10); i++) { if (shutdown) break; try { Thread.sleep(100 + RandomUtil.nextInt(10)); } catch (InterruptedException e) { e.printStackTrace(); } } parent.endTask(taskId); } private boolean shutdown; public boolean isShutdown() { return shutdown; } public void shutdown() { shutdown = true; } }