【问题标题】:Should I care about providing asynchronous calls in my go library?我应该关心在我的 go 库中提供异步调用吗?
【发布时间】:2016-11-13 18:13:47
【问题描述】:

我正在通过 http 为 jsonrpc 开发一个简单的 go 库。

有以下方法:

rpcClient.Call("myMethod", myParam1, myParam2)

此方法在内部执行 http.Get() 并返回结果或错误(元组)。

这当然是调用者的同步,并在 Get() 调用返回时返回。

这是在 go 中提供库的方式吗?如果她愿意,我应该把它留给我图书馆的用户让它异步吗?

或者我应该提供第二个函数:

rpcClient.CallAsync()

并在此处返回频道?因为通道不能提供元组,所以我必须将 (response, error) 元组打包到一个结构中并返回该结构。

这有意义吗?

否则用户将不得不将每个调用都包装在一个丑陋的方法中,例如:

result := make(chan AsyncResponse)
go func() {
    res, err := rpcClient.Call("myMethod", myParam1, myParam2)
    result <- AsyncResponse{res, err}
}()

有 Go 库和异步的最佳实践吗?

【问题讨论】:

    标签: go


    【解决方案1】:

    go 执行模型的全部意义在于向开发人员隐藏异步操作,并且表现得像一个带有阻塞操作的线程模型。在幕后有绿色线程和异步 IO 以及一个非常复杂的调度程序。

    所以不,您不应该为您的库提供异步 API。从代码的角度来看,go 中的网络是以伪阻塞方式完成的,你可以根据需要打开尽可能多的 goroutine,因为它们非常便宜。

    所以你的最后一个例子是要走的路,我不认为它丑陋。因为它允许开发者选择并发模型。在 http 服务器的上下文中,每个命令都在单独的 goroutine 中处理,我只需调用 rpcClient.Call("myMethod", myParam1, myParam2)

    或者如果我想要一个扇出 - 我将创建扇出逻辑。

    您还可以创建一个方便的函数来执行调用并在通道上返回:

    func CallAsync(method, p1, p2) chan AsyncResponse {
        result := make(chan AsyncResponse)
        go func() {
            res, err := rpcClient.Call(method, p1, p2)
            result <- AsyncResponse{res, err}
        }()
        return result
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-13
      • 2019-06-04
      • 2011-02-25
      • 2017-01-14
      相关资源
      最近更新 更多