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/