@Override public ListenableFuture<ResultSet> fetchMoreResultsAsync() { return new AbstractFuture<ResultSet>() { { new Thread() { public void run() { for (int i = 0; i< 5; i++) { try { Thread.sleep(fetchDelayMillis); } catch (InterruptedException ignore) { } System.out.print("z"); } loadNextChunk(); set(null); }; }.start(); } }; }
@Test public void testDelayedCheckingOfCachingProviders() { String soyFileContent = "{namespace ns}\n" + "\n" + "{template .template}\n" + " {@param foo: int}\n" + " Before: {$foo}\n" + "{/template}\n"; final StringBuilder outputSb = new StringBuilder(); final AtomicReference<String> outputAtFutureGetTime = new AtomicReference<>(); AbstractFuture<Integer> fooFuture = new AbstractFuture<Integer>() { { set(1); } @Override public Integer get() throws InterruptedException, ExecutionException { outputAtFutureGetTime.set(outputSb.toString()); return super.get(); } }; SoyRecord data = SoyValueConverterUtility.newDict("foo", fooFuture); assertThat( renderTemplateInFile( SoyFileSetParserBuilder.forFileContents(soyFileContent).parse(), "ns.template", data, TEST_IJ_DATA, Predicates.<String>alwaysFalse(), outputSb)) .isEqualTo("Before: 1"); assertThat(outputAtFutureGetTime.get()).isEqualTo("Before: "); }
/** * Immediately subscribes to the {@link Observable} and returns a future that will contain the only one value T passed in to the * {@link Observer#onNext(Object)}. If more than one value is received then an {@link Observer#onError(Throwable)} is invoked. * <p> * If the source {@link Observable} emits more than one item or no items, notify of an IllegalArgumentException or NoSuchElementException respectively. * * @param observable The source {@link Observable} for the value. * @return a {@link ListenableFuture} that sets the value on completion. */ public static <T> ListenableFuture<T> to(final Observable<T> observable) { class ListenFutureSubscriberAdaptor extends AbstractFuture<T> { final Subscriber<? super T> subscriber; private ListenFutureSubscriberAdaptor() { subscriber = new Subscriber<T>() { private T value; @Override public void onCompleted() { set(value); } @Override public void onError(Throwable e) { setException(e); } @Override public void onNext(T t) { // wait for the onCompleted to make sure the observable on emits one value. value = t; } }; } @Override protected void interruptTask() { subscriber.unsubscribe(); } } ListenFutureSubscriberAdaptor future = new ListenFutureSubscriberAdaptor(); // Futures are hot so subscribe immediately observable.single().subscribe(future.subscriber); return future; }
@Test public void testStreamLazyParamsToOutputStreamDirectly() { String soyFileContent = Joiner.on("\n") .join( "{namespace ns}", "", "{template .callee}", " {@param body: html}", " <div>", " {$body}", " </div>", "{/template}", "", "{template .caller}", " {@param future: string}", " {call .callee}", " {param body kind=\"html\"}", " static-content{sp}", " {$future}", " {/param}", " {/call}", "{/template}"); final StringBuilder outputSb = new StringBuilder(); final AtomicReference<String> outputAtFutureGetTime = new AtomicReference<>(); AbstractFuture<String> future = new AbstractFuture<String>() { { set("future-content"); } @Override public String get() throws InterruptedException, ExecutionException { outputAtFutureGetTime.set(outputSb.toString()); return super.get(); } }; SoyRecord data = SoyValueConverterUtility.newDict("future", future); assertThat( renderTemplateInFile( SoyFileSetParserBuilder.forFileContents(soyFileContent).parse(), "ns.caller", data, TEST_IJ_DATA, Predicates.<String>alwaysFalse(), outputSb)) .isEqualTo("<div>static-content future-content</div>"); assertThat(outputAtFutureGetTime.get()).isEqualTo("<div>static-content "); }