Skip to main content

Background Commands

Hosanna implements a robust system for handling background commands and asynchronous operations through its AsyncCommand framework. This documentation explains how background commands work and how to use them effectively in your application.

Live Example

Try It

Dispatch a background command and watch the UI handle progress and completion.

Core Components

1. AsyncCommand

The AsyncCommand class is the fundamental building block for background operations in Hosanna. It provides:

  • Unique command identification
  • Lifecycle management (dispatch, cancel, pause, resume)
  • Progress tracking
  • State management
  • Promise-based execution

2. Command Structure

Each background command consists of:

  • ID: A unique identifier for tracking

  • Scope: The command's operational context

  • Handler: The specific operation handler

  • Arguments: Optional parameters for the command

  • State: Current execution state

  • Progress: Completion progress (0.0 to 1.0)

    Using Background Commands

1. Creating a Command Handler

@commandCategory('DataLoader')
class LoadDataHandler {
@command('LoadJsonData')
loadJsonData(payload: any): HsPromise<any> {
// Implement async operation
}
}

2. Dispatching Commands

You can dispatch background commands from views using:

this.dispatchAsync('DataLoader', 'LoadJsonData', { url: '/data.json' })
.then((result) => {
// Handle success
})
.catch((error) => {
// Handle error
});

Passing function pointers across tasks

Sometimes you need to pass a function to be executed in a background task. Use AsyncFunctionPointer (module + export name) to reference the function safely across node/task boundaries.

import { processRows } from './transformFunctions';

this.dispatch<IHsFetchResponse>(Http.Get, {
url: 'https://api.example.com/data',
transformFunction: processRows
});

Signature:

// hosanna-api
type AsyncFunctionPointer = Function;

The runtime can retrieve the function later (e.g., via a helper like getAsyncFunctionFromPointer) and execute it inside a task, avoiding closure capture issues.

Command Lifecycle

Background commands go through several states:

  1. Initializing: Command is being created
  2. Running: Command is actively executing
  3. Paused: Command execution is temporarily suspended
  4. Completed: Command has finished successfully
  5. Failed: Command encountered an error
  6. Cancelled: Command was manually cancelled

Integration with Async Framework

Hosanna's background commands integrate with:

  • AsyncManager: Central controller for async tasks
  • HsPromise: Custom promise implementation
  • TimerService: Manages timing and scheduling
  • PortPromise: Platform-specific promise implementation (e.g., for Roku)

Best Practices

  1. Error Handling

    • Always implement proper error handling in command handlers
    • Use try/catch blocks for potential failures
    • Provide meaningful error messages
  2. Progress Tracking

    • Update progress for long-running operations
    • Use progress callbacks for UI updates
  3. Resource Management

    • Properly clean up resources when commands complete
    • Cancel long-running commands when no longer needed
  4. Platform Considerations

    • Use platform-specific implementations when necessary
    • Consider memory constraints on different devices

Example Implementation

// Define a background command handler
@commandCategory('MediaLoader')
class MediaLoadHandler {
@command('LoadVideo')
async loadVideo(payload: {url: string}): HsPromise<void> {
try {
// Initialize progress
this.progress = 0;

// Perform async operation
const result = await fetch(payload.url);

// Update progress
this.progress = 0.5;

// Process result
const videoData = await result.json();

// Complete operation
this.progress = 1.0;
return videoData;
} catch (error) {
throw new Error(`Failed to load video: ${error.message}`);
}
}
}

// Using the command in a view
class VideoPlayerView extends BaseView {
loadVideo(url: string) {
this.dispatchAsync('MediaLoader', 'LoadVideo', { url })
.then(videoData => this.playVideo(videoData))
.catch(error => this.handleError(error));
}
}

Debugging Background Commands

For debugging background commands, Hosanna provides:

  • Command execution logging
  • State tracking
  • Progress monitoring
  • Error reporting

You can use the Remote Debug Panel to monitor and debug background commands during development.