英文:
How to design a connector in go
问题
我正在使用Go语言构建一个简单的连接器组件,具有以下职责:
- 打开、保持和管理与外部服务的连接(在后台运行)。
- 将传入的数据解析为逻辑消息,并将这些消息传递给业务逻辑组件。
- 将业务逻辑中的逻辑消息发送到外部服务。
我还没有决定如何设计连接器的接口。
变体A)使用通道接收传入消息,使用函数调用发送传出消息
// 监听传入消息。
// 传入消息将被发送到提供的通道。
func Listen(msg chan *Message) {...}
// 将消息发送到服务
func Send(msg *Message) {...}
变体B)使用通道接收传入和传出消息
// 监听传入消息 + 发送传出消息。
// 传入消息将被发送到提供的msgIn通道。
// 要发送消息,请将消息放入msgOut通道中。
func ListenAndSend(msgIn chan *Message, msgOut chan *Message) {...}
对我来说,变体B似乎更清晰、更符合Go语言的风格,但我正在寻找以下问题的答案:
- 在Go语言中是否有一种“惯用”的方法来做这件事?
- 或者,在哪些情况下应该优先选择变体A或B?
- 这种问题还有其他值得注意的变体吗?
英文:
I am building a simple connector component in go, with these responsibilities:
- Open, keep & manage connection to an external service (i.e. run in background).
- Parse incoming data into logical messages and pass these messages to business logic component.
- Send logical messages from business logic to external service.
I am undecided how to design the interface of the connector in go.
Variant A) Channel for inbound, function call for outbound messages
// Listen for inbound messages.
// Inbound messages are delivered to the provided channel.
func Listen(msg chan *Message) {...}
// Deliver msg to service
func Send(msg *Message) {...}
Variant B) Channel for inbound and outbound messages
// Listen for inbound messages + send outbound messages.
// Inbound messages are delivered to the provided msgIn channel.
// To send a message, put a message into the msgOut channel.
func ListenAndSend(msgIn chan *Message, msgOut chan *Message) {...}
Variant B seems cleaner and more "go-like" to me, but I am looking for answers to:
- Is there an "idiomatic" way to do this in go?
- alternatively, in which cases should variant A or B be preferred?
- any other notable variants for this kind of problem?
答案1
得分: 3
这两种方法都只允许一个监听器(除非你跟踪监听器的数量,但这种方法相对脆弱),这是一个限制。具体取决于你的编程偏好,但我可能会选择使用回调函数来处理传入的消息,并使用一个发送方法:
func OnReceive(func(*Message) bool) // 如果回调函数返回false,则取消注册。
func Send(*Message)
除此之外,你提出的两种模型都是完全有效的。第二种模型似乎更加“正交”。使用发送方法的一个优点是你可以确保它永远不会阻塞,而不像一个“裸露”的通道。
英文:
Both approaches allow for only one listener (unless you keep track of the amount of listeners, which is a somewhat fragile approach), which is a limitation. It all depends on your programmatic preferences but I'd probably go with callbacks for incoming messages and a send method:
func OnReceive(func(*Message) bool) // If callback returns false, unregister it.
func Send(*Message)
Other than that, both of your proposed models are completely valid. The second seems more "orthogonal". An advantage of using a send method is that you can make sure it never blocks, as opposed to a "bare" channel.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论