Пакетный шаг Java с разделом возвращает неправильный пакетный статус и выходной статус

У меня есть (очень простое) пакетное задание Java в JDL всего за два шага.

Когда шаг «загрузка» возвращает статус «ОСТАНОВЛЕНО», задание должно быть остановлено. После перезапуска должно быть вызвано уведомление об остановке.

Без раздела все работает нормально.

статистика без раздела

after step=download batchStatus=COMPLETED exitStatus=STOPPED
after job=job       batchStatus=STOPPED   exitStatus=STOPPED

С разделом я получаю очень странные данные для выхода из пакета. И задание не останавливается, если шаг загрузки возвращает «ОСТАНОВЛЕНО». Даже если раздел имеет только один поток и один раздел.

При попытке перезагрузки возникает следующая ошибка (разумеется). JBERET000609: Выполнение задания 1 уже завершено и не может быть перезапущено.

статистика с разделом

after step=download batchStatus=STARTED   exitStatus=null
after job=job       batchStatus=COMPLETED exitStatus=COMPLETED

описание работы

<job id="job" xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.0" restartable="true">
    <step id="download" next="notify">
        <batchlet ref="downloadBatchlet">
        </batchlet>
        <partition>
            <mapper ref="basicPartition" />
        </partition>
        <stop on="STOPPED" restart="notify"/>
    </step>
    <step id="notify">
        <batchlet ref="notifyBatchlet"></batchlet>
        <end on="COMPLETED"/>
    </step>
</job>

Каждый намек предложения приветствуются. Что мне не хватает?

Без раздела

При запуске задания задание вызывает - downloadBatchlet => STOPPED и останавливается.

При перезапуске задание вызывает -notifyBatchlet => COMPLETED и завершается.

С разделом

При запуске задания задание вызывает - downloadBatchlet => STOPPED и останавливается.

При перезапуске задание вызывает БЕЗ ШАГОВ и завершается.

@Named
public class DownloadBatchlet extends AbstractBatchlet {
    @Override
    public String process() throws Exception {

        return BatchStatus.STOPPED.toString();
    }
    @Override
    public void stop() throws Exception {
    }
}

person unclescrouge    schedule 16.08.2018    source источник


Ответы (1)


Раздел против статуса пакета/выхода верхнего уровня

В Java Batch существует отдельный пакет и статус выхода для самого шага, а также для каждого раздела.

Поскольку «переход» (к следующему шагу или для остановки задания в вашем случае) происходит здесь на уровне задания, вам нужно будет установить статус выхода не по умолчанию на «верхнем уровне» шага, а не просто на уровне каждого раздела.

Если вы хотите включить логику, которая реагирует на состояние каждого раздела, хорошей отправной точкой будет PartitionAnalyzer#analyzeStatus, который вызывается при завершении каждой секции. Это выполняется в потоке «верхнего уровня» (как и PartitionReducer).

Простой пример анализатора

public class MyPartitionAnalyzer extends AbstractPartitionAnalyzer {

    @Inject
    private StepContext stepCtx;

    @Override
    public void analyzeStatus(BatchStatus batchStatus, String exitStatus) throws Exception {

        // Overrides default exit status if non-COMPLETED partition seen
        if (!exitStatus.equals(BatchStatus.COMPLETED)) {
            stepCtx.setExitStatus(exitStatus);
        }
    }
}

Вы можете использовать любую логику, которую вы хотите реагировать (или нет) на статусы пакетов и выхода разделов. Ключевым моментом здесь является то, что анализатор работает в потоке шага верхнего уровня и, таким образом, устанавливает статус уровня шага. С другой стороны, возвращаемое пакетлетом значение устанавливает только статус уровня раздела.

Анализатор можно использовать для «объединения» состояния на уровне разделов, как вам угодно. Если вы ничего не делаете, статус выхода на уровне шага по умолчанию становится статусом пакета на уровне шага, поэтому, если шаг завершается нормально, статус выхода на уровне шага будет ВЫПОЛНЕН.

person Scott Kurz    schedule 16.08.2018
comment
Большое спасибо за ваш ответ, но я его не понял. Без раздела переход работает отлично. При добавлении раздела всего одним потоком и одним разделом - переход при перезапуске уже не работает. Что ты имеешь в виду, что я должен измениться? - person unclescrouge; 16.08.2018
comment
Как вы устанавливаете статус выхода в своем пакете? - person Scott Kurz; 16.08.2018
comment
Для этого варианта использования и текущей цели тестирования я всегда устанавливаю статус в пакете на ОСТАНОВЛЕНО. Я добавил в пакет к запросу выше. Спасибо за вашу помощь. - person unclescrouge; 16.08.2018
comment
Обновленный ответ. - person Scott Kurz; 16.08.2018
comment
Спасибо за вашу помощь. Я попробую. - person unclescrouge; 16.08.2018
comment
Отлично работает сейчас! Спасибо за подсказку! Изменено ваше условие на !exitStatus.equals. И добавил к заданию ‹analyzer ref=basicPartition/›. - person unclescrouge; 17.08.2018
comment
Рад помочь. Да, проверка статуса выхода лучше подходит для вашего начального кода. Хорошая точка зрения. Скорректировал мой ответ. - person Scott Kurz; 17.08.2018