import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey' ; import { ScriptBasedSortClause , ScriptClause , mustBeAllOf , MustCondition , MustNotCondition , } from './query_clauses' ; export function taskWithLessThanMaxAttempts ( type , maxAttempts ) { return { bool : { must : [ { term : { 'task.taskType' : type } } , { range : { 'task.attempts' : { lt : maxAttempts , } , } , } , ] , } , } ; } export function tasksOfType ( taskTypes ) { return { bool : { should : [ ... taskTypes ] . map ( ( type ) => ( { term : { 'task.taskType' : type } } ) ) , } , } ; } export function tasksClaimedByOwner ( taskManagerId , ... taskFilters ) { return mustBeAllOf ( { term : { 'task.ownerId' : taskManagerId , } , } , { term : { 'task.status' : 'claiming' } } , ... taskFilters ) ; } export const IdleTaskWithExpiredRunAt = { bool : { must : [ { term : { 'task.status' : 'idle' } } , { range : { 'task.runAt' : { lte : 'now' } } } ] , } , } ; export const InactiveTasks = { bool : { must_not : [ { bool : { should : [ { term : { 'task.status' : 'running' } } , { term : { 'task.status' : 'claiming' } } ] , must : { range : { 'task.retryAt' : { gt : 'now' } } } , } , } , ] , } , } ; export const RunningOrClaimingTaskWithExpiredRetryAt = { bool : { must : [ { bool : { should : [ { term : { 'task.status' : 'running' } } , { term : { 'task.status' : 'claiming' } } ] , } , } , { range : { 'task.retryAt' : { lte : 'now' } } } , ] , } , } ; const SortByRunAtAndRetryAtScript = { _script : { type : 'number' , order : 'asc' , script : { lang : 'painless' , source : `
if (doc['task.retryAt'].size()!=0) {
  return doc['task.retryAt'].value.toInstant().toEpochMilli();
}
if (doc['task.runAt'].size()!=0) {
  return doc['task.runAt'].value.toInstant().toEpochMilli();
}
    ` , } , } , } ; export const SortByRunAtAndRetryAt = SortByRunAtAndRetryAtScript as estypes . SortCombinations ; export const updateFieldsAndMarkAsFailed = ( fieldUpdates , claimTasksById , claimableTaskTypes , skippedTaskTypes , taskMaxAttempts ) : ScriptClause => { const markAsClaimingScript = `ctx._source.task.status = "claiming"; ${ Object . keys ( fieldUpdates ) . map ( ( field ) => `ctx._source.task.${ field }=params.fieldUpdates.${ field };` ) . join ( ' ' ) }` ; return { source : `
    if (params.claimableTaskTypes.contains(ctx._source.task.taskType)) {
      if (ctx._source.task.schedule != null || ctx._source.task.attempts < params.taskMaxAttempts[ctx._source.task.taskType] || params.claimTasksById.contains(ctx._id)) {
        ${ markAsClaimingScript }
      } else {
        ctx._source.task.status = "failed";
      }
    } else if (params.skippedTaskTypes.contains(ctx._source.task.taskType) && params.claimTasksById.contains(ctx._id)) {
      ${ markAsClaimingScript }
    } else if (!params.skippedTaskTypes.contains(ctx._source.task.taskType)) {
      ctx._source.task.status = "unrecognized";
    } else {
      ctx.op = "noop";
    }` , lang : 'painless' , params : { fieldUpdates , claimTasksById , claimableTaskTypes , skippedTaskTypes , taskMaxAttempts , } , } ; } ;