summaryrefslogtreecommitdiff
path: root/src/jvm/clojure/lang/Agent.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/jvm/clojure/lang/Agent.java')
-rw-r--r--src/jvm/clojure/lang/Agent.java40
1 files changed, 36 insertions, 4 deletions
diff --git a/src/jvm/clojure/lang/Agent.java b/src/jvm/clojure/lang/Agent.java
index cc81ec18..5b776a70 100644
--- a/src/jvm/clojure/lang/Agent.java
+++ b/src/jvm/clojure/lang/Agent.java
@@ -17,18 +17,24 @@ import java.util.concurrent.atomic.AtomicReference;
public class Agent implements IRef{
volatile Object state;
+volatile IFn validator = null;
AtomicReference<IPersistentStack> q = new AtomicReference(PersistentQueue.EMPTY);
volatile ISeq errors = null;
-final public static Executor pooledExecutor =
+final public static ExecutorService pooledExecutor =
Executors.newFixedThreadPool(2 + Runtime.getRuntime().availableProcessors());
-final static Executor soloExecutor = Executors.newCachedThreadPool();
+final static ExecutorService soloExecutor = Executors.newCachedThreadPool();
final static ThreadLocal<IPersistentVector> nested = new ThreadLocal<IPersistentVector>();
+public static void shutdown(){
+ soloExecutor.shutdown();
+ pooledExecutor.shutdown();
+}
+
static class Action implements Runnable{
final Agent agent;
final IFn fn;
@@ -102,14 +108,31 @@ static class Action implements Runnable{
}
}
-public Agent(Object state){
+public Agent(Object state) throws Exception{
+ this(state,null);
+}
+
+public Agent(Object state, IFn validator) throws Exception{
+ this.validator = validator;
setState(state);
}
-void setState(Object newState){
+void setState(Object newState) throws Exception{
+ validate(getValidator(),newState);
state = newState;
}
+void validate(IFn vf, Object val){
+ try{
+ if(vf != null)
+ vf.invoke(val);
+ }
+ catch(Exception e)
+ {
+ throw new IllegalStateException("Invalid agent state", e);
+ }
+}
+
public Object get() throws Exception{
if(errors != null)
{
@@ -118,6 +141,15 @@ public Object get() throws Exception{
return state;
}
+public void setValidator(IFn vf){
+ validate(vf,state);
+ validator = vf;
+}
+
+public IFn getValidator(){
+ return validator;
+}
+
public ISeq getErrors(){
return errors;
}