Conheça Bond, Microsoft Bond - Uma nova estrutura de serialização de dados

Publicados: 2022-03-11

O Microsoft Bond é uma nova estrutura de serialização para dados esquematizados criados pela Microsoft.

Vamos recapitular onde a serialização de dados é mais usada:

  • Persistência de dados em arquivos, streams, NoSQL e BigData.
  • Transmissão de dados em redes, IPC, etc.

Comumente, esses aplicativos precisam lidar com dados esquematizados, onde esquema significa:

  • Estrutura: hierarquia, relações, ordem.
  • Semântica: idade em anos desde o nascimento.

estrutura de serialização de dados do Microsoft Bond

Na verdade, qualquer dado tem esquema, mesmo que seja implicitamente definido ou suportado por sua linguagem de programação pronta para uso. Quando se trata de estruturas de dados complexas, acabamos escrevendo objetos de transferência de dados (DTOs) de suporte e código responsável por IO, geralmente em diferentes linguagens. Assim que cresce e evolui, rapidamente se torna um pesadelo manter todas essas peças. Aqui é onde os frameworks de serialização ganham o jogo.

Em primeiro lugar, qualquer estrutura de serialização define uma abstração para definição de esquema de dados que não está vinculada a uma linguagem de programação ou plataforma específica. Essa abstração é conhecida como DSL (domain-specific language).

Tendo tal DSL, podemos definir o esquema de dados para um aplicativo específico. A definição, por sua vez, pode ser expressa em várias formas, mas muitas vezes as estruturas de serialização suportam uma única forma que é adequada para sua DSL. Muito complicado? Aqui está um exemplo bem conhecido: XSD e XML.

XSD define uma DSL, XML é (recomendado) para definir documentos que correspondam ao esquema XSD. Mas, você também pode usar “xsd.exe” para gerar classes DTO correspondentes ao XSD, portanto, as classes geradas são apenas outra forma. Observe que você pode gerar XML a partir de DTOs e vice-versa e eles serão semanticamente idênticos, pois a semântica é comum: é definida com o XSD. Para resumir, uma estrutura de serialização fornece uma DSL, que você usa para definir esquemas de dados em um determinado formato que é melhor suportado pela estrutura fornecida.

O esquema de dados abstrato deve ser materializado em um conjunto de entidades expressas em uma linguagem de programação. Todas as estruturas de serialização fornecem ferramentas especiais chamadas geradores de código.

Eles geram todo o código de suporte para linguagens de programação de destino, que é necessário para os clientes trabalharem com dados esquematizados: DTOs, proxy, etc. Isso é necessário para linguagens fortemente tipadas, enquanto pode ser opcional para linguagens tipo pato (dinâmicas) .

A última, mas não menos importante, é a persistência dos dados no fio. Os dados reais devem ser eventualmente serializados em bytes brutos (ou texto) e desserializados de volta.

Todos os frameworks de serialização de dados fornecem outra abstração aqui chamada de protocolos. Um protocolo define um conjunto de regras que definem como os dados estruturados devem ser serializados ou desserializados de acordo com seu esquema. Cada protocolo é normalmente implementado para todas as linguagens de programação e plataformas suportadas por uma determinada estrutura de serialização. Quanto mais linguagens/plataformas de programação ele suporta, mais implementações ele deve fornecer.

Imagine que um framework está disposto a suportar o protocolo JSON, então ele deve fornecer um leitor/gravador JSON para, digamos, C#, C++, Windows, Linux, etc.

Juntando tudo: qualquer estrutura de serialização de dados moderna fornece o seguinte:

  • Abstrações: DSL e Protocolos.
  • Ferramentas de geração de código.
  • Implementações de protocolo.

O Microsoft Bond é uma estrutura moderna de serialização de dados. Ele fornece protocolos DSL e flexíveis poderosos, geradores de código para C++ e C#, implementações de protocolo eficientes para Windows, Linux e Mac OS X.

Por vários anos, Bond permaneceu uma tecnologia de uso interno apenas, mas graças à iniciativa Microsoft Open Source, Bond foi disponibilizado no GitHub: Microsoft Bond.

Concorrentes de serialização de dados

A rivalidade entre os gigantes do software levou ao surgimento de várias estruturas de serialização:

  • Google Inc. - Buffers de protocolo do Google
  • Facebook Inc. - Thrift, que agora é mantido pelo Apache
  • Software da Fundação Apache - Avro

Obviamente, eles são todos incompatíveis, o que não tem problema, a menos que você crie sua API pública usando um deles.

Cada um deles tem prós e contras, então você pode escolher entre eles com base em suas necessidades.

Por que Bond?

A resposta oficial a esta pergunta está aqui: “Por que Bond”.

Aqui está o resumo rápido:

  • Bond suporta sistema de tipos ricos, incluindo genéricos.
  • O Bond suporta versionamento de esquema e compatibilidade bidirecional.
  • O Bond oferece suporte à manipulação de esquema de tempo de execução.
  • Bond suporta várias coleções: “vetor , mapa , Lista ”.
  • O Bond suporta serialização preguiçosa com segurança de tipo: “bonded
  • Bond suporta protocolos plugáveis ​​(formatos) com marshaling e transcodificação

Uma nota importante é que Bond segue a estratégia “pay to play”. Quanto mais recursos você adicionar/usar, mais você pagará pelo tamanho e pela velocidade. Isso dá aos desenvolvedores grande flexibilidade.

Vamos ser honestos e listar as desvantagens também:

  • Bond tem como alvo a pilha da Microsoft com suporte a C++ e C#, mas não suporta Java (ainda).
  • Bond não suporta o tipo de união (“oneof” em protobuf).

E quanto ao desempenho?

Quando se trata de comparar uma estrutura com outra, os desenvolvedores geralmente procuram comparações de desempenho. Mas vamos lembrar que essas estruturas consistem em DSL, geradores de código e protocolos. Se você considerar apenas o desempenho dos protocolos, perderá os recursos fornecidos pelo DSL e pelos codegens. Às vezes, ter um DSL melhor é muito mais importante do que ter uma pequena diferença percentual na velocidade de serialização.

Além da velocidade, as codificações com eficiência de espaço suportadas por alguns protocolos também podem ser importantes. Recomendo que você faça uma comparação de desempenho/espaço com os dados específicos do seu domínio. Essa é a única maneira de estimar todos os benefícios que você pode obter de uma estrutura específica.

vínculo da microsoft

Este artigo vem com o projeto de demonstração que demonstra o uso da estrutura do Bond lendo todos os registros do log de eventos do aplicativo do Windows, serializando-os como objetos Bond e desserializando-os novamente.

Para compilar e executar a demonstração, você não precisa instalar nenhum software além do Visual Studio.

Usando o Microsoft Bond

Obtendo Bond

Consulte o guia oficial sobre como obter o Bond para sua(s) plataforma(s).

Para projetos .NET, isso é tão simples quanto:

 install-package Bond.CSharp

O pacote inclui:

  • Gerador de código (gbc.exe) na pasta bin
  • Bibliotecas .NET
  • Tarefas do MSBuild

Fluxo de trabalho

O fluxo de trabalho inclui as seguintes etapas:

  • Aprenda DSL e defina o esquema de dados escrevendo arquivo(s) “.bond”.
  • Use o gerador de código (“gbc.exe”) para obter DTOs para sua linguagem de programação.
  • Faça referência aos arquivos gerados, bem como às bibliotecas de tempo de execução do Bond em seu projeto.

Considere usar as tarefas do MSBuild fornecidas com a estrutura para automatizar a etapa de geração de código.

Visão geral dos recursos DSL

Quando você começar a escrever seu primeiro arquivo “.bond”, você precisará conhecer sua sintaxe e recursos. Visite a página de documentação oficial que descreve o IDL em detalhes. Vamos revisar apenas os recursos básicos:

  • Módulos: o esquema pode ser dividido em diferentes arquivos, que estão incluídos na instrução “import”.
  • Namespace: tem o mesmo significado que C++/C# tem.
  • Estruturas definidas pelo usuário: uma unidade de definição de tipo de usuário.
  • A declaração de encaminhamento é útil para estruturas de dados recursivas.
  • Tipos básicos: “bool, uint8(até 64), int8(até 64), float, double, string, wstring”.
  • Tipos de contêiner: “blob, lista , vetor , definir , map<K, T>, anulável ”.
  • Aliases e mapeamentos de tipo personalizado, por exemplo, se você quiser ter “DateTime” em C#, mas carrapatos (“int64”) na conexão.
  • Atributos personalizados: úteis para geração de código personalizado.

Entediado? Aqui está um exemplo:

 namespace MyProject struct MyRecord { 0: string Name = "Noname"; 1: vector<double> Constants; }

onde “0” e “1” são os números ordinais do campo (podem ser quaisquer inteiros com qualquer ritmo) e = "Noname" é o valor padrão (opcional).

Geração de código

O framework Bond fornece uma ferramenta de geração de código escrita em Haskell. Aqui está como gerar código C# e C++ a partir de um esquema “.bond” na linha de comando:

 gbc c# example.bond gbc c++ example.bond

Protocolos suportados (formatos)

O Bond pronto para uso suporta três tipos de protocolos:

  • Protocolos marcados: “CompactBinary” e “FastBinary”

Protocolos marcados intercalam metadados de esquema dentro da carga útil. Isso torna a carga útil autodescritiva, permitindo que os consumidores a interpretem mesmo sem conhecer o esquema usado pelo produtor.

  • Protocolos não marcados: “SimpleBinary”

Os protocolos não marcados serializam apenas dados e, portanto, exigem que os consumidores conheçam o esquema de carga útil por meio de algum mecanismo fora de banda. Protocolos não marcados são frequentemente usados ​​em cenários de armazenamento porque permitem armazenar um esquema uma vez (por exemplo, em uma tabela de sistema em um banco de dados), eliminando assim a sobrecarga de metadados de muitos registros usando o mesmo esquema.

  • Protocolos baseados em DOM: “SimpleJson” e “SimpleXml”

O protocolo baseado em DOM analisa toda a carga útil em um modelo de objeto de dados na memória que é consultado durante a desserialização. Normalmente, esse tipo de protocolo é usado para implementar codificações baseadas em texto, como JSON ou XML.

Para cada protocolo, a biblioteca de tempo de execução do Bond fornece as classes Reader e Writer correspondentes, que fazem o trabalho na serialização real.

Usar os protocolos é bem direto e um pouco mais difícil do que o famoso “JsonConvert.SerializeObject()”:

 var record = new MyRecord { Name = "FooBar", Constants = { 3.14, 6.28 } }; var output = new OutputBuffer(); var writer = new CompactBinaryWriter<OutputBuffer>(output); Serialize.To(writer, record); var input = new InputBuffer(output.Data); var reader = new CompactBinaryReader<InputBuffer>(input); record = Deserialize<Example>.From(reader);

Qual é o próximo?

Se você gosta de Bond e tem muito tempo livre para codificar, considere levar um desses itens para o desenvolvimento. Não vou enumerar todos os benefícios que você pode obter ao contribuir, mas sei que muitos desenvolvedores estão procurando ideias para contribuir:

  • Implemente uma porta para Java. Substitua Java por outras linguagens convencionais à sua escolha.
  • Implemente a importação/exportação do esquema Bond para troca com outras DSLs (por exemplo, “.proto <=> .bond”).

O que quer que você decida fazer em relação a Bond, recomendo que entre em contato com Adam Sapek primeiro. Ele é o líder deste projeto e irá orientá-lo com o que é mais exigido pelo mercado.