我正在尝试在f#中实现kafka协议,我想知道是否值得使用反射进行编码/解码,以便获得快速而好的方法来添加新请求,或者让每个请求自行负责以提高性能
反思使人有能力 Codec.encode
以及 Codec.decode<'T>
与协议(表示所有请求和响应的类)分离,只需添加更多记录即可添加新的请求/响应。但它会减慢编码/解码过程。
方法 .Encode()
以及 .Decode()
在每个请求上,添加新请求变得更加困难,它添加了更多的代码,因此有更多的地方出现错误,并且隐藏了协议。
例子:
(* just translated from BNF from kafka protocol page *)
type MetadataRequest = {
TopicName: string list }
type RequestType =
| MetadataRequest of MetadataRequest
// | ProduceRequest of ProduceRequest
// ...
type RequestMessage = {
ApiKey: int16
ApiVersion: int16
CorrelationId: int32
ClientId: string
RequestMessage: RequestType }
type Request = {
Size: int32
Message: RequestMessage }
(* and to use this: *)
// val encode : value:obj -> byte[] option
// val decode : data:byte[] -> 'T option (requires default constructor)
getMetadataRequest [|"topic1"; "topic2"|]
|> Codec.encode
|> connection.send
|> Codec.decode<MetadataResponse>
|> // do something with repsonse
注意:我已经删除了所有匹配选项条目,以显示在编码、发送和解码中应该包含不同错误的想法
下面是一个c#示例,每个请求都知道如何编码/解码自身:jroland提供的kafka net中的metadatarequest.cs
2条答案
按热度按时间8fsztsew1#
我建议看一下fspickler的序列化概念nessos.github.io/fspickler/overview.html
wfsdck302#
据我所知代码示例,
Codec.encode
以及Codec.decode<'a>
两个简单的函数由管道操作符组成。这意味着任何与类型匹配的函数
obj -> byte[] option
以及byte[] -> 'a option
可以使用。我认为提供
Codec.encode
以及Codec.decode<'a>
作为默认机制,允许用户快速入门将是有益的。这种设计并不妨碍有特殊需求的用户编写自定义编码/解码函数,这些函数可以组成管道,而不是默认函数。
因此,基于我对这个问题的有限理解,我认为当前的设计看起来不错,我绝对不建议将它变得更面向对象,这将有可能混合最好分开的职责。