From d23b0d22d59c3f8c0cea88f41f2361d7a4f12a94 Mon Sep 17 00:00:00 2001 From: BobHanson Date: Fri, 29 May 2020 07:34:05 -0500 Subject: [PATCH] AsyncFetchTask for SequenceFetcher --- src/jalview/gui/SequenceFetcher.java | 226 +++++++++++++++++++++------------- 1 file changed, 142 insertions(+), 84 deletions(-) diff --git a/src/jalview/gui/SequenceFetcher.java b/src/jalview/gui/SequenceFetcher.java index 549d198..ae4fffd 100755 --- a/src/jalview/gui/SequenceFetcher.java +++ b/src/jalview/gui/SequenceFetcher.java @@ -437,7 +437,6 @@ public class SequenceFetcher extends JPanel public void fetch(String ids, boolean isAsync) { - isAsync &= Platform.isJS(); if (ids == null) { ids = textArea.getText(); @@ -477,33 +476,39 @@ public class SequenceFetcher extends JPanel private class AsyncFetchTask extends AsyncSwingWorker { - private boolean addToLast = false; + protected boolean addToLast = false; - private List aresultq = new ArrayList<>(); + protected List aresultq = new ArrayList<>(); - private List presultTitle = new ArrayList<>(); + protected List presultTitle = new ArrayList<>(); - private List presult = new ArrayList<>(); + protected List presult = new ArrayList<>(); - private List aresult = new ArrayList<>(); + protected List aresult = new ArrayList<>(); - private FeatureSettingsModelI preferredFeatureColours = null; + protected FeatureSettingsModelI preferredFeatureColours = null; - private List sources; + protected List sources; - private Iterator sourceIterator; + protected Iterator sourceIterator; - private String[] fetchArray; + protected String[] fetchArray; - private List fetchList; + protected List fetchList; - private Iterator fetchIterator; + protected Iterator fetchIterator; - private int fetchCount; + protected int fetchCount; - private DbSourceProxy source; + protected DbSourceProxy source; - private String ids; + protected String ids; + + protected long myID; + + protected boolean isAsync; + + protected Throwable taskError; public AsyncFetchTask(String ids, Component owner, String title, int delayMillis, @@ -511,6 +516,8 @@ public class SequenceFetcher extends JPanel { super(owner, title, delayMillis, min, max); this.ids = ids; + isAsync = (delayMillis != 0); + myID = Thread.currentThread().getId(); } @Override @@ -537,9 +544,14 @@ public class SequenceFetcher extends JPanel private final static int STATE_DONE = 100; + protected static final int STATE_TASK_ERROR = 99; + @Override public int doInBackgroundAsync(int progress) { + System.out.println("SequenceFetcher.AsyncFetchTask " + isAsync + " " + + progress + " " + + taskError); switch (progress) { case STATE_INIT: @@ -574,43 +586,55 @@ public class SequenceFetcher extends JPanel case STATE_FETCH_SINGLE: if (fetchIterator.hasNext()) { - // source only handles one accession id at a time - try + return runSubtask(new Runnable() { - if (delayMillis == 0) - { - // for CrossRef2xmlTest only - Thread.sleep(5); - } - String accession = fetchIterator.next(); - if (!fetchSingleAccession(source, accession, aresultq, aresult)) - { - fetchList.add(accession); - } - } catch (Throwable e) - { - if (!showError(e)) + + @Override + public void run() { - return STATE_DONE; + // source only handles one accession id at a time + try + { + if (!isAsync) + { + // for CrossRef2xmlTest only; to "allow the server to breathe" + // (but we are doing that already when isAsync is true) + Thread.sleep(5); + } + String notFound = fetchSingleAccession(source, + fetchIterator.next(), aresultq, aresult); + if (notFound != null) + { + fetchList.add(notFound); + } + } catch (Throwable e) + { + taskError = e; + } } - } - return STATE_FETCH_SINGLE; + }); } return STATE_PROCESS; case STATE_FETCH_MULTIPLE: // proxy can fetch multiple accessions at one time - try + setProgressAsync(STATE_PROCESS); + return runSubtask(new Runnable() { - fetchMultipleAccessions(source, fetchIterator, aresultq, aresult, - fetchList); - } catch (Throwable e) - { - if (!showError(e)) + + @Override + public void run() { - return STATE_DONE; + try + { + fetchMultipleAccessions(source, fetchIterator, aresultq, + aresult, fetchList); + } catch (Throwable e) + { + taskError = e; + } } - } - return STATE_PROCESS; + + }); case STATE_PROCESS: // Stack results ready for opening in alignment windows if (aresult != null && aresult.size() > 0) @@ -668,13 +692,63 @@ public class SequenceFetcher extends JPanel preferredFeatureColours); } break; + case STATE_TASK_ERROR: + showProgress(null); + super.cancelAsync(); + return 0; // arbitrary; ignored } return STATE_DONE; } - private void showProgress(String msg) + protected void resume() { - guiWindow.setProgressBar(msg, Thread.currentThread().hashCode()); + if (!isAsync) + { + return; + } + super.setPaused(false); + super.stateLoop(); + } + + private int runSubtask(Runnable subtask) + { + + Runnable r = new Runnable() + { + + @Override + public void run() + { + try + { + subtask.run(); + } catch (Throwable e) + { + taskError = e; + } + if (checkError(taskError)) + { + setProgressAsync(STATE_TASK_ERROR); + } + else + { + taskError = null; + } + if (isAsync) + { + resume(); + } + } + }; + + if (isAsync) + { + super.setPaused(true); + new Thread(r).start(); + return 0; // arbitrary return -- ignored because we are paused. + } + r.run(); + return super.getProgressAsync(); } @Override @@ -706,8 +780,17 @@ public class SequenceFetcher extends JPanel resetDialog(); } - private boolean showError(Throwable e) + /** + * + * @param e + * @return true if there was an error and we need to STOP + */ + protected boolean checkError(Throwable e) { + if (e == null) + { + return false; + } String problem = "retrieving " + ids + " from " + database.getSelectedItem(); if (e instanceof Exception) @@ -733,6 +816,11 @@ public class SequenceFetcher extends JPanel return true; } + private void showProgress(String msg) + { + guiWindow.setProgressBar(msg, myID); + } + } /** @@ -800,49 +888,19 @@ public class SequenceFetcher extends JPanel * a list of successful queries to add to * @param aresult * a list of retrieved alignments to add to - * @return true if the fetch was successful, else false + * @return null if the fetch was successful; the accession if not */ - boolean fetchSingleAccession(DbSourceProxy proxy, String accession, - List aresultq, List aresult) + String fetchSingleAccession(DbSourceProxy proxy, String accession, + List aresultq, List aresult) throws Throwable { - boolean success = false; - try - { - // BH no longer necessary; we are doing 5-ms asynchronous delays all along - // if (aresult != null) - // { - // try - // { - // // give the server a chance to breathe - // Thread.sleep(5); - // } catch (Exception e) - // { - // // - // } - // } - // - AlignmentI indres = null; - try - { - indres = proxy.getSequenceRecords(accession); - } catch (OutOfMemoryError oome) - { - new OOMWarning( - "fetching " + accession + " from " + proxy.getDbName(), - oome, this); - } - if (indres != null) - { - aresultq.add(accession); - aresult.add(indres); - success = true; - } - } catch (Exception e) + AlignmentI indres = proxy.getSequenceRecords(accession); + if (indres == null) { - Cache.log.info("Error retrieving " + accession + " from " - + proxy.getDbName(), e); + return accession; } - return success; + aresultq.add(accession); + aresult.add(indres); + return null; } /** -- 1.7.10.2