Validate if resources are available to run a job with the specified plugin. This function is dependency-injected with helper functions to avoid tight coupling with specific plugin registry implementations.
PID of the worker that will run the job (if known)
worker_type
str
transcription
Type of worker (e.g., “transcription”, “llm”, “ollama”)
verbose
bool
False
Whether to print verbose logging
Returns
ValidationResult
ValidationResult with action to take
The validation function uses dependency injection to avoid tight coupling. You provide helper functions that know how to work with your specific plugin registry implementation.
Error Handling Integration
When the cjm-error-handling library is installed, you can convert ValidationResult objects into structured exceptions. This is useful when you want to raise errors instead of returning result objects.
Convert a ValidationResult into a structured error. Requires cjm-error-handling library.
Type
Default
Details
result
ValidationResult
Validation result to convert
plugin_id
Optional
None
Plugin ID for error context
job_id
Optional
None
Job ID for error context
worker_pid
Optional
None
Worker PID for error context
extra_context
VAR_KEYWORD
Returns
Optional
Structured error based on validation action, or None if no error needed
Example: Converting ValidationResult to Errors
This shows how to use the error handling integration:
# Example 1: ABORT case (plugin not found)if _has_error_handling: abort_result = ValidationResult( action=ValidationAction.ABORT, can_proceed=False, message="Plugin transcription_whisper_huge not found." ) error = validation_result_to_error( abort_result, plugin_id="transcription_whisper_huge", job_id="job-123" )print("Example 1: ABORT -> ValidationError")print(f" Error type: {type(error).__name__}")print(f" Message: {error.get_user_message()}")print(f" Retryable: {error.is_retryable}")print(f" Severity: {error.severity.value}")print(f" Context: plugin_id={error.context.plugin_id}, job_id={error.context.job_id}")else:print("cjm-error-handling not installed - skipping example")
Example 1: ABORT -> ValidationError
Error type: ValidationError
Message: Plugin transcription_whisper_huge not found.
Retryable: False
Severity: error
Context: plugin_id=transcription_whisper_huge, job_id=job-123
# Example 2: WAIT_FOR_JOB case (GPU busy with same worker type)if _has_error_handling:# Simulate a worker statefrom cjm_fasthtml_resources.core.manager import WorkerState busy_worker = WorkerState( pid=54321, worker_type="transcription", job_id="job-current", plugin_id="whisper_large", plugin_name="whisper_large", loaded_plugin_resource="openai/whisper-large-v3", config={"model_id": "openai/whisper-large-v3"}, status="running" ) wait_result = ValidationResult( action=ValidationAction.WAIT_FOR_JOB, can_proceed=False, message="GPU in use by running job (PID 54321). Wait for completion or cancel job.", current_worker=busy_worker ) error = validation_result_to_error( wait_result, plugin_id="whisper_base", job_id="job-456" )print("\nExample 2: WAIT_FOR_JOB -> ResourceError")print(f" Error type: {type(error).__name__}")print(f" Message: {error.get_user_message()}")print(f" Retryable: {error.is_retryable}")print(f" Resource type: {error.resource_type}")print(f" Suggested action: {error.suggested_action}")print(f" Context worker PID: {error.context.worker_pid}")else:print("cjm-error-handling not installed - skipping example")
Example 2: WAIT_FOR_JOB -> ResourceError
Error type: ResourceError
Message: GPU in use by running job (PID 54321). Wait for completion or cancel job.
Retryable: True
Resource type: GPU
Suggested action: Wait for current job to complete or cancel it
Context worker PID: 54321
# Example 3: Practical usage pattern - raise error if validation failsif _has_error_handling:print("\nExample 3: Practical Usage Pattern")print("="*60)def start_job_with_validation(plugin_id, job_id, validation_result):"""Example function showing how to use validation + errors together."""# Check if we can proceedifnot validation_result.can_proceed:# Convert to error and raise error = validation_result_to_error( validation_result, plugin_id=plugin_id, job_id=job_id )raise error# Validation passed, proceed with jobreturnf"Job {job_id} started successfully with {plugin_id}"# Test with ABORT casetry: result = ValidationResult( action=ValidationAction.ABORT, can_proceed=False, message="Plugin not found" ) start_job_with_validation("whisper_huge", "job-789", result)except ValidationError as e:print(f"Caught ValidationError: {e.get_user_message()}")print(f" Action: Don't retry, fix the plugin ID")# Test with WAIT_FOR_JOB case (retryable)try: result = ValidationResult( action=ValidationAction.WAIT_FOR_JOB, can_proceed=False, message="GPU busy" ) start_job_with_validation("whisper_base", "job-999", result)except ResourceError as e:print(f"\nCaught ResourceError: {e.get_user_message()}")print(f" Retryable: {e.is_retryable}")print(f" Action: Retry after GPU becomes available")print("\n"+"="*60)else:print("cjm-error-handling not installed - skipping example")
Example 3: Practical Usage Pattern
============================================================
Caught ValidationError: Plugin not found
Action: Don't retry, fix the plugin ID
Caught ResourceError: GPU busy
Retryable: True
Action: Retry after GPU becomes available
============================================================