Skip to content

Commit 2ae31d3

Browse files
committed
Submit in cancellable bg task
1 parent cbb82a5 commit 2ae31d3

File tree

2 files changed

+44
-169
lines changed

2 files changed

+44
-169
lines changed
Lines changed: 3 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,15 @@
11
package fi.helsinki.cs.tmc.actions;
22

3-
import com.google.common.util.concurrent.FutureCallback;
4-
import com.google.common.util.concurrent.Futures;
5-
import com.google.common.util.concurrent.ListenableFuture;
6-
import fi.helsinki.cs.tmc.data.ResultCollector;
73
import fi.helsinki.cs.tmc.events.TmcEvent;
8-
import fi.helsinki.cs.tmc.events.TmcEventBus;
94

105
import fi.helsinki.cs.tmc.model.CourseDb;
116
import fi.helsinki.cs.tmc.model.NbTmcSettings;
127
import fi.helsinki.cs.tmc.model.ProjectMediator;
138
import fi.helsinki.cs.tmc.model.TmcCoreSingleton;
149
import fi.helsinki.cs.tmc.model.TmcProjectInfo;
1510
import fi.helsinki.cs.tmc.ui.ConvenientDialogDisplayer;
16-
import fi.helsinki.cs.tmc.ui.SubmissionResultWaitingDialog;
17-
import fi.helsinki.cs.tmc.ui.TestResultDisplayer;
1811
import fi.helsinki.cs.tmc.core.TmcCore;
19-
import fi.helsinki.cs.tmc.core.domain.Exercise;
20-
import fi.helsinki.cs.tmc.core.domain.submission.SubmissionResult;
21-
import fi.helsinki.cs.tmc.core.exceptions.TmcCoreException;
22-
import java.nio.file.Path;
23-
import java.nio.file.Paths;
24-
import java.util.logging.Level;
25-
import java.util.logging.Logger;
26-
import javax.swing.SwingUtilities;
12+
import fi.helsinki.cs.tmc.exerciseSubmitter.ExerciseSubmitter;
2713
import org.netbeans.api.project.Project;
2814
import org.openide.nodes.Node;
2915
import org.openide.util.NbBundle.Messages;
@@ -70,30 +56,7 @@ protected ProjectMediator getProjectMediator() {
7056

7157
@Override
7258
protected void performAction(Node[] nodes) {
73-
74-
projectMediator.saveAllFiles();
75-
76-
Project[] projects = projectsFromNodes(nodes).toArray(new Project[0]);
77-
for (Project project : projects) {
78-
TmcProjectInfo info = projectMediator.wrapProject(project);
79-
TmcEventBus.getDefault().post(new SubmitExerciseAction.InvokedEvent(info));
80-
submitProject(info);
81-
}
82-
}
83-
84-
private void submitProject(TmcProjectInfo info) {
85-
86-
Exercise exercise = projectMediator.tryGetExerciseForProject(info, courseDb);
87-
final SubmissionResultWaitingDialog dialog = SubmissionResultWaitingDialog.createAndShow();
88-
try {
89-
ListenableFuture<SubmissionResult> result;
90-
Path path = Paths.get(info.getProjectDirAbsPath());
91-
result = core.submit(path);
92-
Futures.addCallback(result, new SubmissionCallback(exercise, dialog));
93-
} catch (TmcCoreException ex) {
94-
String message = "There was an error submitting project " + info.getProjectName();
95-
dialogs.displayError(message, ex);
96-
}
59+
new ExerciseSubmitter().performAction(projectsFromNodes(nodes).toArray(new Project[0]));
9760
}
9861

9962
@Override
@@ -106,57 +69,4 @@ protected String iconResource() {
10669
// The setting in layer.xml doesn't work with NodeAction
10770
return "fi/helsinki/cs/tmc/actions/submit.png";
10871
}
109-
110-
private class SubmissionCallback implements FutureCallback<SubmissionResult> {
111-
112-
private Exercise exercise;
113-
private SubmissionResultWaitingDialog dialog;
114-
private TestResultDisplayer resultDisplayer;
115-
116-
private SubmissionCallback(Exercise exercise, SubmissionResultWaitingDialog dialog) {
117-
SubmissionCallback.this.exercise = exercise;
118-
SubmissionCallback.this.dialog = dialog;
119-
SubmissionCallback.this.resultDisplayer = TestResultDisplayer.getInstance();
120-
}
121-
122-
@Override
123-
public void onSuccess(final SubmissionResult result) {
124-
if (result == null) {
125-
System.err.println("Result is null.");
126-
}
127-
SwingUtilities.invokeLater(new Runnable() {
128-
129-
@Override
130-
public void run() {
131-
dialog.close();
132-
final ResultCollector resultCollector = new ResultCollector(exercise);
133-
resultCollector.setValidationResult(result.getValidationResult());
134-
135-
resultDisplayer.showSubmissionResult(exercise, result, resultCollector);
136-
exercise.setAttempted(true);
137-
if (result.isAllTestsPassed()) {
138-
exercise.setCompleted(true);
139-
}
140-
courseDb.save();
141-
new CheckForNewExercisesOrUpdates(true, false).run();
142-
}
143-
});
144-
}
145-
146-
@Override
147-
public void onFailure(final Throwable ex) {
148-
SwingUtilities.invokeLater(new Runnable() {
149-
150-
@Override
151-
public void run() {
152-
Logger log = Logger.getLogger(SubmitExerciseAction.class.getName());
153-
log.log(Level.INFO, "Error waiting for results from server.", ex);
154-
String msg = ServerErrorHelper.getServerExceptionMsg(ex);
155-
dialogs.displayError("Error trying to get test results.", ex);
156-
dialog.close();
157-
}
158-
159-
});
160-
}
161-
}
162-
}
72+
}
Lines changed: 41 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package fi.helsinki.cs.tmc.exerciseSubmitter;
22

3+
import com.google.common.base.Strings;
4+
import com.google.common.util.concurrent.ListenableFuture;
35
import fi.helsinki.cs.tmc.actions.CheckForNewExercisesOrUpdates;
46
import fi.helsinki.cs.tmc.actions.ServerErrorHelper;
57
import fi.helsinki.cs.tmc.actions.SubmitExerciseAction;
@@ -11,20 +13,15 @@
1113
import fi.helsinki.cs.tmc.model.CourseDb;
1214
import fi.helsinki.cs.tmc.model.ProjectMediator;
1315
import fi.helsinki.cs.tmc.model.ServerAccess;
14-
import fi.helsinki.cs.tmc.model.SubmissionResultWaiter;
1516
import fi.helsinki.cs.tmc.model.TmcProjectInfo;
1617
import fi.helsinki.cs.tmc.model.NbTmcSettings;
18+
import fi.helsinki.cs.tmc.model.TmcCoreSingleton;
1719
import fi.helsinki.cs.tmc.ui.ConvenientDialogDisplayer;
1820
import fi.helsinki.cs.tmc.ui.SubmissionResultWaitingDialog;
1921
import fi.helsinki.cs.tmc.ui.TestResultDisplayer;
2022
import fi.helsinki.cs.tmc.utilities.BgTask;
2123
import fi.helsinki.cs.tmc.utilities.BgTaskListener;
2224
import fi.helsinki.cs.tmc.utilities.CancellableCallable;
23-
import fi.helsinki.cs.tmc.utilities.zip.RecursiveZipper;
24-
25-
import java.util.HashMap;
26-
import java.util.Map;
27-
import java.util.concurrent.Callable;
2825
import java.util.logging.Level;
2926
import java.util.logging.Logger;
3027

@@ -35,7 +32,9 @@ public class ExerciseSubmitter {
3532
private static final Logger log = Logger.getLogger(SubmitExerciseAction.class.getName());
3633

3734
public static class InvokedEvent implements TmcEvent {
35+
3836
public final TmcProjectInfo projectInfo;
37+
3938
public InvokedEvent(TmcProjectInfo projectInfo) {
4039
this.projectInfo = projectInfo;
4140
}
@@ -59,8 +58,7 @@ public ExerciseSubmitter() {
5958
this.eventBus = TmcEventBus.getDefault();
6059
}
6160

62-
63-
public void performAction(Project ... projects) {
61+
public void performAction(Project... projects) {
6462
for (Project nbProject : projects) {
6563
TmcProjectInfo tmcProject = projectMediator.wrapProject(nbProject);
6664
eventBus.post(new InvokedEvent(tmcProject));
@@ -77,53 +75,48 @@ private void submitProject(final TmcProjectInfo project) {
7775
projectMediator.saveAllFiles();
7876

7977
// Oh what a mess :/
80-
8178
final SubmissionResultWaitingDialog dialog = SubmissionResultWaitingDialog.createAndShow();
8279

83-
final BgTaskListener<ServerAccess.SubmissionResponse> submissionListener = new BgTaskListener<ServerAccess.SubmissionResponse>() {
84-
@Override
85-
public void bgTaskReady(ServerAccess.SubmissionResponse response) {
86-
final SubmissionResultWaiter waitingTask = new SubmissionResultWaiter(response.submissionUrl.toString(), dialog);
87-
dialog.setTask(waitingTask);
80+
CancellableCallable<SubmissionResult> submitAndPollTask = new CancellableCallable<SubmissionResult>() {
8881

89-
BgTask.start("Waiting for results from server.", waitingTask, new BgTaskListener<SubmissionResult>() {
82+
ListenableFuture<SubmissionResult> lf;
9083

91-
@Override
92-
public void bgTaskReady(SubmissionResult result) {
84+
@Override
85+
public SubmissionResult call() throws Exception {
86+
lf = TmcCoreSingleton.getInstance().submit(project.getProjectDirAsPath());
87+
return lf.get();
88+
}
9389

94-
dialog.close();
90+
@Override
91+
public boolean cancel() {
92+
return lf.cancel(true);
93+
}
94+
};
9595

96-
final ResultCollector resultCollector = new ResultCollector(exercise);
97-
resultCollector.setValidationResult(result.getValidationResult());
98-
resultDisplayer.showSubmissionResult(exercise, result, resultCollector);
96+
dialog.setTask(submitAndPollTask);
9997

100-
// We change exercise state as a first approximation,
101-
// then refresh from the server and potentially notify the user
102-
// as we might have unlocked new exercises.
103-
exercise.setAttempted(true);
98+
BgTask.start("Submitting and waiting for results from server.", submitAndPollTask, new BgTaskListener<SubmissionResult>() {
10499

105-
if (result.getStatus() == SubmissionResult.Status.OK) {
106-
exercise.setCompleted(true);
107-
}
100+
@Override
101+
public void bgTaskReady(SubmissionResult result) {
102+
dialog.close();
103+
104+
final ResultCollector resultCollector = new ResultCollector(exercise);
105+
resultCollector.setValidationResult(result.getValidationResult());
106+
resultDisplayer.showSubmissionResult(exercise, result, resultCollector);
108107

109-
courseDb.save();
108+
// We change exercise state as a first approximation,
109+
// then refresh from the server and potentially notify the user
110+
// as we might have unlocked new exercises.
111+
exercise.setAttempted(true);
110112

111-
new CheckForNewExercisesOrUpdates(true, false).run();
112-
}
113+
if (result.getStatus() == SubmissionResult.Status.OK) {
114+
exercise.setCompleted(true);
115+
}
113116

114-
@Override
115-
public void bgTaskCancelled() {
116-
dialog.close();
117-
}
117+
courseDb.save();
118118

119-
@Override
120-
public void bgTaskFailed(Throwable ex) {
121-
log.log(Level.INFO, "Error waiting for results from server.", ex);
122-
String msg = ServerErrorHelper.getServerExceptionMsg(ex);
123-
dialogDisplayer.displayError("Error trying to get test results.", ex);
124-
dialog.close();
125-
}
126-
});
119+
new CheckForNewExercisesOrUpdates(true, false).run();
127120
}
128121

129122
@Override
@@ -133,41 +126,13 @@ public void bgTaskCancelled() {
133126

134127
@Override
135128
public void bgTaskFailed(Throwable ex) {
136-
log.log(Level.INFO, "Error submitting exercise.", ex);
129+
log.log(Level.INFO, "Error waiting for results from server.", ex);
137130
String msg = ServerErrorHelper.getServerExceptionMsg(ex);
138-
dialogDisplayer.displayError("Error submitting exercise.", ex);
131+
if (!Strings.isNullOrEmpty(msg)) {
132+
dialogDisplayer.displayError("Error trying to get test results.", ex);
133+
}
139134
dialog.close();
140135
}
141-
};
142-
143-
final String errorMsgLocale = settings.getErrorMsgLocale().toString();
144-
145-
BgTask.start("Zipping up " + exercise.getName(), new Callable<byte[]>() {
146-
@Override
147-
public byte[] call() throws Exception {
148-
RecursiveZipper zipper = new RecursiveZipper(project.getProjectDirAsFile(), project.getZippingDecider());
149-
return zipper.zipProjectSources();
150-
}
151-
}, new BgTaskListener<byte[]>() {
152-
@Override
153-
public void bgTaskReady(byte[] zipData) {
154-
Map<String, String> extraParams = new HashMap<String, String>();
155-
extraParams.put("error_msg_locale", errorMsgLocale);
156-
157-
CancellableCallable<ServerAccess.SubmissionResponse> submitTask = serverAccess.getSubmittingExerciseTask(exercise, zipData, extraParams);
158-
dialog.setTask(submitTask);
159-
BgTask.start("Sending " + exercise.getName(), submitTask, submissionListener);
160-
}
161-
162-
@Override
163-
public void bgTaskCancelled() {
164-
submissionListener.bgTaskCancelled();
165-
}
166-
167-
@Override
168-
public void bgTaskFailed(Throwable ex) {
169-
submissionListener.bgTaskFailed(ex);
170-
}
171136
});
172137
}
173-
}
138+
}

0 commit comments

Comments
 (0)