BoltsFramework / Bolts-Android

Bolts is a collection of low-level libraries designed to make developing mobile apps easier.
http://boltsframework.github.io/Bolts-Android/
MIT License
4.02k stars 518 forks source link

continueWhile #142

Open pharos42 opened 7 years ago

pharos42 commented 7 years ago

This is more of a performance or memory leak/resource management item but as far as I can tell the way continueWhile is written will effectively create a chain of tasks that will keep growing each iteration until the loop completes. In a small loop this probably does not matter but in a long running or infinite loop this grows indefinitely until failure. I believe this can be prevented by using a completion source to manage reporting loop completion and avoiding continueWithTask or related anything that chains the .then's together. The continuation could be rewritten as a Task returning method so returning false ends the loop. the result of each iteration would use continueWith and proxy the error to the task completion source or dispatch the next iteration if result is good.

grantland commented 6 years ago

Thanks for bringing up your concern! Would you be willing to provide a PR with this optimization?

depoll commented 6 years ago

I'm not sure that's right. The existing code chains tasks, but task chains don't keep their history in memory -- only whatever is still being waited on (which in the case of a continueWhile will just be the last operation). Tasks are explicitly designed to hold their references in the other direction and they relinquish the reference once the task is completed. Have you actually seen a leak here?

pharos42 commented 6 years ago

before looping, continueWithTask will create a task completion source who's value will not be set until the task returned by the continuation is completed. The continuation calls onSuccessTask to start the next iteration of the loop and returns a task completion source who is not completed until that inner task is completed. Each loop will generate a task completion source that wont be completed until its subtask is completed.

each iteration will create a new task completion source that does not complete until the new iteration completes and that new iteration cannot complete until the next iteration... thus the chain will keep growing until the loop is done or out of resources.