OSDN Git Service

producer_consumerパターンでダウンロード,変換処理を実現
[coroid/inqubus.git] / frontend / src / yukihane / inqubus / manager / TaskManage.java
1 package yukihane.inqubus.manager;
2
3 import java.util.HashMap;
4 import java.util.Map;
5 import java.util.concurrent.ExecutorService;
6 import java.util.concurrent.Executors;
7 import java.util.concurrent.Future;
8 import java.util.logging.Level;
9 import java.util.logging.Logger;
10 import saccubus.worker.WorkerListener;
11 import saccubus.worker.convert.Convert;
12 import saccubus.worker.convert.ConvertProgress;
13 import saccubus.worker.convert.ConvertResult;
14 import saccubus.worker.download.Download;
15 import saccubus.worker.download.DownloadProgress;
16 import saccubus.worker.download.DownloadResult;
17 import saccubus.worker.profile.ConvertProfile;
18 import saccubus.worker.profile.DownloadProfile;
19
20 /**
21  *
22  * @author yuki
23  */
24 public class TaskManage {
25     private static final Logger logger = Logger.getLogger(TaskManage.class.getName());
26     private final ExecutorService downloadExecutorService;
27     private final ExecutorService convertExecutorService;
28     private final Map<Integer, ManageTarget<DownloadResult>> downloadTargets = new HashMap<>();
29     private final Map<Integer, ManageTarget<ConvertResult>> convertTargets = new HashMap<>();
30     private final TaskManageListener clientListener;
31
32     public TaskManage() {
33         this(1, 1, null);
34     }
35
36     public TaskManage(int maxDownload, int maxConvert) {
37         this(maxDownload, maxConvert, null);
38     }
39
40     public TaskManage(int maxDownload, int maxConvert, TaskManageListener listener) {
41         downloadExecutorService = Executors.newFixedThreadPool(maxDownload);
42         convertExecutorService = Executors.newFixedThreadPool(maxConvert);
43         this.clientListener = listener;
44     }
45
46     public synchronized boolean add(RequestProcess request) {
47         final DownloadProfile dp = request.getDownloadProfile();
48         final ConvertProfile cp = request.getConvertProfile();
49         if (dp != null && (dp.getVideoProfile().isDownload() || dp.getCommentProfile().isDownload())) {
50             // ダウンロードするものがあればまずダウンロード処理
51             final Download task = new Download(dp, request.getVideoId(),
52                     new DownloadListener(request.getRowId()));
53             final Future<DownloadResult> future = downloadExecutorService.submit(task);
54             downloadTargets.put(request.getRowId(), new ManageTarget<>(request, future));
55             return true;
56
57         } else if (cp != null && cp.isConvert()) {
58             final Convert task = new Convert(cp, dp.getVideoProfile().getLocalFile(), dp.getCommentProfile().
59                     getLocalFile(), new ConvertListener(request.getRowId()));
60             final Future<ConvertResult> future = convertExecutorService.submit(task);
61             convertTargets.put(request.getRowId(), new ManageTarget<>(request, future));
62             return true;
63         }
64         return false;
65     }
66
67     private class DownloadListener extends TaskManageInnerListener<DownloadResult, DownloadProgress> {
68
69         private DownloadListener(int rowId) {
70             super(rowId);
71         }
72
73         @Override
74         public void done(DownloadResult result) {
75             super.done(result);
76             // TODO 変換が必要なら変換キューに入れる
77         }
78
79         @Override
80         protected TaskKind getKind() {
81             return TaskKind.DOWNLOAD;
82         }
83     }
84
85     private class ConvertListener extends TaskManageInnerListener<ConvertResult, ConvertProgress> {
86
87         private ConvertListener(int rowId) {
88             super(rowId);
89         }
90
91         @Override
92         protected TaskKind getKind() {
93             return TaskKind.CONVERT;
94         }
95     }
96
97     abstract class TaskManageInnerListener<T, V> implements WorkerListener<T, V> {
98
99         private final int rowId;
100
101         protected TaskManageInnerListener(int rowId) {
102             this.rowId = rowId;
103         }
104
105         private void notify(TaskStatus status) {
106             notify(status, 0.0, "");
107         }
108
109         private void notify(TaskStatus status, double percentage, String message) {
110             if (getListener() == null) {
111                 return;
112             }
113             getListener().process(rowId, getKind(), status, percentage, message);
114         }
115
116         private TaskManageListener getListener() {
117             return clientListener;
118         }
119
120         protected abstract TaskKind getKind();
121
122         @Override
123         public void process(V progress) {
124             logger.log(Level.FINEST, "process: {0}", progress);
125             // TOOD
126             notify(TaskStatus.DOING, 0.0, "");
127         }
128
129         @Override
130         public void cancelled() {
131             logger.log(Level.FINE, "cancelled: {0}", toString());
132             notify(TaskStatus.CANCELLED);
133         }
134
135         @Override
136         public void done(T result) {
137             logger.log(Level.FINE, "done: {0}", result);
138             notify(TaskStatus.DONE);
139         }
140
141         @Override
142         public void error(Throwable th) {
143             logger.log(Level.SEVERE, "error", th);
144             notify(TaskStatus.ERROR, 0.0, th.getMessage());
145         }
146     }
147
148     class ManageTarget<T> {
149
150         private final RequestProcess request;
151         private final Future<T> future;
152
153         ManageTarget(RequestProcess request, Future<T> future) {
154             this.request = request;
155             this.future = future;
156         }
157
158         Future<T> getFuture() {
159             return future;
160         }
161
162         RequestProcess getRequest() {
163             return request;
164         }
165     }
166 }