use of com.microsoft.azure.batch.interceptor.BatchClientParallelOptions in project azure-sdk-for-java by Azure.
the class TaskOperations method createTasks.
/**
* Adds multiple tasks to a job.
*
* @param jobId The ID of the job to which to add the task.
* @param taskList A collection of {@link CloudTask tasks} to add.
* @param additionalBehaviors A collection of {@link BatchClientBehavior} instances that are applied to the Batch service request.
* @throws BatchErrorException Exception thrown from REST call
* @throws IOException Exception thrown from serialization/deserialization
* @throws InterruptedException exception thrown if any thread has interrupted the current thread.
*/
public void createTasks(String jobId, List<TaskAddParameter> taskList, Iterable<BatchClientBehavior> additionalBehaviors) throws BatchErrorException, IOException, InterruptedException {
BehaviorManager bhMgr = new BehaviorManager(this.customBehaviors(), additionalBehaviors);
// Default thread number is 1
int threadNumber = 1;
// Get user defined thread number
for (BatchClientBehavior op : bhMgr.getMasterListOfBehaviors()) {
if (op instanceof BatchClientParallelOptions) {
threadNumber = ((BatchClientParallelOptions) op).maxDegreeOfParallelism();
break;
}
}
final Object lock = new Object();
ConcurrentLinkedQueue<TaskAddParameter> pendingList = new ConcurrentLinkedQueue<>(taskList);
CopyOnWriteArrayList<TaskAddResult> failures = new CopyOnWriteArrayList<>();
Map<Thread, WorkingThread> threads = new HashMap<>();
Exception innerException = null;
while (!pendingList.isEmpty()) {
if (threads.size() < threadNumber) {
// Kick as many as possible add tasks requests by max allowed threads
WorkingThread worker = new WorkingThread(this._parentBatchClient, bhMgr, jobId, pendingList, failures, lock);
Thread thread = new Thread(worker);
thread.start();
threads.put(thread, worker);
} else {
// Wait any thread finished
synchronized (lock) {
lock.wait();
}
List<Thread> finishedThreads = new ArrayList<>();
for (Thread t : threads.keySet()) {
if (t.getState() == Thread.State.TERMINATED) {
finishedThreads.add(t);
// If any exception happened, do not care the left requests
innerException = threads.get(t).getException();
if (innerException != null) {
break;
}
}
}
// Free thread pool, so we can start more threads to send the request
threads.keySet().removeAll(finishedThreads);
// Any errors happened, we stop
if (innerException != null || !failures.isEmpty()) {
break;
}
}
}
// May sure all the left threads finished
for (Thread t : threads.keySet()) {
t.join();
}
if (innerException == null) {
// Anything bad happened at the left threads?
for (Thread t : threads.keySet()) {
innerException = threads.get(t).getException();
if (innerException != null) {
break;
}
}
}
if (innerException != null) {
// We throw any exception happened in sub thread
if (innerException instanceof BatchErrorException) {
throw (BatchErrorException) innerException;
} else {
throw (IOException) innerException;
}
}
if (!failures.isEmpty()) {
// Report any client error with leftover request
List<TaskAddParameter> notFinished = new ArrayList<>();
for (TaskAddParameter param : pendingList) {
notFinished.add(param);
}
throw new CreateTasksTerminatedException("At least one task failed to be added.", failures, notFinished);
}
// We succeed here
}
Aggregations