Reliable way to know whether or not asset_generate_preview() is finished?

What is the recommended way by the Blender developers to determine whether or not an asset has finished generating a preview (and thus has an available icon_id to display in a drawn layout) in a safe way that doesn’t lead to race conditions or crashing?

Here is one such low-tech synchronous attempt:

obj.asset_generate_preview()
while not obj.preview:
    pass
icon_id = obj.preview.icon_id

This attempt to use the is_job_running function unfortunately doesn’t seem to work as intended.

obj.asset_generate_preview()
while bpy.app.is_job_running("RENDER_PREVIEW"):
    pass # Infinite loop
icon_id = obj.preview.icon_id

Here’s another asynchronous attempt:

obj.asset_generate_preview()
blender33_or_above = bpy.app.version >= (3, 3, 0)
interval = 1e-4

def wait_for_asset_previews_generation(check_interval_seconds=interval):
    if blender33_or_above and bpy.app.is_job_running("RENDER_PREVIEW"):
        return check_interval_seconds
    else:
        icon_id = obj.preview.icon_id
        # Do more stuff here

first_interval = 0 if blender33_or_above else interval
bpy.app.timers.register(wait_for_asset_previews_generation, first_interval=first_interval)

Both the first and third snippets “works for me” but the third seems to have users reporting semi-random crashes, and I just got my first potential crash report for the first attempt too (haven’t yet fully isolated it to the preview generation, but it is a possibility).

Instead of guessing, I thought I’d ask to see if there is a recommended approach by the Blender devs :slight_smile: This would be generating asset preview of many objects.

I think there is no need to wait until the preview is done rendering. You can request the icon ID immediately after triggering the preview rendering. If you use it for a UI element, the preview will draw empty until the rendering is done.