From 437781b7d61fe8c72120d64f23516ec98efb989d Mon Sep 17 00:00:00 2001 From: Ricardo Mello Date: Wed, 22 Apr 2015 22:58:02 -0300 Subject: [PATCH] Added AnnotationHookProvider --- .../com/ea/orbit/actors/runtime/IRuntime.java | 16 ++++- .../ea/orbit/actors/runtime/Execution.java | 6 +- .../com/ea/orbit/actors/runtime/Hosting.java | 13 +++- .../com/ea/orbit/actors/test/ClientTest.java | 2 +- samples/annotation/README.md | 10 +++ samples/{memoize => annotation}/pom.xml | 6 +- .../annotation/AnnotationHookProvider.java} | 33 +++++----- .../annotation/IAnnotationHandler.java | 44 +++++++++++++ .../annotation/examples/IMemoizeExample.java} | 5 +- .../annotation/examples/IOnlyExample.java | 44 +++++++++++++ .../examples/MemoizeExampleActor.java} | 4 +- .../annotation/examples/OnlyExampleActor.java | 54 +++++++++++++++ .../samples/annotation}/memoize/Memoize.java | 2 +- .../memoize/MemoizeAnnotationHandler.java | 66 +++++++++++++++++++ .../onlyifactivated/OnlyIfActivated.java | 41 ++++++++++++ .../OnlyIfActivatedAnnotationHandler.java | 58 ++++++++++++++++ .../src/main/resources/logback.xml | 0 .../customannotation/AnnotationTest.java} | 61 +++++++++++++---- samples/memoize/README.md | 27 -------- samples/pom.xml | 2 +- samples/trace/pom.xml | 2 +- 21 files changed, 425 insertions(+), 71 deletions(-) create mode 100644 samples/annotation/README.md rename samples/{memoize => annotation}/pom.xml (95%) rename samples/{memoize/src/main/java/com/ea/orbit/samples/memoize/MemoizeHookProvider.java => annotation/src/main/java/com/ea/orbit/samples/annotation/AnnotationHookProvider.java} (66%) create mode 100644 samples/annotation/src/main/java/com/ea/orbit/samples/annotation/IAnnotationHandler.java rename samples/{memoize/src/main/java/com/ea/orbit/samples/memoize/IExample.java => annotation/src/main/java/com/ea/orbit/samples/annotation/examples/IMemoizeExample.java} (91%) create mode 100644 samples/annotation/src/main/java/com/ea/orbit/samples/annotation/examples/IOnlyExample.java rename samples/{memoize/src/main/java/com/ea/orbit/samples/memoize/ExampleActor.java => annotation/src/main/java/com/ea/orbit/samples/annotation/examples/MemoizeExampleActor.java} (93%) create mode 100644 samples/annotation/src/main/java/com/ea/orbit/samples/annotation/examples/OnlyExampleActor.java rename samples/{memoize/src/main/java/com/ea/orbit/samples => annotation/src/main/java/com/ea/orbit/samples/annotation}/memoize/Memoize.java (87%) create mode 100644 samples/annotation/src/main/java/com/ea/orbit/samples/annotation/memoize/MemoizeAnnotationHandler.java create mode 100644 samples/annotation/src/main/java/com/ea/orbit/samples/annotation/onlyifactivated/OnlyIfActivated.java create mode 100644 samples/annotation/src/main/java/com/ea/orbit/samples/annotation/onlyifactivated/OnlyIfActivatedAnnotationHandler.java rename samples/{memoize => annotation}/src/main/resources/logback.xml (100%) rename samples/{memoize/src/test/java/com/ea/orbit/samples/helloworld/MemoizeTest.java => annotation/src/test/java/com/ea/orbit/samples/customannotation/AnnotationTest.java} (61%) delete mode 100644 samples/memoize/README.md diff --git a/actors/core/src/main/java/com/ea/orbit/actors/runtime/IRuntime.java b/actors/core/src/main/java/com/ea/orbit/actors/runtime/IRuntime.java index ad656de21..6501ee05c 100644 --- a/actors/core/src/main/java/com/ea/orbit/actors/runtime/IRuntime.java +++ b/actors/core/src/main/java/com/ea/orbit/actors/runtime/IRuntime.java @@ -30,6 +30,7 @@ import com.ea.orbit.actors.IAddressable; import com.ea.orbit.actors.IRemindable; +import com.ea.orbit.actors.cluster.INodeAddress; import com.ea.orbit.concurrent.Task; import java.lang.reflect.Method; @@ -114,11 +115,24 @@ public interface IRuntime String runtimeIdentity(); /** + * Gets current Activation, the actor reference that is currently invoking the method * - * @return + * @return caller actor */ ActorReference getCurrentActivation(); + /** + * Gets a long representing the current tracing id + * + * @return unique trace id + */ long getCurrentTraceId(); + /** + * Gets an address for an active actor + * + * @return actor address, null if actor is not active + */ + Task locateActiveActor(final IAddressable actorReference); + } diff --git a/actors/stage/src/main/java/com/ea/orbit/actors/runtime/Execution.java b/actors/stage/src/main/java/com/ea/orbit/actors/runtime/Execution.java index 45fbdabad..57a751773 100644 --- a/actors/stage/src/main/java/com/ea/orbit/actors/runtime/Execution.java +++ b/actors/stage/src/main/java/com/ea/orbit/actors/runtime/Execution.java @@ -1027,7 +1027,7 @@ public Task sendMessage(IAddressable toReference, boolean oneWay, final int m if (toNode == null) { // TODO: Ensure that both paths encode exception the same way. - return hosting.locateActor(actorReference) + return hosting.locateAndActivateActor(actorReference) .thenCompose(x -> messaging.sendMessage(x, oneWay, actorReference._interfaceId(), methodId, actorReference.id, params)); } return messaging.sendMessage(toNode, oneWay, actorReference._interfaceId(), methodId, actorReference.id, params); @@ -1141,4 +1141,8 @@ public void activationCleanup(final boolean block) Task.allOf(futures).join(); } } + + public Task locateActiveActor(final IAddressable actorReference){ + return hosting.locateActiveActor(actorReference); + } } diff --git a/actors/stage/src/main/java/com/ea/orbit/actors/runtime/Hosting.java b/actors/stage/src/main/java/com/ea/orbit/actors/runtime/Hosting.java index c6b7db655..d14039c85 100644 --- a/actors/stage/src/main/java/com/ea/orbit/actors/runtime/Hosting.java +++ b/actors/stage/src/main/java/com/ea/orbit/actors/runtime/Hosting.java @@ -167,7 +167,18 @@ private void updateServerNodes() } } - public Task locateActor(final IAddressable actorReference) + public Task locateActiveActor(final IAddressable actorReference){ + ActorKey addressable = new ActorKey(((ActorReference) actorReference)._interfaceClass().getName(), + String.valueOf(((ActorReference) actorReference).id)); + INodeAddress address = localAddressCache.get(addressable); + if (address != null && activeNodes.containsKey(address)) + { + return Task.fromValue(address); + } + return Task.fromValue(null); + } + + public Task locateAndActivateActor(final IAddressable actorReference) { ActorKey addressable = new ActorKey(((ActorReference) actorReference)._interfaceClass().getName(), String.valueOf(((ActorReference) actorReference).id)); diff --git a/actors/test/actor-tests/src/test/java/com/ea/orbit/actors/test/ClientTest.java b/actors/test/actor-tests/src/test/java/com/ea/orbit/actors/test/ClientTest.java index 87a436f2d..d66e5117e 100644 --- a/actors/test/actor-tests/src/test/java/com/ea/orbit/actors/test/ClientTest.java +++ b/actors/test/actor-tests/src/test/java/com/ea/orbit/actors/test/ClientTest.java @@ -138,7 +138,7 @@ public void ensureNoObjectsAreCreatedClientTest() throws ExecutionException, Int ISomeActor player = IActor.getReference(ISomeActor.class, String.valueOf(i)); client.bind(); assertEquals("bla", player.sayHello("meh").join()); - assertTrue(serverAddresses.contains(client.getHosting().locateActor((ActorReference) player).join())); + assertTrue(serverAddresses.contains(client.getHosting().locateAndActivateActor((ActorReference) player).join())); } } diff --git a/samples/annotation/README.md b/samples/annotation/README.md new file mode 100644 index 000000000..75fd6cfe6 --- /dev/null +++ b/samples/annotation/README.md @@ -0,0 +1,10 @@ + +Annotation Sample +=================== + +This is a custom annotation provider. + + + + + diff --git a/samples/memoize/pom.xml b/samples/annotation/pom.xml similarity index 95% rename from samples/memoize/pom.xml rename to samples/annotation/pom.xml index 15991214c..233a1274d 100644 --- a/samples/memoize/pom.xml +++ b/samples/annotation/pom.xml @@ -37,8 +37,8 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 4.0.0 - Orbit Samples: Memoize - orbit-samples-memoize + Orbit Samples: Annotation + orbit-samples-annotation @@ -96,7 +96,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. exec-maven-plugin 1.3.2 - com.ea.orbit.samples.memoize.Main + com.ea.orbit.samples.customannotation.Main diff --git a/samples/memoize/src/main/java/com/ea/orbit/samples/memoize/MemoizeHookProvider.java b/samples/annotation/src/main/java/com/ea/orbit/samples/annotation/AnnotationHookProvider.java similarity index 66% rename from samples/memoize/src/main/java/com/ea/orbit/samples/memoize/MemoizeHookProvider.java rename to samples/annotation/src/main/java/com/ea/orbit/samples/annotation/AnnotationHookProvider.java index 5ac121e3d..8479a7add 100644 --- a/samples/memoize/src/main/java/com/ea/orbit/samples/memoize/MemoizeHookProvider.java +++ b/samples/annotation/src/main/java/com/ea/orbit/samples/annotation/AnnotationHookProvider.java @@ -26,42 +26,41 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package com.ea.orbit.samples.memoize; +package com.ea.orbit.samples.annotation; import com.ea.orbit.actors.IAddressable; import com.ea.orbit.actors.providers.IInvokeHookProvider; import com.ea.orbit.actors.runtime.IRuntime; import com.ea.orbit.concurrent.Task; -import net.jodah.expiringmap.ExpiringMap; - import java.lang.reflect.Method; -import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; -import java.util.stream.Stream; +import java.util.ArrayList; +import java.util.List; -public class MemoizeHookProvider implements IInvokeHookProvider +public class AnnotationHookProvider implements IInvokeHookProvider { - ExpiringMap memoizeMap = ExpiringMap.builder().variableExpiration().build(); + private List handlers = new ArrayList<>(); @Override public Task invoke(IRuntime runtime, IAddressable toReference, Method m, boolean oneWay, int methodId, Object[] params) { - Memoize memoizeAnnotation = m.getAnnotation(Memoize.class); - if (memoizeAnnotation != null) + for (IAnnotationHandler handler : handlers) { - long memoizeMaxMillis = memoizeAnnotation.unit().toMillis(memoizeAnnotation.time()); - String key = Integer.toString(methodId) + "_" + Stream.of(params).map(p -> Integer.toString(p.hashCode())).collect(Collectors.joining("_")); - Task cached = memoizeMap.get(key); - if (cached == null) + if (m.isAnnotationPresent(handler.annotationClass())) { - cached = runtime.sendMessage(toReference, oneWay, methodId, params); - memoizeMap.put(key, cached, ExpiringMap.ExpirationPolicy.CREATED, memoizeMaxMillis, TimeUnit.MILLISECONDS); + Task result = handler.invoke(m.getAnnotation(handler.annotationClass()), runtime, toReference, m, oneWay, methodId, params); + if (result != null) + { + return result; + } } - return cached; } return runtime.sendMessage(toReference, oneWay, methodId, params); } + public void addHandler(IAnnotationHandler handler) + { + handlers.add(handler); + } } diff --git a/samples/annotation/src/main/java/com/ea/orbit/samples/annotation/IAnnotationHandler.java b/samples/annotation/src/main/java/com/ea/orbit/samples/annotation/IAnnotationHandler.java new file mode 100644 index 000000000..edfd6dc03 --- /dev/null +++ b/samples/annotation/src/main/java/com/ea/orbit/samples/annotation/IAnnotationHandler.java @@ -0,0 +1,44 @@ +/* + Copyright (C) 2015 Electronic Arts Inc. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of Electronic Arts, Inc. ("EA") nor the names of + its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY ELECTRONIC ARTS AND ITS CONTRIBUTORS "AS IS" AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL ELECTRONIC ARTS OR ITS CONTRIBUTORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.ea.orbit.samples.annotation; + +import com.ea.orbit.actors.IAddressable; +import com.ea.orbit.actors.runtime.IRuntime; +import com.ea.orbit.concurrent.Task; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; + +public interface IAnnotationHandler +{ + Class annotationClass(); + + Task invoke(T ann, IRuntime runtime, IAddressable toReference, Method m, boolean oneWay, int methodId, Object[] params); + +} diff --git a/samples/memoize/src/main/java/com/ea/orbit/samples/memoize/IExample.java b/samples/annotation/src/main/java/com/ea/orbit/samples/annotation/examples/IMemoizeExample.java similarity index 91% rename from samples/memoize/src/main/java/com/ea/orbit/samples/memoize/IExample.java rename to samples/annotation/src/main/java/com/ea/orbit/samples/annotation/examples/IMemoizeExample.java index 5d94fc88f..142247fb5 100644 --- a/samples/memoize/src/main/java/com/ea/orbit/samples/memoize/IExample.java +++ b/samples/annotation/src/main/java/com/ea/orbit/samples/annotation/examples/IMemoizeExample.java @@ -26,14 +26,15 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package com.ea.orbit.samples.memoize; +package com.ea.orbit.samples.annotation.examples; import com.ea.orbit.actors.IActor; import com.ea.orbit.concurrent.Task; +import com.ea.orbit.samples.annotation.memoize.Memoize; import java.util.concurrent.TimeUnit; -public interface IExample extends IActor +public interface IMemoizeExample extends IActor { @Memoize(time = 5, unit = TimeUnit.SECONDS) diff --git a/samples/annotation/src/main/java/com/ea/orbit/samples/annotation/examples/IOnlyExample.java b/samples/annotation/src/main/java/com/ea/orbit/samples/annotation/examples/IOnlyExample.java new file mode 100644 index 000000000..f1011b92e --- /dev/null +++ b/samples/annotation/src/main/java/com/ea/orbit/samples/annotation/examples/IOnlyExample.java @@ -0,0 +1,44 @@ +/* + Copyright (C) 2015 Electronic Arts Inc. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of Electronic Arts, Inc. ("EA") nor the names of + its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY ELECTRONIC ARTS AND ITS CONTRIBUTORS "AS IS" AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL ELECTRONIC ARTS OR ITS CONTRIBUTORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.ea.orbit.samples.annotation.examples; + +import com.ea.orbit.actors.IActor; +import com.ea.orbit.concurrent.Task; +import com.ea.orbit.samples.annotation.onlyifactivated.OnlyIfActivated; + +public interface IOnlyExample extends IActor +{ + + @OnlyIfActivated + Task doSomethingSpecial(String greeting); + + Task makeActiveNow(); + +} + diff --git a/samples/memoize/src/main/java/com/ea/orbit/samples/memoize/ExampleActor.java b/samples/annotation/src/main/java/com/ea/orbit/samples/annotation/examples/MemoizeExampleActor.java similarity index 93% rename from samples/memoize/src/main/java/com/ea/orbit/samples/memoize/ExampleActor.java rename to samples/annotation/src/main/java/com/ea/orbit/samples/annotation/examples/MemoizeExampleActor.java index d4f785355..603017700 100644 --- a/samples/memoize/src/main/java/com/ea/orbit/samples/memoize/ExampleActor.java +++ b/samples/annotation/src/main/java/com/ea/orbit/samples/annotation/examples/MemoizeExampleActor.java @@ -26,14 +26,14 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package com.ea.orbit.samples.memoize; +package com.ea.orbit.samples.annotation.examples; import com.ea.orbit.actors.runtime.OrbitActor; import com.ea.orbit.concurrent.Task; @SuppressWarnings("rawtypes") -public class ExampleActor extends OrbitActor implements IExample +public class MemoizeExampleActor extends OrbitActor implements IMemoizeExample { public static int accessCount = 0; diff --git a/samples/annotation/src/main/java/com/ea/orbit/samples/annotation/examples/OnlyExampleActor.java b/samples/annotation/src/main/java/com/ea/orbit/samples/annotation/examples/OnlyExampleActor.java new file mode 100644 index 000000000..214d2202e --- /dev/null +++ b/samples/annotation/src/main/java/com/ea/orbit/samples/annotation/examples/OnlyExampleActor.java @@ -0,0 +1,54 @@ +/* + Copyright (C) 2015 Electronic Arts Inc. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of Electronic Arts, Inc. ("EA") nor the names of + its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY ELECTRONIC ARTS AND ITS CONTRIBUTORS "AS IS" AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL ELECTRONIC ARTS OR ITS CONTRIBUTORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.ea.orbit.samples.annotation.examples; + + +import com.ea.orbit.actors.runtime.OrbitActor; +import com.ea.orbit.concurrent.Task; + +@SuppressWarnings("rawtypes") +public class OnlyExampleActor extends OrbitActor implements IOnlyExample +{ + public static int accessCount = 0; + + @Override + public Task doSomethingSpecial(final String greeting) + { + accessCount++; + return Task.done(); + } + + @Override + public Task makeActiveNow() + { + //does really nothing, but allows the actor to be activated + return Task.done(); + } +} + diff --git a/samples/memoize/src/main/java/com/ea/orbit/samples/memoize/Memoize.java b/samples/annotation/src/main/java/com/ea/orbit/samples/annotation/memoize/Memoize.java similarity index 87% rename from samples/memoize/src/main/java/com/ea/orbit/samples/memoize/Memoize.java rename to samples/annotation/src/main/java/com/ea/orbit/samples/annotation/memoize/Memoize.java index 76ec460d2..9c6562164 100644 --- a/samples/memoize/src/main/java/com/ea/orbit/samples/memoize/Memoize.java +++ b/samples/annotation/src/main/java/com/ea/orbit/samples/annotation/memoize/Memoize.java @@ -1,4 +1,4 @@ -package com.ea.orbit.samples.memoize; +package com.ea.orbit.samples.annotation.memoize; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/samples/annotation/src/main/java/com/ea/orbit/samples/annotation/memoize/MemoizeAnnotationHandler.java b/samples/annotation/src/main/java/com/ea/orbit/samples/annotation/memoize/MemoizeAnnotationHandler.java new file mode 100644 index 000000000..387ffa6cd --- /dev/null +++ b/samples/annotation/src/main/java/com/ea/orbit/samples/annotation/memoize/MemoizeAnnotationHandler.java @@ -0,0 +1,66 @@ +/* + Copyright (C) 2015 Electronic Arts Inc. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of Electronic Arts, Inc. ("EA") nor the names of + its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY ELECTRONIC ARTS AND ITS CONTRIBUTORS "AS IS" AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL ELECTRONIC ARTS OR ITS CONTRIBUTORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.ea.orbit.samples.annotation.memoize; + +import com.ea.orbit.actors.IAddressable; +import com.ea.orbit.actors.runtime.IRuntime; +import com.ea.orbit.concurrent.Task; +import com.ea.orbit.samples.annotation.IAnnotationHandler; + +import net.jodah.expiringmap.ExpiringMap; + +import java.lang.reflect.Method; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class MemoizeAnnotationHandler implements IAnnotationHandler +{ + ExpiringMap memoizeMap = ExpiringMap.builder().variableExpiration().build(); + + @Override + public Class annotationClass() + { + return Memoize.class; + } + + @Override + public Task invoke(Memoize memoize, final IRuntime runtime, final IAddressable toReference, final Method m, final boolean oneWay, final int methodId, final Object[] params) + { + long memoizeMaxMillis = memoize.unit().toMillis(memoize.time()); + String key = Integer.toString(methodId) + "_" + Stream.of(params).map(p -> Integer.toString(p.hashCode())).collect(Collectors.joining("_")); + Task cached = memoizeMap.get(key); + if (cached == null) + { + cached = runtime.sendMessage(toReference, oneWay, methodId, params); + memoizeMap.put(key, cached, ExpiringMap.ExpirationPolicy.CREATED, memoizeMaxMillis, TimeUnit.MILLISECONDS); + } + return cached; + } +} diff --git a/samples/annotation/src/main/java/com/ea/orbit/samples/annotation/onlyifactivated/OnlyIfActivated.java b/samples/annotation/src/main/java/com/ea/orbit/samples/annotation/onlyifactivated/OnlyIfActivated.java new file mode 100644 index 000000000..172b6665a --- /dev/null +++ b/samples/annotation/src/main/java/com/ea/orbit/samples/annotation/onlyifactivated/OnlyIfActivated.java @@ -0,0 +1,41 @@ +/* + Copyright (C) 2015 Electronic Arts Inc. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of Electronic Arts, Inc. ("EA") nor the names of + its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY ELECTRONIC ARTS AND ITS CONTRIBUTORS "AS IS" AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL ELECTRONIC ARTS OR ITS CONTRIBUTORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.ea.orbit.samples.annotation.onlyifactivated; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface OnlyIfActivated +{ + +} diff --git a/samples/annotation/src/main/java/com/ea/orbit/samples/annotation/onlyifactivated/OnlyIfActivatedAnnotationHandler.java b/samples/annotation/src/main/java/com/ea/orbit/samples/annotation/onlyifactivated/OnlyIfActivatedAnnotationHandler.java new file mode 100644 index 000000000..78b17287c --- /dev/null +++ b/samples/annotation/src/main/java/com/ea/orbit/samples/annotation/onlyifactivated/OnlyIfActivatedAnnotationHandler.java @@ -0,0 +1,58 @@ +/* + Copyright (C) 2015 Electronic Arts Inc. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of Electronic Arts, Inc. ("EA") nor the names of + its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY ELECTRONIC ARTS AND ITS CONTRIBUTORS "AS IS" AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL ELECTRONIC ARTS OR ITS CONTRIBUTORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.ea.orbit.samples.annotation.onlyifactivated; + +import com.ea.orbit.actors.IAddressable; +import com.ea.orbit.actors.cluster.INodeAddress; +import com.ea.orbit.actors.runtime.IRuntime; +import com.ea.orbit.concurrent.Task; +import com.ea.orbit.samples.annotation.IAnnotationHandler; + +import java.lang.reflect.Method; + +public class OnlyIfActivatedAnnotationHandler implements IAnnotationHandler +{ + + @Override + public Class annotationClass() + { + return OnlyIfActivated.class; + } + + @Override + public Task invoke(final OnlyIfActivated ann, final IRuntime runtime, final IAddressable toReference, final Method m, final boolean oneWay, final int methodId, final Object[] params) + { + INodeAddress address = runtime.locateActiveActor(toReference).join(); + if (address == null) + { + return Task.done(); + } + return runtime.sendMessage(toReference, oneWay, methodId, params); + } +} diff --git a/samples/memoize/src/main/resources/logback.xml b/samples/annotation/src/main/resources/logback.xml similarity index 100% rename from samples/memoize/src/main/resources/logback.xml rename to samples/annotation/src/main/resources/logback.xml diff --git a/samples/memoize/src/test/java/com/ea/orbit/samples/helloworld/MemoizeTest.java b/samples/annotation/src/test/java/com/ea/orbit/samples/customannotation/AnnotationTest.java similarity index 61% rename from samples/memoize/src/test/java/com/ea/orbit/samples/helloworld/MemoizeTest.java rename to samples/annotation/src/test/java/com/ea/orbit/samples/customannotation/AnnotationTest.java index b69de740c..ba2ebb27b 100644 --- a/samples/memoize/src/test/java/com/ea/orbit/samples/helloworld/MemoizeTest.java +++ b/samples/annotation/src/test/java/com/ea/orbit/samples/customannotation/AnnotationTest.java @@ -26,55 +26,84 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package com.ea.orbit.samples.helloworld; +package com.ea.orbit.samples.customannotation; import com.ea.orbit.actors.IActor; import com.ea.orbit.actors.OrbitStage; import com.ea.orbit.actors.test.ActorBaseTest; import com.ea.orbit.actors.test.FakeClusterPeer; import com.ea.orbit.actors.test.FakeStorageProvider; -import com.ea.orbit.samples.memoize.ExampleActor; -import com.ea.orbit.samples.memoize.IExample; -import com.ea.orbit.samples.memoize.MemoizeHookProvider; +import com.ea.orbit.samples.annotation.AnnotationHookProvider; +import com.ea.orbit.samples.annotation.examples.IMemoizeExample; +import com.ea.orbit.samples.annotation.examples.IOnlyExample; +import com.ea.orbit.samples.annotation.examples.MemoizeExampleActor; +import com.ea.orbit.samples.annotation.examples.OnlyExampleActor; +import com.ea.orbit.samples.annotation.memoize.MemoizeAnnotationHandler; +import com.ea.orbit.samples.annotation.onlyifactivated.OnlyIfActivatedAnnotationHandler; import org.junit.Test; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -public class MemoizeTest extends ActorBaseTest +public class AnnotationTest extends ActorBaseTest { + @Test - public void test() + public void onlyIfActivatedTest() { - OrbitStage stage1 = initStage(); + OrbitStage stage = initStage(); + + IOnlyExample only = IActor.getReference(IOnlyExample.class, "234"); + only.doSomethingSpecial("A").join(); + only.doSomethingSpecial("A").join(); + only.doSomethingSpecial("A").join(); + only.doSomethingSpecial("A").join(); + only.doSomethingSpecial("A").join(); + assertEquals(0, OnlyExampleActor.accessCount); + only.makeActiveNow().join(); + only.doSomethingSpecial("A").join(); + only.doSomethingSpecial("A").join(); + only.doSomethingSpecial("A").join(); + only.doSomethingSpecial("A").join(); + only.doSomethingSpecial("A").join(); + assertEquals(5, OnlyExampleActor.accessCount); + } - IExample memoize = IActor.getReference(IExample.class, "0"); + @Test + public void memoizeTest() + { + OrbitStage stage = initStage(); - stage1.bind(); + IMemoizeExample memoize = IActor.getReference(IMemoizeExample.class, "45"); long firstA = memoize.getNow("A").join(); sleep(1000); long firstB = memoize.getNow("B").join(); long secondA = memoize.getNow("A").join(); - assertTrue(ExampleActor.accessCount == 2); + assertTrue(MemoizeExampleActor.accessCount == 2); assertTrue(firstA != firstB); assertTrue(firstA == secondA); sleep(1000); long thirdA = memoize.getNow("A").join(); long secondB = memoize.getNow("B").join(); - assertTrue(ExampleActor.accessCount == 2); + assertTrue(MemoizeExampleActor.accessCount == 2); assertTrue(thirdA != secondB); assertTrue(secondA == thirdA); assertTrue(firstB == secondB); sleep(4500); long fourthA = memoize.getNow("A").join(); long thirdB = memoize.getNow("B").join(); - assertTrue(ExampleActor.accessCount == 4); + assertTrue(MemoizeExampleActor.accessCount == 4); assertTrue(thirdA != fourthA); assertTrue(secondB != thirdB); + //stage.cleanup(true); + stage.stop().join(); + } + public static void sleep(long millis) { try @@ -93,7 +122,13 @@ public OrbitStage initStage() stage.setMode(OrbitStage.StageMode.HOST); stage.setExecutionPool(commonPool); stage.setMessagingPool(commonPool); - stage.addProvider(new MemoizeHookProvider()); + + AnnotationHookProvider custom = new AnnotationHookProvider(); + custom.addHandler(new MemoizeAnnotationHandler()); + custom.addHandler(new OnlyIfActivatedAnnotationHandler()); + stage.addProvider(custom); + + stage.addProvider(new FakeStorageProvider(fakeDatabase)); stage.setClock(clock); diff --git a/samples/memoize/README.md b/samples/memoize/README.md deleted file mode 100644 index f91f62ac0..000000000 --- a/samples/memoize/README.md +++ /dev/null @@ -1,27 +0,0 @@ - -Memoize Sample -=================== - -This is a custom Memoize annotation (result cache). -In clusters, strategically placed memoized methods can save a *lot* of IO inside the cluster and increase the scalability. In a real world scenario there is always information that can be cached for a few seconds. -It is also a proof-of-concept for the invoke interceptors. - -###### Usage - -adding the provider: -```java -stage.addProvider(new MemoizeHookProvider()); -``` - -using in the actor: -```java -public interface IExample extends IActor { - @Memoize(time = 5, unit = TimeUnit.SECONDS) - Task getSomething(String greeting); -} -``` - - - - - diff --git a/samples/pom.xml b/samples/pom.xml index 4c9e646c9..a1dc2c775 100644 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -46,7 +46,7 @@ chat hello async - memoize + annotation trace diff --git a/samples/trace/pom.xml b/samples/trace/pom.xml index b1f1be5bb..f2a7fb01c 100644 --- a/samples/trace/pom.xml +++ b/samples/trace/pom.xml @@ -118,7 +118,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. exec-maven-plugin 1.3.2 - com.ea.orbit.samples.memoize.Main + com.ea.orbit.samples.trace.demo