View - IFBa

Transcrição

View - IFBa
Git
Controle de versão distribuída
E.J.R.SILVA
Abstract—Este artigo apresenta uma análise arquitetural do
Sistema de Controle de Versão Git e como esta atende seus
requisitos funcionais e não-funcionais identificando os estilos
arquiteturais utilizados no projeto.
Keywords— control version, architecture of system;
I.
INTRODUÇÃO
O Git surgiu da necessidade de substituir o BitKeeper, um
sistema de controle de versão proprietário, por um sistema
open-source e de alta performance. Utilizado para controle de
versão do Kernel do Linux, o BitKeeper, foi abandonado pelos
desenvolvedores do Linux pois o relacionamento entre estes e e
a empresa que desenvolvia comercialmente o BitKeeper se
desfez, e a isenção de pagamento da licença para a ferramenta
foi revogada. Linus Torvalds, criador do Linux, foi quem
iniciou o desenvolvimento do Git, com a alegação de que
nenhum outro sistema open-source atendia a sua necessidade
de desempenho. Com o projeto desenvolvido para superar as
deficiências que outros sistemas possuíam, o Git foi lançado e
incorporado em projetos fora do Linux[1].
I. LABORBA
II.
Em sistemas de controle de versão centralizados, como é o
caso o Subversion (SVN) e o CVS, existe um ponto único de
falha que é o repositório central. Este repositório necessita estar
disponível todo o tempo, caso contrário prejudica o trabalho da
equipe de desenvolvimento pois não seria possível enviar
modificações e consultar o histórico por exemplo.
Em Sistemas de Controle de Versão Distribuídos
(Distribuited Version Control System ou DVCS) os clientes
não fazem apenas cópias das últimas versões dos arquivos e
sima a cópia completa do repositório central. DVCS, em geral,
controlam com eficiência a multiplicidade de repositórios
permitindo que desenvolvedores trabalhem de forma
colaborativa com diversas possibilidades de workflows que em
sistemas centralizados não são triviais, como e o caso do
modelo hierárquico.
O presente artigo tem como objetivo apresentar o projeto
arquitetural do Git, com algumas visões arquiteturais e os
estilos arquiteturais adotados para atender aos requisitos
funcionais e também os não-funcionais. O trabalho realizado
foi buscar no código-fonte do sistema seus componentes e
conectores, para saber como eles se comunicam e suas
definições. Sendo os componentes a parte do código
responsável por armazenar dados e executar algum
processamento sobre os dados e os conectores parte do código
responsável por ligar os componentes e transferir os dados
entre eles, analisar cada um deles é necessário para a
construção do modelo arquitetural do sistema.
Este artigo está dividido da seguinte forma: na seção 2 é
apresentada uma descrição do sistema e seus requisitos
demonstrando assim suas características e forma de
funcionamento. Após isso na seção 3 é explicitado o projeto
arquitetural do sistema com as views do modelo estrutural e de
concorrência com seus respectivos componentes e conectores,
expandindo assim o entendimento do papel de cada um deles.
Na seção 4 são enumeradas as tecnologias utilizadas no projeto
com objetivo de definir os artefatos agregados ao Git que
podem ser middleware, framework e COTS (Commercial Off
The Shelf). Na cultura open-source o termo COTS é entendido
por LIBs, diminutivo de Libraries (bibliotecas). Também é
exibida uma view de implantação para entrar em mais detalhes
sobre os aspectos de implantação do sistema. Por fim, na seção
5 é feita uma conclusão e discussão sobre o sistema seus
objetivos pontos fortes e fracos.
CONTROLE DE VERSÃO DISTRIBUÍDA COM O GIT
Figura 1: Modelo de workflow hierárquico
O Git é um DVCS e seus principais requisitos não
funcionais são:
•
Alta performance: Em sistemas grandes e com muitos
commiters, como é o caso do Kernel do Linux, a
quantidade de merges de arquivos é altíssima. Um
sistema de controle de arquivos deve atender essa
demanda de maneira eficiente;
•
Confiabilidade: O sistema precisa garantir que o
conteúdo do que foi recuperado é o mesmo que foi
armazenado e, caso não seja, identificar que o dado
desejado está corrompido;
•
Distribuído: No Git pode ou não existir um repositório
central, porém ele foi conceitualmente desenvolvido
para ser descentralizado.
•
Escalabilidade: O repositório pode aumentar o
número de branches a partir da necessidade dos
usuários do sistema.
Para garantir a alta performance o Git foi desenvolvido
utilizando a linguagem de programação C, o que reduz o
overhead de execução pertinentes a linguagens de programação
de alto nível. Além disso, como o repositório local é uma copia
do repositório remoto, a maioria das operações são feitas
localmente, possibilitando também ao programador ter acesso
ao histórico sem a necessidade de estar conectado a um
repositório central. Além de garantir a alta performance,
manter a cópia do repositório central em clientes garante a
escalabilidade e também a distribuição mantendo backups do
repositório central em diversas máquinas. A medida que um
novo desenvolvedor faz o clone do repositório um novo
backup é criado em uma máquina diferente[1].
III.
PROJETO ARQUITETURAL
A. Visão estrutural
A figura 2 apresenta os principais componentes do Git. O
artigo não tem como objetivo ensinar como o Git funciona e
sim apresentar sua arquitetura e demonstrar como ela atende
aos requisitos que motivaram o desenvolvimento do mesmo.
Sendo assim, focaremos nos componentes que atendem esses
requisitos.
1) RUN-COMMAND
Praticamente todos os comandos do Git utilizam o conector
arbitrator run-command que é responsável por coordenar a
criação de subprocessos, redirecionando as entradas e saídas do
processo pai para o processo filho. É também responsável por
coordenar a execução de threads capturando as saídas
produzidas no processo caller para ser processada pela thread
gerada. Além disso é responsável por executar os Hooks[2]
que serão explicados no item 7.
2) SEND-PACK
O Componente send-pack é geralmente invocado pelo
comando push. Ele basicamente executa trés passos: 1. solicita
ao run_command a criação de uma thread chamando packobjects; 2 Estabelece uma conexão com o servidor remoto
solicitando que este receba os pacotes; 3. Encaminha os objetos
empacotados e compactados para o protocolo encaminhá-los ao
servidor[2].
3) PACK-OBJECTS
O componente pack-objects empacota uma lista de objetos
comprimindo-os para otimizar não somente o armazenamento
como também o tráfego na rede[2].
4) RECEIVE-PACK
Invocado no repositório remoto pelo componente sendpack do repositório cliente. Executa os mesmos passos do
send-pack, porém no lugar do comando pack-objects o
comando invocado é o unpack-objects[2].
5) UNPACK-OBJECTS
Desempacota os arquivos previamente empacotados pelo
componente pack-objects[2].
6) DAEMON
O daemon é um servidor para o protocolo Git, geralmente
utilizando para respositórios read-only mas é possível habilitar
a permissão de escrita[2].
Figura 2: Visão estrutural do Git
7) GIT REPOSITORY
•
Hooks: O diretório Hooks é onde ficam armazenados
scripts personalizados que serão executados antes ou
após alguns comandos básicos do git: checkout,
merge, add, commit. Essa característica é que torna
possível o comportamento do Git ser escalável
podendo novas funcionalidades serem adicionadas a
qualquer momento.
•
Info: Nesta pasta encontra-se o arquivo exclude que
serve para definir alguns arquivos que serão
ignorados.
•
Objects: Nesta pasta encontram-se os arquivos
versionados. Os arquivos ficam compactados e são
identificados por um código hash.
•
Refs: Contém as referências para todas as branches e
tags do projeto.
Este componente é um dos principais diferenciais do GIT
em relação aos outros sistemas de controle de versão. É
dividido em alguns subdiretórios.
Figura 3: Visão Estrutural do Git Repository
Figura 4: Visão de concorrência do git
O repositório apresentado na figura 2 e detalhado na figura 3
pode ser um tanto um repositório local, como também, um
repositório remoto. O repositório remoto pode ser de um
servidor central ou de um outro cliente. Essa característica
permite observar um estilo arquitetural híbrido entre clienteservidor e peer-to-peer.
B. Visão de concorrência
A Figura 4 apresenta a visão de concorrência do Git. O Git
tem como componentes ativos o daemon, send-pack, receivepack, pack-objects, unpack-object.
1) Recebendo arquivos (pull, clone)
Para o recebimento de arquivos o daemon solicita ao runcommand uma chamada síncrona para o receive-pack e este
solicita ao run-command uma chamada assíncrona para o
unpack-objects.
2) Enviando arquivos (push)
O send-pack também é executado pelo run_command. Ao
ser executado o comando push, este solicita ao run_command
uma chamada síncrona para o send-pack e este envia um
pedido o run-command executar assincronamente o comando
pack-objects.
Para garantir acesso seguro aos objetos a serem
empacotados o pack-objects, através do componente threadutils bloqueia o objeto em uso pela thread em execução. Essa
forma de empacotamento e desempacotamento assíncrono é
responsável pela alta performance do Git e atende um de seus
principais requisitos: performance.
IV.
IMPLEMENTAÇÃO E IMPLANTAÇÃO
Essa seção tem por finalidade descrever as tecnologias
utilizadas no projeto e suas respectivas justificativas.
Linguagem C – Linguagem de programação principal do
sistema que possui um alto desempenho.
PCRE (Perl Compatible Regular Expressions) – É uma
biblioteca que implementa expressões regulares inspirada na
interface externa do Perl. Utilizada como motor de expressões
regulares do Git.
PTHREAD (Posix Threads) – É uma API para criar e
manipular threads. Todo comando funciona de forma
assíncrona no servidor e essa API fornece essa funcionalidade.
Para o Windows, os desenvolvedores do Git fizeram uma
implementação específica baseada na lib pthread, porém sem
algumas features que o Git não utiliza.
Figura 5: Estilo peer-to-peer
CURL – Biblioteca para transferir dado utilizando vários
protocolos. Como o Git transmite dados em mais de um
protocolo essa lib se faz necessária.
SSL (Secure Sockets Layer) – É um protocolo para prover
privacidade e integridade de dados na comunicação via web.
ZLIB – Biblioteca para compressão de dados, utilizada
para a compressão de arquivos.
ICONV - API para converter codificações de um arquivo
em outra codificação.
GCOV – Biblioteca para testes de cobertura de código
fonte. Utilizada para analisar quais partes do programa devem
ser otimizadas.
EXPAT – Biblioteca para análise de documentos XML.
Utilizada na comunicação http. Requerida quando o repositório
do Git é configurado para permitir escrita, que é feito através
do protocolo WebDAV (Web-based Distributed Authoring and
Versioning)
FNMATCH – Biblioteca para adicionar expressões
regulares no sistema.
Para o processo de implantação se faz necessário que cada
ator possua as bibliotecas requeridas e um arquivo de
instalação do Git. As bibliotecas requeridas já foram citadas
são elas curl, zlib, openssl, expat e libiconv. A Figura 5 exibe a
visão de implantação do sistema. Cada computador com o Git
instalado possui o papel de cliente e servidor.
V.
CONCLUSÃO
O Git apresenta uma boa solução para controle de versão
distribuído e open-souce. Através do artigo ficou claro que um
dos seus principais requisitos é a performance. Este requisito
influenciou até na linguagem escolhida para sua
implementação. Apesar da linguagem C estar diretamente
ligada ao estilo arquitetural Main program and Subroutines, o
que torna o sistema mais difícil de dar manutenção e ser
reutilizado, sua performance em relação as outras linguagens
de programação de alto nível foi preponderante para sua
escolha.
Outro requisito é de ser distribuído. Para isso sua
arquitetura apresenta um estilo arquitetural híbrido de clienteservidor e peer-to-peer. Outro requisito atendido por este
estilo arquitetural é a escalabilidade. A medida que novos
desenvolvedores fazem clone de um repositório um novo
ponto de recuperação é criado.
O sistema permite que novos comportamentos sejam
adicionados sem a necessidade de recompilação através de
Hooks, o que sugere um outro estilo arquitetural, baseado em
interpretadores.
REFERÊNCIAS
[1]
[2]
Chacon. S. Pro Git. n.d. Retrieved on April, 27, 2013, from http://gitscm.com/book
Torvalds, L. ET AL. Git Manual Page n.d. Retrieved on April, 27, 2013
from https://www.kernel.org/pub/software/scm/git/docs/