Tutorial: Implementing Asynchronous Document Conversion

Learning Objectives

In this tutorial, you’ll learn how to:

  • Implement asynchronous document conversion for handling large files
  • Start conversion jobs that run in the background
  • Monitor conversion status and handle notifications
  • Retrieve conversion results when processing is complete
  • Structure your code for efficient asynchronous operations
  • Handle timeouts and errors in asynchronous processing

Prerequisites

Before starting this tutorial, you should have:

  • A GroupDocs.Conversion Cloud account (if you don’t have one, register for a free trial)
  • Your Client ID and Client Secret credentials
  • Basic understanding of REST API concepts and asynchronous programming
  • Familiarity with your preferred programming language (C#, Java, Python, PHP, Ruby, or Node.js)
  • Large documents to test async conversion (the benefits are more noticeable with larger files)

Why Use Asynchronous Conversion?

Synchronous (direct) document conversion works well for smaller files, but has several limitations when working with larger documents:

  • Timeout issues: API calls may time out if the conversion takes too long
  • Connection problems: Extended connections are more vulnerable to network disruptions
  • Resource blocking: Your application can become unresponsive while waiting for conversion to complete
  • User experience: Users must wait for the entire process to finish before continuing

Asynchronous conversion solves these problems by:

  • Starting the conversion process and immediately returning a job ID
  • Allowing your application to continue other operations
  • Providing a way to check conversion status
  • Enabling retrieval of results when the conversion is complete

Implementation Steps

Step 1: Set Up Your Development Environment

First, ensure you have the GroupDocs.Conversion Cloud SDK installed for your language: For .NET:

Install-Package GroupDocs.Conversion-Cloud

For Java:

<dependency>
    <groupId>com.groupdocs</groupId>
    <artifactId>groupdocs-conversion-cloud</artifactId>
    <version>latest-version</version>
</dependency>

For Python:

pip install groupdocs-conversion-cloud

Step 2: Authenticate with the API

To use GroupDocs.Conversion Cloud API, you need to authenticate using your Client ID and Client Secret:

// Initialize the API with your credentials
string MyClientId = "XXXX-XXXX-XXXX-XXXX"; // Your Client ID
string MyClientSecret = "XXXXXXXXXXXXXXXX"; // Your Client Secret
var configuration = new Configuration(MyClientId, MyClientSecret);

// Create API instance for async operations
var asyncApi = new AsyncApi(configuration);

Step 3: Start an Asynchronous Conversion Job

Now, let’s initiate an asynchronous conversion process:

// Prepare convert settings
var settings = new ConvertSettings
{
    FilePath = "WordProcessing/large-document.docx",
    Format = "pdf",
    OutputPath = "converted/async-result.pdf"
};

// Start the conversion process asynchronously
var operationId = asyncApi.StartConvertAndSave(new StartConvertAndSaveRequest(settings));

Console.WriteLine("Operation started. ID: " + operationId);

This call initiates the conversion but doesn’t wait for it to complete. Instead, it returns an operation ID that you can use to check the status later.

Step 4: Check Conversion Status

After starting the conversion, you need to periodically check its status:

// Check operation status
bool isCompleted = false;
while (!isCompleted)
{
    // Wait a bit before checking (don't poll too frequently)
    Thread.Sleep(1000); // 1 second

    // Get current status
    var statusRequest = new GetOperationStatusRequest(operationId);
    var statusResult = asyncApi.GetOperationStatus(statusRequest);

    Console.WriteLine("Current status: " + statusResult.Status);

    // Check if the operation has completed (either successfully or with an error)
    if (statusResult.Status == OperationResult.StatusEnum.Finished)
    {
        Console.WriteLine("Conversion completed successfully!");
        isCompleted = true;
    }
    else if (statusResult.Status == OperationResult.StatusEnum.Failed)
    {
        Console.WriteLine("Conversion failed: " + statusResult.Error);
        isCompleted = true;
    }
    // Otherwise, the status is 'Processing', and we continue waiting
}

Step 5: Retrieve Conversion Results

Once the conversion is complete, you can retrieve the results:

// Get operation results
if (statusResult.Status == OperationResult.StatusEnum.Finished)
{
    // Results are available in statusResult.Result
    foreach (var file in statusResult.Result)
    {
        Console.WriteLine("Converted file: " + file.Name);
        Console.WriteLine("File URL: " + file.Url);
    }
}

Complete Code Examples

Using C#

using System;
using System.Threading;
using GroupDocs.Conversion.Cloud.Sdk.Api;
using GroupDocs.Conversion.Cloud.Sdk.Client;
using GroupDocs.Conversion.Cloud.Sdk.Model;
using GroupDocs.Conversion.Cloud.Sdk.Model.Requests;

namespace GroupDocs.Conversion.Cloud.Examples
{
    class AsyncConversionExample
    {
        public static void Run()
        {
            // Get your credentials from https://dashboard.groupdocs.cloud/applications
            string MyClientId = "XXXX-XXXX-XXXX-XXXX"; // Your Client ID
            string MyClientSecret = "XXXXXXXXXXXXXXXX"; // Your Client Secret
            
            var configuration = new Configuration(MyClientId, MyClientSecret);
            
            // Create API instance for async operations
            var asyncApi = new AsyncApi(configuration);
            
            try
            {
                // Prepare convert settings
                var settings = new ConvertSettings
                {
                    FilePath = "WordProcessing/large-document.docx",
                    Format = "pdf",
                    OutputPath = "converted/async-result.pdf"
                };
                
                // Start the conversion process asynchronously
                var operationId = asyncApi.StartConvertAndSave(new StartConvertAndSaveRequest(settings));
                
                Console.WriteLine("Operation started. ID: " + operationId);
                
                // Check operation status
                bool isCompleted = false;
                OperationResult statusResult = null;
                
                while (!isCompleted)
                {
                    // Wait a bit before checking (don't poll too frequently)
                    Thread.Sleep(1000); // 1 second
                    
                    // Get current status
                    var statusRequest = new GetOperationStatusRequest(operationId);
                    statusResult = asyncApi.GetOperationStatus(statusRequest);
                    
                    Console.WriteLine("Current status: " + statusResult.Status);
                    
                    // Check if the operation has completed (either successfully or with an error)
                    if (statusResult.Status == OperationResult.StatusEnum.Finished)
                    {
                        Console.WriteLine("Conversion completed successfully!");
                        isCompleted = true;
                    }
                    else if (statusResult.Status == OperationResult.StatusEnum.Failed)
                    {
                        Console.WriteLine("Conversion failed: " + statusResult.Error);
                        isCompleted = true;
                    }
                    // Otherwise, the status is 'Processing', and we continue waiting
                }
                
                // Get operation results
                if (statusResult.Status == OperationResult.StatusEnum.Finished)
                {
                    // Results are available in statusResult.Result
                    foreach (var file in statusResult.Result)
                    {
                        Console.WriteLine("Converted file: " + file.Name);
                        Console.WriteLine("File URL: " + file.Url);
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("Exception during async operation: " + e.Message);
            }
        }
    }
}

Using Python

# Import required modules
import groupdocs_conversion_cloud
import time
import os

# Get your credentials from https://dashboard.groupdocs.cloud/applications
client_id = "XXXX-XXXX-XXXX-XXXX"  # Your Client ID
client_secret = "XXXXXXXXXXXXXXXX"  # Your Client Secret

# Create instance of the API for async operations
async_api = groupdocs_conversion_cloud.AsyncApi.from_keys(client_id, client_secret)

try:
    # Prepare convert settings
    settings = groupdocs_conversion_cloud.ConvertSettings()
    settings.file_path = "WordProcessing/large-document.docx"
    settings.format = "pdf"
    settings.output_path = "converted/async-result.pdf"
    
    # Start the conversion process asynchronously
    operation_id = async_api.start_convert_and_save(groupdocs_conversion_cloud.StartConvertAndSaveRequest(settings))
    
    print(f"Operation started. ID: {operation_id}")
    
    # Check operation status
    is_completed = False
    status_result = None
    
    while not is_completed:
        # Wait a bit before checking (don't poll too frequently)
        time.sleep(1)  # 1 second
        
        # Get current status
        status_request = groupdocs_conversion_cloud.GetOperationStatusRequest(operation_id)
        status_result = async_api.get_operation_status(status_request)
        
        print(f"Current status: {status_result.status}")
        
        # Check if the operation has completed (either successfully or with an error)
        if status_result.status == "Finished":
            print("Conversion completed successfully!")
            is_completed = True
        elif status_result.status == "Failed":
            print(f"Conversion failed: {status_result.error}")
            is_completed = True
        # Otherwise, the status is 'Processing', and we continue waiting
    
    # Get operation results
    if status_result.status == "Finished":
        # Results are available in status_result.result
        for file in status_result.result:
            print(f"Converted file: {file.name}")
            print(f"File URL: {file.url}")

except groupdocs_conversion_cloud.ApiException as e:
    print(f"Exception during async operation: {e}")

Using Java

// Import required packages
import com.groupdocs.cloud.conversion.api.*;
import com.groupdocs.cloud.conversion.api.AsyncApi;
import com.groupdocs.cloud.conversion.client.ApiException;
import com.groupdocs.cloud.conversion.model.*;
import com.groupdocs.cloud.conversion.model.requests.*;
import java.util.List;

public class AsyncConversionExample {
    public static void main(String[] args) {
        // Get your credentials from https://dashboard.groupdocs.cloud/applications
        String clientId = "XXXX-XXXX-XXXX-XXXX"; // Your Client ID
        String clientSecret = "XXXXXXXXXXXXXXXX"; // Your Client Secret
        
        Configuration configuration = new Configuration(clientId, clientSecret);
        
        // Create API instance for async operations
        AsyncApi asyncApi = new AsyncApi(configuration);
        
        try {
            // Prepare convert settings
            ConvertSettings settings = new ConvertSettings();
            settings.setFilePath("WordProcessing/large-document.docx");
            settings.setFormat("pdf");
            settings.setOutputPath("converted/async-result.pdf");
            
            // Start the conversion process asynchronously
            String operationId = asyncApi.startConvertAndSave(new StartConvertAndSaveRequest(settings));
            
            System.out.println("Operation started. ID: " + operationId);
            
            // Check operation status
            boolean isCompleted = false;
            OperationResult statusResult = null;
            
            while (!isCompleted) {
                // Wait a bit before checking (don't poll too frequently)
                Thread.sleep(1000); // 1 second
                
                // Get current status
                GetOperationStatusRequest statusRequest = new GetOperationStatusRequest(operationId);
                statusResult = asyncApi.getOperationStatus(statusRequest);
                
                System.out.println("Current status: " + statusResult.getStatus());
                
                // Check if the operation has completed (either successfully or with an error)
                if (statusResult.getStatus() == OperationResult.StatusEnum.FINISHED) {
                    System.out.println("Conversion completed successfully!");
                    isCompleted = true;
                }
                else if (statusResult.getStatus() == OperationResult.StatusEnum.FAILED) {
                    System.out.println("Conversion failed: " + statusResult.getError());
                    isCompleted = true;
                }
                // Otherwise, the status is 'Processing', and we continue waiting
            }
            
            // Get operation results
            if (statusResult.getStatus() == OperationResult.StatusEnum.FINISHED) {
                // Results are available in statusResult.getResult()
                List<StoredConvertedResult> results = statusResult.getResult();
                for (StoredConvertedResult file : results) {
                    System.out.println("Converted file: " + file.getName());
                    System.out.println("File URL: " + file.getUrl());
                }
            }
        } catch (Exception e) {
            System.err.println("Exception during async operation: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

Using cURL

# First get JSON Web Token
curl -v "https://api.groupdocs.cloud/connect/token" \
-X POST \
-d "grant_type=client_credentials&client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET" \
-H "Content-Type: application/x-www-form-urlencoded" \
-H "Accept: application/json"

# Get token from JSON response
# Now start async conversion
curl -v "https://api.groupdocs.cloud/v2.0/conversion/async" \
-X POST \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-d "{
    'FilePath': 'WordProcessing/large-document.docx',
    'Format': 'pdf',
    'OutputPath': 'converted/async-result.pdf'
}"

# You'll receive an operation ID in the response
# Now check operation status
curl -v "https://api.groupdocs.cloud/v2.0/conversion/async/YOUR_OPERATION_ID/status" \
-X GET \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"

# When status is "Finished", you can access your converted document at the OutputPath

Best Practices for Asynchronous Conversion

1. Implement Exponential Backoff

Instead of checking status at fixed intervals, use exponential backoff to reduce API calls:

int retryCount = 0;
int maxRetries = 10;
int delay = 1000; // Start with 1 second

while (retryCount < maxRetries && !isCompleted)
{
    // Wait with increasing delay
    Thread.Sleep(delay);
    delay *= 2; // Double the delay each time
    
    // Get current status and check as before...
    
    retryCount++;
}

2. Implement Webhook Callbacks

For production applications, consider implementing webhook notifications instead of polling:

// In your conversion request, include a webhook URL
var settings = new ConvertSettings
{
    FilePath = "WordProcessing/large-document.docx",
    Format = "pdf",
    OutputPath = "converted/async-result.pdf",
    // Note: Webhook functionality would need to be implemented on the server side
};

3. Set Reasonable Timeouts

Always implement a maximum wait time for your asynchronous operations:

// Set a maximum wait time (e.g., 5 minutes)
DateTime startTime = DateTime.Now;
TimeSpan maxWaitTime = TimeSpan.FromMinutes(5);

while (!isCompleted)
{
    // Check if we've exceeded the maximum wait time
    if (DateTime.Now - startTime > maxWaitTime)
    {
        Console.WriteLine("Timeout: Conversion is taking too long");
        break;
    }
    
    // Check status as before...
}

Troubleshooting Tips

Operation Not Found

Issue: The API returns “Operation not found” when checking status.Solution: Verify that you’re using the correct operation ID and that it hasn’t expired. Operation IDs are typically valid for 24 hours.

Long-Running Conversions

Issue: Very large documents take a long time to convert.Solution:

  • Ensure your polling mechanism has appropriate timeouts
  • Consider breaking large documents into smaller chunks if possible
  • For extremely large files, use optimized conversion settings

Error Handling

Issue: How to handle conversion failures gracefully.Solution: Implement comprehensive error handling:

if (statusResult.Status == OperationResult.StatusEnum.Failed)
{
    // Log detailed error information
    Console.WriteLine("Conversion failed with error: " + statusResult.Error);
    
    // Implement retry logic if appropriate
    if (statusResult.Error.Contains("temporary"))
    {
        // Maybe retry the conversion
    }
    
    // Notify appropriate channels
    // NotifyAdministrator(statusResult.Error);
}

Try It Yourself

Now that you’ve learned about asynchronous conversion, try these exercises:

  1. Implement async conversion for a large document with progress reporting
  2. Add a timeout mechanism with appropriate error handling
  3. Compare performance between synchronous and asynchronous conversion
  4. Implement a simple webhook receiver to handle conversion notifications

What You’ve Learned

In this tutorial, you’ve learned how to:

  • Implement asynchronous document conversion for handling large files
  • Start conversion jobs that run in the background
  • Monitor conversion status efficiently
  • Retrieve conversion results when processing is complete
  • Structure your code for robust asynchronous operations
  • Handle timeouts and errors in asynchronous processing

Helpful Resources

If you have questions about this tutorial, please feel free to post them in our support forum.