Skip to content
This repository has been archived by the owner on Jan 5, 2024. It is now read-only.

Recursion #2

Open
1Dragoon opened this issue Mar 20, 2022 · 2 comments
Open

Recursion #2

1Dragoon opened this issue Mar 20, 2022 · 2 comments

Comments

@1Dragoon
Copy link

Can this be used for recursive async functions?

@jaboatman
Copy link
Owner

Yes, for example:

    #[test]
    fn recursive_test() {
        #[async_recursion::async_recursion]
        async fn recursive(data: &mut String, count: usize) {
            if count == 10 {
                return;
            }
            data.push('a');
            recursive(data, count + 1).await;
        }
        let rt = make_runtime();
        let scoped = scoped(rt.handle());
        let mut data = String::new();
        scoped.scope(|scope| {
            scope.spawn(async {
                recursive(&mut data, 0).await;
            });
        });
        assert_eq!(data, "aaaaaaaaaa");
    }

    #[tokio::test(flavor = "multi_thread")]
    async fn recursive_test2() {
        #[async_recursion::async_recursion]
        async fn recursive(data: &mut String, count: usize) {
            if count == 10 {
                return;
            }
            super::scope(|scope| {
                scope.spawn(async {
                    recursive(data, count + 1).await;
                });
            });
            data.push('a');
        }
        let mut data = String::new();
        recursive(&mut data, 0).await;
        assert_eq!(data, "aaaaaaaaaa");
    }

Is this not what you had in mind?

@1Dragoon
Copy link
Author

1Dragoon commented Mar 22, 2022

How do the nested calls stay within the same scope if you aren't passing the scope variable to them? Unless the async_recursion macro is doing more than I thought it was doing

EDIT: For a little pretext, I'm only familiar with the rayon version of scope, which allows you call the recursive function and then pass the scope variable into the function so then it can in turn use it to spawn successive recursive calls within the same scope. This allows you to guarantee that all recursive subtasks have completed prior to the initial function call being able to complete, thus no orphaned tasks that were still running remain when the program terminates.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants