Need help to create non-blocking long running function

I’m looking for ideas on how create a long running function that does not block events/timers/etc.
My guess is my function could take a couple minutes to run, and I’d run it at some inconsequential time during each night.

I’ve got a couple of ideas I’m trying, both basically involve splitting the long running function down to as small (time execution wise) as makes sense in to sub-functions. Then from there my two ideas are:

  1. Call mgos_wdt_feed() before each sub-function is executed
  2. Schedule the sub-functions with mgos_set_timer(0, 0, sub_function, NULL); and then manage the overall state somehow between sub-functions.

Option 2 feels like the right way, but I’m struggling trying to work out how best to manage state between each sub-function run. My only idea is via some static enum that tracks progress that I increment “state” with each sub-function, then re-schedule the main function at the end of each sub-function.

Any ideas or even general programming principals/patterns would be much appreciated.

mongoose_poll(0) is a better idea than mgos_wdt_feed() because it allows other events to be processed.

Have a look here.

1 Like

Think of your problem in smaller units.
Your option 2 looks like a finite state machine to me. The only caveat is that since you can’t just loop, you’ll have to find events that trigger your next call to the machine handler. Since I don’t know what you are doing, I can only suggest a periodic timer call (as you already thought, and if the problem requires periodicity or tight timing) or perhaps register your event base and just trigger another event when you know you have to keep processing:

Thanks @scaprile, I’ve read about FSM before but never implemented one. This could be my chance!.
I really like your idea about event based triggers, I’ll look in to that further.

Nah no tight timing, I’m basically logging data points to file during the day and then looking to validate/review/calculate/update some parameters based on a few days worth of collected data.

Batch processing in the background is OK for preemptive multitasking OSs, but here you’ll have to think in terms of event -> action. I guess you can split the whole process in smaller units, if you have a loop you can break it and re-trigger while you have more elements to process, persisting the loop variables in a state structure, that can perhaps be passed in the user_data field.
You can start your process at certain times using crontab (similar to a Un*x crontab)

@klimbot Looks like re-triggering an event is not something to be done as mOS is now. I thought calling the trigger function will queue an event and that will be handled after all things done, but the trigger function just calls the callback again, so re-triggering yourself inside the callback function is actually worse than looping.
You can use the poll function as Liviu suggested or use timer callbacks, working out the self re-trigger concept would require extra work in mOS.

Thanks for the feedback @scaprile, I wasn’t sure how that would work.

Yeah I think I will just start with the mgos_poll(0) option and see how it progresses from there.
I’m thinking now that 2 minutes was probably excessive, should be done in less than 30s so might not be worth the effort.

Well, I’ve worked with other event-driven environments and it does work.