compiler.shared.event.group

This commit is contained in:
Vladimir Krivosheev
2016-06-16 13:07:23 +02:00
parent 09cd61e37d
commit 031bd1a73a
6 changed files with 43 additions and 22 deletions
@@ -36,6 +36,7 @@ import com.intellij.execution.process.ProcessHandler;
import com.intellij.ide.DataManager;
import com.intellij.ide.PowerSaveMode;
import com.intellij.ide.file.BatchFileChangeListener;
import com.intellij.idea.StartupUtil;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.application.Application;
@@ -90,7 +91,9 @@ import gnu.trove.THashSet;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.oio.OioEventLoopGroup;
import io.netty.handler.codec.protobuf.ProtobufDecoder;
import io.netty.handler.codec.protobuf.ProtobufEncoder;
import io.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder;
@@ -98,6 +101,7 @@ import io.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender;
import io.netty.util.internal.ThreadLocalRandom;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.io.BuiltInServer;
import org.jetbrains.io.ChannelRegistrar;
import org.jetbrains.io.NettyKt;
import org.jetbrains.jps.api.*;
@@ -160,7 +164,7 @@ public class BuildManager implements Disposable {
private final ExecutorService myRequestsProcessor = SequentialTaskExecutor.createSequentialApplicationPoolExecutor();
private final Map<String, ProjectData> myProjectDataMap = Collections.synchronizedMap(new HashMap<String, ProjectData>());
private final BuildManagerPeriodicTask myAutoMakeTask = new BuildManagerPeriodicTask() {
private final BuildManagerPeriodicTask myAutoMakeTask = new BuildManagerPeriodicTask(this) {
@Override
protected int getDelay() {
return Registry.intValue("compiler.automake.trigger.delay");
@@ -172,7 +176,7 @@ public class BuildManager implements Disposable {
}
};
private final BuildManagerPeriodicTask myDocumentSaveTask = new BuildManagerPeriodicTask() {
private final BuildManagerPeriodicTask myDocumentSaveTask = new BuildManagerPeriodicTask(this) {
@Override
protected int getDelay() {
return Registry.intValue("compiler.document.save.trigger.delay");
@@ -1293,11 +1297,20 @@ public class BuildManager implements Disposable {
@NotNull
private Future<?> stopListening() {
myListenPort = -1;
return myChannelRegistrar.close(true);
return myChannelRegistrar.close();
}
private int startListening() throws Exception {
final ServerBootstrap bootstrap = NettyKt.serverBootstrap(new NioEventLoopGroup(1, ConcurrencyUtil.newNamedThreadFactory("External compiler")));
EventLoopGroup group;
BuiltInServer mainServer = StartupUtil.getServer();
boolean isOwnEventLoopGroup = !Registry.is("compiler.shared.event.group", false) || mainServer == null || mainServer.getEventLoopGroup() instanceof OioEventLoopGroup;
if (isOwnEventLoopGroup) {
group = new NioEventLoopGroup(1, ConcurrencyUtil.newNamedThreadFactory("External compiler"));
}
else {
group = mainServer.getEventLoopGroup();
}
final ServerBootstrap bootstrap = NettyKt.serverBootstrap(group);
bootstrap.childHandler(new ChannelInitializer() {
@Override
protected void initChannel(@NotNull Channel channel) throws Exception {
@@ -1310,7 +1323,7 @@ public class BuildManager implements Disposable {
}
});
Channel serverChannel = bootstrap.bind(InetAddress.getLoopbackAddress(), 0).syncUninterruptibly().channel();
myChannelRegistrar.add(serverChannel);
myChannelRegistrar.add(serverChannel, isOwnEventLoopGroup);
return ((InetSocketAddress)serverChannel.localAddress()).getPort();
}
@@ -1337,7 +1350,7 @@ public class BuildManager implements Disposable {
}
private abstract static class BuildManagerPeriodicTask implements Runnable {
private final Alarm myAlarm = new Alarm(Alarm.ThreadToUse.POOLED_THREAD);
private final Alarm myAlarm;
private final AtomicBoolean myInProgress = new AtomicBoolean(false);
private final Runnable myTaskRunnable = () -> {
try {
@@ -1348,6 +1361,10 @@ public class BuildManager implements Disposable {
}
};
protected BuildManagerPeriodicTask(@NotNull Disposable disposable) {
myAlarm = new Alarm(Alarm.ThreadToUse.POOLED_THREAD, disposable);
}
public final void schedule() {
cancelPendingExecution();
final int delay = Math.max(100, getDelay());
@@ -76,7 +76,7 @@ public final class SubServer implements CustomPortServerManager.CustomPortServic
try {
bootstrap.localAddress(user.isAvailableExternally() ? new InetSocketAddress(port) : NetKt.loopbackSocketAddress(port));
channelRegistrar.add(bootstrap.bind().syncUninterruptibly().channel());
channelRegistrar.add(bootstrap.bind().syncUninterruptibly().channel(), false);
return true;
}
catch (Exception e) {
@@ -97,7 +97,7 @@ public final class SubServer implements CustomPortServerManager.CustomPortServic
private void stop() {
if (channelRegistrar != null) {
channelRegistrar.close(false);
channelRegistrar.close();
}
}
@@ -41,7 +41,6 @@ public class BuiltInServer implements Disposable {
private final EventLoopGroup eventLoopGroup;
private final int port;
private final ChannelRegistrar channelRegistrar;
private final boolean isOwnerOfEventLoopGroup;
static {
// IDEA-120811
@@ -54,12 +53,10 @@ public class BuiltInServer implements Disposable {
private BuiltInServer(@NotNull EventLoopGroup eventLoopGroup,
int port,
@NotNull ChannelRegistrar channelRegistrar,
boolean isOwnerOfEventLoopGroup) {
@NotNull ChannelRegistrar channelRegistrar) {
this.eventLoopGroup = eventLoopGroup;
this.port = port;
this.channelRegistrar = channelRegistrar;
this.isOwnerOfEventLoopGroup = isOwnerOfEventLoopGroup;
}
@NotNull
@@ -77,7 +74,7 @@ public class BuiltInServer implements Disposable {
@Override
public void dispose() {
channelRegistrar.close(isOwnerOfEventLoopGroup);
channelRegistrar.close();
Logger.getInstance(BuiltInServer.class).info("web server stopped");
}
@@ -118,8 +115,8 @@ public class BuiltInServer implements Disposable {
ChannelRegistrar channelRegistrar = new ChannelRegistrar();
ServerBootstrap bootstrap = NettyKt.serverBootstrap(eventLoopGroup);
configureChildHandler(bootstrap, channelRegistrar, handler);
int port = bind(firstPort, portsCount, tryAnyPort, bootstrap, channelRegistrar);
return new BuiltInServer(eventLoopGroup, port, channelRegistrar, isEventLoopGroupOwner);
int port = bind(firstPort, portsCount, tryAnyPort, bootstrap, channelRegistrar, isEventLoopGroupOwner);
return new BuiltInServer(eventLoopGroup, port, channelRegistrar);
}
static void configureChildHandler(@NotNull ServerBootstrap bootstrap,
@@ -138,7 +135,8 @@ public class BuiltInServer implements Disposable {
int portsCount,
boolean tryAnyPort,
@NotNull ServerBootstrap bootstrap,
@NotNull ChannelRegistrar channelRegistrar) throws Exception {
@NotNull ChannelRegistrar channelRegistrar,
boolean isEventLoopGroupOwner) throws Exception {
InetAddress address = InetAddress.getLoopbackAddress();
for (int i = 0; i < portsCount; i++) {
@@ -150,7 +148,7 @@ public class BuiltInServer implements Disposable {
ChannelFuture future = bootstrap.bind(address, port).awaitUninterruptibly();
if (future.isSuccess()) {
channelRegistrar.add(future.channel());
channelRegistrar.add(future.channel(), isEventLoopGroupOwner);
return port;
}
else if (!tryAnyPort && i == portsCount - 1) {
@@ -161,7 +159,7 @@ public class BuiltInServer implements Disposable {
Logger.getInstance(BuiltInServer.class).info("We cannot bind to our default range, so, try to bind to any free port");
ChannelFuture future = bootstrap.bind(address, 0).awaitUninterruptibly();
if (future.isSuccess()) {
channelRegistrar.add(future.channel());
channelRegistrar.add(future.channel(), isEventLoopGroupOwner);
return ((InetSocketAddress)future.channel().localAddress()).getPort();
}
ExceptionUtil.rethrowAll(future.cause());
@@ -32,12 +32,14 @@ public final class ChannelRegistrar extends ChannelInboundHandlerAdapter {
private static final Logger LOG = Logger.getInstance(ChannelRegistrar.class);
private final ChannelGroup openChannels = new DefaultChannelGroup(ImmediateEventExecutor.INSTANCE);
private boolean isEventLoopGroupOwner;
public boolean isEmpty() {
return openChannels.isEmpty();
}
public void add(@NotNull Channel serverChannel) {
public void add(@NotNull Channel serverChannel, boolean isOwnEventLoopGroup) {
this.isEventLoopGroupOwner = isOwnEventLoopGroup;
assert serverChannel instanceof ServerChannel;
openChannels.add(serverChannel);
}
@@ -50,12 +52,13 @@ public final class ChannelRegistrar extends ChannelInboundHandlerAdapter {
super.channelActive(context);
}
public void close() {
close(true);
@NotNull
public Future<?> close() {
return close(isEventLoopGroupOwner);
}
@NotNull
public Future<?> close(boolean shutdownEventLoopGroup) {
private Future<?> close(boolean shutdownEventLoopGroup) {
EventLoopGroup eventLoopGroup = null;
if (shutdownEventLoopGroup) {
for (Channel channel : openChannels) {
@@ -82,6 +82,7 @@ public class ThreadTracker {
wellKnownOffenders.add("main");
wellKnownOffenders.add("Monitor Ctrl-Break");
wellKnownOffenders.add("Netty ");
wellKnownOffenders.add("External compiler");
wellKnownOffenders.add("Reference Handler");
wellKnownOffenders.add("RMI TCP Connection");
wellKnownOffenders.add("Signal Dispatcher");
@@ -255,6 +255,8 @@ compiler.document.save.trigger.delay.description=Delay in milliseconds before tr
compiler.build.data.unused.threshold=30
compiler.build.data.unused.threshold.description=If project is not opened for the specified number of days, its build data will be cleared to save disk space
compiler.shared.event.group=false
vcs.annotations.preload=false
vcs.showConsole=true
vcs.log.bek.sort.disabled=false