# How `query_coco_fusion` Integrates Multiple Backend Services: The Complete Pattern

> Discover the query_coco_fusion integration pattern. Learn how it unifies backend services using a trait-based registry for parallel queries, timeout isolation, and fair result merging.

- Repository: [INFINI Labs/coco-app](https://github.com/infinilabs/coco-app)
- Tags: how-to-guide
- Published: 2026-03-04

---

**`query_coco_fusion` unifies searches across heterogeneous backend services through a trait-based registry pattern that executes queries in parallel with timeout isolation and merges results using fair distribution algorithms.**

The `query_coco_fusion` command serves as the central orchestration point in the infinilabs/coco-app repository, enabling a Rust-based desktop application to aggregate search results from remote HTTP APIs, local filesystems, and OS-level services through a single interface. This integration pattern relies on a **plugin architecture** that allows new backends to register at runtime without modifying core query logic, providing resilience against service failures while ensuring equitable result distribution.

## The `SearchSource` Trait Registration Pattern

Every searchable backend in Coco implements the **`SearchSource`** trait defined in [`src-tauri/src/common/traits.rs`](https://github.com/infinilabs/coco-app/blob/main/src-tauri/src/common/traits.rs). This contract standardizes how the system interacts with diverse data sources, requiring implementers to provide a `get_type` method identifying the source and a `search` method handling the actual query execution.

Registration occurs through the **`SearchSourceRegistry`** in [`src-tauri/src/common/register.rs`](https://github.com/infinilabs/coco-app/blob/main/src-tauri/src/common/register.rs), which maintains a runtime collection of available sources. During application initialization, concrete implementations—such as `CocoSearchSource` for remote servers or filesystem-based extensions—register themselves with the global registry, making them immediately available to the fusion engine without recompilation.

## Entry Point and Dispatch Logic

The frontend initiates searches through `platformAdapter.commands("query_coco_fusion", payload)`, handled by the Rust command in [`src-tauri/src/search/mod.rs`](https://github.com/infinilabs/coco-app/blob/main/src-tauri/src/search/mod.rs) (lines 40-84). This entry point receives:
- Pagination controls (`from`, `size`)
- A map of `query_strings` containing search terms
- A `query_timeout` value in milliseconds

### Single vs. Multi-Source Routing

The dispatcher examines the presence of a **`querysource`** parameter to determine execution strategy:
- **Single-source mode**: Routes to `query_coco_fusion_single_query_source` when querying one specific backend by ID
- **Multi-source mode**: Invokes `query_coco_fusion_multi_query_sources` to query all registered sources simultaneously

This branching allows the same command interface to serve both targeted queries and broad aggregation use cases.

## Parallel Execution with Timeout Isolation

In multi-source mode, the system executes searches concurrently using **`FuturesUnordered`** collections wrapped with **`tokio::time::timeout`** (lines 20-38 in [`src-tauri/src/search/mod.rs`](https://github.com/infinilabs/coco-app/blob/main/src-tauri/src/search/mod.rs)). Each registered `SearchSource` spawns as an async future, allowing true parallel execution rather than sequential polling.

If a backend exceeds its timeout threshold, the system logs a warning and invokes `query_coco_fusion_handle_failed_request` to record the failure in the response's `failed` array without aborting the entire request. This pattern ensures that slow or unresponsive services cannot block results from healthy backends.

## Concrete Backend Implementation Examples

### Coco Server HTTP Source

The primary remote backend, implemented in [`src-tauri/src/server/search.rs`](https://github.com/infinilabs/coco-app/blob/main/src-tauri/src/server/search.rs), demonstrates HTTP integration. `CocoSearchSource` constructs POST requests to the `/_search` endpoint, converting query parameters into URL-encoded strings:

```rust
let url = "/query/_search";
let mut query_params = vec![
    format!("from={}", query.from),
    format!("size={}", query.size),
];
for (k, v) in query.query_strings {
    if let Some(p) = convert_query_string(&k, &v) {
        query_params.push(p);
    }
}
let response = HttpClient::post(&self.server.id, url, Some(query_params), Some(body))
    .await
    .context(HttpSnafu)?;

```

### Extension and Local Sources

Additional backends in `src-tauri/src/extension/**` handle window management queries, filesystem search, calculator functions, and third-party extensions. Each implements the `search` method using its specific data retrieval mechanism while returning standardized `QueryResponse` objects containing `hits`, `total_hits`, and optional `aggregations`.

## Result Aggregation and Fair Distribution

The fusion algorithm prevents single-source dominance through a **two-phase distribution strategy** in [`src-tauri/src/search/mod.rs`](https://github.com/infinilabs/coco-app/blob/main/src-tauri/src/search/mod.rs) (lines 29-45):

1. **Minimum allocation**: First collects `max_hits_per_source` hits from each contributing backend
2. **Merit-based remainder**: Fills remaining slots with highest-scoring hits from the pruned results across all sources

After collection, **`re_score_hits`** normalizes relevance scores across different ranking systems, ensuring the final `MultiSourceQueryResponse` presents coherent ordering despite originating from heterogeneous sources. The system merges facet aggregations via `merge_aggregations` (lines 57-61).

## Frontend Integration Pattern

Consumer code interacts with this architecture through a consistent command interface:

```typescript
// src/hooks/useSearch.ts
const response = await platformAdapter.commands("query_coco_fusion", {
  from: 0,
  size: 20,
  query_strings: { 
    query: searchText,
    // Optional: querysource: "coco-servers" to target specific backend
  },
  query_timeout: 3000,
});

```

The function returns a `MultiSourceQueryResponse` containing the merged `hits` array, a `failed` array listing any sources that errored or timed out, `total_hits`, and optional aggregation data.

## Implementing a Custom Backend

Developers extend the system by implementing the `SearchSource` trait and registering during app initialization:

```rust
use crate::common::traits::SearchSource;
use crate::common::search::{SearchQuery, QueryResponse};

pub struct MyCustomSearchSource;

#[async_trait::async_trait]
impl SearchSource for MyCustomSearchSource {
    fn get_type(&self) -> QuerySource {
        QuerySource {
            r#type: "my-custom".into(),
            name: "My Custom Service".into(),
            id: "my_custom".into(),
        }
    }

    async fn search(
        &self,
        _app: AppHandle,
        query: SearchQuery,
    ) -> Result<QueryResponse, SearchError> {
        // Backend-specific query logic here
        Ok(QueryResponse {
            hits: vec![],
            total_hits: 0,
            // ... other fields
        })
    }
}

```

Registration code:

```rust
let registry = app_handle.state::<SearchSourceRegistry>();
registry.register_source(MyCustomSearchSource::new()).await;

```

## Summary

- **`query_coco_fusion`** in [`src-tauri/src/search/mod.rs`](https://github.com/infinilabs/coco-app/blob/main/src-tauri/src/search/mod.rs) serves as the unified entry point for all search operations, handling both single-source and multi-source queries
- The **`SearchSource`** trait and **`SearchSourceRegistry`** enable runtime extensibility without requiring modifications to core fusion logic
- **Parallel execution** via `FuturesUnordered` with `tokio::time::timeout` ensures resilience against slow or failing backends while collecting partial results
- **Fair distribution algorithms** prevent result flooding from any single source, and `re_score_hits` provides unified ranking across heterogeneous backends
- The pattern exposes a consistent API to frontend consumers while abstracting the complexity of coordinating multiple disparate data sources

## Frequently Asked Questions

### How does `query_coco_fusion` handle timeouts from slow backend services?

The system wraps each backend query in a `tokio::time::timeout` future according to the `query_timeout` parameter. When a source exceeds this limit, the error is caught and passed to `query_coco_fusion_handle_failed_request`, which records the failure in the response's `failed` array while allowing other sources to complete normally. This ensures that a single slow backend cannot block the entire search operation.

### Can I query only specific backend services instead of all registered sources?

Yes. By including a `querysource` field in the query payload, the command routes to `query_coco_fusion_single_query_source` rather than the multi-source variant. This targets a specific backend by its registered ID, bypassing the parallel execution and aggregation logic to return results from only that source.

### What prevents one backend from dominating the search results?

The `query_coco_fusion_multi_query_sources` function implements an **even hit distribution** algorithm that first allocates a minimum slice (`max_hits_per_source`) from every responding backend before filling remaining slots with the highest-scoring documents from the pooled results. This guarantees that every functional source contributes at least some results, preventing scenarios where a high-volume backend overwhelms narrower, more specific sources.

### How do I add a new backend service to the Coco app?

Create a struct implementing the `SearchSource` trait from [`src-tauri/src/common/traits.rs`](https://github.com/infinilabs/coco-app/blob/main/src-tauri/src/common/traits.rs), defining the `get_type` metadata and `search` execution logic. Register the implementation during app initialization using `SearchSourceRegistry` from [`src-tauri/src/common/register.rs`](https://github.com/infinilabs/coco-app/blob/main/src-tauri/src/common/register.rs). Once registered, `query_coco_fusion` automatically includes your backend in multi-source queries without additional configuration.