Skip to content

Implement Async Functionality for execute_command Function #25

@csmangum

Description

@csmangum

Implement Async Functionality for execute_command Function

Description:
We need to extend the existing execute_command function to support asynchronous command execution. This will allow the function to handle methods that are coroutines, which can improve performance when working with I/O-bound or time-consuming operations.

Tasks:

  1. Update CommandData class:

    • Ensure that the CommandData class remains compatible with both synchronous and asynchronous functions.
  2. Create execute_command_async function:

    • Create a new function named execute_command_async that will:
      • Check if the provided command is a coroutine using asyncio.iscoroutinefunction.
      • Use await to execute the coroutine if it is asynchronous.
      • Execute the command directly if it is not a coroutine.
    • Ensure that the function logs initial values, final values, and changes in tracked attributes as in the original function.
  3. Modify Logging for Async Support:

    • Update logging logic to ensure proper handling of asynchronous behavior and context.
    • Consider using asyncio.create_task for any background logging or validations, if needed.
  4. Add Tests for Async Functionality:

    • Test 1: Async Command Execution
      • Create a mock object with an asynchronous method (e.g., async def async_method(self):).
      • Verify that execute_command_async properly awaits this method and logs the changes.
      • Ensure that the results reflect the method’s effects on tracked attributes.
    • Test 2: Mixed Sync and Async Command Handling
      • Create a test where both synchronous and asynchronous methods are used.
      • Verify that execute_command_async correctly handles both types without errors.
      • Check that the tracked attributes and logs are accurate for both cases.
    • Test 3: Validation with Async Commands
      • Use an asynchronous validation function (e.g., async def validate_async(self):).
      • Verify that the execute_command_async function handles asynchronous validations correctly.
      • Ensure that any failed validations are logged as warnings.
    • Test 4: Error Handling for Missing Async Command
      • Test the behavior when execute_command_async is provided a non-existent method.
      • Verify that an appropriate error message is logged and returned in the result.
    • Test 5: Attribute Changes Logging
      • Test that the initial and final values of tracked attributes are accurately logged for an async method.
      • Verify that the changes are computed correctly, even when the command involves a delay (e.g., using asyncio.sleep).
    • Test 6: Async Command with Arguments
      • Test execute_command_async with an asynchronous command that takes positional and keyword arguments.
      • Verify that the function correctly passes these arguments to the async command and that the method behaves as expected.
    • Test 7: Handling of Long-Running Async Commands
      • Use a long-running asynchronous command (e.g., async def long_running_task(self): await asyncio.sleep(2)).
      • Verify that execute_command_async properly awaits the method without blocking other tests.
      • Ensure that the final state is consistent with the expected behavior after the long-running task.
  5. Update Documentation:

    • Update the function’s docstring to reflect async capabilities.
    • Add a new section in the README or documentation files to explain how to use execute_command_async and when to use it over the synchronous version.

Acceptance Criteria:

  • The execute_command_async function is implemented and works as expected.
  • The function is thoroughly tested with both synchronous and asynchronous methods.
  • All tracked attributes are correctly logged, and any asynchronous validations are handled properly.
  • The documentation is updated with clear usage examples for the async functionality.

Additional Context:
The new async functionality will be beneficial in scenarios where commands involve I/O-bound operations like network requests or disk writes, allowing other tasks to proceed without blocking. This feature aims to make our command execution system more versatile and performant.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions