|
21 | 21 | from ..models import EvaluateResult, EvaluationRow |
22 | 22 |
|
23 | 23 |
|
| 24 | +def _execute_function(func: Callable, **kwargs) -> Any: |
| 25 | + """ |
| 26 | + Execute a function with proper async handling. |
| 27 | +
|
| 28 | + This is a pure function that handles both async and non-async function execution |
| 29 | + with proper event loop management for async functions. |
| 30 | +
|
| 31 | + Args: |
| 32 | + func: The function to execute |
| 33 | + **kwargs: Arguments to pass to the function |
| 34 | +
|
| 35 | + Returns: |
| 36 | + The result of the function execution |
| 37 | + """ |
| 38 | + is_async = asyncio.iscoroutinefunction(func) |
| 39 | + if is_async: |
| 40 | + # Handle async functions with proper event loop management |
| 41 | + try: |
| 42 | + loop = asyncio.get_event_loop() |
| 43 | + if not loop.is_closed(): |
| 44 | + # Use existing loop |
| 45 | + task = loop.create_task(func(**kwargs)) |
| 46 | + results = loop.run_until_complete(task) |
| 47 | + else: |
| 48 | + # Loop is closed, create a new one |
| 49 | + results = asyncio.run(func(**kwargs)) |
| 50 | + except RuntimeError: |
| 51 | + # No event loop or other issues, create a new one |
| 52 | + results = asyncio.run(func(**kwargs)) |
| 53 | + else: |
| 54 | + results = func(**kwargs) |
| 55 | + return results |
| 56 | + |
| 57 | + |
24 | 58 | def evaluate( |
25 | 59 | rows: List[EvaluationRow], reward_fn: Callable[..., EvaluateResult], **kwargs: Any |
26 | 60 | ) -> List[EvaluationRow]: |
@@ -200,23 +234,7 @@ def execute_with_params( |
200 | 234 | kwargs["model"] = model |
201 | 235 | if row is not None: |
202 | 236 | kwargs["row"] = row |
203 | | - if is_async: |
204 | | - # Handle async functions with proper event loop management |
205 | | - try: |
206 | | - loop = asyncio.get_event_loop() |
207 | | - if not loop.is_closed(): |
208 | | - # Use existing loop |
209 | | - task = loop.create_task(test_func(**kwargs)) |
210 | | - results = loop.run_until_complete(task) |
211 | | - else: |
212 | | - # Loop is closed, create a new one |
213 | | - results = asyncio.run(test_func(**kwargs)) |
214 | | - except RuntimeError: |
215 | | - # No event loop or other issues, create a new one |
216 | | - results = asyncio.run(test_func(**kwargs)) |
217 | | - else: |
218 | | - results = test_func(**kwargs) |
219 | | - return results |
| 237 | + return _execute_function(test_func, **kwargs) |
220 | 238 |
|
221 | 239 | # Calculate all possible combinations of parameters |
222 | 240 | def generate_combinations(): |
@@ -291,21 +309,7 @@ def wrapper_body(**kwargs): |
291 | 309 | initial_messages=kwargs.get("input_messages") if "input_messages" in kwargs else [], |
292 | 310 | ) |
293 | 311 | for row in data: |
294 | | - is_async = inspect.iscoroutinefunction(rollout_processor) |
295 | | - if is_async: |
296 | | - try: |
297 | | - loop = asyncio.get_event_loop() |
298 | | - if not loop.is_closed(): |
299 | | - # Use existing loop |
300 | | - task = loop.create_task(rollout_processor(row, config=config)) |
301 | | - processed: List[EvaluationRow] = loop.run_until_complete(task) |
302 | | - else: |
303 | | - processed: List[EvaluationRow] = asyncio.run(rollout_processor(row, config=config)) |
304 | | - except RuntimeError: |
305 | | - # No event loop or other issues, create a new one |
306 | | - processed: List[EvaluationRow] = asyncio.run(rollout_processor(row, config=config)) |
307 | | - else: |
308 | | - processed: List[EvaluationRow] = rollout_processor(row, config=config) |
| 312 | + processed: List[EvaluationRow] = _execute_function(rollout_processor, row=row, config=config) |
309 | 313 | input_dataset.extend(processed) |
310 | 314 |
|
311 | 315 | all_results: List[EvaluationRow] = [] |
|
0 commit comments