Repository: risingwavelabs/risingwave
File: src/frontend/src/handler/util.rs (Rust)

Code before:
/// ).await?;
/// ```
#[derive(Clone, Copy)]
pub enum LongRunningNotificationAction {
    SuggestRecover,
    DiagnoseBarrierLatency,
    MonitorBackfillJob,
}

impl LongRunningNotificationAction {
    fn build_message(self, operation_name: &str, notify_timeout_secs: u32) -> String {
        match self {
            LongRunningNotificationAction::SuggestRecover => format!(
                "{} has taken more than {} secs, likely due to high barrier latency.\n\
                You may trigger cluster recovery to let {} take effect immediately.\n\
                Run RECOVER in a separate session to trigger recovery.\n\
                See: https://docs.risingwave.com/sql/commands/sql-recover#recover",
                operation_name, notify_timeout_secs, operation_name
            ),
            LongRunningNotificationAction::DiagnoseBarrierLatency => format!(
                "{} has taken more than {} secs, likely due to high barrier latency.\n\
                See: https://docs.risingwave.com/performance/metrics#barrier-monitoring for steps to diagnose high barrier latency.",
                operation_name, notify_timeout_secs
            ),
            LongRunningNotificationAction::MonitorBackfillJob => format!(
                "{} has taken more than {} secs; barrier latency might be high. Please check barrier latency metrics to confirm.\n\
                You can also run SHOW JOBS to track the progress of the job.\n\
                See: https://docs.risingwave.com/performance/metrics#barrier-monitoring and https://docs.risingwave.com/sql/commands/sql-show-jobs",
                operation_name, notify_timeout_secs
            ),
        }
    }
}

pub async fn execute_with_long_running_notification<F, T>(
    operation_fut: F,
    session: &SessionImpl,
    operation_name: &str,
    action: LongRunningNotificationAction,
) -> RwResult<T>
where
    F: std::future::Future<Output = RwResult<T>>,
{
    let notify_timeout_secs = session.config().slow_ddl_notification_secs();

    // If timeout is 0, disable notifications and just execute the operation
    if notify_timeout_secs == 0 {
        return operation_fut.await;
    }

    let notify_fut = sleep(Duration::from_secs(notify_timeout_secs as u64));

Review comment (performance):
Inconsistent punctuation: this message uses a semicolon (`;`) after "secs" while the other messages (lines 351 and 358) use commas. For consistency, consider using a comma here as well:
```
"{} has taken more than {} secs, barrier latency might be high. Please check barrier latency metrics to confirm.\n\
```
```suggestion
                "{} has taken more than {} secs, barrier latency might be high. Please check barrier latency metrics to confirm.\n\
```

Code after:
/// ).await?;
/// ```
#[derive(Clone, Copy)]
pub enum LongRunningNotificationAction {
    SuggestRecover,
    DiagnoseBarrierLatency,
    MonitorBackfillJob,
}

impl LongRunningNotificationAction {
    fn build_message(self, operation_name: &str, notify_timeout_secs: u32) -> String {
        match self {
            LongRunningNotificationAction::SuggestRecover => format!(
                "{} has taken more than {} secs, likely due to high barrier latency.\n\
                You may trigger cluster recovery to let {} take effect immediately.\n\
                Run RECOVER in a separate session to trigger recovery.\n\
                See: https://docs.risingwave.com/sql/commands/sql-recover#recover",
                operation_name, notify_timeout_secs, operation_name
            ),
            LongRunningNotificationAction::DiagnoseBarrierLatency => format!(
                "{} has taken more than {} secs, likely due to high barrier latency.\n\
                See: https://docs.risingwave.com/performance/metrics#barrier-monitoring for steps to diagnose high barrier latency.",
                operation_name, notify_timeout_secs
            ),
            LongRunningNotificationAction::MonitorBackfillJob => format!(
                "{} has taken more than {} secs, barrier latency might be high. Please check barrier latency metrics to confirm.\n\
                You can also run SHOW JOBS to track the progress of the job.\n\
                See: https://docs.risingwave.com/performance/metrics#barrier-monitoring and https://docs.risingwave.com/sql/commands/sql-show-jobs",
                operation_name, notify_timeout_secs
            ),
        }
    }
}

pub async fn execute_with_long_running_notification<F, T>(
    operation_fut: F,
    session: &SessionImpl,
    operation_name: &str,
    action: LongRunningNotificationAction,
) -> RwResult<T>
where
    F: std::future::Future<Output = RwResult<T>>,
{
    let notify_timeout_secs = session.config().slow_ddl_notification_secs();

    // If timeout is 0, disable notifications and just execute the operation
    if notify_timeout_secs == 0 {
        return operation_fut.await;
    }

    let notify_fut = sleep(Duration::from_secs(notify_timeout_secs as u64));