/** * Asynchronously submit a request to the supplied source. This is typically called when the forked requests are not needed * before continuing. * * @param request the request to be submitted; may not be null * @param sourceName the name of the source; may not be null * @see #submitAndAwait(Request, String) * @see #submit(Request, String, CountDownLatch) */ protected void submit( Request request, String sourceName ) { assert request != null; CompositeRequestChannel channel = channelBySourceName.get(sourceName); if (channel == null) { channel = new CompositeRequestChannel(sourceName); channelBySourceName.put(sourceName, channel); channel.start(executor, getExecutionContext(), connectionFactory); } channel.add(request); }
/** * Await until all of this processor's channels have completed. * * @throws CancellationException if the channel was cancelled * @throws ExecutionException if the channel execution threw an exception * @throws InterruptedException if the current thread is interrupted while waiting */ public void await() throws ExecutionException, InterruptedException, CancellationException { for (CompositeRequestChannel channel : channelBySourceName.values()) { channel.await(); } }
/** * {@inheritDoc} * * @see org.modeshape.graph.request.processor.RequestProcessor#close() */ @Override public void close() { super.close(); for (CompositeRequestChannel channel : channelBySourceName.values()) { channel.close(); } }
/** * Submit a request to the supplied source, and block until the request has been processed. This method is typically used when * a federated request is forked into multiple source-specific requests, but the output of a source-specific request is * required before forking other source-specific requests. This pattern is common in requests that update one source and any * information not stored by that source needs to be stored in another source. * * @param request the request to be submitted; may not be null * @param sourceName the name of the source; may not be null * @throws InterruptedException if the current thread is interrupted while waiting * @see #submit(Request, String) * @see #submit(Request, String, CountDownLatch) */ protected void submitAndAwait( Request request, String sourceName ) throws InterruptedException { assert request != null; CompositeRequestChannel channel = channelBySourceName.get(sourceName); if (channel == null) { channel = new CompositeRequestChannel(sourceName); channelBySourceName.put(sourceName, channel); channel.start(executor, getExecutionContext(), connectionFactory); } channel.addAndAwait(request); }
@Test public void shouldSubmitRequestsToConnection() throws Exception { // Start the channel ... channel.start(executor, context, connectionFactory); // Submit the requests to the channel ... for (Request request : requests) { channel.add(request); } // Mark the channel as done ... channel.close(); // Wait until the channel has completed ... channel.await(); // Verify that all the requests to the channel were processed ... Iterator<Request> iter = executedRequests.iterator(); for (Request expected : requests) { assertThat(iter.hasNext(), is(true)); assertThat(iter.next(), is(sameInstance(expected))); } assertThat(iter.hasNext(), is(false)); }
@Test public void shouldCreateIteratorOverRequestsAddedToChannelAfterObtainingIterator() { Iterator<Request> iter = channel.createIterator(); // Add the requests ... for (Request request : requests) { channel.add(request); } // Call done ... channel.close(); // Start iterating ... for (Request expected : requests) { assertThat(iter.hasNext(), is(true)); assertThat(iter.next(), is(sameInstance(expected))); } assertThat(iter.hasNext(), is(false)); }
@Test public void shouldCreateEmptyIteratorIfDoneCalledBeforeObtainingIterator() { channel.close(); Iterator<Request> iter = channel.createIterator(); assertThat(iter.hasNext(), is(false)); }
this.sourceName = searchEngine.getSourceName(); this.connectionFactory = connectionFactory; this.channel = new CompositeRequestChannel(this.sourceName, false, true); this.service = Executors.newSingleThreadExecutor(new NamedThreadFactory("search-" + sourceName)); this.channel.start(service, this.context, this.connectionFactory); this.processor = this.searchEngine.createProcessor(this.context, null, false); this.maxDepthPerRead = maxDepthPerRead;
/** * {@inheritDoc} * * @see org.modeshape.graph.request.CompositeRequest#iterator() */ @Override public Iterator<Request> iterator() { return createIterator(); }
/** * Add the request to this channel for processing, but wait to return until the request has been processed. * * @param request the request to be submitted; may not be null * @throws InterruptedException if the current thread is interrupted while waiting */ public void addAndAwait( Request request ) throws InterruptedException { // Add the request with a latch, then block until the request has completed ... add(request, new CountDownLatch(1)).await(); }
@Before public void beforeEach() { MockitoAnnotations.initMocks(this); context = new ExecutionContext(); sourceName = "SourceA"; channel = new CompositeRequestChannel(sourceName); requests = new ArrayList<Request>(); requests.add(new MockRequest()); requests.add(new MockRequest()); requests.add(new MockRequest()); requests.add(new MockRequest()); // Create the mock connection ... executedRequests = new LinkedList<Request>(); // this is where requests submitted to the connection will go connection = new MockRepositoryConnection(sourceName, executedRequests); // Stub the connection factory ... when(connectionFactory.createConnection(sourceName)).thenReturn(connection); // Create the executor ... executor = Executors.newSingleThreadExecutor(); }
protected void indexProperties( String workspaceName, Location location ) { ReadAllPropertiesRequest readProps = new ReadAllPropertiesRequest(location, workspaceName); try { channel.addAndAwait(readProps); } catch (InterruptedException e) { // Clear the interrupted status of the thread and continue ... Thread.interrupted(); } checkRequestForErrors(readProps); // Now update the properties in the search engine ... location = readProps.getActualLocationOfNode(); Map<Name, Property> properties = readProps.getPropertiesByName(); UpdatePropertiesRequest request = new UpdatePropertiesRequest(location, workspaceName, properties, true); request.setActualLocationOfNode(location); process(request); checkRequestForErrors(readProps); }
protected void cancel( boolean mayInterruptIfRunning ) { for (CompositeRequestChannel channel : channelBySourceName.values()) { channel.cancel(mayInterruptIfRunning); } } }
@Test public void shouldSubmitBlockedRequestsToConnection() throws Exception { // Start the channel ... channel.start(executor, context, connectionFactory); // Submit the requests to the channel ... List<CountDownLatch> latches = new ArrayList<CountDownLatch>(); for (Request request : requests) { CountDownLatch latch = new CountDownLatch(1); latches.add(latch); channel.add(request, latch); } // Mark the channel as done ... channel.close(); // Wait until the channel has completed ... channel.await(); // Verify that all of the latches were decremented ... for (CountDownLatch latch : latches) { latch.await(); assertThat(latch.getCount(), is(0L)); } // Verify that all the requests to the channel were processed ... Iterator<Request> iter = executedRequests.iterator(); for (Request expected : requests) { assertThat(iter.hasNext(), is(true)); assertThat(iter.next(), is(sameInstance(expected))); } assertThat(iter.hasNext(), is(false)); }
@Test public void shouldCreateEmptyIteratorIfDoneCalledAfterObtainingIterator() { Iterator<Request> iter = channel.createIterator(); channel.close(); assertThat(iter.hasNext(), is(false)); }
@Test public void shouldCreateIteratorOverRequestsAddedToChannelAfterBeginningIteration() { Iterator<Request> iter = channel.createIterator(); // Add the requests in a separate thread ... new Thread(new AddRequestsRunnable(channel, requests, 100)).start(); // Start iterating ... for (Request expected : requests) { assertThat(iter.hasNext(), is(true)); // blocks assertThat(iter.next(), is(sameInstance(expected))); } assertThat(iter.hasNext(), is(false)); }
/** * Index (or re-index) all of the content in all of the workspaces within the source. This method operates synchronously and * returns when the requested indexing is completed. * * @return this object for convenience in method chaining; never null * @throws RepositorySourceException if there is a problem accessing the content * @throws SearchEngineException if there is a problem updating the indexes * @throws IllegalArgumentException if the context is null, or if depth per read is not positive */ public SearchEngineIndexer indexAllWorkspaces() throws RepositorySourceException, SearchEngineException { // Get the names of all the workspaces ... GetWorkspacesRequest getWorkspaces = new GetWorkspacesRequest(); try { channel.addAndAwait(getWorkspaces); checkRequestForErrors(getWorkspaces); } catch (InterruptedException e) { // Clear the interrupted status of the thread and continue ... Thread.interrupted(); return this; } // Index all of the workspaces ... Path rootPath = context.getValueFactories().getPathFactory().createRootPath(); Location rootLocation = Location.create(rootPath); for (String workspaceName : getWorkspaces.getAvailableWorkspaceNames()) { index(workspaceName, rootLocation); } return this; }
private void cancelAllRequestsDueToError( Throwable t ) { LOGGER.error(t, GraphI18n.executingRequest, sourceName); try { for (Request request : this.composite.getRequests()) { try { request.cancel(); } finally { request.freeze(); } } cancel(true); } finally { this.composite.freeze(); } }
channel = new CompositeRequestChannel(delegate().getName()); channel.start(executorService, context, connectionFactory); channel.add(request); if (channel != null) { try { channel.close(); } finally { try { channel.await(); } catch (CancellationException err) { composite.cancel();