Repository: qdrant/qdrant
File: lib/collection/src/shards/local_shard/shard_ops.rs (Rust)

Code before:
            // TODO: Refactor `lock_and_write`, so this is less terrible? :/
            let (operation_id, _wal_lock) = match self.wal.lock_and_write(&mut operation).await {
                Ok(id_and_lock) => id_and_lock,

                Err(shard::wal::WalError::ClockRejected) => {
                    // Propagate clock rejection to operation sender
                    return Ok(UpdateResult {
                        operation_id: None,
                        status: UpdateStatus::ClockRejected,
                        clock_tag: operation.clock_tag,
                    });
                }

                Err(err) => return Err(err.into()),
            };

            // If there are too many pending operations, don't keep operation data in RAM.
            // Instead, read operation data from the WAL when processing the operation.
            let keep_operation_in_ram = pending_operations_count < DEFAULT_UPDATE_QUEUE_RAM_BUFFER;
            let operation = keep_operation_in_ram.then_some(Box::new(operation.operation));

            channel_permit.send(UpdateSignal::Operation(OperationData {
                op_num: operation_id,
                operation,
                sender: callback_sender,
                hw_measurements: hw_measurement_acc.clone(),
            }));

            operation_id
        };

        match (callback_receiver, timeout) {
            // Wait indefinitely
            (Some(receiver), None) => {
                let _ = receiver.await??;
                Ok(UpdateResult {
                    operation_id: Some(operation_id),
                    status: UpdateStatus::Completed,
                    clock_tag: operation.clock_tag,
                })
            }
            // Wait for timeout
            (Some(receiver), Some(timeout)) => {
                match tokio::time::timeout(timeout, receiver).await {
                    Ok(res) => {
                        res??;
                        Ok(UpdateResult {
                            operation_id: Some(operation_id),
                            status: UpdateStatus::Completed,
                            clock_tag: operation.clock_tag,
                        })

Review comment (suggestion):
This struct is at least 152 bytes per operation, even for just a pointer to the WAL.

Just the `hw_measurements` field takes 120 bytes.

With that, we should probably box it too. An alternative would be an enum that satisfies all variants, but I cannot come up with a good one with these three fields.

I think it's worth a little bit of effort.

Code after:
            let channel_permit = update_sender.reserve().await?;

            // It is *critical* to hold `_wal_lock` while sending operation to the update handler!
            //
            // TODO: Refactor `lock_and_write`, so this is less terrible? :/
            let (operation_id, _wal_lock) = match self.wal.lock_and_write(&mut operation).await {
                Ok(id_and_lock) => id_and_lock,

                Err(shard::wal::WalError::ClockRejected) => {
                    // Propagate clock rejection to operation sender
                    return Ok(UpdateResult {
                        operation_id: None,
                        status: UpdateStatus::ClockRejected,
                        clock_tag: operation.clock_tag,
                    });
                }

                Err(err) => return Err(err.into()),
            };

            // If there are too many pending operations, don't keep operation data in RAM.
            // Instead, read operation data from the WAL when processing the operation.
            let keep_operation_in_ram = pending_operations_count < DEFAULT_UPDATE_QUEUE_RAM_BUFFER;
            let operation = keep_operation_in_ram.then_some(Box::new(operation.operation));

            channel_permit.send(UpdateSignal::Operation(OperationData {
                op_num: operation_id,
                operation,
                sender: callback_sender,
                hw_measurements: hw_measurement_acc.clone(),
            }));

            operation_id
        };

        match (callback_receiver, timeout) {
            // Wait indefinitely
            (Some(receiver), None) => {
                let _ = receiver.await??;
                Ok(UpdateResult {
                    operation_id: Some(operation_id),
                    status: UpdateStatus::Completed,
                    clock_tag: operation.clock_tag,
                })
            }
            // Wait for timeout
            (Some(receiver), Some(timeout)) => {
                match tokio::time::timeout(timeout, receiver).await {
                    Ok(res) => {
                        res??;
                        Ok(UpdateResult {