40
42
* This stage is performed by consumer.consume method.
42
44
public abstract class MultiTaskJob<TaskKey,TaskResult,Result> extends Job {
43
private transient LinkedHashMap<TaskKey,TaskJob> tasks;
45
private transient LinkedHashMap<TaskKey,Task> tasks;
46
private transient ArrayList<Task> allTasks;
47
private transient int tasksDone;
48
private transient Environment env;
49
private transient EThread ownerThread;
50
private transient int numberOfRunningThreads;
51
private transient int numberOfFinishedThreads;
44
52
private Consumer<Result> consumer;
47
55
* Constructor creates a new instance of MultiTaskJob.
48
56
* @param jobName a string that describes this MultiTaskJob.
49
57
* @param t the Tool that originated this MultiTaskJob.
50
* @param jobType the Type of this Job (SERVER_EXAMINE or CHANGE).
51
58
* @param c interface which consumes the result on server
53
public MultiTaskJob(String jobName, Tool t, Type jobType, Consumer<Result> c) {
54
super(jobName, t, jobType, null, null, Job.Priority.USER);
60
public MultiTaskJob(String jobName, Tool t, Consumer<Result> c) {
61
super(jobName, t, Job.Type.SERVER_EXAMINE, null, null, Job.Priority.USER);
59
66
* This abstract method split large computation into smaller task.
60
67
* Smaller tasks are identified by TaskKey class.
61
68
* Each task is scheduled by startTask method.
62
69
* @throws com.sun.electric.tool.JobException
64
public abstract void prepareTasks() throws JobException;
71
public abstract void prepareTasks() throws JobException;
67
74
* This abtract methods performs computation of each task.
68
75
* @param taskKey task key which identifies the task
78
85
* @throws com.sun.electric.tool.JobException
80
87
public abstract Result mergeTaskResults(Map<TaskKey,TaskResult> taskResults) throws JobException;
83
90
// * This method executes in the Client side after normal termination of full computation.
84
91
// * This method should perform all needed termination actions.
85
92
// * @param result result of full computation.
87
94
// public void terminateOK(Result result) {}
90
* Schedules task. Should be callled from prepareTasks or runTask methods only.
91
* @param taskName task name which is appeared in Jobs Explorer Tree
92
* @param taskKey task key which identifies the task.
94
public void startTask(String taskName, TaskKey taskKey) {
95
TaskJob task = new TaskJob(taskName, taskKey);
97
if (tasks.containsKey(taskKey))
98
throw new IllegalArgumentException();
99
tasks.put(taskKey, task);
101
task.startJobOnMyResult();
105
97
* This method is not overriden by subclasses.
106
98
* Override methods prepareTasks, runTask, mergeTaskResults instead.
110
102
public final boolean doIt() throws JobException {
111
tasks = new LinkedHashMap<TaskKey,TaskJob>();
103
tasks = new LinkedHashMap<TaskKey,Task>();
104
allTasks = new ArrayList<Task>();
113
(new MergeJob()).startJob();
106
env = Environment.getThreadEnvironment();
107
ownerThread = (EThread)Thread.currentThread();
108
numberOfRunningThreads = ServerJobManager.getMaxNumberOfThreads();
109
for (int id = 0; id < numberOfRunningThreads; id++)
110
new WorkingThread(id).start();
113
LinkedHashMap<TaskKey,TaskResult> taskResults = new LinkedHashMap<TaskKey,TaskResult>();
114
for (Task task: tasks.values()) {
115
if (task.taskResult != null)
116
taskResults.put(task.taskKey, task.taskResult);
118
Result result = mergeTaskResults(taskResults);
119
if (consumer != null)
120
consumer.consume(result);
117
private class TaskJob extends Job {
118
private transient final TaskKey taskKey;
119
private transient TaskResult taskResult;
121
private TaskJob(String taskName, TaskKey tK) {
122
super(taskName, MultiTaskJob.this.tool,
123
Job.Type.SERVER_EXAMINE, null, null, Job.Priority.USER);
128
public boolean doIt() throws JobException {
129
taskResult = runTask(taskKey);
134
public void abort() {
135
MultiTaskJob.this.abort();
139
private class MergeJob extends Job {
140
private Result result;
143
super(MultiTaskJob.this.ejob.jobName + "merge", MultiTaskJob.this.tool,
144
Job.Type.CHANGE, null, null, Job.Priority.USER);
148
public boolean doIt() throws JobException {
149
LinkedHashMap<TaskKey,TaskResult> taskResults = new LinkedHashMap<TaskKey,TaskResult>();
150
for (TaskJob task: tasks.values()) {
151
if (task.taskResult != null)
152
taskResults.put(task.taskKey, task.taskResult);
125
* Schedules task. Should be callled from prepareTasks or runTask methods only.
126
* @param taskName task name which is appeared in Jobs Explorer Tree
127
* @param taskKey task key which identifies the task.
129
public synchronized void startTask(String taskName, TaskKey taskKey) {
130
Task task = new Task(taskName, taskKey);
131
if (tasks.containsKey(taskKey))
132
throw new IllegalArgumentException();
133
tasks.put(taskKey, task);
137
private synchronized Task getTask() {
138
if (tasksDone == allTasks.size()) {
141
return allTasks.get(tasksDone++);
144
private synchronized void waitTasks() {
146
while (numberOfFinishedThreads < numberOfRunningThreads)
148
} catch (InterruptedException e) {
153
private synchronized void finishWorkingThread() {
154
numberOfFinishedThreads++;
159
private final String taskName;
160
private final TaskKey taskKey;
161
private TaskResult taskResult;
163
private Task(String taskName, TaskKey taskKey) {
164
this.taskName = taskName;
165
this.taskKey = taskKey;
169
class WorkingThread extends EThread {
171
private WorkingThread(int id) {
172
super("WorkingThread-"+id);
173
userInterface = new ServerJobManager.UserInterfaceRedirect(ownerThread.ejob.jobKey);
174
ejob = ownerThread.ejob;
175
isServerThread = ownerThread.isServerThread;
176
database = ownerThread.database;
181
Environment.setThreadEnvironment(env);
188
t.taskResult = runTask(t.taskKey);
189
} catch (Throwable e) {
191
e.printStackTrace(System.out);
154
result = mergeTaskResults(taskResults);
155
if (consumer != null)
156
consumer.consume(result);
157
// fieldVariableChanged("result");
162
public void abort() {
163
MultiTaskJob.this.abort();
166
// * This method executes in the Client side after normal termination of doIt method.
167
// * This method should perform all needed termination actions.
170
// public void terminateOK() {
171
// MultiTaskJob.this.terminateOK(result);
195
finishWorkingThread();