diff --git a/.classpath b/.classpath deleted file mode 100644 index b10b8d9..0000000 --- a/.classpath +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..df4afe9 --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__junit_junit_4_11.xml b/.idea/libraries/Gradle__junit_junit_4_11.xml new file mode 100644 index 0000000..dc26b34 --- /dev/null +++ b/.idea/libraries/Gradle__junit_junit_4_11.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_hamcrest_hamcrest_core_1_3.xml b/.idea/libraries/Gradle__org_hamcrest_hamcrest_core_1_3.xml new file mode 100644 index 0000000..8262f72 --- /dev/null +++ b/.idea/libraries/Gradle__org_hamcrest_hamcrest_core_1_3.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml new file mode 100644 index 0000000..e96534f --- /dev/null +++ b/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.project b/.project deleted file mode 100644 index 0692e5b..0000000 --- a/.project +++ /dev/null @@ -1,17 +0,0 @@ - - - actor - - - - - - org.eclipse.jdt.core.javabuilder - - - - - - org.eclipse.jdt.core.javanature - - diff --git a/README.md b/README.md index 16bc13e..5f50277 100644 --- a/README.md +++ b/README.md @@ -1,39 +1,6 @@ actor ===== -A java actor library with linked and priority queue support. +A one file java actor library. -To produce a jar file simply run ant. - - package com.benbria.actor; - - public class ActorExample { - public static void main(String[] args) throws InterruptedException { - Actor actor = ThreadActor.spawn(new Behaviour() { - @Override - public boolean receive(Actor self, String msg) { - System.out.println("Got: " + msg); - return !msg.equals("stop"); - } - - @Override - public void exception(Actor self, Exception e) {} - }); - - actor.send("hello"); - actor.send("world"); - Thread.sleep(1000); - actor.send("stop"); - } - } - -Output: -
-Got: hello
-Got: world
-
- -License -- - -MIT +This is a simplified version of \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..95dc6e4 --- /dev/null +++ b/build.gradle @@ -0,0 +1,8 @@ +apply plugin: 'java' +repositories { + jcenter() +} + +dependencies { + testCompile 'junit:junit:4.11' +} diff --git a/build.xml b/build.xml deleted file mode 100644 index ceec359..0000000 --- a/build.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/lib/junit-4.8.1.jar b/lib/junit-4.8.1.jar deleted file mode 100644 index 524cd65..0000000 Binary files a/lib/junit-4.8.1.jar and /dev/null differ diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..bcca799 --- /dev/null +++ b/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'actor' diff --git a/src/com/benbria/actor/Actor.java b/src/com/benbria/actor/Actor.java deleted file mode 100644 index 64e0898..0000000 --- a/src/com/benbria/actor/Actor.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.benbria.actor; - -/** - * @author Eric des Courtis - * - */ - -/* - The MIT License (MIT) - - Copyright (c) 2013 Benbria Corporation - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. -*/ - - -public interface Actor extends Runnable { - public abstract void send(T msg) throws InterruptedException; -} \ No newline at end of file diff --git a/src/com/benbria/actor/Behaviour.java b/src/com/benbria/actor/Behaviour.java deleted file mode 100644 index d7b4416..0000000 --- a/src/com/benbria/actor/Behaviour.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.benbria.actor; - -/** - * @author Eric des Courtis - * - */ - -/* - The MIT License (MIT) - - Copyright (c) 2013 Benbria Corporation - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. -*/ - - -public interface Behaviour { - boolean receive(Actor self, T msg); - void exception(Actor actor, Exception e); -} diff --git a/src/com/benbria/actor/ThreadActor.java b/src/com/benbria/actor/ThreadActor.java deleted file mode 100644 index 54e9368..0000000 --- a/src/com/benbria/actor/ThreadActor.java +++ /dev/null @@ -1,104 +0,0 @@ -package com.benbria.actor; - -/** - * @author Eric des Courtis - * - */ - -/* - The MIT License (MIT) - - Copyright (c) 2013 Benbria Corporation - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - */ - -import java.util.Comparator; -import java.util.concurrent.ArrayBlockingQueue; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.PriorityBlockingQueue; - -public final class ThreadActor implements Actor { - private final BlockingQueue queue; - private final Behaviour behaviour; - - public static Actor create(Behaviour behaviour) { - return new ThreadActor(behaviour); - } - - public static Actor spawn(Behaviour behaviour){ - Actor a = create(behaviour); - new Thread(a).start(); - return a; - } - - public static Actor createWithArrayBlockingQueue(Behaviour behaviour, int capacity) { - return new ThreadActor(behaviour, new ArrayBlockingQueue(capacity)); - } - - public static Actor spawnWithArrayBlockingQueue(Behaviour behaviour, int capacity){ - Actor a = createWithArrayBlockingQueue(behaviour, capacity); - new Thread(a).start(); - return a; - } - - public static Actor createWithPriorityQueue(Behaviour behaviour, int initialCapacity, Comparator comparator) { - return new ThreadActor(behaviour, new PriorityBlockingQueue(initialCapacity, comparator)); - } - - public static Actor spawnWithPriorityQueue(Behaviour behaviour, int initialCapacity, Comparator comparator){ - Actor a = createWithPriorityQueue(behaviour, initialCapacity, comparator); - new Thread(a).start(); - return a; - } - - public static Actor createWithPriorityQueue(Behaviour behaviour, Comparator comparator) { - return createWithPriorityQueue(behaviour, 10, comparator); - } - - public static Actor spawnWithPriorityQueue(Behaviour behaviour, Comparator comparator){ - Actor a = createWithPriorityQueue(behaviour, comparator); - new Thread(a).start(); - return a; - } - - private ThreadActor(Behaviour behaviour, BlockingQueue queue) { - this.behaviour = behaviour; - this.queue = queue; - } - - private ThreadActor(Behaviour behaviour) { - this(behaviour, new LinkedBlockingQueue()); - } - - public void run() { - try { - while( behaviour.receive(this, queue.take()) ){}; - } catch (Exception ex) { - behaviour.exception(this, ex); - } - } - - @Override - public void send(T msg) throws InterruptedException { - queue.put(msg); - } - -} diff --git a/src/com/benbria/actor/behaviours/BroadcastBehaviour.java b/src/com/benbria/actor/behaviours/BroadcastBehaviour.java deleted file mode 100644 index 97f709e..0000000 --- a/src/com/benbria/actor/behaviours/BroadcastBehaviour.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.benbria.actor.behaviours; - -/** - * @author Eric des Courtis - * - */ - -/* - The MIT License (MIT) - - Copyright (c) 2013 Benbria Corporation - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - */ - -import java.util.LinkedList; -import java.util.List; - -import com.benbria.actor.Actor; -import com.benbria.actor.Behaviour; - -public class BroadcastBehaviour implements Behaviour { - private List> behaviourList = new LinkedList>(); - - public BroadcastBehaviour(List> behaviourList) { - this.behaviourList.addAll(behaviourList); - } - - @Override - public boolean receive(Actor self, T msg) { - boolean result = true; - for(Behaviour behaviour: behaviourList){ - result &= behaviour.receive(self, msg); - } - return result; - } - - @Override - public void exception(Actor self, Exception e) { - for(Behaviour behaviour: behaviourList){ - behaviour.exception(self, e); - } - } -} diff --git a/src/com/benbria/actor/behaviours/LoggingBehaviour.java b/src/com/benbria/actor/behaviours/LoggingBehaviour.java deleted file mode 100644 index 1b9729c..0000000 --- a/src/com/benbria/actor/behaviours/LoggingBehaviour.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.benbria.actor.behaviours; - -/** - * @author Eric des Courtis - * - */ - -/* - The MIT License (MIT) - - Copyright (c) 2013 Benbria Corporation - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - */ - - -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; -import java.util.logging.Logger; - -import com.benbria.actor.Actor; -import com.benbria.actor.Behaviour; - -public final class LoggingBehaviour implements -Behaviour { - private final static Logger logger = Logger.getLogger(LoggingBehaviour.class.getName()); - @Override - public boolean receive(Actor self, T msg) { - logger.info(self + ": " + msg); - return true; - } - - @Override - public void exception(Actor self, Exception e) { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - e.printStackTrace(new PrintStream(baos, true)); - logger.severe(self + ": " + baos.toString()); - } -} diff --git a/src/com/benbria/actor/behaviours/NullBehaviour.java b/src/com/benbria/actor/behaviours/NullBehaviour.java deleted file mode 100644 index e13f589..0000000 --- a/src/com/benbria/actor/behaviours/NullBehaviour.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.benbria.actor.behaviours; - -/** - * @author Eric des Courtis - * - */ - -/* - The MIT License (MIT) - - Copyright (c) 2013 Benbria Corporation - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - */ - -import com.benbria.actor.Actor; -import com.benbria.actor.Behaviour; - -public final class NullBehaviour implements -Behaviour { - @Override - public boolean receive(Actor self, T msg) { - return true; - } - - @Override - public void exception(Actor actor, Exception e) { } -} \ No newline at end of file diff --git a/src/com/benbria/actor/tests/ThreadActorTests.java b/src/com/benbria/actor/tests/ThreadActorTests.java deleted file mode 100644 index f22f17d..0000000 --- a/src/com/benbria/actor/tests/ThreadActorTests.java +++ /dev/null @@ -1,101 +0,0 @@ -/** - * - */ -package com.benbria.actor.tests; - -import static org.junit.Assert.*; - -import org.junit.Test; - -import com.benbria.actor.Actor; -import com.benbria.actor.Behaviour; -import com.benbria.actor.ThreadActor; - -/** - * @author Eric des Courtis - * - */ - -/* - The MIT License (MIT) - - Copyright (c) 2013 Benbria Corporation - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - */ - -public class ThreadActorTests { - class ExceptionGeneratingBehaviour implements Behaviour { - private boolean exceptionOccurred = false; - public boolean hasExceptionOccurred() { - return exceptionOccurred; - } - - @Override - public boolean receive(Actor self, String msg) { - throw new RuntimeException("evil"); - } - - @Override - public void exception(Actor self, Exception e) { - exceptionOccurred = true; - } - } - - @Test - public void testException() { - ExceptionGeneratingBehaviour behaviour = new ExceptionGeneratingBehaviour(); - Actor a = ThreadActor.spawn(behaviour); - try { - a.send("hello"); - Thread.sleep(1000); - } catch (InterruptedException e) { } - assertTrue(behaviour.hasExceptionOccurred()); - } - - class ReceivedMessageCheckingBehaviour implements Behaviour { - private String msg; - - @Override - public boolean receive(Actor self, String msg) { - this.msg = msg; - return false; - } - - public String getMsg() { - return msg; - } - - @Override - public void exception(Actor self, Exception e) { - assertTrue(false); - } - } - - @Test - public void testSend() { - ReceivedMessageCheckingBehaviour behaviour = new ReceivedMessageCheckingBehaviour(); - Actor a = ThreadActor.spawn(behaviour); - try { - a.send("testing"); - Thread.sleep(1000); - } catch (InterruptedException e) { } - assertEquals("testing", behaviour.getMsg()); - } -} diff --git a/src/main/java/com/benbria/actor/Actor.java b/src/main/java/com/benbria/actor/Actor.java new file mode 100644 index 0000000..1acdc71 --- /dev/null +++ b/src/main/java/com/benbria/actor/Actor.java @@ -0,0 +1,84 @@ +package com.benbria.actor; + +/** + * This is a simplified version of + */ + +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; + +public class Actor implements Runnable { + enum STATE { + alive, dead + } + + @SuppressWarnings("serial") + public static class DeadException extends Exception{}; + + interface Behavior { + /** + * @param self + * @param msg + * @return - `false` - stop the actor; `true` - continue + */ + public abstract boolean onReceive(Actor self, Msg msg); + + /** + * DeadException thrown by the actor `self`. The thread is dead. + * + * @param self + * @param e + */ + public abstract void onException(Actor self, Exception e); + } + + private final BlockingQueue queue; + private final Behavior behavior; + private STATE state; + + public static Actor create(Behavior behavior) { + return new Actor(behavior); + } + + public static Actor createAndStart(Behavior behavior) { + Actor a = create(behavior); + new Thread(a).start(); + return a; + } + + private Actor(Behavior behavior, BlockingQueue queue) { + this.state = STATE.alive; + this.behavior = behavior; + this.queue = queue; + } + + private Actor(Behavior behavior) { + this(behavior, new LinkedBlockingQueue()); + } + + public void run() { + try { + while (behavior.onReceive(this, queue.take())) {} + } + catch (InterruptedException ex) { + behavior.onException(this, ex); + } + this.state = STATE.dead; + this.queue.clear(); + } + + /** + * Try to send "msg" to the actor + * + * @param msg + * @return true if successfully sent, false - if not + * @throws DeadException - if the actor is already dead + */ + public boolean send(Msg msg) throws DeadException { + if (state == STATE.dead) { + // System.out.println("-- cleaning the queue ["+queue.size()+"]"); + throw new DeadException(); + } + return queue.offer(msg); + } +} diff --git a/src/test/java/com/benbria/actor/ActorTest.java b/src/test/java/com/benbria/actor/ActorTest.java new file mode 100644 index 0000000..cce39c7 --- /dev/null +++ b/src/test/java/com/benbria/actor/ActorTest.java @@ -0,0 +1,37 @@ +package com.benbria.actor; + +import org.junit.Test; + +import static org.junit.Assert.assertTrue; + +public class ActorTest { + int numberOfMessagesToAccept = 10; + @Test + public void testCreateAndStart() { + Actor myActor = Actor.createAndStart(new Actor.Behavior() { + int counter = 0; + public boolean onReceive(Actor < String > self, String msg){ + counter++; + System.out.println(counter+". "+msg); + return (counter < numberOfMessagesToAccept); + } + + @Override + public void onException(Actor self, Exception e) { + System.out.println("Ehhh"); + } + }); + + int count = 0; + while (true) { + try { + myActor.send("toto"); + count++; + } catch (Actor.DeadException e) { + assertTrue(count > numberOfMessagesToAccept); + return; + } + } + } + +} \ No newline at end of file