Bläddra i källkod

fix #407 : set timeout to actionGet()

Shinsuke Sugaya 9 år sedan
förälder
incheckning
08de9da936

+ 1 - 1
src/main/java/org/codelibs/fess/app/service/SearchService.java

@@ -238,7 +238,7 @@ public class SearchService {
             final UpdateRequestBuilder builder =
                     fessEsClient.prepareUpdate(fessConfig.getIndexDocumentUpdateIndex(), fessConfig.getIndexDocumentType(), id);
             builderLambda.accept(builder);
-            final UpdateResponse response = builder.execute().actionGet();
+            final UpdateResponse response = builder.execute().actionGet(fessConfig.getIndexIndexTimeout());
             return response.isCreated();
         } catch (final ElasticsearchException e) {
             throw new FessEsClientException("Failed to update doc  " + id, e);

+ 31 - 19
src/main/java/org/codelibs/fess/es/client/FessEsClient.java

@@ -210,7 +210,8 @@ public class FessEsClient implements Client {
     }
 
     public String getStatus() {
-        return admin().cluster().prepareHealth().execute().actionGet().getStatus().name();
+        return admin().cluster().prepareHealth().execute().actionGet(ComponentUtil.getFessConfig().getIndexHealthTimeout()).getStatus()
+                .name();
     }
 
     public void setRunner(final ElasticsearchClusterRunner runner) {
@@ -307,7 +308,7 @@ public class FessEsClient implements Client {
                 final String configType = values[1];
                 boolean exists = false;
                 try {
-                    client.prepareExists(configIndex).execute().actionGet();
+                    client.prepareExists(configIndex).execute().actionGet(fessConfig.getIndexSearchTimeout());
                     exists = true;
                 } catch (final IndexNotFoundException e) {
                     // ignore
@@ -350,7 +351,8 @@ public class FessEsClient implements Client {
                     final String dictionaryPath = System.getProperty("fess.dictionary.path", StringUtil.EMPTY);
                     source = source.replaceAll(Pattern.quote("${fess.dictionary.path}"), dictionaryPath);
                     final CreateIndexResponse indexResponse =
-                            client.admin().indices().prepareCreate(configIndex).setSource(source).execute().actionGet();
+                            client.admin().indices().prepareCreate(configIndex).setSource(source).execute()
+                                    .actionGet(fessConfig.getIndexIndicesTimeout());
                     if (indexResponse.isAcknowledged()) {
                         logger.info("Created " + configIndex + " index.");
                     } else if (logger.isDebugEnabled()) {
@@ -364,7 +366,8 @@ public class FessEsClient implements Client {
             }
 
             final GetMappingsResponse getMappingsResponse =
-                    client.admin().indices().prepareGetMappings(configIndex).setTypes(configType).execute().actionGet();
+                    client.admin().indices().prepareGetMappings(configIndex).setTypes(configType).execute()
+                            .actionGet(fessConfig.getIndexIndicesTimeout());
             final ImmutableOpenMap<String, MappingMetaData> indexMappings = getMappingsResponse.mappings().get(configIndex);
             if (indexMappings == null || !indexMappings.containsKey(configType)) {
                 String source = null;
@@ -375,7 +378,8 @@ public class FessEsClient implements Client {
                     logger.warn(mappingFile + " is not found.", e);
                 }
                 final PutMappingResponse putMappingResponse =
-                        client.admin().indices().preparePutMapping(configIndex).setType(configType).setSource(source).execute().actionGet();
+                        client.admin().indices().preparePutMapping(configIndex).setType(configType).setSource(source).execute()
+                                .actionGet(fessConfig.getIndexIndicesTimeout());
                 if (putMappingResponse.isAcknowledged()) {
                     logger.info("Created " + configIndex + "/" + configType + " mapping.");
                 } else {
@@ -417,7 +421,7 @@ public class FessEsClient implements Client {
                                     }
                                     return StringUtil.EMPTY;
                                 });
-                        final BulkResponse response = builder.execute().actionGet();
+                        final BulkResponse response = builder.execute().actionGet(fessConfig.getIndexBulkTimeout());
                         if (response.hasFailures()) {
                             logger.warn("Failed to register " + dataPath + ": " + response.buildFailureMessage());
                         }
@@ -435,7 +439,9 @@ public class FessEsClient implements Client {
     }
 
     private void waitForYellowStatus() {
-        final ClusterHealthResponse response = client.admin().cluster().prepareHealth().setWaitForYellowStatus().execute().actionGet();
+        final ClusterHealthResponse response =
+                client.admin().cluster().prepareHealth().setWaitForYellowStatus().execute()
+                        .actionGet(ComponentUtil.getFessConfig().getIndexHealthTimeout());
         if (logger.isDebugEnabled()) {
             logger.debug("Elasticsearch Cluster Status: " + response.getStatus());
         }
@@ -445,7 +451,8 @@ public class FessEsClient implements Client {
     @PreDestroy
     public void close() {
         try {
-            client.admin().indices().prepareFlush().setForce(true).execute().actionGet();
+            client.admin().indices().prepareFlush().setForce(true).execute()
+                    .actionGet(ComponentUtil.getFessConfig().getIndexIndicesTimeout());
         } catch (Exception e) {
             logger.warn("Failed to flush indices.", e);
         }
@@ -461,7 +468,8 @@ public class FessEsClient implements Client {
         final FessConfig fessConfig = ComponentUtil.getFessConfig();
         SearchResponse response =
                 client.prepareSearch(index).setTypes(type).setScroll(scrollForDelete).setSize(sizeForDelete)
-                        .addField(fessConfig.getIndexFieldId()).setQuery(queryBuilder).execute().actionGet();
+                        .addField(fessConfig.getIndexFieldId()).setQuery(queryBuilder).execute()
+                        .actionGet(fessConfig.getIndexScrollSearchTimeoutTimeout());
 
         int count = 0;
         String scrollId = response.getScrollId();
@@ -478,12 +486,13 @@ public class FessEsClient implements Client {
                 bulkRequest.add(client.prepareDelete(index, type, hit.getId()));
             }
             count += hits.length;
-            final BulkResponse bulkResponse = bulkRequest.execute().actionGet();
+            final BulkResponse bulkResponse = bulkRequest.execute().actionGet(fessConfig.getIndexBulkTimeout());
             if (bulkResponse.hasFailures()) {
                 throw new IllegalBehaviorStateException(bulkResponse.buildFailureMessage());
             }
 
-            response = client.prepareSearchScroll(scrollId).setScroll(scrollForDelete).execute().actionGet();
+            response =
+                    client.prepareSearchScroll(scrollId).setScroll(scrollForDelete).execute().actionGet(fessConfig.getIndexBulkTimeout());
             scrollId = response.getScrollId();
         }
         return count;
@@ -511,7 +520,7 @@ public class FessEsClient implements Client {
                 }
             }
 
-            response = requestBuilder.execute().actionGet();
+            response = requestBuilder.execute().actionGet(ComponentUtil.getFessConfig().getIndexSearchTimeout());
         }
         final long execTime = System.currentTimeMillis() - startTime;
 
@@ -545,7 +554,7 @@ public class FessEsClient implements Client {
             }
 
             try {
-                searchResponse = searchRequestBuilder.execute().actionGet();
+                searchResponse = searchRequestBuilder.execute().actionGet(ComponentUtil.getFessConfig().getIndexSearchTimeout());
             } catch (final SearchPhaseExecutionException e) {
                 throw new InvalidQueryException(messages -> messages.addErrorsInvalidQueryParseError(UserMessages.GLOBAL_PROPERTY_KEY),
                         "Invalid query: " + searchRequestBuilder, e);
@@ -673,7 +682,8 @@ public class FessEsClient implements Client {
 
     public boolean update(final String index, final String type, final String id, final String field, final Object value) {
         try {
-            return client.prepareUpdate(index, type, id).setDoc(field, value).execute().actionGet().isCreated();
+            return client.prepareUpdate(index, type, id).setDoc(field, value).execute()
+                    .actionGet(ComponentUtil.getFessConfig().getIndexIndexTimeout()).isCreated();
         } catch (final ElasticsearchException e) {
             throw new FessEsClientException("Failed to set " + value + " to " + field + " for doc " + id, e);
         }
@@ -716,7 +726,8 @@ public class FessEsClient implements Client {
 
     public PingResponse ping() {
         try {
-            final ClusterHealthResponse response = client.admin().cluster().prepareHealth().execute().actionGet();
+            final ClusterHealthResponse response =
+                    client.admin().cluster().prepareHealth().execute().actionGet(ComponentUtil.getFessConfig().getIndexHealthTimeout());
             return new PingResponse(response);
         } catch (final ElasticsearchException e) {
             throw new FessEsClientException("Failed to process a ping request.", e);
@@ -730,7 +741,7 @@ public class FessEsClient implements Client {
             final Object id = doc.remove(fessConfig.getIndexFieldId());
             bulkRequestBuilder.add(client.prepareIndex(index, type, id.toString()).setSource(doc));
         }
-        final BulkResponse response = bulkRequestBuilder.execute().actionGet();
+        final BulkResponse response = bulkRequestBuilder.execute().actionGet(ComponentUtil.getFessConfig().getIndexBulkTimeout());
         if (response.hasFailures()) {
             if (logger.isDebugEnabled()) {
                 final List<ActionRequest> requests = bulkRequestBuilder.request().requests();
@@ -895,12 +906,13 @@ public class FessEsClient implements Client {
             if (id == null) {
                 // create
                 response =
-                        client.prepareIndex(index, type).setSource(source).setRefresh(true).setOpType(OpType.CREATE).execute().actionGet();
+                        client.prepareIndex(index, type).setSource(source).setRefresh(true).setOpType(OpType.CREATE).execute()
+                                .actionGet(fessConfig.getIndexIndexTimeout());
             } else {
                 // create or update
                 response =
                         client.prepareIndex(index, type, id).setSource(source).setRefresh(true).setOpType(OpType.INDEX).setVersion(version)
-                                .execute().actionGet();
+                                .execute().actionGet(fessConfig.getIndexIndexTimeout());
             }
             return response.isCreated();
         } catch (final ElasticsearchException e) {
@@ -914,7 +926,7 @@ public class FessEsClient implements Client {
             if (version > 0) {
                 builder.setVersion(version);
             }
-            final DeleteResponse response = builder.execute().actionGet();
+            final DeleteResponse response = builder.execute().actionGet(ComponentUtil.getFessConfig().getIndexDeleteTimeout());
             return response.isFound();
         } catch (final ElasticsearchException e) {
             throw new FessEsClientException("Failed to delete: " + index + "/" + type + "/" + id + "/" + version, e);

+ 54 - 11
src/main/java/org/codelibs/fess/es/config/allcommon/EsAbstractBehavior.java

@@ -69,6 +69,11 @@ public abstract class EsAbstractBehavior<ENTITY extends Entity, CB extends Condi
     protected String scrollForDelete = "1m";
     protected int sizeForCursor = 100;
     protected String scrollForCursor = "1m";
+    protected String searchTimeout = "3m";
+    protected String indexTimeout = "3m";
+    protected String scrollSearchTimeout = "3m";
+    protected String bulkTimeout = "3m";
+    protected String deleteTimeout = "3m";
 
     protected abstract String asEsIndex();
 
@@ -85,7 +90,7 @@ public abstract class EsAbstractBehavior<ENTITY extends Entity, CB extends Condi
     protected int delegateSelectCountUniquely(final ConditionBean cb) {
         // #pending check response and cast problem
         final CountRequestBuilder builder = client.prepareCount(asEsIndex()).setTypes(asEsSearchType());
-        return (int) ((EsAbstractConditionBean) cb).build(builder).execute().actionGet().getCount();
+        return (int) ((EsAbstractConditionBean) cb).build(builder).execute().actionGet(searchTimeout).getCount();
     }
 
     @Override
@@ -117,7 +122,7 @@ public abstract class EsAbstractBehavior<ENTITY extends Entity, CB extends Condi
         builder.setFrom(from);
         builder.setSize(size);
         ((EsAbstractConditionBean) cb).request().build(builder);
-        final SearchResponse response = ((EsAbstractConditionBean) cb).build(builder).execute().actionGet();
+        final SearchResponse response = ((EsAbstractConditionBean) cb).build(builder).execute().actionGet(searchTimeout);
 
         final EsPagingResultBean<RESULT> list = new EsPagingResultBean<>();
         final SearchHits searchHits = response.getHits();
@@ -196,11 +201,12 @@ public abstract class EsAbstractBehavior<ENTITY extends Entity, CB extends Condi
                 client.prepareSearch(asEsIndex()).setTypes(asEsIndexType()).setSearchType(SearchType.SCAN).setScroll(scrollForCursor)
                         .setSize(sizeForCursor);
         ((EsAbstractConditionBean) cb).request().build(builder);
-        final SearchResponse response = ((EsAbstractConditionBean) cb).build(builder).execute().actionGet();
+        final SearchResponse response = ((EsAbstractConditionBean) cb).build(builder).execute().actionGet(scrollSearchTimeout);
 
         String scrollId = response.getScrollId();
         while (scrollId != null) {
-            final SearchResponse scrollResponse = client.prepareSearchScroll(scrollId).setScroll(scrollForDelete).execute().actionGet();
+            final SearchResponse scrollResponse =
+                    client.prepareSearchScroll(scrollId).setScroll(scrollForDelete).execute().actionGet(scrollSearchTimeout);
             scrollId = scrollResponse.getScrollId();
             final SearchHits searchHits = scrollResponse.getHits();
             final SearchHit[] hits = searchHits.getHits();
@@ -237,7 +243,7 @@ public abstract class EsAbstractBehavior<ENTITY extends Entity, CB extends Condi
         final EsAbstractEntity esEntity = (EsAbstractEntity) entity;
         IndexRequestBuilder builder = createInsertRequest(esEntity);
 
-        final IndexResponse response = builder.execute().actionGet();
+        final IndexResponse response = builder.execute().actionGet(indexTimeout);
         esEntity.asDocMeta().id(response.getId());
         return response.isCreated() ? 1 : 0;
     }
@@ -260,7 +266,7 @@ public abstract class EsAbstractBehavior<ENTITY extends Entity, CB extends Condi
         final EsAbstractEntity esEntity = (EsAbstractEntity) entity;
         final IndexRequestBuilder builder = createUpdateRequest(esEntity);
 
-        final IndexResponse response = builder.execute().actionGet();
+        final IndexResponse response = builder.execute().actionGet(indexTimeout);
         long version = response.getVersion();
         if (version != -1) {
             esEntity.asDocMeta().version(version);
@@ -287,7 +293,7 @@ public abstract class EsAbstractBehavior<ENTITY extends Entity, CB extends Condi
         final EsAbstractEntity esEntity = (EsAbstractEntity) entity;
         final DeleteRequestBuilder builder = createDeleteRequest(esEntity);
 
-        final DeleteResponse response = builder.execute().actionGet();
+        final DeleteResponse response = builder.execute().actionGet(deleteTimeout);
         return response.isFound() ? 1 : 0;
     }
 
@@ -306,12 +312,13 @@ public abstract class EsAbstractBehavior<ENTITY extends Entity, CB extends Condi
                 client.prepareSearch(asEsIndex()).setTypes(asEsIndexType()).setSearchType(SearchType.SCAN).setScroll(scrollForDelete)
                         .setSize(sizeForDelete);
         ((EsAbstractConditionBean) cb).request().build(builder);
-        final SearchResponse response = ((EsAbstractConditionBean) cb).build(builder).execute().actionGet();
+        final SearchResponse response = ((EsAbstractConditionBean) cb).build(builder).execute().actionGet(scrollSearchTimeout);
 
         int count = 0;
         String scrollId = response.getScrollId();
         while (scrollId != null) {
-            final SearchResponse scrollResponse = client.prepareSearchScroll(scrollId).setScroll(scrollForDelete).execute().actionGet();
+            final SearchResponse scrollResponse =
+                    client.prepareSearchScroll(scrollId).setScroll(scrollForDelete).execute().actionGet(scrollSearchTimeout);
             scrollId = scrollResponse.getScrollId();
             final SearchHits searchHits = scrollResponse.getHits();
             final SearchHit[] hits = searchHits.getHits();
@@ -325,7 +332,7 @@ public abstract class EsAbstractBehavior<ENTITY extends Entity, CB extends Condi
                 bulkRequest.add(client.prepareDelete(asEsIndex(), asEsIndexType(), hit.getId()));
             }
             count += hits.length;
-            final BulkResponse bulkResponse = bulkRequest.execute().actionGet();
+            final BulkResponse bulkResponse = bulkRequest.execute().actionGet(bulkTimeout);
             if (bulkResponse.hasFailures()) {
                 throw new IllegalBehaviorStateException(bulkResponse.buildFailureMessage());
             }
@@ -390,7 +397,7 @@ public abstract class EsAbstractBehavior<ENTITY extends Entity, CB extends Condi
             builderCall.callback(bulkBuilder);
         }
 
-        final BulkResponse response = bulkBuilder.execute().actionGet();
+        final BulkResponse response = bulkBuilder.execute().actionGet(bulkTimeout);
         final BulkItemResponse[] itemResponses = response.getItems();
         if (itemResponses.length != entityList.size()) {
             throw new IllegalStateException("Invalid response size: " + itemResponses.length + " != " + entityList.size());
@@ -419,6 +426,42 @@ public abstract class EsAbstractBehavior<ENTITY extends Entity, CB extends Condi
         return true;
     }
 
+    public void setSizeForDelete(int sizeForDelete) {
+        this.sizeForDelete = sizeForDelete;
+    }
+
+    public void setScrollForDelete(String scrollForDelete) {
+        this.scrollForDelete = scrollForDelete;
+    }
+
+    public void setSizeForCursor(int sizeForCursor) {
+        this.sizeForCursor = sizeForCursor;
+    }
+
+    public void setScrollForCursor(String scrollForCursor) {
+        this.scrollForCursor = scrollForCursor;
+    }
+
+    public void setSearchTimeout(String searchTimeout) {
+        this.searchTimeout = searchTimeout;
+    }
+
+    public void setIndexTimeout(String indexTimeout) {
+        this.indexTimeout = indexTimeout;
+    }
+
+    public void setScrollSearchTimeout(String scrollSearchTimeout) {
+        this.scrollSearchTimeout = scrollSearchTimeout;
+    }
+
+    public void setBulkTimeout(String bulkTimeout) {
+        this.bulkTimeout = bulkTimeout;
+    }
+
+    public void setDeleteTimeout(String deleteTimeout) {
+        this.deleteTimeout = deleteTimeout;
+    }
+
     // ===================================================================================
     //                                                                        Assist Logic
     //                                                                        ============

+ 54 - 11
src/main/java/org/codelibs/fess/es/log/allcommon/EsAbstractBehavior.java

@@ -69,6 +69,11 @@ public abstract class EsAbstractBehavior<ENTITY extends Entity, CB extends Condi
     protected String scrollForDelete = "1m";
     protected int sizeForCursor = 100;
     protected String scrollForCursor = "1m";
+    protected String searchTimeout = "3m";
+    protected String indexTimeout = "3m";
+    protected String scrollSearchTimeout = "3m";
+    protected String bulkTimeout = "3m";
+    protected String deleteTimeout = "3m";
 
     protected abstract String asEsIndex();
 
@@ -85,7 +90,7 @@ public abstract class EsAbstractBehavior<ENTITY extends Entity, CB extends Condi
     protected int delegateSelectCountUniquely(final ConditionBean cb) {
         // #pending check response and cast problem
         final CountRequestBuilder builder = client.prepareCount(asEsIndex()).setTypes(asEsSearchType());
-        return (int) ((EsAbstractConditionBean) cb).build(builder).execute().actionGet().getCount();
+        return (int) ((EsAbstractConditionBean) cb).build(builder).execute().actionGet(searchTimeout).getCount();
     }
 
     @Override
@@ -117,7 +122,7 @@ public abstract class EsAbstractBehavior<ENTITY extends Entity, CB extends Condi
         builder.setFrom(from);
         builder.setSize(size);
         ((EsAbstractConditionBean) cb).request().build(builder);
-        final SearchResponse response = ((EsAbstractConditionBean) cb).build(builder).execute().actionGet();
+        final SearchResponse response = ((EsAbstractConditionBean) cb).build(builder).execute().actionGet(searchTimeout);
 
         final EsPagingResultBean<RESULT> list = new EsPagingResultBean<>();
         final SearchHits searchHits = response.getHits();
@@ -196,11 +201,12 @@ public abstract class EsAbstractBehavior<ENTITY extends Entity, CB extends Condi
                 client.prepareSearch(asEsIndex()).setTypes(asEsIndexType()).setSearchType(SearchType.SCAN).setScroll(scrollForCursor)
                         .setSize(sizeForCursor);
         ((EsAbstractConditionBean) cb).request().build(builder);
-        final SearchResponse response = ((EsAbstractConditionBean) cb).build(builder).execute().actionGet();
+        final SearchResponse response = ((EsAbstractConditionBean) cb).build(builder).execute().actionGet(scrollSearchTimeout);
 
         String scrollId = response.getScrollId();
         while (scrollId != null) {
-            final SearchResponse scrollResponse = client.prepareSearchScroll(scrollId).setScroll(scrollForDelete).execute().actionGet();
+            final SearchResponse scrollResponse =
+                    client.prepareSearchScroll(scrollId).setScroll(scrollForDelete).execute().actionGet(scrollSearchTimeout);
             scrollId = scrollResponse.getScrollId();
             final SearchHits searchHits = scrollResponse.getHits();
             final SearchHit[] hits = searchHits.getHits();
@@ -237,7 +243,7 @@ public abstract class EsAbstractBehavior<ENTITY extends Entity, CB extends Condi
         final EsAbstractEntity esEntity = (EsAbstractEntity) entity;
         IndexRequestBuilder builder = createInsertRequest(esEntity);
 
-        final IndexResponse response = builder.execute().actionGet();
+        final IndexResponse response = builder.execute().actionGet(indexTimeout);
         esEntity.asDocMeta().id(response.getId());
         return response.isCreated() ? 1 : 0;
     }
@@ -260,7 +266,7 @@ public abstract class EsAbstractBehavior<ENTITY extends Entity, CB extends Condi
         final EsAbstractEntity esEntity = (EsAbstractEntity) entity;
         final IndexRequestBuilder builder = createUpdateRequest(esEntity);
 
-        final IndexResponse response = builder.execute().actionGet();
+        final IndexResponse response = builder.execute().actionGet(indexTimeout);
         long version = response.getVersion();
         if (version != -1) {
             esEntity.asDocMeta().version(version);
@@ -287,7 +293,7 @@ public abstract class EsAbstractBehavior<ENTITY extends Entity, CB extends Condi
         final EsAbstractEntity esEntity = (EsAbstractEntity) entity;
         final DeleteRequestBuilder builder = createDeleteRequest(esEntity);
 
-        final DeleteResponse response = builder.execute().actionGet();
+        final DeleteResponse response = builder.execute().actionGet(deleteTimeout);
         return response.isFound() ? 1 : 0;
     }
 
@@ -306,12 +312,13 @@ public abstract class EsAbstractBehavior<ENTITY extends Entity, CB extends Condi
                 client.prepareSearch(asEsIndex()).setTypes(asEsIndexType()).setSearchType(SearchType.SCAN).setScroll(scrollForDelete)
                         .setSize(sizeForDelete);
         ((EsAbstractConditionBean) cb).request().build(builder);
-        final SearchResponse response = ((EsAbstractConditionBean) cb).build(builder).execute().actionGet();
+        final SearchResponse response = ((EsAbstractConditionBean) cb).build(builder).execute().actionGet(scrollSearchTimeout);
 
         int count = 0;
         String scrollId = response.getScrollId();
         while (scrollId != null) {
-            final SearchResponse scrollResponse = client.prepareSearchScroll(scrollId).setScroll(scrollForDelete).execute().actionGet();
+            final SearchResponse scrollResponse =
+                    client.prepareSearchScroll(scrollId).setScroll(scrollForDelete).execute().actionGet(scrollSearchTimeout);
             scrollId = scrollResponse.getScrollId();
             final SearchHits searchHits = scrollResponse.getHits();
             final SearchHit[] hits = searchHits.getHits();
@@ -325,7 +332,7 @@ public abstract class EsAbstractBehavior<ENTITY extends Entity, CB extends Condi
                 bulkRequest.add(client.prepareDelete(asEsIndex(), asEsIndexType(), hit.getId()));
             }
             count += hits.length;
-            final BulkResponse bulkResponse = bulkRequest.execute().actionGet();
+            final BulkResponse bulkResponse = bulkRequest.execute().actionGet(bulkTimeout);
             if (bulkResponse.hasFailures()) {
                 throw new IllegalBehaviorStateException(bulkResponse.buildFailureMessage());
             }
@@ -390,7 +397,7 @@ public abstract class EsAbstractBehavior<ENTITY extends Entity, CB extends Condi
             builderCall.callback(bulkBuilder);
         }
 
-        final BulkResponse response = bulkBuilder.execute().actionGet();
+        final BulkResponse response = bulkBuilder.execute().actionGet(bulkTimeout);
         final BulkItemResponse[] itemResponses = response.getItems();
         if (itemResponses.length != entityList.size()) {
             throw new IllegalStateException("Invalid response size: " + itemResponses.length + " != " + entityList.size());
@@ -419,6 +426,42 @@ public abstract class EsAbstractBehavior<ENTITY extends Entity, CB extends Condi
         return true;
     }
 
+    public void setSizeForDelete(int sizeForDelete) {
+        this.sizeForDelete = sizeForDelete;
+    }
+
+    public void setScrollForDelete(String scrollForDelete) {
+        this.scrollForDelete = scrollForDelete;
+    }
+
+    public void setSizeForCursor(int sizeForCursor) {
+        this.sizeForCursor = sizeForCursor;
+    }
+
+    public void setScrollForCursor(String scrollForCursor) {
+        this.scrollForCursor = scrollForCursor;
+    }
+
+    public void setSearchTimeout(String searchTimeout) {
+        this.searchTimeout = searchTimeout;
+    }
+
+    public void setIndexTimeout(String indexTimeout) {
+        this.indexTimeout = indexTimeout;
+    }
+
+    public void setScrollSearchTimeout(String scrollSearchTimeout) {
+        this.scrollSearchTimeout = scrollSearchTimeout;
+    }
+
+    public void setBulkTimeout(String bulkTimeout) {
+        this.bulkTimeout = bulkTimeout;
+    }
+
+    public void setDeleteTimeout(String deleteTimeout) {
+        this.deleteTimeout = deleteTimeout;
+    }
+
     // ===================================================================================
     //                                                                        Assist Logic
     //                                                                        ============

+ 54 - 11
src/main/java/org/codelibs/fess/es/user/allcommon/EsAbstractBehavior.java

@@ -69,6 +69,11 @@ public abstract class EsAbstractBehavior<ENTITY extends Entity, CB extends Condi
     protected String scrollForDelete = "1m";
     protected int sizeForCursor = 100;
     protected String scrollForCursor = "1m";
+    protected String searchTimeout = "3m";
+    protected String indexTimeout = "3m";
+    protected String scrollSearchTimeout = "3m";
+    protected String bulkTimeout = "3m";
+    protected String deleteTimeout = "3m";
 
     protected abstract String asEsIndex();
 
@@ -85,7 +90,7 @@ public abstract class EsAbstractBehavior<ENTITY extends Entity, CB extends Condi
     protected int delegateSelectCountUniquely(final ConditionBean cb) {
         // #pending check response and cast problem
         final CountRequestBuilder builder = client.prepareCount(asEsIndex()).setTypes(asEsSearchType());
-        return (int) ((EsAbstractConditionBean) cb).build(builder).execute().actionGet().getCount();
+        return (int) ((EsAbstractConditionBean) cb).build(builder).execute().actionGet(searchTimeout).getCount();
     }
 
     @Override
@@ -117,7 +122,7 @@ public abstract class EsAbstractBehavior<ENTITY extends Entity, CB extends Condi
         builder.setFrom(from);
         builder.setSize(size);
         ((EsAbstractConditionBean) cb).request().build(builder);
-        final SearchResponse response = ((EsAbstractConditionBean) cb).build(builder).execute().actionGet();
+        final SearchResponse response = ((EsAbstractConditionBean) cb).build(builder).execute().actionGet(searchTimeout);
 
         final EsPagingResultBean<RESULT> list = new EsPagingResultBean<>();
         final SearchHits searchHits = response.getHits();
@@ -196,11 +201,12 @@ public abstract class EsAbstractBehavior<ENTITY extends Entity, CB extends Condi
                 client.prepareSearch(asEsIndex()).setTypes(asEsIndexType()).setSearchType(SearchType.SCAN).setScroll(scrollForCursor)
                         .setSize(sizeForCursor);
         ((EsAbstractConditionBean) cb).request().build(builder);
-        final SearchResponse response = ((EsAbstractConditionBean) cb).build(builder).execute().actionGet();
+        final SearchResponse response = ((EsAbstractConditionBean) cb).build(builder).execute().actionGet(scrollSearchTimeout);
 
         String scrollId = response.getScrollId();
         while (scrollId != null) {
-            final SearchResponse scrollResponse = client.prepareSearchScroll(scrollId).setScroll(scrollForDelete).execute().actionGet();
+            final SearchResponse scrollResponse =
+                    client.prepareSearchScroll(scrollId).setScroll(scrollForDelete).execute().actionGet(scrollSearchTimeout);
             scrollId = scrollResponse.getScrollId();
             final SearchHits searchHits = scrollResponse.getHits();
             final SearchHit[] hits = searchHits.getHits();
@@ -237,7 +243,7 @@ public abstract class EsAbstractBehavior<ENTITY extends Entity, CB extends Condi
         final EsAbstractEntity esEntity = (EsAbstractEntity) entity;
         IndexRequestBuilder builder = createInsertRequest(esEntity);
 
-        final IndexResponse response = builder.execute().actionGet();
+        final IndexResponse response = builder.execute().actionGet(indexTimeout);
         esEntity.asDocMeta().id(response.getId());
         return response.isCreated() ? 1 : 0;
     }
@@ -260,7 +266,7 @@ public abstract class EsAbstractBehavior<ENTITY extends Entity, CB extends Condi
         final EsAbstractEntity esEntity = (EsAbstractEntity) entity;
         final IndexRequestBuilder builder = createUpdateRequest(esEntity);
 
-        final IndexResponse response = builder.execute().actionGet();
+        final IndexResponse response = builder.execute().actionGet(indexTimeout);
         long version = response.getVersion();
         if (version != -1) {
             esEntity.asDocMeta().version(version);
@@ -287,7 +293,7 @@ public abstract class EsAbstractBehavior<ENTITY extends Entity, CB extends Condi
         final EsAbstractEntity esEntity = (EsAbstractEntity) entity;
         final DeleteRequestBuilder builder = createDeleteRequest(esEntity);
 
-        final DeleteResponse response = builder.execute().actionGet();
+        final DeleteResponse response = builder.execute().actionGet(deleteTimeout);
         return response.isFound() ? 1 : 0;
     }
 
@@ -306,12 +312,13 @@ public abstract class EsAbstractBehavior<ENTITY extends Entity, CB extends Condi
                 client.prepareSearch(asEsIndex()).setTypes(asEsIndexType()).setSearchType(SearchType.SCAN).setScroll(scrollForDelete)
                         .setSize(sizeForDelete);
         ((EsAbstractConditionBean) cb).request().build(builder);
-        final SearchResponse response = ((EsAbstractConditionBean) cb).build(builder).execute().actionGet();
+        final SearchResponse response = ((EsAbstractConditionBean) cb).build(builder).execute().actionGet(scrollSearchTimeout);
 
         int count = 0;
         String scrollId = response.getScrollId();
         while (scrollId != null) {
-            final SearchResponse scrollResponse = client.prepareSearchScroll(scrollId).setScroll(scrollForDelete).execute().actionGet();
+            final SearchResponse scrollResponse =
+                    client.prepareSearchScroll(scrollId).setScroll(scrollForDelete).execute().actionGet(scrollSearchTimeout);
             scrollId = scrollResponse.getScrollId();
             final SearchHits searchHits = scrollResponse.getHits();
             final SearchHit[] hits = searchHits.getHits();
@@ -325,7 +332,7 @@ public abstract class EsAbstractBehavior<ENTITY extends Entity, CB extends Condi
                 bulkRequest.add(client.prepareDelete(asEsIndex(), asEsIndexType(), hit.getId()));
             }
             count += hits.length;
-            final BulkResponse bulkResponse = bulkRequest.execute().actionGet();
+            final BulkResponse bulkResponse = bulkRequest.execute().actionGet(bulkTimeout);
             if (bulkResponse.hasFailures()) {
                 throw new IllegalBehaviorStateException(bulkResponse.buildFailureMessage());
             }
@@ -390,7 +397,7 @@ public abstract class EsAbstractBehavior<ENTITY extends Entity, CB extends Condi
             builderCall.callback(bulkBuilder);
         }
 
-        final BulkResponse response = bulkBuilder.execute().actionGet();
+        final BulkResponse response = bulkBuilder.execute().actionGet(bulkTimeout);
         final BulkItemResponse[] itemResponses = response.getItems();
         if (itemResponses.length != entityList.size()) {
             throw new IllegalStateException("Invalid response size: " + itemResponses.length + " != " + entityList.size());
@@ -419,6 +426,42 @@ public abstract class EsAbstractBehavior<ENTITY extends Entity, CB extends Condi
         return true;
     }
 
+    public void setSizeForDelete(int sizeForDelete) {
+        this.sizeForDelete = sizeForDelete;
+    }
+
+    public void setScrollForDelete(String scrollForDelete) {
+        this.scrollForDelete = scrollForDelete;
+    }
+
+    public void setSizeForCursor(int sizeForCursor) {
+        this.sizeForCursor = sizeForCursor;
+    }
+
+    public void setScrollForCursor(String scrollForCursor) {
+        this.scrollForCursor = scrollForCursor;
+    }
+
+    public void setSearchTimeout(String searchTimeout) {
+        this.searchTimeout = searchTimeout;
+    }
+
+    public void setIndexTimeout(String indexTimeout) {
+        this.indexTimeout = indexTimeout;
+    }
+
+    public void setScrollSearchTimeout(String scrollSearchTimeout) {
+        this.scrollSearchTimeout = scrollSearchTimeout;
+    }
+
+    public void setBulkTimeout(String bulkTimeout) {
+        this.bulkTimeout = bulkTimeout;
+    }
+
+    public void setDeleteTimeout(String deleteTimeout) {
+        this.deleteTimeout = deleteTimeout;
+    }
+
     // ===================================================================================
     //                                                                        Assist Logic
     //                                                                        ============

+ 1 - 1
src/main/java/org/codelibs/fess/helper/IndexingHelper.java

@@ -142,7 +142,7 @@ public class IndexingHelper {
 
         final CountResponse countResponse =
                 fessEsClient.prepareCount(fessConfig.getIndexDocumentSearchIndex()).setTypes(fessConfig.getIndexDocumentType())
-                        .setQuery(queryBuilder).execute().actionGet();
+                        .setQuery(queryBuilder).execute().actionGet(fessConfig.getIndexSearchTimeout());
         final long numFound = countResponse.getCount();
         // TODO max threshold
 

+ 1 - 1
src/main/java/org/codelibs/fess/helper/SuggestHelper.java

@@ -88,7 +88,7 @@ public class SuggestHelper {
             roleFilterList.add(Pattern.compile(filter));
         });
 
-        fessEsClient.admin().cluster().prepareHealth().setWaitForYellowStatus().execute().actionGet();
+        fessEsClient.admin().cluster().prepareHealth().setWaitForYellowStatus().execute().actionGet(fessConfig.getIndexHealthTimeout());
 
         suggester = Suggester.builder().build(fessEsClient, fessConfig.getIndexDocumentSearchIndex());
         suggester.settings().array().delete(SuggestSettings.DefaultKeys.SUPPORTED_FIELDS);

+ 99 - 0
src/main/java/org/codelibs/fess/mylasta/direction/FessConfig.java

@@ -318,6 +318,27 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction
     /** The key of the configuration. e.g. doc */
     String INDEX_DOCUMENT_TYPE = "index.document.type";
 
+    /** The key of the configuration. e.g. 3m */
+    String INDEX_SEARCH_TIMEOUT = "index.search.timeout";
+
+    /** The key of the configuration. e.g. 3m */
+    String INDEX_SCROLL_SEARCH_TIMEOUT_TIMEOUT = "index.scroll.search.timeout.timeout";
+
+    /** The key of the configuration. e.g. 3m */
+    String INDEX_INDEX_TIMEOUT = "index.index.timeout";
+
+    /** The key of the configuration. e.g. 3m */
+    String INDEX_BULK_TIMEOUT = "index.bulk.timeout";
+
+    /** The key of the configuration. e.g. 3m */
+    String INDEX_DELETE_TIMEOUT = "index.delete.timeout";
+
+    /** The key of the configuration. e.g. 10m */
+    String INDEX_HEALTH_TIMEOUT = "index.health.timeout";
+
+    /** The key of the configuration. e.g. 1m */
+    String INDEX_INDICES_TIMEOUT = "index.indices.timeout";
+
     /** The key of the configuration. e.g. 1000 */
     String QUERY_MAX_LENGTH = "query.max.length";
 
@@ -1572,6 +1593,56 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction
      */
     String getIndexDocumentType();
 
+    /**
+     * Get the value for the key 'index.search.timeout'. <br>
+     * The value is, e.g. 3m <br>
+     * comment: timeout
+     * @return The value of found property. (NotNull: if not found, exception but basically no way)
+     */
+    String getIndexSearchTimeout();
+
+    /**
+     * Get the value for the key 'index.scroll.search.timeout.timeout'. <br>
+     * The value is, e.g. 3m <br>
+     * @return The value of found property. (NotNull: if not found, exception but basically no way)
+     */
+    String getIndexScrollSearchTimeoutTimeout();
+
+    /**
+     * Get the value for the key 'index.index.timeout'. <br>
+     * The value is, e.g. 3m <br>
+     * @return The value of found property. (NotNull: if not found, exception but basically no way)
+     */
+    String getIndexIndexTimeout();
+
+    /**
+     * Get the value for the key 'index.bulk.timeout'. <br>
+     * The value is, e.g. 3m <br>
+     * @return The value of found property. (NotNull: if not found, exception but basically no way)
+     */
+    String getIndexBulkTimeout();
+
+    /**
+     * Get the value for the key 'index.delete.timeout'. <br>
+     * The value is, e.g. 3m <br>
+     * @return The value of found property. (NotNull: if not found, exception but basically no way)
+     */
+    String getIndexDeleteTimeout();
+
+    /**
+     * Get the value for the key 'index.health.timeout'. <br>
+     * The value is, e.g. 10m <br>
+     * @return The value of found property. (NotNull: if not found, exception but basically no way)
+     */
+    String getIndexHealthTimeout();
+
+    /**
+     * Get the value for the key 'index.indices.timeout'. <br>
+     * The value is, e.g. 1m <br>
+     * @return The value of found property. (NotNull: if not found, exception but basically no way)
+     */
+    String getIndexIndicesTimeout();
+
     /**
      * Get the value for the key 'query.max.length'. <br>
      * The value is, e.g. 1000 <br>
@@ -3220,6 +3291,34 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction
             return get(FessConfig.INDEX_DOCUMENT_TYPE);
         }
 
+        public String getIndexSearchTimeout() {
+            return get(FessConfig.INDEX_SEARCH_TIMEOUT);
+        }
+
+        public String getIndexScrollSearchTimeoutTimeout() {
+            return get(FessConfig.INDEX_SCROLL_SEARCH_TIMEOUT_TIMEOUT);
+        }
+
+        public String getIndexIndexTimeout() {
+            return get(FessConfig.INDEX_INDEX_TIMEOUT);
+        }
+
+        public String getIndexBulkTimeout() {
+            return get(FessConfig.INDEX_BULK_TIMEOUT);
+        }
+
+        public String getIndexDeleteTimeout() {
+            return get(FessConfig.INDEX_DELETE_TIMEOUT);
+        }
+
+        public String getIndexHealthTimeout() {
+            return get(FessConfig.INDEX_HEALTH_TIMEOUT);
+        }
+
+        public String getIndexIndicesTimeout() {
+            return get(FessConfig.INDEX_INDICES_TIMEOUT);
+        }
+
         public String getQueryMaxLength() {
             return get(FessConfig.QUERY_MAX_LENGTH);
         }

+ 9 - 0
src/main/resources/fess_config.properties

@@ -156,6 +156,15 @@ index.document.search.index=fess
 index.document.update.index=fess
 index.document.type=doc
 
+# timeout
+index.search.timeout=3m
+index.scroll.search.timeout.timeout=3m
+index.index.timeout=3m
+index.bulk.timeout=3m
+index.delete.timeout=3m
+index.health.timeout=10m
+index.indices.timeout=1m
+
 # query
 query.max.length=1000
 query.replace.term.with.prefix.query=true