Resource gets stuck awaiting a callable that awaits a timer

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By OgGhostJelly

This resource gets stuck awaiting for the callable to finish, even after the callable has finished. The resource ends up awaiting forever. Is this a bug or not?

In test_scene.gd

extends Node
func _ready() -> void:
	var test_resource = preload('res://TestResource.gd').new()
	
	test_resource.call_callable(func():
		print('Callable called')
		await get_tree().create_timer(0.02).timeout
        # "Callable finished" is successfully printed to console
		print('Callable finished')
		)

In TestResource.gd

extends Resource


func call_callable(callable: Callable) -> void:
	print('TestResource calling %s' % callable)
    # Gets stuck waiting for this
	await callable.call()
    # This print function is never ran.
	print('TestResource finished calling %s' % callable)

I’m using Godot v4.1.beta2.official

Interesting. Removing the await from await callable.call() will work as expected (waiting for the timer judging by the output). However, removing the await in the lambda (I commented the line…) will also work (kinda - there’s no timer but it doesn’t get stuck). I wondered if the timer was too short a value but no, increasing it to 1 sec still gets stuck with the original code.

So could there be a problem with await’ing in an await using a lambda? I was tempted to try regular methods to see if the result was the same but didn’t. I also suspected that there might be a problem interacting with the SceneTree as I was unsure which context the lambda would be running (from the Resource, which isn’t in the tree but is owned by a Node that is?).

I’d be tempted to open a bug to clarify with the official devs.

spaceyjase | 2023-06-21 10:54

you should probably open an issue on this, Also I tried creating my own version of a timer and it still had the same issue. So, I really don’t know.

OgGhostJelly | 2023-06-21 13:14

:bust_in_silhouette: Reply From: OgGhostJelly

I’m almost 100% sure it’s a bug, but awaiting the test_resource fixes it

await test_resource.call_callable(func():
    print('Callable called')
    await get_tree().create_timer(0.02).timeout
    # "Callable finished" is successfully printed to console
    print('Callable finished')
    )