View Javadoc
1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  package org.apache.hc.client5.http.fluent;
28  
29  import java.util.concurrent.Future;
30  
31  import org.apache.hc.core5.concurrent.BasicFuture;
32  import org.apache.hc.core5.concurrent.FutureCallback;
33  import org.apache.hc.core5.http.io.HttpClientResponseHandler;
34  
35  /**
36   * Asynchronous executor for {@link Request}s.
37   *
38   * @since 4.3
39   */
40  public class Async {
41  
42      private Executor executor;
43      private java.util.concurrent.Executor concurrentExec;
44  
45      public static Async newInstance() {
46          return new Async();
47      }
48  
49      Async() {
50          super();
51      }
52  
53      public Async use(final Executor executor) {
54          this.executor = executor;
55          return this;
56      }
57  
58      public Async use(final java.util.concurrent.Executor concurrentExec) {
59          this.concurrentExec = concurrentExec;
60          return this;
61      }
62  
63      static class ExecRunnable<T> implements Runnable {
64  
65          private final BasicFuture<T> future;
66          private final Request request;
67          private final Executor executor;
68          private final HttpClientResponseHandler<T> handler;
69  
70          ExecRunnable(
71                  final BasicFuture<T> future,
72                  final Request request,
73                  final Executor executor,
74                  final HttpClientResponseHandler<T> handler) {
75              super();
76              this.future = future;
77              this.request = request;
78              this.executor = executor;
79              this.handler = handler;
80          }
81  
82          @Override
83          public void run() {
84              try {
85                  final Response response = this.executor.execute(this.request);
86                  final T result = response.handleResponse(this.handler);
87                  this.future.completed(result);
88              } catch (final Exception ex) {
89                  this.future.failed(ex);
90              }
91          }
92  
93      }
94  
95      public <T> Future<T> execute(
96              final Request request, final HttpClientResponseHandler<T> handler, final FutureCallback<T> callback) {
97          final BasicFuture<T> future = new BasicFuture<>(callback);
98          final ExecRunnable<T> runnable = new ExecRunnable<>(
99                  future,
100                 request,
101                 this.executor != null ? this.executor : Executor.newInstance(),
102                 handler);
103         if (this.concurrentExec != null) {
104             this.concurrentExec.execute(runnable);
105         } else {
106             final Thread t = new Thread(runnable);
107             t.setDaemon(true);
108             t.start();
109         }
110         return future;
111     }
112 
113     public <T> Future<T> execute(final Request request, final HttpClientResponseHandler<T> handler) {
114         return execute(request, handler, null);
115     }
116 
117     public Future<Content> execute(final Request request, final FutureCallback<Content> callback) {
118         return execute(request, new ContentResponseHandler(), callback);
119     }
120 
121     public Future<Content> execute(final Request request) {
122         return execute(request, new ContentResponseHandler(), null);
123     }
124 
125 }