Permalink
Browse files

Job stopping functionality

  • Loading branch information...
1 parent 300f54d commit 897805ab4dda73d7b09367847fb48dae7244d619 Acerbic committed Oct 11, 2012
View
@@ -28,7 +28,7 @@
/**
* All submitted jobs have their Future's here. For result reporting/error checking/job resubmitting... etc
*/
- private ConcurrentLinkedQueue<Future<?>> results;
+ private ConcurrentLinkedQueue<Future<?>> submittedJobs;
/**
* READCACHEPAGES - get pages tree ONLY from cache (prefetch)
@@ -64,7 +64,7 @@
threadsNumber = CORETHREADS_NUMBER;
executor = Executors.newFixedThreadPool(threadsNumber);
assert (executor instanceof ThreadPoolExecutor);
- results = new ConcurrentLinkedQueue<Future<?>>();
+ submittedJobs = new ConcurrentLinkedQueue<Future<?>>();
this.whatToDo = whatToDo;
this.rootPage = rootPage;
@@ -89,13 +89,22 @@ void goGoGo() {
}
// wait until all the jobs are finished before terminating this thread.
- while (!results.isEmpty())
+ while (!submittedJobs.isEmpty()) {
+ Future<?> job = submittedJobs.poll();
try {
- results.poll().get();
+ job.get(); // can't use awaitTermination, because jobs are submitting other jobs
} catch (InterruptedException | ExecutionException e) {
- // TODO Stop all jobs
+ // Stop all jobs
+ executor.shutdown(); // no new jobs submitted
+
+ job.cancel(true); // stop one we are currently waiting for
+
+ // stop all jobs submitted (whether running or not)
+ for (Future<?> job2: submittedJobs)
+ job2.cancel(true);
break;
}
+ }
executor.shutdown();
}
@@ -106,7 +115,7 @@ void goGoGo() {
*/
synchronized public
void submit (Runnable job) {
- results.add(executor.submit(job));
+ submittedJobs.add(executor.submit(job));
}
@@ -11,6 +11,7 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
import java.nio.file.StandardOpenOption;
import dloader.pagejob.ProgressReporter;
@@ -29,8 +30,9 @@
* @return size of the downloaded file in bytes,
* 0 if download was skipped (file exists and not zero length)
* @throws IOException on stream problems or server has responded bad
+ * @throws InterruptedException
*/
- public static long fetchWebFile(String from, String to, ProgressReporter reporter) throws IOException {
+ public static long fetchWebFile(String from, String to, ProgressReporter reporter) throws IOException, InterruptedException {
URL u = new URL(from);
return fetchWebFile(u,to, reporter);
}
@@ -42,8 +44,9 @@ public static long fetchWebFile(String from, String to, ProgressReporter reporte
* @return size of the downloaded file in bytes,
* 0 if download was skipped (file exists and not zero-length or server has responded badly)
* @throws IOException on stream problems AND on server errors/timeouts
+ * InterruptedException when being interrupted
*/
- public static long fetchWebFile(URL from, String to, ProgressReporter reporter) throws IOException {
+ public static long fetchWebFile(URL from, String to, ProgressReporter reporter) throws IOException, InterruptedException {
StatisticGatherer.totalFileDownloadAttempts.incrementAndGet();
Path dstPath = Paths.get(to);
@@ -59,17 +62,28 @@ public static long fetchWebFile(URL from, String to, ProgressReporter reporter)
else Files.deleteIfExists(dstPath);
else throw new IOException ("Destination is not a regular file");
+ Path tmpPathDir = dstPath.getParent(); // should be directory
+ if (!Files.isDirectory(tmpPathDir))
+ return 0;
+
+ Path tmpFile = Files.createTempFile(tmpPathDir, "tmp_mp3_", "");
+
URLConnection connection = from.openConnection();
if (!checkHttpResponseOK(connection))
throw new IOException("failed to get OK response from server");
if (reporter != null) reporter.report("file size", connection.getContentLengthLong());
long totalRead = 0;
- try (InputStream is = connection.getInputStream();
- SeekableByteChannel boch = Files.newByteChannel(dstPath,
+
+ try ( InputStream is = connection.getInputStream();
+ SeekableByteChannel boch = Files.newByteChannel(
+ tmpFile,
StandardOpenOption.WRITE,
StandardOpenOption.CREATE,
StandardOpenOption.TRUNCATE_EXISTING))
{
+ if (Thread.interrupted()) // Clears interrupted status!
+ throw new InterruptedException();
+
byte[] buff = new byte[1024 * 1024];
ByteBuffer buff2 = ByteBuffer.wrap(buff);
int numRead;
@@ -83,10 +97,12 @@ public static long fetchWebFile(URL from, String to, ProgressReporter reporter)
}
boch.close();
- } catch (IOException e) {
+
+ Files.move(tmpFile, dstPath, StandardCopyOption.REPLACE_EXISTING);
+
+ } finally {
// on actual write loop to the file: delete half-baked file;
- Files.deleteIfExists(dstPath);
- throw e;
+ Files.deleteIfExists(tmpFile);
}
if (Files.exists(dstPath)) {
@@ -38,6 +38,7 @@
private JobMaster jm;
private HashMap<AbstractPage, Long> savingReqJobResults;
+ private Thread workerThread;
public MyWorker(AbstractPage rootPage, JobType whatToDo) {
jm = new JobMaster(whatToDo, rootPage, 0) {
@@ -57,6 +58,7 @@ public void report(AbstractPage page, String type, long i) {
// called in worker thread
@Override
protected Object doInBackground() throws Exception {
+ workerThread = Thread.currentThread();
if (jm != null)
jm.goGoGo(); // -> several calls to PageJob.report() -> jm.report() -> SwingWorker.publish() -> this.process() -> gui.updateTree()
return null; // call to done() -> gui.myWorkerDone()
@@ -96,6 +98,6 @@ protected void done() {
* @param pageOfNode
*/
public void stopJobsForPage(AbstractPage pageOfNode) {
- // TODO Auto-generated method stub
+ workerThread.interrupt();
}
}
@@ -137,7 +137,7 @@ public AbstractPage(String stringURL, String saveTo, AbstractPage parent) throws
* (don't check for existing file collisions, only validness of a name)
* @param name - string to convert
* @return proper file name
- * @throws IOException if file name is not valid
+ * @throws IOException if file name is not valid or null
*/
public static final
String getFSSafeName(String name) throws IOException {
@@ -208,8 +208,9 @@ String getFSSafeName(String name) throws IOException {
* @param reporter - to output progress of long operations
* @return operation status report. True on completion, false if skipped (results already saved)
* @throws IOException if saving was terminated by error - retry might be possible.
+ * @throws InterruptedException
*/
- public abstract boolean saveResult(ProgressReporter reporter) throws IOException;
+ public abstract boolean saveResult(ProgressReporter reporter) throws IOException, InterruptedException;
/**
* Generate new saving path for the children of this page from its own saveTo and page data
@@ -53,7 +53,7 @@ public String getCoverSavePath() throws IOException {
@Override
public synchronized
- boolean saveResult(ProgressReporter reporter) throws IOException {
+ boolean saveResult(ProgressReporter reporter) throws IOException, InterruptedException {
Path p = Paths.get(saveTo, getFSSafeName(getTitle()));
Files.createDirectories(p);
@@ -93,7 +93,7 @@ public Track(String url, String saveTo, AbstractPage parent) throws IllegalArgum
@Override
public
- boolean saveResult(ProgressReporter reporter) throws IOException {
+ boolean saveResult(ProgressReporter reporter) throws IOException, InterruptedException {
Path p;
String fileURL;
synchronized (this) {
@@ -43,6 +43,9 @@ public void run() {
report("saving caused exception", 1);
//TODO: job rescheduling and error handling
// e.printStackTrace();
+ } catch (InterruptedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
}
}
@@ -22,7 +22,7 @@ public void tearDown() throws Exception {
}
@Test
- public void testFetchWebFileURLString() throws IOException {
+ public void testFetchWebFileURLString() throws IOException, InterruptedException {
Path p = Paths.get("test/classicplus.png");
Files.deleteIfExists(p);
WebDownloader.fetchWebFile("http://www.google.com/logos/classicplus.png",
@@ -234,7 +234,7 @@ public void testAbstractPage_constructor() {
assertEquals(page, page2.getParent());
}
- @Test (expected = NullPointerException.class)
+ @Test (expected = IOException.class)
public void testgetFSSafeName_NullArg() throws IOException {
AbstractPage.getFSSafeName(null);
}
View
@@ -616,15 +616,15 @@
<Track mediaLink="http://popplers5.bandcamp.com/download/track?enc=mp3-128&amp;fsig=fb63259a869f20147e072202b8874fd3&amp;id=3449436372&amp;stream=1&amp;ts=1308167428.0" artist="Hera" track="14" album="rattle my bones" title="it's a funeral thing" url="http://herasings.bandcamp.com/track/its-a-funeral-thing" />
<Track mediaLink="http://popplers5.bandcamp.com/download/track?enc=mp3-128&amp;fsig=da6564ad0f572d763835952c4d6e15d5&amp;id=4246928543&amp;stream=1&amp;ts=1308002330.0" artist="RX Bandits" track="" album="Progress" title="Anyone But You" url="http://rxmusic.bandcamp.com/track/anyone-but-you" />
<Track mediaLink="http://popplers5.bandcamp.com/download/track?enc=mp3-128&amp;fsig=4833b174f183a2027c60f41b1c0526bd&amp;id=3881049666&amp;stream=1&amp;ts=1308170653.0" artist="RX Bandits" track="" album="Progress" title="Analog Boy" url="http://rxmusic.bandcamp.com/track/analog-boy" />
- <Discography title="emancipator" url="file:/D:/Gleb/Eclipse%20Workspaces/Dloader/Dloader/test/emancipator.htm">
- <childref class="Album" url="file:/D:/Gleb/Eclipse%20Workspaces/Dloader/Dloader/test/emancipator-children/remixes-2.htm" />
- <childref class="Album" url="file:/D:/Gleb/Eclipse%20Workspaces/Dloader/Dloader/test/emancipator-children/soon-it-will-be-cold-enough.htm" />
- <childref class="Album" url="file:/D:/Gleb/Eclipse%20Workspaces/Dloader/Dloader/test/emancipator-children/safe-in-the-steep-cliffs.htm" />
- <childref class="Album" url="file:/D:/Gleb/Eclipse%20Workspaces/Dloader/Dloader/test/emancipator-children/free-downloads.htm" />
+ <Discography title="emancipator" url="file:/d:/gleb/eclipse%20workspaces/dloader/dloader/test/emancipator.htm">
+ <childref class="Album" url="file:/d:/gleb/eclipse%20workspaces/dloader/dloader/test/emancipator-children/remixes-2.htm" />
+ <childref class="Album" url="file:/d:/gleb/eclipse%20workspaces/dloader/dloader/test/emancipator-children/soon-it-will-be-cold-enough.htm" />
+ <childref class="Album" url="file:/d:/gleb/eclipse%20workspaces/dloader/dloader/test/emancipator-children/safe-in-the-steep-cliffs.htm" />
+ <childref class="Album" url="file:/d:/gleb/eclipse%20workspaces/dloader/dloader/test/emancipator-children/free-downloads.htm" />
</Discography>
- <Album coverUrl="http://f0.bcbits.com/z/23/99/2399004206-1.jpg" title="Free Downloads" url="file:/D:/Gleb/Eclipse%20Workspaces/Dloader/Dloader/test/emancipator-children/free-downloads.htm" />
- <Album coverUrl="http://f0.bcbits.com/z/29/36/2936937824-1.jpg" title="soon it will be cold enough" url="file:/D:/Gleb/Eclipse%20Workspaces/Dloader/Dloader/test/emancipator-children/soon-it-will-be-cold-enough.htm" />
- <Album coverUrl="http://f0.bcbits.com/z/17/92/1792496746-1.jpg" title="Remixes" url="file:/D:/Gleb/Eclipse%20Workspaces/Dloader/Dloader/test/emancipator-children/remixes-2.htm">
+ <Album coverUrl="http://f0.bcbits.com/z/23/99/2399004206-1.jpg" title="Free Downloads" url="file:/d:/gleb/eclipse%20workspaces/dloader/dloader/test/emancipator-children/free-downloads.htm" />
+ <Album coverUrl="http://f0.bcbits.com/z/29/36/2936937824-1.jpg" title="soon it will be cold enough" url="file:/d:/gleb/eclipse%20workspaces/dloader/dloader/test/emancipator-children/soon-it-will-be-cold-enough.htm" />
+ <Album coverUrl="http://f0.bcbits.com/z/17/92/1792496746-1.jpg" title="Remixes" url="file:/d:/gleb/eclipse%20workspaces/dloader/dloader/test/emancipator-children/remixes-2.htm">
<childref class="Track" url="file:/track/anthem-nym-remix" />
<childref class="Track" url="file:/track/ares-big-gigantic-remix" />
<childref class="Track" url="file:/track/bury-them-bones-marley-carroll-remix" />

0 comments on commit 897805a

Please sign in to comment.