Делайте в Mule 4.0

Мне нужно создать цикл do while в Mule 4.0. Мне нужен цикл, который завершится при заданном условии.

К сожалению, я не могу понять, как это сделать в Mule 4.0.

Использование рекурсивных циклов, хотя и не идеальное, раньше работало в Mule 3, но больше не работает в Mule 4.

Я также использовал область до успешного завершения, чтобы иметь возможность зацикливаться до тех пор, пока не будет выполнено определенное условие, однако в Mule 4.0 нет выражения отказа, поэтому я не могу проверить условие для завершения.

Каков путь вперед в Mule 4.0 для создания простого цикла do-while.

ТИА


person malteser    schedule 23.07.2019    source источник


Ответы (5)


Я думаю, что until-successful по-прежнему является лучшим решением, поскольку оно дает вам возможность выйти из цикла после X попыток. Просто, к сожалению, нужно контролировать ошибки. Вы можете использовать простой процессор choice и raise-error:

       <until-successful  maxRetries="5">
            <http:request method="GET" url="http://something" doc:name="Request" />
            <choice>
                <when expression="#[payload.status !='OK']">
                    <raise-error type="APP:REQUEST_NOT_FINISHED"/>
                </when>
            </choice>
        </until-successful>
person Ryan Carter    schedule 23.07.2019
comment
спасибо, не знал об обработчике повышения ошибки - вместо этого я собирался генерировать исключение внутри Groovy. Да, это, кажется, единственный вариант, как вы написали. Мне кажется странным, что это невозможно сделать без ошибок. - person malteser; 23.07.2019
comment
У этого решения есть существенный недостаток — ERROR регистрируется приложением, что не подходит для мониторинга журналов и устранения ошибок. - person zdenekca; 20.08.2020

Потоки мулов не предназначены для работы в качестве языка программирования. У вас есть область действия foreach для перебора вещей, а DataWeave имеет функциональную операцию map().

Вызов рекурсивных потоков считается плохой практикой, и его следует избегать. Это возможно, но это ограничено в Mule 4, потому что это может легко привести к ошибкам переполнения стека.

Если вам абсолютно необходимо это сделать, вы должны сделать это на Java или языке сценариев.

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

person aled    schedule 23.07.2019
comment
Для каждого будет недостаточно, так как у меня нет коллекции для повторения. У меня есть флаг состояния, который меняется, и я проверяю этот флаг, чтобы убедиться, что задание на стороне сервера завершено, прежде чем продолжить мой поток. Раньше я мог проверить флаг до тех пор, пока не добьюсь успеха, и теперь это больше не вариант. Раньше рекурсия была вариантом, а теперь нет, хотя это не мое предпочтительное решение. Единственный вариант — проверить флаг и продолжать генерировать исключение, используя отличный скрипт, как я его вижу, чтобы я мог запустить цикл до успешного завершения. - person malteser; 23.07.2019

Если вы ожидаете завершения задания, работающего на сервере, прежде чем продолжить, вы можете добиться такого рода оркестровки с помощью очередей — я использовал этот подход.

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

Такой подход предотвращает проблему переполнения стека, но не подходит, если по какой-то причине весь процесс должен быть синхронным.

person Johnson    schedule 23.07.2019

Следующее решение имитирует цикл в цикле Mule с использованием компонента foreach без задержек или ошибок запуска:

            <set-variable value="#[1 to 100]" doc:name="loopArray"  variableName="loopArray"/>
            <foreach doc:name="For Each" collection="#[vars.loopArray]">
                <choice doc:name="Choice" >
                    <when expression="#[vars.hasNextPage &gt; 0]">                          
                        <flow-ref doc:name="getNextPage" name="getNextPage" />
                    </when>
                    <otherwise >
                        <logger level="DEBUG" doc:name="Logger" message="noop" />
                    </otherwise>
                </choice>
            </foreach>
person zdenekca    schedule 20.08.2020

Я надеюсь, что есть надежда. Я видел DO в некоторых ответах, но не мог понять, как добавить условие. По крайней мере, это работает и не выдает синтаксическую ошибку

%dw 2.0
output application/json
---
do {
     {
      n: 1
     } 
} 

У Mule нет концепции do-while. Однако его можно сымитировать с помощью небольшой хитрости. Единственная итеративная (эмулирующая do) функция — это reduce, но она имеет только один аккумулятор, который передается от итерации к итерации. Эту единственную переменную следует использовать для накопления результатов и указания конца итераций (для эмуляции в то время). Самый простой способ - использовать значение в качестве аккумулятора и знак в качестве индикатора. При накоплении суммарного значения отрицательный результат указывает на окончание циклов.

%dw 2.0
var x=[1,2,3,4,5]
output application/json
---
-(x reduce (item, acc=0) -> if (item <4 and acc >= 0) acc + item else if (acc>0) -acc else acc) 

Некоторый сложный объект может использоваться для сбора результатов, а также иметь индикатор конца цикла как часть объекта.

%dw 2.0
var x=[1,2,3,4,5]
output application/json
---
(x reduce (item, acc={sum:0}) -> if (item < 4 and acc.end==null ) (acc - 'sum' ++ {sum: acc.sum+item}) else ( acc ++ {end:true} )).sum

https://simpleflatservice.com/mule4/DoWhileImitation.html

person Alex    schedule 30.03.2020