提交 7e0613f0 编写于 作者: L lei.yul 提交者: yulei

[Misc] Polish rcm API

Summary:
- Replace null with root() to represent root container for consistency
- Support rcm inheritance by Thread.inheritedResourceContainer

Test Plan: jtreg com/alibaba/rcm/ multi-tenent/

Reviewed-by: luchsh, tanghaoth90

Issue: https://github.com/alibaba/dragonwell8/issues/95
上级 92f30fa3
...@@ -1315,6 +1315,11 @@ public final class System { ...@@ -1315,6 +1315,11 @@ public final class System {
public AbstractResourceContainer getResourceContainer(Thread thread) { public AbstractResourceContainer getResourceContainer(Thread thread) {
return thread.resourceContainer; return thread.resourceContainer;
} }
@Override
public AbstractResourceContainer getInheritedResourceContainer(Thread thread) {
return thread.inheritedResourceContainer;
}
}); });
} }
} }
...@@ -227,6 +227,11 @@ class Thread implements Runnable { ...@@ -227,6 +227,11 @@ class Thread implements Runnable {
*/ */
AbstractResourceContainer resourceContainer; AbstractResourceContainer resourceContainer;
/**
* {@code ResourceContainer} inherited from parent
*/
AbstractResourceContainer inheritedResourceContainer;
private static synchronized long nextThreadID() { private static synchronized long nextThreadID() {
return ++threadSeqNumber; return ++threadSeqNumber;
} }
...@@ -439,6 +444,7 @@ class Thread implements Runnable { ...@@ -439,6 +444,7 @@ class Thread implements Runnable {
/* com.alibaba.rcm API */ /* com.alibaba.rcm API */
this.resourceContainer = AbstractResourceContainer.root(); this.resourceContainer = AbstractResourceContainer.root();
this.inheritedResourceContainer = parent.resourceContainer;
/* Set the tenant container */ /* Set the tenant container */
if (VM.isBooted() && TenantGlobals.isTenantEnabled()) { if (VM.isBooted() && TenantGlobals.isTenantEnabled()) {
...@@ -788,6 +794,8 @@ class Thread implements Runnable { ...@@ -788,6 +794,8 @@ class Thread implements Runnable {
blocker = null; blocker = null;
uncaughtExceptionHandler = null; uncaughtExceptionHandler = null;
inheritedTenantContainer = null; inheritedTenantContainer = null;
resourceContainer = null;
inheritedResourceContainer = null;
} }
/** /**
......
...@@ -145,4 +145,9 @@ public interface JavaLangAccess { ...@@ -145,4 +145,9 @@ public interface JavaLangAccess {
* Get the reference to the thread attached {@code ResourceContainer} * Get the reference to the thread attached {@code ResourceContainer}
*/ */
AbstractResourceContainer getResourceContainer(Thread thread); AbstractResourceContainer getResourceContainer(Thread thread);
/**
* Get the reference to the thread's inherited {@code ResourceContainer}
*/
AbstractResourceContainer getInheritedResourceContainer(Thread thread);
} }
...@@ -46,14 +46,16 @@ public class TestConfiguration { ...@@ -46,14 +46,16 @@ public class TestConfiguration {
MyResourceType.MY_RESOURCE1.newConstraint(), MyResourceType.MY_RESOURCE1.newConstraint(),
MyResourceType.MY_RESOURCE2.newConstraint())); MyResourceType.MY_RESOURCE2.newConstraint()));
assertTrue(iterator2Stream(mc.operations.iterator()).collect(Collectors.toSet()) assertTrue(iterator2Stream(mc.operations.iterator()).collect(Collectors.toSet())
.equals(new HashSet<>(Arrays.asList("update MY_RESOURCE1", "update MY_RESOURCE2")))); .equals(new HashSet<>(Arrays.asList("update " + MyResourceType.MY_RESOURCE1.toString(),
"update " + MyResourceType.MY_RESOURCE2.toString()))));
mc.updateConstraint(MyResourceType.MY_RESOURCE2.newConstraint()); mc.updateConstraint(MyResourceType.MY_RESOURCE2.newConstraint());
assertTrue(iterator2Stream(mc.operations.iterator()).collect(Collectors.toSet()) assertTrue(iterator2Stream(mc.operations.iterator()).collect(Collectors.toSet())
.equals(new HashSet<>(Arrays.asList("update MY_RESOURCE1", "update MY_RESOURCE2", "update MY_RESOURCE2")))); .equals(new HashSet<>(Arrays.asList("update " + MyResourceType.MY_RESOURCE1.toString(),
"update " + MyResourceType.MY_RESOURCE2.toString(),
"update " + MyResourceType.MY_RESOURCE2.toString()))));
} }
private static <T> Stream<T> iterator2Stream(Iterator<T> iterator) { private static <T> Stream<T> iterator2Stream(Iterator<T> iterator) {
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
*/ */
import com.alibaba.rcm.ResourceContainer; import com.alibaba.rcm.ResourceContainer;
import demo.RCInheritedThreadFactory;
import demo.MyResourceFactory; import demo.MyResourceFactory;
import java.util.Collections; import java.util.Collections;
...@@ -44,23 +45,23 @@ public class TestInherit { ...@@ -44,23 +45,23 @@ public class TestInherit {
rc.run(() -> { rc.run(() -> {
assertEQ(ResourceContainer.current(), rc); assertEQ(ResourceContainer.current(), rc);
FutureTask<ResourceContainer> f1 = new FutureTask<>(ResourceContainer::current); FutureTask<ResourceContainer> f1 = new FutureTask<>(ResourceContainer::current);
new Thread(f1).start(); RCInheritedThreadFactory.INSTANCE.newThread(f1).start();
assertEQ(get(f1), rc); assertEQ(get(f1), rc);
FutureTask<ResourceContainer> f2 = new FutureTask<>(ResourceContainer::current); FutureTask<ResourceContainer> f2 = new FutureTask<>(ResourceContainer::current);
ResourceContainer.root().run(() -> new Thread(f2).start()); ResourceContainer.root().run(() -> RCInheritedThreadFactory.INSTANCE.newThread(f2).start());
assertEQ(get(f2), ResourceContainer.root()); assertEQ(get(f2), ResourceContainer.root());
}); });
// thread is bound to it's parent thread(the thread called Thread::init()) // thread is bound to it's parent thread(the thread called Thread::init())
// not dependent on where Thread::start() called. // not dependent on where Thread::start() called.
FutureTask<ResourceContainer> f3 = new FutureTask<>(ResourceContainer::current); FutureTask<ResourceContainer> f3 = new FutureTask<>(ResourceContainer::current);
Thread t3 = new Thread(f3); Thread t3 = RCInheritedThreadFactory.INSTANCE.newThread(f3);
// Thread::init is called in root() // Thread::init is called in root()
rc.run(t3::start); rc.run(t3::start);
assertEQ(get(f3), ResourceContainer.root()); assertEQ(get(f3), ResourceContainer.root());
FutureTask<ResourceContainer> f4 = new FutureTask<>(ResourceContainer::current); FutureTask<ResourceContainer> f4 = new FutureTask<>(ResourceContainer::current);
FutureTask<Thread> newThread = new FutureTask<>(() -> new Thread(f4)); FutureTask<Thread> newThread = new FutureTask<>(() -> RCInheritedThreadFactory.INSTANCE.newThread(f4));
// Thread::init is called in container // Thread::init is called in container
rc.run(newThread); rc.run(newThread);
get(newThread).start(); get(newThread).start();
......
/*
* Copyright (c) 2020 Alibaba Group Holding Limited. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Alibaba designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
/*
* @test
* @summary Test ONLY inheritedResourceContainer is inherited from parent
* @library /lib/testlibrary
* @run main TestInheritedContainer
*/
import com.alibaba.rcm.ResourceContainer;
import demo.MyResourceFactory;
import sun.misc.JavaLangAccess;
import sun.misc.SharedSecrets;
import java.util.Collections;
import java.util.concurrent.CompletableFuture;
import static jdk.testlibrary.Asserts.assertEQ;
public class TestInheritedContainer {
public static void main(String[] args) throws Exception {
ResourceContainer rc = MyResourceFactory.INSTANCE.createContainer(Collections.emptyList());
JavaLangAccess JLA = SharedSecrets.getJavaLangAccess();
rc.run(() -> {
try {
assertEQ(ResourceContainer.root(),
CompletableFuture.supplyAsync(() -> JLA.getResourceContainer(Thread.currentThread())).get());
assertEQ(rc,
CompletableFuture.supplyAsync(() -> JLA.getInheritedResourceContainer(Thread.currentThread())).get());
} catch (Exception e) {
throw new AssertionError(e);
}
});
}
}
/*
* Copyright (c) 2020 Alibaba Group Holding Limited. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Alibaba designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
/*
* @test
* @summary Test default ResourceContainer is root() instead of null
* @library /lib/testlibrary
* @run main TestRootNotNull
*/
import sun.misc.SharedSecrets;
import static jdk.testlibrary.Asserts.assertNotNull;
public class TestRootNotNull {
public static void main(String[] args) {
assertNotNull(SharedSecrets.getJavaLangAccess().getResourceContainer(Thread.currentThread()));
}
}
/*
* Copyright (c) 2020 Alibaba Group Holding Limited. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Alibaba designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
package demo;
import com.alibaba.rcm.internal.AbstractResourceContainer;
import sun.misc.JavaLangAccess;
import sun.misc.SharedSecrets;
import java.util.concurrent.ThreadFactory;
public class RCInheritedThreadFactory implements ThreadFactory {
public final static ThreadFactory INSTANCE = new RCInheritedThreadFactory();
private final static JavaLangAccess JLA = SharedSecrets.getJavaLangAccess();
@Override
public Thread newThread(Runnable r) {
return new Thread(() -> {
AbstractResourceContainer irc = JLA.getInheritedResourceContainer(Thread.currentThread());
if (irc != null) {
irc.run(r);
} else {
r.run();
}
});
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册