go - 谁应该分配频道,被叫方的主叫方?
问题描述
我正在尝试用 Go 设计一个简单的家庭自动化程序。当状态改变时,我的灯泡会返回消息流。这可以通过回调来处理,或者在 Go 中使用通道可能会更好。
通过回调,很明显灯泡 API 的调用者实现了特定的函数签名并将函数传递给库。当灯泡改变状态或发生通信错误时,将调用该函数。当客户端不再对更新感兴趣时,库将分配一个要调用的完成函数。例如
type DeviceUpdate = func(Device, error)
type Done = func()
func (client *Client) ObserveDevice(deviceID int, deviceUpdate DeviceUpdate) (Done, error) {
在我的情况下,通道似乎呈现出更好的抽象,因为它们可以轻松合并,可以添加缓冲,可以轻松编织中间件等。我对上述声明的通道表示有点挣扎。对于这种情况,Go 中的正确约定是什么,即整个系统上的数据通道、错误通道和完成/关闭操作。
我在想通道应该由调用者分配,类似于函数。这样,调用者可以在激活整个设置之前正确地实例化通道并连接中间件。
func (client *Client) ObserveDevice(deviceID int, data chan Device, done chan struct{}, err chan error) error {
另一方面,让灯泡库分配通道对于消费者代码来说似乎要简单得多——您只需调用一个函数,无需分配 3 个通道。Go time 模块似乎也勇敢地走这条路,例如https://golang.org/pkg/time/#After
在我的情况下,让库分配通道将导致如下签名
func (client *Client) ObserveDevice(deviceID int) (data chan Device, done chan struct{}, err chan error) {
那么通道分配的 Go 标准做法是什么?是调用者与被调用者还是生产者与消费者?
从网络流汇集更新时通常的做法是有 3 个通道 - 数据、错误和完成?
我在有关 Go 的通道和并发性的文章和视频中进行了一些挖掘,但找不到(可能是由于懒惰)记录的最佳实践。我假设示例中隐含了分配通道的调用者。见https://gobyexample.com/closing-channels,https://blog.golang.org/pipelines
解决方案
推荐阅读
- flutter - Flutter:在MultiSelect中选定项目后未触发onSaved事件
- javascript - 显示单个图像和结束循环的问题
- python - 无法保持 chrome 驱动程序窗口打开
- c++ - 生成所有可能组合的列表并从列表中随机选择一个组合
- html - 导航栏的背景颜色
- python - 每次点击“开始”按钮,秒表都会变得更快
- sql - 具有集群和分区的表上的 Bigquery SQL 性能问题
- asp.net - 在 ASP.net Web 服务中设置 Content-Type
- python - 使用 seaborn 和 matplotlib 对热图进行注释的绘图
- ethereum - 使用 ERC20 的接口调用传输函数