mercredi 20 janvier 2016

Is it better to have decode<'T> function or each api should know how to decode/encode itself?

I'm trying to implement kafka protocol in f# and I would like to know is it worth to use reflection for encode/decode in order to get fast and nice way to add new requests or leave each request to be responsible on it's own to increase performance

Reflection gives ability to have Codec.encode and Codec.decode<'T> that are separated from the protocol (classes that represents all requests and responses) and makes adding new requests/responses just by adding more records. But it slows down encoding/decoding process.

Methods .Encode() and .Decode() on each request makes it harder to add new requests, it adds more code so more places to get a bug and it hides protocol.

Example:

(* 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

Note: I've removed all match option entries to show the idea that should wrap different errors in encoding, sending, decoding

Here is C# example with each request knows how to encode/decode itself: MetadataRequest.cs from kafka-net by Jroland





Aucun commentaire:

Enregistrer un commentaire