提交 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 {
public AbstractResourceContainer getResourceContainer(Thread thread) {
return thread.resourceContainer;
}
@Override
public AbstractResourceContainer getInheritedResourceContainer(Thread thread) {
return thread.inheritedResourceContainer;
}
});
}
}
......@@ -227,6 +227,11 @@ class Thread implements Runnable {
*/
AbstractResourceContainer resourceContainer;
/**
* {@code ResourceContainer} inherited from parent
*/
AbstractResourceContainer inheritedResourceContainer;
private static synchronized long nextThreadID() {
return ++threadSeqNumber;
}
......@@ -439,6 +444,7 @@ class Thread implements Runnable {
/* com.alibaba.rcm API */
this.resourceContainer = AbstractResourceContainer.root();
this.inheritedResourceContainer = parent.resourceContainer;
/* Set the tenant container */
if (VM.isBooted() && TenantGlobals.isTenantEnabled()) {
......@@ -788,6 +794,8 @@ class Thread implements Runnable {
blocker = null;
uncaughtExceptionHandler = null;
inheritedTenantContainer = null;
resourceContainer = null;
inheritedResourceContainer = null;
}
/**
......
......@@ -145,4 +145,9 @@ public interface JavaLangAccess {
* Get the reference to the thread attached {@code ResourceContainer}
*/
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 {
MyResourceType.MY_RESOURCE1.newConstraint(),
MyResourceType.MY_RESOURCE2.newConstraint()));
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());
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) {
......
......@@ -28,6 +28,7 @@
*/
import com.alibaba.rcm.ResourceContainer;
import demo.RCInheritedThreadFactory;
import demo.MyResourceFactory;
import java.util.Collections;
......@@ -44,23 +45,23 @@ public class TestInherit {
rc.run(() -> {
assertEQ(ResourceContainer.current(), rc);
FutureTask<ResourceContainer> f1 = new FutureTask<>(ResourceContainer::current);
new Thread(f1).start();
RCInheritedThreadFactory.INSTANCE.newThread(f1).start();
assertEQ(get(f1), rc);
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());
});
// thread is bound to it's parent thread(the thread called Thread::init())
// not dependent on where Thread::start() called.
FutureTask<ResourceContainer> f3 = new FutureTask<>(ResourceContainer::current);
Thread t3 = new Thread(f3);
Thread t3 = RCInheritedThreadFactory.INSTANCE.newThread(f3);
// Thread::init is called in root()
rc.run(t3::start);
assertEQ(get(f3), ResourceContainer.root());
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
rc.run(newThread);
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.
先完成此消息的编辑!
想要评论请 注册