55 */
66package org .elasticsearch .xpack .search ;
77
8- import org .apache .logging .log4j .LogManager ;
9- import org .apache .logging .log4j .Logger ;
10- import org .apache .logging .log4j .message .ParameterizedMessage ;
11- import org .elasticsearch .ExceptionsHelper ;
12- import org .elasticsearch .ResourceNotFoundException ;
138import org .elasticsearch .action .ActionListener ;
149import org .elasticsearch .action .ActionListenerResponseHandler ;
1510import org .elasticsearch .action .support .ActionFilters ;
1914import org .elasticsearch .cluster .service .ClusterService ;
2015import org .elasticsearch .common .inject .Inject ;
2116import org .elasticsearch .common .io .stream .NamedWriteableRegistry ;
22- import org .elasticsearch .rest .RestStatus ;
2317import org .elasticsearch .tasks .Task ;
2418import org .elasticsearch .threadpool .ThreadPool ;
2519import org .elasticsearch .transport .TransportRequestOptions ;
2620import org .elasticsearch .transport .TransportService ;
27- import org .elasticsearch .xpack .core .async .AsyncExecutionId ;
21+ import org .elasticsearch .xpack .core .async .AsyncResultsService ;
2822import org .elasticsearch .xpack .core .async .AsyncTaskIndexService ;
23+ import org .elasticsearch .xpack .core .async .GetAsyncResultRequest ;
2924import org .elasticsearch .xpack .core .search .action .AsyncSearchResponse ;
3025import org .elasticsearch .xpack .core .search .action .GetAsyncSearchAction ;
3126
3227import static org .elasticsearch .xpack .core .ClientHelper .ASYNC_SEARCH_ORIGIN ;
3328
34- public class TransportGetAsyncSearchAction extends HandledTransportAction <GetAsyncSearchAction .Request , AsyncSearchResponse > {
35- private final Logger logger = LogManager .getLogger (TransportGetAsyncSearchAction .class );
36- private final ClusterService clusterService ;
29+ public class TransportGetAsyncSearchAction extends HandledTransportAction <GetAsyncResultRequest , AsyncSearchResponse > {
30+ private final AsyncResultsService <AsyncSearchTask , AsyncSearchResponse > resultsService ;
3731 private final TransportService transportService ;
38- private final AsyncTaskIndexService <AsyncSearchResponse > store ;
3932
4033 @ Inject
4134 public TransportGetAsyncSearchAction (TransportService transportService ,
@@ -44,113 +37,23 @@ public TransportGetAsyncSearchAction(TransportService transportService,
4437 NamedWriteableRegistry registry ,
4538 Client client ,
4639 ThreadPool threadPool ) {
47- super (GetAsyncSearchAction .NAME , transportService , actionFilters , GetAsyncSearchAction .Request ::new );
48- this .clusterService = clusterService ;
40+ super (GetAsyncSearchAction .NAME , transportService , actionFilters , GetAsyncResultRequest ::new );
4941 this .transportService = transportService ;
50- this .store = new AsyncTaskIndexService <>(AsyncSearch .INDEX , clusterService , threadPool .getThreadContext (), client ,
51- ASYNC_SEARCH_ORIGIN , AsyncSearchResponse ::new , registry );
42+ AsyncTaskIndexService <AsyncSearchResponse > store = new AsyncTaskIndexService <>(AsyncSearch .INDEX , clusterService ,
43+ threadPool .getThreadContext (), client , ASYNC_SEARCH_ORIGIN , AsyncSearchResponse ::new , registry );
44+ resultsService = new AsyncResultsService <>(store , true , AsyncSearchTask .class , AsyncSearchTask ::addCompletionListener ,
45+ transportService .getTaskManager (), clusterService );
5246 }
5347
5448 @ Override
55- protected void doExecute (Task task , GetAsyncSearchAction .Request request , ActionListener <AsyncSearchResponse > listener ) {
56- try {
57- long nowInMillis = System .currentTimeMillis ();
58- AsyncExecutionId searchId = AsyncExecutionId .decode (request .getId ());
59- DiscoveryNode node = clusterService .state ().nodes ().get (searchId .getTaskId ().getNodeId ());
60- if (clusterService .localNode ().getId ().equals (searchId .getTaskId ().getNodeId ()) || node == null ) {
61- if (request .getKeepAlive ().getMillis () > 0 ) {
62- long expirationTime = nowInMillis + request .getKeepAlive ().getMillis ();
63- store .updateExpirationTime (searchId .getDocId (), expirationTime ,
64- ActionListener .wrap (
65- p -> getSearchResponseFromTask (searchId , request , nowInMillis , expirationTime , listener ),
66- exc -> {
67- //don't log when: the async search document or its index is not found. That can happen if an invalid
68- //search id is provided or no async search initial response has been stored yet.
69- RestStatus status = ExceptionsHelper .status (ExceptionsHelper .unwrapCause (exc ));
70- if (status != RestStatus .NOT_FOUND ) {
71- logger .error (() -> new ParameterizedMessage ("failed to update expiration time for async-search [{}]" ,
72- searchId .getEncoded ()), exc );
73- }
74- listener .onFailure (new ResourceNotFoundException (searchId .getEncoded ()));
75- }
76- ));
77- } else {
78- getSearchResponseFromTask (searchId , request , nowInMillis , -1 , listener );
79- }
80- } else {
81- TransportRequestOptions .Builder builder = TransportRequestOptions .builder ();
82- transportService .sendRequest (node , GetAsyncSearchAction .NAME , request , builder .build (),
83- new ActionListenerResponseHandler <>(listener , AsyncSearchResponse ::new , ThreadPool .Names .SAME ));
84- }
85- } catch (Exception exc ) {
86- listener .onFailure (exc );
49+ protected void doExecute (Task task , GetAsyncResultRequest request , ActionListener <AsyncSearchResponse > listener ) {
50+ DiscoveryNode node = resultsService .getNode (request .getId ());
51+ if (node == null || resultsService .isLocalNode (node )) {
52+ resultsService .retrieveResult (request , listener );
53+ } else {
54+ TransportRequestOptions .Builder builder = TransportRequestOptions .builder ();
55+ transportService .sendRequest (node , GetAsyncSearchAction .NAME , request , builder .build (),
56+ new ActionListenerResponseHandler <>(listener , AsyncSearchResponse ::new , ThreadPool .Names .SAME ));
8757 }
8858 }
89-
90- private void getSearchResponseFromTask (AsyncExecutionId searchId ,
91- GetAsyncSearchAction .Request request ,
92- long nowInMillis ,
93- long expirationTimeMillis ,
94- ActionListener <AsyncSearchResponse > listener ) {
95- try {
96- final AsyncSearchTask task = store .getTask (taskManager , searchId , AsyncSearchTask .class );
97- if (task == null ) {
98- getSearchResponseFromIndex (searchId , request , nowInMillis , listener );
99- return ;
100- }
101-
102- if (task .isCancelled ()) {
103- listener .onFailure (new ResourceNotFoundException (searchId .getEncoded ()));
104- return ;
105- }
106-
107- if (expirationTimeMillis != -1 ) {
108- task .setExpirationTime (expirationTimeMillis );
109- }
110- task .addCompletionListener (new ActionListener <>() {
111- @ Override
112- public void onResponse (AsyncSearchResponse response ) {
113- sendFinalResponse (request , response , nowInMillis , listener );
114- }
115-
116- @ Override
117- public void onFailure (Exception exc ) {
118- listener .onFailure (exc );
119- }
120- }, request .getWaitForCompletion ());
121- } catch (Exception exc ) {
122- listener .onFailure (exc );
123- }
124- }
125-
126- private void getSearchResponseFromIndex (AsyncExecutionId searchId ,
127- GetAsyncSearchAction .Request request ,
128- long nowInMillis ,
129- ActionListener <AsyncSearchResponse > listener ) {
130- store .getResponse (searchId , true ,
131- new ActionListener <>() {
132- @ Override
133- public void onResponse (AsyncSearchResponse response ) {
134- sendFinalResponse (request , response , nowInMillis , listener );
135- }
136-
137- @ Override
138- public void onFailure (Exception e ) {
139- listener .onFailure (e );
140- }
141- });
142- }
143-
144- private void sendFinalResponse (GetAsyncSearchAction .Request request ,
145- AsyncSearchResponse response ,
146- long nowInMillis ,
147- ActionListener <AsyncSearchResponse > listener ) {
148- // check if the result has expired
149- if (response .getExpirationTime () < nowInMillis ) {
150- listener .onFailure (new ResourceNotFoundException (request .getId ()));
151- return ;
152- }
153-
154- listener .onResponse (response );
155- }
15659}
0 commit comments