@@ -68,8 +68,15 @@ export async function existingFieldsRoute(setup: CoreSetup<PluginStartContract>,
68
68
} ) ,
69
69
} ) ;
70
70
} catch ( e ) {
71
+ if ( e instanceof errors . TimeoutError ) {
72
+ logger . info ( `Field existence check timed out on ${ req . params . indexPatternId } ` ) ;
73
+ // 408 is Request Timeout
74
+ return res . customError ( { statusCode : 408 , body : e . message } ) ;
75
+ }
71
76
logger . info (
72
- `Field existence check failed: ${ isBoomError ( e ) ? e . output . payload . message : e . message } `
77
+ `Field existence check failed on ${ req . params . indexPatternId } : ${
78
+ isBoomError ( e ) ? e . output . payload . message : e . message
79
+ } `
73
80
) ;
74
81
if ( e instanceof errors . ResponseError && e . statusCode === 404 ) {
75
82
return res . notFound ( { body : e . message } ) ;
@@ -182,31 +189,44 @@ async function fetchIndexPatternStats({
182
189
183
190
const scriptedFields = fields . filter ( ( f ) => f . isScript ) ;
184
191
const runtimeFields = fields . filter ( ( f ) => f . runtimeField ) ;
185
- const { body : result } = await client . search ( {
186
- index,
187
- body : {
188
- size : SAMPLE_SIZE ,
189
- query,
190
- sort : timeFieldName && fromDate && toDate ? [ { [ timeFieldName ] : 'desc' } ] : [ ] ,
191
- fields : [ '*' ] ,
192
- _source : false ,
193
- runtime_mappings : runtimeFields . reduce ( ( acc , field ) => {
194
- if ( ! field . runtimeField ) return acc ;
195
- // @ts -expect-error @elastic/elasticsearch StoredScript.language is required
196
- acc [ field . name ] = field . runtimeField ;
197
- return acc ;
198
- } , { } as Record < string , estypes . RuntimeField > ) ,
199
- script_fields : scriptedFields . reduce ( ( acc , field ) => {
200
- acc [ field . name ] = {
201
- script : {
202
- lang : field . lang ! ,
203
- source : field . script ! ,
204
- } ,
205
- } ;
206
- return acc ;
207
- } , { } as Record < string , estypes . ScriptField > ) ,
192
+ const { body : result } = await client . search (
193
+ {
194
+ index,
195
+ body : {
196
+ size : SAMPLE_SIZE ,
197
+ query,
198
+ // Sorted queries are usually able to skip entire shards that don't match
199
+ sort : timeFieldName && fromDate && toDate ? [ { [ timeFieldName ] : 'desc' } ] : [ ] ,
200
+ fields : [ '*' ] ,
201
+ _source : false ,
202
+ runtime_mappings : runtimeFields . reduce ( ( acc , field ) => {
203
+ if ( ! field . runtimeField ) return acc ;
204
+ // @ts -expect-error @elastic/elasticsearch StoredScript.language is required
205
+ acc [ field . name ] = field . runtimeField ;
206
+ return acc ;
207
+ } , { } as Record < string , estypes . RuntimeField > ) ,
208
+ script_fields : scriptedFields . reduce ( ( acc , field ) => {
209
+ acc [ field . name ] = {
210
+ script : {
211
+ lang : field . lang ! ,
212
+ source : field . script ! ,
213
+ } ,
214
+ } ;
215
+ return acc ;
216
+ } , { } as Record < string , estypes . ScriptField > ) ,
217
+ // Small improvement because there is overhead in counting
218
+ track_total_hits : false ,
219
+ // Per-shard timeout, must be lower than overall. Shards return partial results on timeout
220
+ timeout : '4500ms' ,
221
+ } ,
208
222
} ,
209
- } ) ;
223
+ {
224
+ // Global request timeout. Will cancel the request if exceeded. Overrides the elasticsearch.requestTimeout
225
+ requestTimeout : '5000ms' ,
226
+ // Fails fast instead of retrying- default is to retry
227
+ maxRetries : 0 ,
228
+ }
229
+ ) ;
210
230
return result . hits . hits ;
211
231
}
212
232
0 commit comments