OSDN Git Service

画面のプロファイル生成処理で共通化できる部分を共通化
[coroid/inqubus.git] / frontend / src / yukihane / inqubus / manager / TaskManage.java
index b38531d..983bd10 100644 (file)
@@ -1,17 +1,22 @@
 package yukihane.inqubus.manager;
 
+import java.io.File;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 import saccubus.worker.WorkerListener;
-import saccubus.worker.convert.Convert;
-import saccubus.worker.convert.ConvertProgress;
-import saccubus.worker.convert.ConvertResult;
-import saccubus.worker.download.Download;
-import saccubus.worker.download.DownloadProgress;
-import saccubus.worker.download.DownloadResult;
+import saccubus.worker.impl.MessageReportable;
+import saccubus.worker.impl.PercentageReportable;
+import saccubus.worker.impl.convert.Convert;
+import saccubus.worker.impl.convert.ConvertProgress;
+import saccubus.worker.impl.convert.ConvertResult;
+import saccubus.worker.impl.download.Download;
+import saccubus.worker.impl.download.DownloadProgress;
+import saccubus.worker.impl.download.DownloadResult;
 import saccubus.worker.profile.ConvertProfile;
 import saccubus.worker.profile.DownloadProfile;
 
@@ -21,32 +26,36 @@ import saccubus.worker.profile.DownloadProfile;
  */
 public class TaskManage {
 
+    private static final Logger logger = Logger.getLogger(TaskManage.class.getName());
     private final ExecutorService downloadExecutorService;
     private final ExecutorService convertExecutorService;
     private final Map<Integer, ManageTarget<DownloadResult>> downloadTargets = new HashMap<>();
     private final Map<Integer, ManageTarget<ConvertResult>> convertTargets = new HashMap<>();
     private final TaskManageListener clientListener;
+    private final int waitDownload;
 
     public TaskManage() {
-        this(1, 1, null);
+        this(1, 30, 1, null);
     }
 
     public TaskManage(int maxDownload, int maxConvert) {
-        this(maxDownload, maxConvert, null);
+        this(maxDownload, 30, maxConvert, null);
     }
 
-    public TaskManage(int maxDownload, int maxConvert, TaskManageListener listener) {
+    public TaskManage(int maxDownload, int waitDownload, int maxConvert, TaskManageListener listener) {
         downloadExecutorService = Executors.newFixedThreadPool(maxDownload);
         convertExecutorService = Executors.newFixedThreadPool(maxConvert);
+        this.waitDownload = waitDownload;
         this.clientListener = listener;
     }
 
     public synchronized boolean add(RequestProcess request) {
         final DownloadProfile dp = request.getDownloadProfile();
         final ConvertProfile cp = request.getConvertProfile();
-        if (dp != null && !dp.getVideoProfile().isDownload() && !dp.getCommentProfile().isDownload()) {
+        if (dp != null && (dp.getVideoProfile().isDownload() || dp.getCommentProfile().isDownload())) {
+            // ダウンロードするものがあればまずダウンロード処理
             final Download task = new Download(dp, request.getVideoId(),
-                    new DownloadListener(request.getRowId()));
+                    new DownloadListener(request.getRowId()), waitDownload);
             final Future<DownloadResult> future = downloadExecutorService.submit(task);
             downloadTargets.put(request.getRowId(), new ManageTarget<>(request, future));
             return true;
@@ -61,104 +70,164 @@ public class TaskManage {
         return false;
     }
 
-    private class DownloadListener implements WorkerListener<DownloadResult, DownloadProgress> {
+    public synchronized boolean cancel(int rowId) {
+        // FIXME 実行前にキャンセルした場合にはcancelledイベントが飛ばないのでMapからリクエストを削除できない
+        final ManageTarget<DownloadResult> down = downloadTargets.get(rowId);
+        if (down != null) {
+            return down.getFuture().cancel(true);
+        }
+        final ManageTarget<ConvertResult> conv = convertTargets.get(rowId);
+        if (conv != null) {
+            return conv.getFuture().cancel(true);
+        }
 
-        private final int rowId;
+        return false;
+    }
+
+    private class DownloadListener extends TaskManageInnerListener<DownloadResult, DownloadProgress> {
 
         private DownloadListener(int rowId) {
-            this.rowId = rowId;
+            super(rowId);
         }
 
-        private void notify(TaskStatus status) {
-            notify(status, 0.0, "");
+        @Override
+        public void done(DownloadResult result) {
+            super.done(result);
+            synchronized (TaskManage.this) {
+                final ManageTarget<DownloadResult> mt = removeRequest(getRowId());
+                final RequestProcess request = mt.getRequest();
+                if (request.getConvertProfile().isConvert()) {
+                    final DownloadProfile dp = request.getDownloadProfile();
+                    final File video = (dp.getVideoProfile().isDownload()) ? result.getDownloadVideo() : dp.
+                            getVideoProfile().getLocalFile();
+                    final File comment = (dp.getCommentProfile().isDownload()) ? result.getDownloadComment() : dp.
+                            getCommentProfile().getLocalFile();
+                    final ConvertProfile cp = request.getConvertProfile();
+                    final Convert task = new Convert(cp, video, comment, new ConvertListener(getRowId()));
+                    final Future<ConvertResult> future = convertExecutorService.submit(task);
+                    convertTargets.put(request.getRowId(), new ManageTarget<>(request, future));
+                }
+            }
         }
 
-        private void notify(TaskStatus status, double percentage, String message) {
-            if (clientListener == null) {
-                return;
-            }
-            clientListener.process(rowId, TaskKind.DOWNLOAD, status, percentage, message);
+        @Override
+        protected TaskKind getKind() {
+            return TaskKind.DOWNLOAD;
         }
 
         @Override
-        public void process(DownloadProgress progress) {
-            // TOOD
-            notify(TaskStatus.DOING, 0.0, "");
+        protected ManageTarget<DownloadResult> removeRequest(int rowId) {
+            return downloadTargets.remove(rowId);
+        }
+    }
+
+    private class ConvertListener extends TaskManageInnerListener<ConvertResult, ConvertProgress> {
+
+        private ConvertListener(int rowId) {
+            super(rowId);
         }
 
         @Override
-        public void cancelled() {
-            notify(TaskStatus.CANCELLED);
+        protected TaskKind getKind() {
+            return TaskKind.CONVERT;
         }
 
         @Override
-        public void done(DownloadResult result) {
-            notify(TaskStatus.DONE);
+        public void done(ConvertResult result) {
+            super.done(result);
+            synchronized (TaskManage.this) {
+                removeRequest(getRowId());
+            }
         }
 
         @Override
-        public void error(Throwable th) {
-            notify(TaskStatus.ERROR, 0.0, th.getMessage());
+        protected ManageTarget<ConvertResult> removeRequest(int rowId) {
+            return convertTargets.remove(rowId);
         }
     }
 
-    private class ConvertListener implements WorkerListener<ConvertResult, ConvertProgress> {
+    abstract class TaskManageInnerListener<T, V extends PercentageReportable & MessageReportable> implements WorkerListener<T, V> {
 
         private final int rowId;
 
-        private ConvertListener(int rowId) {
+        protected TaskManageInnerListener(int rowId) {
             this.rowId = rowId;
         }
 
+        protected int getRowId() {
+            return rowId;
+        }
+
         private void notify(TaskStatus status) {
-            notify(status, 0.0, "");
+            notify(status, -1.0, "");
         }
 
         private void notify(TaskStatus status, double percentage, String message) {
-            if (clientListener == null) {
+            if (getListener() == null) {
                 return;
             }
-            clientListener.process(rowId, TaskKind.DOWNLOAD, status, percentage, message);
+            getListener().process(rowId, getKind(), status, percentage, message);
+        }
+
+        private TaskManageListener getListener() {
+            return clientListener;
         }
 
+        protected abstract TaskKind getKind();
+
         @Override
-        public void process(ConvertProgress progress) {
-            // TOOD
-            notify(TaskStatus.DOING, 0.0, "");
+        public void process(V progress) {
+            logger.log(Level.FINEST, "process: {0}", progress);
+            notify(TaskStatus.DOING, progress.getPercentage(), progress.getMessage());
         }
 
         @Override
-        public void cancelled() {
+        public final void cancelled() {
+            logger.log(Level.FINE, "cancelled: {0}", toString());
+            synchronized (TaskManage.this) {
+                removeRequest(rowId);
+            }
             notify(TaskStatus.CANCELLED);
         }
 
+        /**
+         * この処理をオーバライドしてキューからリクエストを削除する必要があります.
+         * @param result 処理結果.
+         */
         @Override
-        public void done(ConvertResult result) {
+        public void done(T result) {
+            logger.log(Level.FINE, "done: {0}", result);
             notify(TaskStatus.DONE);
         }
 
         @Override
-        public void error(Throwable th) {
+        public final void error(Throwable th) {
+            logger.log(Level.SEVERE, "error", th);
+            synchronized (TaskManage.this) {
+                removeRequest(rowId);
+            }
             notify(TaskStatus.ERROR, 0.0, th.getMessage());
         }
+
+        protected abstract ManageTarget<T> removeRequest(int rowId);
     }
-}
 
-class ManageTarget<T> {
+    class ManageTarget<T> {
 
-    private final RequestProcess request;
-    private final Future<T> future;
+        private final RequestProcess request;
+        private final Future<T> future;
 
-    ManageTarget(RequestProcess request, Future<T> future) {
-        this.request = request;
-        this.future = future;
-    }
+        ManageTarget(RequestProcess request, Future<T> future) {
+            this.request = request;
+            this.future = future;
+        }
 
-    Future<T> getFuture() {
-        return future;
-    }
+        Future<T> getFuture() {
+            return future;
+        }
 
-    RequestProcess getRequest() {
-        return request;
+        RequestProcess getRequest() {
+            return request;
+        }
     }
-}
+}
\ No newline at end of file