Hi João,
I'm not sure where that error message comes from, as I don't see any obvious recursive loops. Can it be that one of the Actions inside the For Each loop has the full list as input, and tries to iterate over the list?
That said, the restart logic of your Timer is flawed. What happens when the loop is finished (20 records have been processed), is that:
- You adjust var1;
- You try to restart the Timer;
- You execute the query again;
- You restart the loop again, in the same Timer.
First, restarting a Timer doesn't do anything while the Timer is still running. Check my article here on the gritty details. The only thing that'll happen is that when the Timer is finished, it will restart. But... your Timer never finishes, until all records have been processed.
Secondly, you execute the query each iteration. This is typically not what you want, as if the data changes, you'll process different records, and may even reprocess certain records, depending on the criteria in the Aggregate.
Thirdly, why do you process only 20 records, if you are going to process all records anyway (since the Timer won't stop until Var1 (very bad name btw!) has a value greater than the number of records in the query result.
Fourthly, why do you limit the number of records in the For Each, instead of in the Aggregate? Unless you adhere to a number of specific limitations, you will transfer way more data from the database server than you need, which is slow.
So what did you intend to do, functionally? Process only 20 records, then restart the Timer, then process the next 20? (Btw, Timers can conveniently run for large stretches of time, the processing must be really slow to warrent only 20 records, 1000 records is more typical.) Note that you cannot set Var1 and then expect it to keep its value between Timer runs - each Timer run is fully independent of the previous one!
What you would typically want is this:
- Query only the limited set you want to process. Make sure that the query does not select records you already processed (e.g. by left-joining an Entity that only gets filled when processing, or by keeping track of a processing status per record, etc.);
- After processing the records in the For Each (don't use a Start Index or Maximum Iterations, that's not needed if you design your query correctly), check whether the number of records the Aggregate returns against the Max. Records you specified - if it's less, you know everything's been processed and you can End the Timer, otherwise call the Timer's Wake action, then End the action.
That's it. The Timer will restart itself, query a fresh set of records, process them, etc. until there's nothing more to query.