use of org.eclipse.xtext.generator.FileSystemAccessQueue in project xtext-eclipse by eclipse.
the class ParallelBuilderParticipant method doBuild.
@Override
protected void doBuild(List<Delta> deltas, Map<String, OutputConfiguration> outputConfigurations, Map<OutputConfiguration, Iterable<IMarker>> generatorMarkers, IBuildContext context, EclipseResourceFileSystemAccess2 access, IProgressMonitor progressMonitor) throws CoreException {
BlockingQueue<FileSystemAccessRequest> requestQueue = newBlockingQueue(QUEUE_CAPACITY);
// This queue is only used from the current thread
// thus there is no need for a blocking queue. The add operation should also not block the
// builder thread
Queue<ParallelBuildContext> afterGenerateQueue = new ArrayDeque<ParallelBuildContext>(QUEUE_CAPACITY);
FileSystemAccessQueue fileSystemAccessQueue = new FileSystemAccessQueue(requestQueue, progressMonitor);
Tripwire tripwire = new Tripwire();
EList<Adapter> adapters = context.getResourceSet().eAdapters();
EObservableAdapterList observableAdapters = (EObservableAdapterList) adapters;
adapters.add(fileSystemAccessQueue);
observableAdapters.addListener(tripwire);
try {
SubMonitor subMonitor = SubMonitor.convert(progressMonitor, 1);
subMonitor.subTask("Compiling...");
access.setMonitor(subMonitor.split(1));
List<ListenableFuture<?>> tasks = Lists.newArrayList();
ListeningExecutorService executor = executors.getExecutor();
for (IResourceDescription.Delta delta : deltas) {
if (getResourceServiceProvider().canHandle(delta.getUri())) {
try {
ParallelBuildContext parallelBuildContext = new ParallelBuildContext(delta, context, outputConfigurations, generatorMarkers, fileSystemAccessQueue, afterGenerateQueue, access, progressMonitor);
Runnable runnable = createRunnable(parallelBuildContext);
tasks.add(executor.submit(runnable));
} catch (Exception e) {
addMarkerAndLogError(delta.getUri(), e);
}
}
}
ListenableFuture<List<Object>> generatorResult = Futures.successfulAsList(tasks);
List<SimpleEntry<URI, Throwable>> exceptions = Lists.newArrayList();
boolean interrupted = false;
try {
/*
* it is important to check generatorResult and requestQueue second
* as it can happen that if you use !requestQueue.isEmpty() || !generatorResult.isDone()
* that the generatorResult.isDone() becomes true after requestQueue.isEmpty() was checked
* and thus requestQueue.isEmpty() changes back to false
* but we stop the while loop anyway and thus miss generated files.
*/
while (!generatorResult.isDone() || !requestQueue.isEmpty()) {
if (subMonitor.isCanceled()) {
cancelProcessing(requestQueue, afterGenerateQueue, generatorResult);
throw new OperationCanceledException();
}
FileSystemAccessRequest request = null;
try {
request = requestQueue.poll(QUEUE_POLL_TIMEOUT, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
interrupted = true;
}
if (request != null) {
try {
request.run();
} catch (OperationCanceledException e) {
cancelProcessing(requestQueue, afterGenerateQueue, generatorResult);
throw e;
} catch (Exception e) {
Throwable cause = e;
if (cause instanceof CoreException) {
cause = cause.getCause();
}
exceptions.add(new SimpleEntry<URI, Throwable>(request.getUri(), cause));
}
}
}
} finally {
if (interrupted) {
Thread.currentThread().interrupt();
}
for (SimpleEntry<URI, Throwable> exception : exceptions) {
addMarkerAndLogError(exception.getKey(), exception.getValue());
}
}
} finally {
observableAdapters.removeListener(tripwire);
adapters.remove(fileSystemAccessQueue);
}
}
use of org.eclipse.xtext.generator.FileSystemAccessQueue in project xtext-eclipse by eclipse.
the class ParallelBuilderParticipant method createRunnable.
/**
* @since 2.9
*/
protected Runnable createRunnable(final ParallelBuildContext buildContext) {
final IGenerator2 generator = getGenerator2();
final Resource resource = buildContext.resource;
if (resource != null) {
generator.beforeGenerate(resource, buildContext.synchronousFileSystemAccess, buildContext.getGeneratorContext());
buildContext.afterGenerateQueue.add(buildContext);
}
return new Runnable() {
@Override
public void run() {
Delta delta = buildContext.delta;
try {
Set<IFile> derivedResources = getDerivedResources(delta, buildContext.outputConfigurations, buildContext.generatorMarkers);
FileSystemAccessQueue fileSystemAccessQueue = buildContext.fileSystemAccessQueue;
IFileSystemAccess2 fsa = getParallelFileSystemAccess(delta, buildContext, derivedResources, fileSystemAccessQueue, buildContext.synchronousFileSystemAccess);
boolean generated = doGenerate(delta, buildContext, fsa);
final Runnable derivedResourceCallback = getFlushAndCleanDerivedResourcesCallback(buildContext, derivedResources, generated);
fileSystemAccessQueue.sendAsync(delta.getUri(), new Runnable() {
@Override
public void run() {
try {
derivedResourceCallback.run();
} finally {
if (resource != null) {
generator.afterGenerate(resource, buildContext.synchronousFileSystemAccess, buildContext.getGeneratorContext());
buildContext.afterGenerateQueue.remove(buildContext);
}
}
}
});
} catch (OperationCanceledException e) {
// do nothing
} catch (Throwable e) {
addMarkerAndLogError(delta.getUri(), e);
}
}
};
}
Aggregations