Repository: reef
Updated Branches:
  refs/heads/master 18c25fdcf -> 1fc8cd051


[REEF-1642] Make sure there is only one instance of Evaluators per 
REEFEnvironment/Driver

   * Improve `SingletonAsserter` to support both global and scoped singletons
   * Add unit tests for new functionality of `SingletonAsserter`
   * Use scoped `SingletonAsserter` in the `Evaluators` class

This is work towards 
[REEF-1561](https://issues.apache.org/jira/browse/REEF-1561)
*"REEF as a library"* effort.

JIRA:
  [REEF-1642](https://issues.apache.org/jira/browse/REEF-1642)

Pull Request:
  This closes #1157


Project: http://git-wip-us.apache.org/repos/asf/reef/repo
Commit: http://git-wip-us.apache.org/repos/asf/reef/commit/1fc8cd05
Tree: http://git-wip-us.apache.org/repos/asf/reef/tree/1fc8cd05
Diff: http://git-wip-us.apache.org/repos/asf/reef/diff/1fc8cd05

Branch: refs/heads/master
Commit: 1fc8cd0515dcfa520a8193202b3e9aa099e806c6
Parents: 18c25fd
Author: Sergiy Matusevych <mo...@apache.org>
Authored: Tue Oct 11 13:52:05 2016 -0700
Committer: Markus Weimer <wei...@apache.org>
Committed: Mon Oct 17 15:30:51 2016 -0700

----------------------------------------------------------------------
 .../common/driver/evaluator/Evaluators.java     | 10 +++--
 .../org/apache/reef/util/SingletonAsserter.java | 29 ++++++++++++--
 .../apache/reef/util/SingletonAsserterTest.java | 41 +++++++++++++++++---
 3 files changed, 66 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/reef/blob/1fc8cd05/lang/java/reef-common/src/main/java/org/apache/reef/runtime/common/driver/evaluator/Evaluators.java
----------------------------------------------------------------------
diff --git 
a/lang/java/reef-common/src/main/java/org/apache/reef/runtime/common/driver/evaluator/Evaluators.java
 
b/lang/java/reef-common/src/main/java/org/apache/reef/runtime/common/driver/evaluator/Evaluators.java
index 8962895..341d37d 100644
--- 
a/lang/java/reef-common/src/main/java/org/apache/reef/runtime/common/driver/evaluator/Evaluators.java
+++ 
b/lang/java/reef-common/src/main/java/org/apache/reef/runtime/common/driver/evaluator/Evaluators.java
@@ -20,9 +20,12 @@ package org.apache.reef.runtime.common.driver.evaluator;
 
 import org.apache.reef.annotations.audience.DriverSide;
 import org.apache.reef.annotations.audience.Private;
+import org.apache.reef.driver.parameters.DriverIdentifier;
 import 
org.apache.reef.runtime.common.driver.resourcemanager.ResourceAllocationEvent;
+import org.apache.reef.tang.annotations.Parameter;
 import org.apache.reef.util.Optional;
 import org.apache.reef.tang.util.MonotonicSet;
+import org.apache.reef.util.SingletonAsserter;
 
 import javax.inject.Inject;
 import java.util.*;
@@ -50,12 +53,11 @@ public final class Evaluators implements AutoCloseable {
   private final MonotonicSet<String> closedEvaluatorIds = new MonotonicSet<>();
 
   @Inject
-  Evaluators() {
-    LOG.log(Level.FINE, "Instantiated 'Evaluators'");
-    // TODO[REEF-1642] Assert singleton per REEFEnvironment
+  private Evaluators(@Parameter(DriverIdentifier.class) final String driverId) 
{
+    LOG.log(Level.FINE, "Instantiated 'Evaluators' for driver {0}", driverId);
     // There can be several instances of the class for multiple 
REEFEnvironments.
     // It is still a singleton when REEF Driver owns the entire JVM.
-    // assert SingletonAsserter.assertSingleton(Evaluators.class);
+    assert SingletonAsserter.assertSingleton(driverId, Evaluators.class);
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/reef/blob/1fc8cd05/lang/java/reef-common/src/main/java/org/apache/reef/util/SingletonAsserter.java
----------------------------------------------------------------------
diff --git 
a/lang/java/reef-common/src/main/java/org/apache/reef/util/SingletonAsserter.java
 
b/lang/java/reef-common/src/main/java/org/apache/reef/util/SingletonAsserter.java
index 5c6d0a9..da3b994 100644
--- 
a/lang/java/reef-common/src/main/java/org/apache/reef/util/SingletonAsserter.java
+++ 
b/lang/java/reef-common/src/main/java/org/apache/reef/util/SingletonAsserter.java
@@ -18,7 +18,8 @@
  */
 package org.apache.reef.util;
 
-import java.util.Collections;
+import org.apache.reef.io.Tuple;
+
 import java.util.HashSet;
 import java.util.Set;
 
@@ -27,7 +28,11 @@ import java.util.Set;
  */
 public final class SingletonAsserter {
 
-  private static final Set<Class> CLASSES = Collections.synchronizedSet(new 
HashSet<Class>());
+  private static final Set<Class> ALL_CLASSES = new HashSet<>();
+
+  private static final Set<Class> SINGLETONS_GLOBAL = new HashSet<>();
+
+  private static final Set<Tuple<String, Class>> SINGLETONS_SCOPED = new 
HashSet<>();
 
   /**
    * This class operates purely in static mode.
@@ -35,7 +40,23 @@ public final class SingletonAsserter {
   private SingletonAsserter() {
   }
 
-  public static boolean assertSingleton(final Class clazz) {
-    return CLASSES.add(clazz);
+  /**
+   * Check if a given class is instantiated only once.
+   * @param clazz Class to check.
+   * @return True if the class was not instantiated before, false otherwise.
+   */
+  public static synchronized boolean assertSingleton(final Class clazz) {
+    return SINGLETONS_GLOBAL.add(clazz) && ALL_CLASSES.add(clazz);
+  }
+
+  /**
+   * Check if given class is singleton within a particular environment or 
scope.
+   * @param scopeId Environment id, e.g. Driver name or REEF job id.
+   * @param clazz Class that must have no more than 1 instance in that 
environment.
+   * @return true if the instance is unique within that particular 
environment, false otherwise.
+   */
+  public static synchronized boolean assertSingleton(final String scopeId, 
final Class clazz) {
+    ALL_CLASSES.add(clazz);
+    return SINGLETONS_SCOPED.add(new Tuple<>(scopeId, clazz)) && 
!SINGLETONS_GLOBAL.contains(clazz);
   }
 }

http://git-wip-us.apache.org/repos/asf/reef/blob/1fc8cd05/lang/java/reef-common/src/test/java/org/apache/reef/util/SingletonAsserterTest.java
----------------------------------------------------------------------
diff --git 
a/lang/java/reef-common/src/test/java/org/apache/reef/util/SingletonAsserterTest.java
 
b/lang/java/reef-common/src/test/java/org/apache/reef/util/SingletonAsserterTest.java
index c25f462..ede9697 100644
--- 
a/lang/java/reef-common/src/test/java/org/apache/reef/util/SingletonAsserterTest.java
+++ 
b/lang/java/reef-common/src/test/java/org/apache/reef/util/SingletonAsserterTest.java
@@ -21,17 +21,46 @@ package org.apache.reef.util;
 import org.junit.Assert;
 import org.junit.Test;
 
-import java.util.List;
-
 /**
  * Test for SingletonAsserter.
  */
 public final class SingletonAsserterTest {
 
+  private static final class GlobalA { }
+  private static final class GlobalB { }
+
+  @Test
+  public void testSingletonAsserterGlobal() {
+    Assert.assertTrue(SingletonAsserter.assertSingleton(GlobalA.class));
+    Assert.assertTrue(SingletonAsserter.assertSingleton(GlobalB.class));
+    Assert.assertFalse(SingletonAsserter.assertSingleton(GlobalA.class));
+  }
+
+  private static final class LocalA { }
+  private static final class LocalB { }
+
+  @Test
+  public void testSingletonAsserterScoped() {
+    Assert.assertTrue(SingletonAsserter.assertSingleton("A", LocalA.class));
+    Assert.assertTrue(SingletonAsserter.assertSingleton("A", LocalB.class));
+    Assert.assertTrue(SingletonAsserter.assertSingleton("B", LocalA.class));
+    Assert.assertFalse(SingletonAsserter.assertSingleton("A", LocalA.class));
+  }
+
+  private static final class Mixed1 { }
+
+  @Test
+  public void testSingletonAsserterMixed1() {
+    Assert.assertTrue(SingletonAsserter.assertSingleton("A", Mixed1.class));
+    Assert.assertTrue(SingletonAsserter.assertSingleton("B", Mixed1.class));
+    Assert.assertFalse(SingletonAsserter.assertSingleton(Mixed1.class));
+  }
+
+  private static final class Mixed2 { }
+
   @Test
-  public void testSingletonAsserter() {
-    
Assert.assertTrue(SingletonAsserter.assertSingleton(SingletonAsserterTest.class));
-    Assert.assertTrue(SingletonAsserter.assertSingleton(List.class));
-    Assert.assertFalse(SingletonAsserter.assertSingleton(List.class));
+  public void testSingletonAsserterMixed2() {
+    Assert.assertTrue(SingletonAsserter.assertSingleton(Mixed2.class));
+    Assert.assertFalse(SingletonAsserter.assertSingleton("A", Mixed2.class));
   }
 }

Reply via email to