Example #1
0
    /** Start a server that handles the supplied protocol. */
    public boolean startServer(final int port) {
      if (server == null) {
        return false; // Did not initialize yet.
      }

      // Create a new connection & state manager.
      final CommManager manager = new CommManager();

      // Create a new pipeline. This time use an anonymous class.
      server.setPipelineFactory(
          new ChannelPipelineFactory() {
            public ChannelPipeline getPipeline() {
              return Channels.pipeline(
                  new PaxosMessageDecoder(), new PaxosMessageEncoder(), manager);
            }
          });

      try { // Try to bind to the given port.
        serverChannel = server.bind(new InetSocketAddress(port));
        return true;
      } catch (Exception e) {
        e.printStackTrace();
        return false;
      }
    }
  @Nullable
  public RequestFuture scheduleBuild(
      final Project project,
      final boolean isRebuild,
      final boolean isMake,
      final Collection<String> modules,
      final Collection<String> artifacts,
      final Collection<String> paths,
      final Map<String, String> userData,
      DefaultMessageHandler handler) {

    final String projectPath = getProjectPath(project);
    final UUID sessionId = UUID.randomUUID();
    final CmdlineRemoteProto.Message.ControllerMessage params;
    CmdlineRemoteProto.Message.ControllerMessage.GlobalSettings globals = myGlobals;
    if (globals == null) {
      globals = buildGlobalSettings();
      myGlobals = globals;
    }

    CmdlineRemoteProto.Message.ControllerMessage.FSEvent currentFSChanges = null;
    final SequentialTaskExecutor projectTaskQueue;
    synchronized (myProjectDataMap) {
      ProjectData data = myProjectDataMap.get(projectPath);
      if (data == null) {
        data = new ProjectData(new SequentialTaskExecutor(myPooledThreadExecutor));
        myProjectDataMap.put(projectPath, data);
      }
      if (isRebuild) {
        data.dropChanges();
      }
      currentFSChanges = data.getAndResetRescanFlag() ? null : data.createNextEvent();
      projectTaskQueue = data.taskQueue;
    }

    if (isRebuild) {
      params = CmdlineProtoUtil.createRebuildRequest(projectPath, userData, globals);
    } else {
      params =
          isMake
              ? CmdlineProtoUtil.createMakeRequest(
                  projectPath, modules, artifacts, userData, globals, currentFSChanges)
              : CmdlineProtoUtil.createForceCompileRequest(
                  projectPath, modules, artifacts, paths, userData, globals, currentFSChanges);
    }

    myMessageDispatcher.registerBuildMessageHandler(sessionId, handler, params);

    // ensure server is listening
    if (myListenPort < 0) {
      try {
        myListenPort = startListening();
      } catch (Exception e) {
        myMessageDispatcher.unregisterBuildMessageHandler(sessionId);
        handler.handleFailure(sessionId, CmdlineProtoUtil.createFailure(e.getMessage(), null));
        handler.sessionTerminated();
        return null;
      }
    }

    final RequestFuture<BuilderMessageHandler> future =
        new RequestFuture<BuilderMessageHandler>(
            handler,
            sessionId,
            new RequestFuture.CancelAction<BuilderMessageHandler>() {
              @Override
              public void cancel(RequestFuture<BuilderMessageHandler> future) throws Exception {
                myMessageDispatcher.cancelSession(future.getRequestID());
              }
            });

    projectTaskQueue.submit(
        new Runnable() {
          @Override
          public void run() {
            try {
              if (project.isDisposed()) {
                future.cancel(false);
                return;
              }
              myBuildsInProgress.put(projectPath, future);
              final Process process = launchBuildProcess(project, myListenPort, sessionId);
              final OSProcessHandler processHandler =
                  new OSProcessHandler(process, null) {
                    @Override
                    protected boolean shouldDestroyProcessRecursively() {
                      return true;
                    }
                  };
              final StringBuilder stdErrOutput = new StringBuilder();
              processHandler.addProcessListener(
                  new ProcessAdapter() {
                    @Override
                    public void processTerminated(ProcessEvent event) {
                      final BuilderMessageHandler handler =
                          myMessageDispatcher.unregisterBuildMessageHandler(sessionId);
                      if (handler != null) {
                        handler.sessionTerminated();
                      }
                    }

                    @Override
                    public void onTextAvailable(ProcessEvent event, Key outputType) {
                      // re-translate builder's output to idea.log
                      final String text = event.getText();
                      if (!StringUtil.isEmpty(text)) {
                        LOG.info("BUILDER_PROCESS [" + outputType.toString() + "]: " + text.trim());
                        if (stdErrOutput.length() < 1024
                            && ProcessOutputTypes.STDERR.equals(outputType)) {
                          stdErrOutput.append(text);
                        }
                      }
                    }
                  });
              processHandler.startNotify();
              final boolean terminated = processHandler.waitFor();
              if (terminated) {
                final int exitValue = processHandler.getProcess().exitValue();
                if (exitValue != 0) {
                  final StringBuilder msg = new StringBuilder();
                  msg.append("Abnormal build process termination: ");
                  if (stdErrOutput.length() > 0) {
                    msg.append("\n").append(stdErrOutput);
                  } else {
                    msg.append("unknown error");
                  }
                  future
                      .getMessageHandler()
                      .handleFailure(
                          sessionId, CmdlineProtoUtil.createFailure(msg.toString(), null));
                }
              } else {
                future
                    .getMessageHandler()
                    .handleFailure(
                        sessionId,
                        CmdlineProtoUtil.createFailure("Disconnected from build process", null));
              }
            } catch (ExecutionException e) {
              myMessageDispatcher.unregisterBuildMessageHandler(sessionId);
              future
                  .getMessageHandler()
                  .handleFailure(sessionId, CmdlineProtoUtil.createFailure(e.getMessage(), e));
              future.getMessageHandler().sessionTerminated();
            } finally {
              myBuildsInProgress.remove(projectPath);
              future.setDone();
            }
          }
        });

    return future;
  }