Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CHE-3464: fix a problem with stopping the process #3613

Merged
merged 3 commits into from
Jan 13, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,7 @@
import com.google.web.bindery.event.shared.EventBus;

import org.eclipse.che.api.core.model.machine.Machine;
import org.eclipse.che.api.core.rest.shared.dto.Link;
import org.eclipse.che.api.machine.shared.Constants;
import org.eclipse.che.api.machine.shared.dto.MachineProcessDto;
import org.eclipse.che.api.machine.shared.dto.event.MachineProcessEvent;
import org.eclipse.che.api.machine.shared.dto.execagent.ProcessKillResponseDto;
import org.eclipse.che.api.machine.shared.dto.execagent.ProcessSubscribeResponseDto;
import org.eclipse.che.api.machine.shared.dto.execagent.event.ProcessDiedEventDto;
Expand All @@ -28,24 +25,12 @@
import org.eclipse.che.api.machine.shared.dto.execagent.event.ProcessStdOutEventDto;
import org.eclipse.che.api.promises.client.Operation;
import org.eclipse.che.api.promises.client.OperationException;
import org.eclipse.che.api.promises.client.PromiseError;
import org.eclipse.che.ide.api.command.CommandImpl;
import org.eclipse.che.ide.api.command.CommandManager;
import org.eclipse.che.ide.api.machine.CommandOutputMessageUnmarshaller;
import org.eclipse.che.ide.api.machine.ExecAgentCommandManager;
import org.eclipse.che.ide.api.macro.MacroProcessor;
import org.eclipse.che.ide.extension.machine.client.MachineResources;
import org.eclipse.che.ide.extension.machine.client.processes.ProcessFinishedEvent;
import org.eclipse.che.ide.rest.AsyncRequestFactory;
import org.eclipse.che.ide.rest.DtoUnmarshallerFactory;
import org.eclipse.che.ide.rest.StringUnmarshaller;
import org.eclipse.che.ide.util.loging.Log;
import org.eclipse.che.ide.websocket.MessageBus;
import org.eclipse.che.ide.websocket.MessageBusProvider;
import org.eclipse.che.ide.websocket.WebSocketException;
import org.eclipse.che.ide.websocket.events.MessageHandler;
import org.eclipse.che.ide.websocket.rest.SubscriptionHandler;
import org.eclipse.che.ide.websocket.rest.Unmarshallable;
import org.vectomatic.dom.svg.ui.SVGResource;

import java.util.ArrayList;
Expand All @@ -62,20 +47,15 @@
public class CommandOutputConsolePresenter implements CommandOutputConsole, OutputConsoleView.ActionDelegate {

private final OutputConsoleView view;
private final DtoUnmarshallerFactory dtoUnmarshallerFactory;
private final MachineResources resources;
private final CommandImpl command;
private final EventBus eventBus;
private final Machine machine;
private final CommandManager commandManager;
private final AsyncRequestFactory asyncRequestFactory;
private final ExecAgentCommandManager execAgentCommandManager;
private final MessageBus messageBus;

private int pid;
private boolean finished;
private String outputChannel;
private MessageHandler outputHandler;

/** Wrap text or not */
private boolean wrapText = false;
Expand All @@ -87,21 +67,15 @@ public class CommandOutputConsolePresenter implements CommandOutputConsole, Outp

@Inject
public CommandOutputConsolePresenter(final OutputConsoleView view,
DtoUnmarshallerFactory dtoUnmarshallerFactory,
final MessageBusProvider messageBusProvider,
MachineResources resources,
CommandManager commandManager,
MacroProcessor macroProcessor,
EventBus eventBus,
AsyncRequestFactory asyncRequestFactory,
ExecAgentCommandManager execAgentCommandManager,
@Assisted CommandImpl command,
@Assisted Machine machine) {
this.view = view;
this.dtoUnmarshallerFactory = dtoUnmarshallerFactory;
this.messageBus = messageBusProvider.getMessageBus();
this.resources = resources;
this.asyncRequestFactory = asyncRequestFactory;
this.execAgentCommandManager = execAgentCommandManager;
this.command = command;
this.machine = machine;
Expand Down Expand Up @@ -147,113 +121,10 @@ public SVGResource getTitleIcon() {

@Override
public void listenToOutput(String wsChannel) {
view.enableStopButton(true);
view.toggleScrollToEndButton(true);

outputChannel = wsChannel;
outputHandler = new SubscriptionHandler<String>(new CommandOutputMessageUnmarshaller(machine.getConfig().getName())) {
@Override
protected void onMessageReceived(String result) {
view.print(result, result.endsWith("\r"));

for (ActionDelegate actionDelegate : actionDelegates) {
actionDelegate.onConsoleOutput(CommandOutputConsolePresenter.this);
}
}

@Override
protected void onErrorReceived(Throwable exception) {
wsUnsubscribe(outputChannel, this);
}
};

wsSubscribe(outputChannel, outputHandler);
}

@Override
public void attachToProcess(MachineProcessDto process) {
this.pid = process.getPid();
view.showCommandLine(process.getCommandLine());
//try to restore previous log of the process
final Link link = process.getLink(Constants.LINK_REL_GET_PROCESS_LOGS);
if (link != null) {
asyncRequestFactory.createGetRequest(link.getHref()).send(new StringUnmarshaller()).then(
new Operation<String>() {
@Override
public void apply(String arg) throws OperationException {
view.print(arg.replaceAll("\\[STDOUT\\] ", ""), false);//logs comes from server side with ""[STDOUT] " in start
//so we will remove it in this brutal way
handelProcessEvents(); //start handel incoming events
}
}).catchError(new Operation<PromiseError>() {
@Override
public void apply(PromiseError arg) throws OperationException {
Log.error(getClass(), arg);
//if logs not found will handel incoming events any way
handelProcessEvents();
}
});
} else {
handelProcessEvents();
}
}

private void handelProcessEvents() {
final Unmarshallable<MachineProcessEvent> unmarshaller = dtoUnmarshallerFactory.newWSUnmarshaller(MachineProcessEvent.class);
final String processStateChannel = "machine:process:" + machine.getId();
final MessageHandler handler = new SubscriptionHandler<MachineProcessEvent>(unmarshaller) {
@Override
protected void onMessageReceived(MachineProcessEvent result) {
final int processId = result.getProcessId();
if (pid != processId) {
return;
}
switch (result.getEventType()) {
case STOPPED:
finished = true;
view.enableStopButton(false);
eventBus.fireEvent(new ProcessFinishedEvent(processId));
break;
case ERROR:
finished = true;
view.enableStopButton(false);
eventBus.fireEvent(new ProcessFinishedEvent(processId));
wsUnsubscribe(processStateChannel, this);
wsUnsubscribe(outputChannel, outputHandler);
String error = result.getError();
if (error == null) {
return;
}
view.print(error, false);
break;
}
}

@Override
protected void onErrorReceived(Throwable exception) {
finished = true;
view.enableStopButton(false);
wsUnsubscribe(processStateChannel, this);
wsUnsubscribe(outputChannel, outputHandler);
}
};
wsSubscribe(processStateChannel, handler);
}

private void wsSubscribe(String wsChannel, MessageHandler handler) {
try {
messageBus.subscribe(wsChannel, handler);
} catch (WebSocketException e) {
Log.error(getClass(), e);
}
}

private void wsUnsubscribe(String wsChannel, MessageHandler handler) {
try {
messageBus.unsubscribe(wsChannel, handler);
} catch (WebSocketException e) {
Log.error(getClass(), e);
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@

import org.eclipse.che.api.core.model.machine.Command;
import org.eclipse.che.api.core.model.machine.Machine;
import static org.eclipse.che.api.core.model.machine.MachineStatus.CREATING;
import org.eclipse.che.api.core.model.machine.Server;
import org.eclipse.che.api.core.model.workspace.Environment;
import org.eclipse.che.api.core.model.workspace.ExtendedMachine;
Expand Down Expand Up @@ -92,6 +91,7 @@
import static com.google.common.base.Strings.isNullOrEmpty;
import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
import static org.eclipse.che.api.core.model.machine.MachineStatus.CREATING;
import static org.eclipse.che.api.core.model.machine.MachineStatus.RUNNING;
import static org.eclipse.che.api.machine.shared.Constants.TERMINAL_REFERENCE;
import static org.eclipse.che.ide.api.notification.StatusNotification.DisplayMode.FLOAT_MODE;
Expand Down Expand Up @@ -1081,8 +1081,9 @@ public void apply(PromiseError arg) throws OperationException {
private void subscribeToProcess(CommandOutputConsole console, int pid) {
String stderr = "stderr";
String stdout = "stdout";
String processStatus = "process_status";
String after = null;
execAgentCommandManager.subscribe(machine.getId(), pid, asList(stderr, stdout), after)
execAgentCommandManager.subscribe(machine.getId(), pid, asList(stderr, stdout, processStatus), after)
.thenIfProcessStartedEvent(console.getProcessStartedOperation())
.thenIfProcessDiedEvent(console.getProcessDiedOperation())
.thenIfProcessStdOutEvent(console.getStdOutOperation())
Expand Down