How to design a connector in go

huangapple go评论82阅读模式
英文:

How to design a connector in go

问题

我正在使用Go语言构建一个简单的连接器组件,具有以下职责:

  1. 打开、保持和管理与外部服务的连接(在后台运行)。
  2. 将传入的数据解析为逻辑消息,并将这些消息传递给业务逻辑组件。
  3. 将业务逻辑中的逻辑消息发送到外部服务。

我还没有决定如何设计连接器的接口。

变体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:

  1. Open, keep & manage connection to an external service (i.e. run in background).
  2. Parse incoming data into logical messages and pass these messages to business logic component.
  3. 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.

huangapple
  • 本文由 发表于 2013年8月28日 23:13:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/18491845.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定