All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.dooapp.gaedo.prevalence.space.basic.SimpleExecutionSpace Maven / Gradle / Ivy

Go to download

A gaedo-inspired prevalence layer and the associated service, for making the most gaedo-efficient use of that layer

There is a newer version: 1.0.16
Show newest version
package com.dooapp.gaedo.prevalence.space.basic;

import java.io.File;
import java.io.Serializable;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;

import com.dooapp.gaedo.prevalence.space.Command;
import com.dooapp.gaedo.prevalence.space.ExecutionSpace;
import com.dooapp.gaedo.prevalence.space.PrevalenceException;
import com.dooapp.gaedo.prevalence.space.StorageSpace;

public class SimpleExecutionSpace implements
		ExecutionSpace {
	/**
	 * Thread factory creating only one thread
	 * 
	 * @author ndx
	 * 
	 */
	private static class UniThread implements ThreadFactory {
		private boolean created = false;

		@Override
		public Thread newThread(Runnable r) {
			if (!created) {
				synchronized (this) {
					if (!created) {
						created = true;
						return new Thread(r);
					}
				}
			}
			return null;
		}

	}

	private static class CommandExecutionException extends PrevalenceException {

		public CommandExecutionException(Command command, Exception e) {
			super("unable to execute command " + command, e);
		}

	}

	/**
	 * Command executor runs command on space and memorizes it for later use
	 * 
	 * @author ndx
	 * 
	 * @param 
	 */
	private class CommandExecutor implements
			Callable {
		private final Command toExecute;

		public CommandExecutor(Command toExecute) {
			super();
			this.toExecute = toExecute;
		}

		@Override
		public CommandReturnType call() throws Exception {
			CommandReturnType toReturn = toExecute.execute(storage);
			commandLogger.logCommand(toExecute);
			return toReturn;
		}
	}

	/**
	 * Used storage space
	 */
	private StorageSpace storage;

	/**
	 * Executor service used to ensure all commands are executed in the right
	 * order.
	 */
	private ScheduledExecutorService executor;

	private SpacePersister commandLogger;

	/**
	 * Default constructor providing sensible defaults.
	 * 
    *
  • Storage space is a {@link SimpleStorageSpace}
  • *
  • Executor service is a {@link ScheduledThreadPoolExecutor} using as * {@link ThreadFactory} a factory that always return null, to ensure no * thread is created after the first one.
  • *
* * @see SimpleExecutionSpace#SimpleExecutionSpace(StorageSpace, * ExecutorService) */ public SimpleExecutionSpace() { this(new SimpleStorageSpace(), new ScheduledThreadPoolExecutor(1, new UniThread()), new DefaultSpacePersister()); } /** * The easiest to use constructor : it creates a * {@link SimpleExecutionSpace} with a given folder * * @param storageDir * storage directory */ public SimpleExecutionSpace(File storageDir) { this(new SimpleStorageSpace(), new ScheduledThreadPoolExecutor(1, new UniThread()), new DefaultSpacePersister(storageDir)); } /** * Full configurable constructor. Notice that at construction, Three * sophisticated things are done : *
    *
  • Restore storage from its persisted state, if any
  • *
  • Schedule periodic execution of full storage space persistance
  • *
* * @param storageSpace * used storage space. This space is given only as an indication, * as it should theorically be restored from storage by the space * persister * @param executor * used schedulable executor * @param spacePersister * used space persister */ public SimpleExecutionSpace(StorageSpace storageSpace, ScheduledExecutorService executor, SpacePersister spacePersister) { this.executor = executor; this.commandLogger = spacePersister; // Restore space from command logger this.storage = spacePersister.restore(storageSpace); // Now space is restored, install space persister execution mechanisms spacePersister.install(executor, this.storage); // this.storage = spacePersister.restore(this, storageSpace); } /** * Execute given command in the associated {@link #executor} and silently * throws its associated exception (if any) thanks to advices of * http://blog. * developpez.com/adiguba/p8434/java/unchecked-checked-exception/ */ @Override public CommandReturnType execute( Command command) { try { Future futureResult = executor .submit(new CommandExecutor(command)); return futureResult.get(); } catch (InterruptedException e) { throw new CommandExecutionException(command, e); } catch (ExecutionException e) { /* * Inner process failed and must be rethrowed. We cast this * exception as a Runtime one, event if it is not the case, as Java * virtual machine do not handle type checking at runtime, but only * at compile time. */ throw (RuntimeException) e.getCause(); } catch (RuntimeException e) { throw e; } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy