Features: - 🤖 AI image generation with Gemini models - 🎬 Video planning and storyboard creation - ✨ Advanced prompt optimization and analysis - 🔧 Smart API key configuration and management - 📊 Multiple model support (Gemini 2.5 Flash/Pro) - 🛡️ Robust error handling and rate limiting - 📖 Comprehensive documentation and quick start guide Created by FloatFloat-chan with ❤️ for the ComfyUI community
89 lines
2.8 KiB
Python
89 lines
2.8 KiB
Python
import asyncio
|
|
import threading
|
|
import queue
|
|
import time
|
|
import logging
|
|
from concurrent.futures import ThreadPoolExecutor
|
|
from typing import Any, Callable, Coroutine
|
|
|
|
class ComfyUIAsyncHandler:
|
|
"""Handles async operations in ComfyUI's synchronous execution context"""
|
|
|
|
def __init__(self, max_workers: int = 4):
|
|
self.executor = ThreadPoolExecutor(max_workers=max_workers)
|
|
self.active_tasks = {}
|
|
self.logger = logging.getLogger(__name__)
|
|
|
|
def run_async_in_thread(self, coro: Coroutine) -> Any:
|
|
"""Run async coroutine in separate thread with event loop"""
|
|
|
|
def run_in_thread():
|
|
loop = asyncio.new_event_loop()
|
|
asyncio.set_event_loop(loop)
|
|
try:
|
|
return loop.run_until_complete(coro)
|
|
finally:
|
|
loop.close()
|
|
|
|
future = self.executor.submit(run_in_thread)
|
|
return future.result()
|
|
|
|
def run_with_progress(self, coro: Coroutine, progress_callback: Callable = None) -> Any:
|
|
"""Run async operation with progress tracking"""
|
|
|
|
progress_queue = queue.Queue()
|
|
result_queue = queue.Queue()
|
|
|
|
def async_wrapper():
|
|
loop = asyncio.new_event_loop()
|
|
asyncio.set_event_loop(loop)
|
|
|
|
async def tracked_operation():
|
|
task = asyncio.create_task(coro)
|
|
|
|
# Monitor progress
|
|
start_time = time.time()
|
|
while not task.done():
|
|
if progress_callback:
|
|
elapsed = time.time() - start_time
|
|
progress_queue.put(f"Processing... {elapsed:.1f}s")
|
|
await asyncio.sleep(0.5)
|
|
|
|
return await task
|
|
|
|
try:
|
|
result = loop.run_until_complete(tracked_operation())
|
|
result_queue.put(("success", result))
|
|
except Exception as e:
|
|
self.logger.error(f"Async operation failed: {e}")
|
|
result_queue.put(("error", e))
|
|
finally:
|
|
loop.close()
|
|
|
|
# Start async operation in thread
|
|
thread = threading.Thread(target=async_wrapper)
|
|
thread.start()
|
|
|
|
# Handle progress updates
|
|
while thread.is_alive():
|
|
try:
|
|
progress = progress_queue.get_nowait()
|
|
if progress_callback:
|
|
progress_callback(progress)
|
|
except queue.Empty:
|
|
time.sleep(0.1)
|
|
|
|
thread.join()
|
|
|
|
# Get result
|
|
status, result = result_queue.get()
|
|
if status == "error":
|
|
raise result
|
|
return result
|
|
|
|
def shutdown(self):
|
|
"""Shutdown the executor"""
|
|
self.executor.shutdown(wait=True)
|
|
|
|
# Global async handler instance
|
|
async_handler = ComfyUIAsyncHandler() |