smallnest / rpcx

Best microservices framework in Go, like alibaba Dubbo, but with more features, Scale easily. Try it. Test it. If you feel it's better, use it! 𝐉𝐚𝐯𝐚有𝐝𝐮𝐛𝐛𝐨, 𝐆𝐨𝐥𝐚𝐧𝐠有𝐫𝐩𝐜𝐱! build for cloud!
https://rpcx.io
Other
8.11k stars 1.17k forks source link

客户端context的超时设置 #870

Closed weiiqi closed 2 months ago

weiiqi commented 3 months ago

大佬您好,这里看到,客户端使用context设置超时 时, 您在底层实现了透传到服务端 如果在上层业务实现服务端逻辑超时则需要逻辑业务上再包一层 go routine 。如果rpcx底层实现,业务上就可以少一倍的go routine. 或则有没有更好的实现方式

smallnest commented 2 months ago

没太理解,最好代码描述

smallnest commented 2 months ago

ctx给你了,用不用goroutine完全由你自己。

比如新开了goroutine:

func operation(ctx context.Context) {
    // 模拟一个耗时任务
    select {
    case <-time.After(5 * time.Second): // 假设这个操作需要5秒才能完成
        fmt.Println("操作完成")
    case <-ctx.Done():
        fmt.Println("操作取消:", ctx.Err())
    }
}

func main() {
    // 创建一个超时时间为2秒的context
    timeout := 2 * time.Second
    ctx, cancel := context.WithTimeout(context.Background(), timeout)
    defer cancel() // 非常重要:确保资源正确释放

    go operation(ctx)

    // 等待足够的时间,查看操作是否完成
    time.Sleep(6 * time.Second) // 等待时间应比操作的最长耗时长以确保出结果
}

不新开goroutine:

func operation(ctx context.Context) {
    // 模拟一个耗时任务
    select {
    case <-time.After(5 * time.Second): // 假设这个操作需要5秒才能完成
        fmt.Println("操作完成")
    case <-ctx.Done():
        fmt.Println("操作取消:", ctx.Err())
    }
}

func main() {
    // 创建一个超时时间为2秒的context
    timeout := 2 * time.Second
    ctx, cancel := context.WithTimeout(context.Background(), timeout)
    defer cancel() // 非常重要:确保资源正确释放

        operation(ctx)

    // 等待足够的时间,查看操作是否完成
    time.Sleep(6 * time.Second) // 等待时间应比操作的最长耗时长以确保出结果
}

丰俭由人,框架不用考虑呀。 不知道回到你的问题了么

weiiqi commented 2 months ago
package main

import (
    "context"
    "fmt"
    "time"
)

func operation(ctx context.Context, task func()) {
    done := make(chan struct{})

    // 在另一个 goroutine 中执行传入的函数
    go func() {
        defer close(done)
        task() // 执行实际的任务
    }()

    select {
    case <-done:
        fmt.Println("操作完成")
    case <-ctx.Done():
        fmt.Println("操作取消:", ctx.Err())
    }
}

func exampleTask() {
    // 模拟一个需要执行的任务
    fmt.Println("任务开始")
    time.Sleep(5 * time.Second) // 假设任务需要 5 秒完成
    fmt.Println("任务结束")
}

func main() {
    // 创建一个超时时间为 2 秒的 context
    timeout := 2 * time.Second
    ctx, cancel := context.WithTimeout(context.Background(), timeout)
    defer cancel()

    // 调用 operation,传入上下文和任务函数
    operation(ctx, exampleTask)
}

大佬你好,理解你意思了,谢谢您的解答。我本来要实现这种逻辑,在超时后,task就不继续执行了,但好像只能用主线程退出的方式来实现。