Search in sources :

Example 1 with FileSystemAccessQueue

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);
    }
}
Also used : IResourceDescription(org.eclipse.xtext.resource.IResourceDescription) OperationCanceledException(org.eclipse.core.runtime.OperationCanceledException) Adapter(org.eclipse.emf.common.notify.Adapter) FileSystemAccessQueue(org.eclipse.xtext.generator.FileSystemAccessQueue) URI(org.eclipse.emf.common.util.URI) FileSystemAccessRequest(org.eclipse.xtext.generator.FileSystemAccessRequest) EObservableAdapterList(org.eclipse.emf.common.notify.impl.BasicNotifierImpl.EObservableAdapterList) EList(org.eclipse.emf.common.util.EList) List(java.util.List) EObservableAdapterList(org.eclipse.emf.common.notify.impl.BasicNotifierImpl.EObservableAdapterList) SimpleEntry(java.util.AbstractMap.SimpleEntry) SubMonitor(org.eclipse.core.runtime.SubMonitor) ArrayDeque(java.util.ArrayDeque) CoreException(org.eclipse.core.runtime.CoreException) OperationCanceledException(org.eclipse.core.runtime.OperationCanceledException) CoreException(org.eclipse.core.runtime.CoreException) Delta(org.eclipse.xtext.resource.IResourceDescription.Delta) ListenableFuture(com.google.common.util.concurrent.ListenableFuture) ListeningExecutorService(com.google.common.util.concurrent.ListeningExecutorService)

Example 2 with 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);
            }
        }
    };
}
Also used : IFile(org.eclipse.core.resources.IFile) IFileSystemAccess2(org.eclipse.xtext.generator.IFileSystemAccess2) Delta(org.eclipse.xtext.resource.IResourceDescription.Delta) OperationCanceledException(org.eclipse.core.runtime.OperationCanceledException) Resource(org.eclipse.emf.ecore.resource.Resource) IGenerator2(org.eclipse.xtext.generator.IGenerator2) FileSystemAccessQueue(org.eclipse.xtext.generator.FileSystemAccessQueue)

Aggregations

OperationCanceledException (org.eclipse.core.runtime.OperationCanceledException)2 FileSystemAccessQueue (org.eclipse.xtext.generator.FileSystemAccessQueue)2 Delta (org.eclipse.xtext.resource.IResourceDescription.Delta)2 ListenableFuture (com.google.common.util.concurrent.ListenableFuture)1 ListeningExecutorService (com.google.common.util.concurrent.ListeningExecutorService)1 SimpleEntry (java.util.AbstractMap.SimpleEntry)1 ArrayDeque (java.util.ArrayDeque)1 List (java.util.List)1 IFile (org.eclipse.core.resources.IFile)1 CoreException (org.eclipse.core.runtime.CoreException)1 SubMonitor (org.eclipse.core.runtime.SubMonitor)1 Adapter (org.eclipse.emf.common.notify.Adapter)1 EObservableAdapterList (org.eclipse.emf.common.notify.impl.BasicNotifierImpl.EObservableAdapterList)1 EList (org.eclipse.emf.common.util.EList)1 URI (org.eclipse.emf.common.util.URI)1 Resource (org.eclipse.emf.ecore.resource.Resource)1 FileSystemAccessRequest (org.eclipse.xtext.generator.FileSystemAccessRequest)1 IFileSystemAccess2 (org.eclipse.xtext.generator.IFileSystemAccess2)1 IGenerator2 (org.eclipse.xtext.generator.IGenerator2)1 IResourceDescription (org.eclipse.xtext.resource.IResourceDescription)1