Repository: qdrant/qdrant
File: lib/collection/src/update_workers/optimization_worker.rs (Rust)

Code before:
        finished_any
    }

    #[allow(clippy::too_many_arguments)]
    pub(crate) async fn process_optimization(
        optimizers: Arc<Vec<Arc<Optimizer>>>,
        segments: LockedSegmentHolder,
        optimization_handles: Arc<TokioMutex<Vec<StoppableTaskHandle<bool>>>>,
        optimizers_log: Arc<Mutex<TrackerLog>>,
        total_optimized_points: Arc<AtomicUsize>,
        optimizer_resource_budget: &ResourceBudget,
        sender: Sender<OptimizerSignal>,
        optimization_finished_sender: watch::Sender<()>,
        limit: usize,
    ) {
        let mut new_handles = Self::launch_optimization(
            optimizers.clone(),
            optimizers_log,
            total_optimized_points,
            optimizer_resource_budget,
            segments.clone(),
            move || {
                // Notify other components that optimization is finished
                // We do not care if there are no receivers or if they are lagging behind
                let _ = optimization_finished_sender.send(());

                // After optimization is finished, we still need to check if there are
                // some further optimizations possible.
                // If receiver is already dead - we do not care.
                // If channel is full - optimization will be triggered by some other signal
                let _ = sender.try_send(OptimizerSignal::Nop);
            },
            Some(limit),
        );
        let mut handles = optimization_handles.lock().await;
        handles.append(&mut new_handles);
    }

    /// Checks conditions for all optimizers until there is no suggested segment
    /// Starts a task for each optimization
    /// Returns handles for started tasks
    pub(crate) fn launch_optimization<F>(
        optimizers: Arc<Vec<Arc<Optimizer>>>,
        optimizers_log: Arc<Mutex<TrackerLog>>,
        total_optimized_points: Arc<AtomicUsize>,
        optimizer_resource_budget: &ResourceBudget,
        segments: LockedSegmentHolder,
        callback: F,
        limit: Option<usize>,
    ) -> Vec<StoppableTaskHandle<bool>>
    where

Review comment (suggestion):
Potential fix for [this](https://github.com/qdrant/qdrant/pull/7643#discussion_r2686375216) using [`send_modify()`](https://docs.rs/tokio/latest/tokio/sync/watch/struct.Sender.html#method.send_modify):

```suggestion
                optimization_finished_sender.send_modify(());
```

Code after:

        finished_any
    }

    #[allow(clippy::too_many_arguments)]
    pub(crate) async fn process_optimization(
        optimizers: Arc<Vec<Arc<Optimizer>>>,
        segments: LockedSegmentHolder,
        optimization_handles: Arc<TokioMutex<Vec<StoppableTaskHandle<bool>>>>,
        optimizers_log: Arc<Mutex<TrackerLog>>,
        total_optimized_points: Arc<AtomicUsize>,
        optimizer_resource_budget: &ResourceBudget,
        sender: Sender<OptimizerSignal>,
        optimization_finished_sender: watch::Sender<()>,
        limit: usize,
    ) {
        let mut new_handles = Self::launch_optimization(
            optimizers.clone(),
            optimizers_log,
            total_optimized_points,
            optimizer_resource_budget,
            segments.clone(),
            move || {
                // Notify other components that optimization is finished
                // We do not care if there are no receivers or if they are lagging behind
                let _ = optimization_finished_sender.send(());

                // After optimization is finished, we still need to check if there are
                // some further optimizations possible.
                // If receiver is already dead - we do not care.
                // If channel is full - optimization will be triggered by some other signal
                let _ = sender.try_send(OptimizerSignal::Nop);
            },
            Some(limit),
        );
        let mut handles = optimization_handles.lock().await;
        handles.append(&mut new_handles);
    }

    /// Checks conditions for all optimizers until there is no suggested segment
    /// Starts a task for each optimization
    /// Returns handles for started tasks
    pub(crate) fn launch_optimization<F>(
        optimizers: Arc<Vec<Arc<Optimizer>>>,
        optimizers_log: Arc<Mutex<TrackerLog>>,
        total_optimized_points: Arc<AtomicUsize>,
        optimizer_resource_budget: &ResourceBudget,
        segments: LockedSegmentHolder,
        callback: F,
        limit: Option<usize>,
    ) -> Vec<StoppableTaskHandle<bool>>