Attempt at fixing Issue 500: Sequential creation of related columns using apply-operation command

by letting long-running processes report errors.

git-svn-id: http://google-refine.googlecode.com/svn/trunk@2394 7d457c2a-affb-35e4-300a-418c747d4874
This commit is contained in:
David Huynh 2011-11-30 23:54:40 +00:00
parent 4a8145d624
commit a7e2704655
3 changed files with 60 additions and 8 deletions

View File

@ -148,14 +148,6 @@ public class ColumnAdditionByFetchingURLsOperation extends EngineDependentOperat
@Override @Override
public Process createProcess(Project project, Properties options) throws Exception { public Process createProcess(Project project, Properties options) throws Exception {
Column column = project.columnModel.getColumnByName(_baseColumnName);
if (column == null) {
throw new Exception("No column named " + _baseColumnName);
}
if (project.columnModel.getColumnByName(_newColumnName) != null) {
throw new Exception("Another column already named " + _newColumnName);
}
Engine engine = createEngine(project); Engine engine = createEngine(project);
engine.initializeFromJSON(_engineConfig); engine.initializeFromJSON(_engineConfig);
@ -209,6 +201,16 @@ public class ColumnAdditionByFetchingURLsOperation extends EngineDependentOperat
@Override @Override
public void run() { public void run() {
Column column = _project.columnModel.getColumnByName(_baseColumnName);
if (column == null) {
_project.processManager.onFailedProcess(this, new Exception("No column named " + _baseColumnName));
return;
}
if (_project.columnModel.getColumnByName(_newColumnName) != null) {
_project.processManager.onFailedProcess(this, new Exception("Another column already named " + _newColumnName));
return;
}
List<CellAtRow> urls = new ArrayList<CellAtRow>(_project.rows.size()); List<CellAtRow> urls = new ArrayList<CellAtRow>(_project.rows.size());
FilteredRows filteredRows = _engine.getAllFilteredRows(); FilteredRows filteredRows = _engine.getAllFilteredRows();

View File

@ -46,6 +46,7 @@ import com.google.refine.history.HistoryProcess;
public class ProcessManager implements Jsonizable { public class ProcessManager implements Jsonizable {
protected List<Process> _processes = new LinkedList<Process>(); protected List<Process> _processes = new LinkedList<Process>();
protected List<Exception> _latestExceptions = null;
public ProcessManager() { public ProcessManager() {
@ -62,11 +63,22 @@ public class ProcessManager implements Jsonizable {
} }
writer.endArray(); writer.endArray();
if (_latestExceptions != null) {
writer.key("exceptions"); writer.array();
for (Exception e : _latestExceptions) {
writer.object();
writer.key("message"); writer.value(e.getLocalizedMessage());
writer.endObject();
}
writer.endArray();
}
writer.endObject(); writer.endObject();
} }
public HistoryEntry queueProcess(Process process) throws Exception { public HistoryEntry queueProcess(Process process) throws Exception {
if (process.isImmediate() && _processes.size() == 0) { if (process.isImmediate() && _processes.size() == 0) {
_latestExceptions = null;
return process.performImmediate(); return process.performImmediate();
} else { } else {
_processes.add(process); _processes.add(process);
@ -78,6 +90,7 @@ public class ProcessManager implements Jsonizable {
public boolean queueProcess(HistoryProcess process) throws Exception { public boolean queueProcess(HistoryProcess process) throws Exception {
if (process.isImmediate() && _processes.size() == 0) { if (process.isImmediate() && _processes.size() == 0) {
_latestExceptions = null;
return process.performImmediate() != null; return process.performImmediate() != null;
} else { } else {
_processes.add(process); _processes.add(process);
@ -96,6 +109,18 @@ public class ProcessManager implements Jsonizable {
update(); update();
} }
public void onFailedProcess(Process p, Exception exception) {
List<Exception> exceptions = new LinkedList<Exception>();
exceptions.add(exception);
onFailedProcess(p, exceptions);
}
public void onFailedProcess(Process p, List<Exception> exceptions) {
_latestExceptions = exceptions;
_processes.remove(p);
// Do not call update(); Just pause?
}
public void cancelAll() { public void cancelAll() {
for (Process p : _processes) { for (Process p : _processes) {
if (!p.isImmediate() && p.isRunning()) { if (!p.isImmediate() && p.isRunning()) {
@ -103,12 +128,14 @@ public class ProcessManager implements Jsonizable {
} }
} }
_processes.clear(); _processes.clear();
_latestExceptions = null;
} }
protected void update() { protected void update() {
while (_processes.size() > 0) { while (_processes.size() > 0) {
Process p = _processes.get(0); Process p = _processes.get(0);
if (p.isImmediate()) { if (p.isImmediate()) {
_latestExceptions = null;
try { try {
p.performImmediate(); p.performImmediate();
} catch (Exception e) { } catch (Exception e) {
@ -120,6 +147,7 @@ public class ProcessManager implements Jsonizable {
_processes.remove(0); _processes.remove(0);
} else { } else {
if (!p.isRunning()) { if (!p.isRunning()) {
_latestExceptions = null;
p.startPerforming(this); p.startPerforming(this);
} }
break; break;

View File

@ -191,6 +191,28 @@ ProcessPanel.prototype._render = function(newData) {
} }
this._data = newData; this._data = newData;
if (this._data.exceptions) {
var messages = $.map(this._data.exceptions, function(e) {
return e.message;
}).join('\n');
if (this._data.processes.length == 0) {
window.alert('The last operation encountered some errors:\n' + messages);
} else {
if (window.confirm('The last operation encountered some errors:\n' + messages +
'\n\nContinue with the remaining operations?')) {
$.post(
"/command/core/apply-operations?" + $.param({ project: theProject.id }),
{ operations: '[]' },
function(o) {},
"json"
);
} else {
self._cancelAll();
}
}
}
if (this._data.processes.length && !this._timerID) { if (this._data.processes.length && !this._timerID) {
this._timerID = window.setTimeout(function() { this._timerID = window.setTimeout(function() {
self._timerID = null; self._timerID = null;