Categoria: Uncategorized

Quer trabalhar na Inglaterra?

Quem acompanha o blog deve estar sabendo que eu estou passando uma temporada (?) na Inglaterra. E sim, tem muito trabalho para desenvolvedor aqui, principalmente desenvolvedor bom.

A empresa que eu trabalho está procurando mais gente para compor o time. O que estamos procurando?

Em primeiro lugar, o processo ainda não está dando sponsorship para vistos. Mas se você tem nacionalidade italiana, portuguesa, espanhola ou de qualquer outro país da união europeia, você pode trabalhar aqui sem problemas e o processo seletivo vale para você.

Esse não é o job description formal, mas estamos procurando algo como:

  • Perfil técnico: C#/.NET, SQL Server, Web services (REST/WCF), etc. Coisas básicas como princípios SOLID, design orientado a objeto, design patterns também entram na conta
  • Práticas, processos, etc: metodologias ágeis, Test-Driven Development, pair programming, automação de build e release (obviamente isso inclui integração contínua, CI servers, MSBuild, NAnt ou qualquer coisa parecida).
  • Perfil pessoal: saber lidar com humanos (isso inclui humanos não-desenvolvedores), engajamento em comunidade, capacidade e receptividade para aceitar críticas no código e sugerir melhorias, trabalhar colaborativamente, etc.
  • Bonus: Desenvolvimento para devices (Windows CE/Mobile, Android, etc), conhecimento em virtualização com Vagrant, ferramentas de provisionamento como Puppet.

Ahhh, e se você pretende trabalhar e morar na Inglaterra, é realmente importante falar inglês!

Se quiser mais informações sobre a empresa e o produto, veja o vídeo abaixo:

Caso esteja interessado, me procure.

Anúncios

Os números de 2014

Os duendes de estatísticas do WordPress.com prepararam um relatório para o ano de 2014 deste blog.

Aqui está um resumo:

A sala de concertos em Sydney, Opera House tem lugar para 2.700 pessoas. Este blog foi visto por cerca de 21.000 vezes em Se fosse um show na Opera House, levaria cerca de 8 shows lotados para que muitas pessoas pudessem vê-lo.

Clique aqui para ver o relatório completo

Sobre a relação entre metodologia ágil e morar fora do país

Recentemente, me vi diante de um processo de mudar de país. Quando esta idéia começou a se tornar possível, me vi, da noite para o dia com uma infinidade de coisas para resolver, num tempo muito curto e coisas que não tinha a menor idéia de como resolver. Como lidar com a saudade, pedir demissão do emprego, decidir o que eu vou fazer com o cachorro, decidir o que levar, desmontar a casa, passar procuração, resolver visto, fazer um planejamento financeiro, reservar vôo, tirar carteira de motorista internacional, ver onde ficar temporariamente até alugar uma casa, alugar uma casa em outro país, vender o carro, cancelar contas de prestadores de serviços (água, luz, internet, TV), fazer despedidas para os amigos e família e sai lá quantas outras coisas.

É muito difícil descrever como é essa sensação. Parece que você caiu de pára-quedas no meio de uma guerra.

Se nesse momento, eu tentasse resolver de uma vez só todos os problemas, provavelmente desistiria de tudo. Seria muito mais cômodo deixar tudo como estava. Mudar era um processo cheio de incertezas, riscos e custos.

Como um bom geek, resolvi atacar esses problemas como um projeto. Fui no visualstudio.com, montei meu projeto e comecei a organizar um backlog. Primeiro as estórias (cada uma das coisas que relacionei acima, tratei como uma história pois tinham objetivos e entregáveis bem definidos) depois a prioridade. O que é mais importante e o que tem maior risco primeiro. Depois quebrei o backlog em tarefas, numa idéia de entender o que precisava fazer para atingir aquele objetivo.

Mesmo nos casos onde não tinha a menor idéia de como resolver, como: tirar carteira de motorista internacional, lançava as atividades possíveis como “entender o processo de tirar carteira de motorista internacional”. Coisas como “tirar o visto”, lançava os formulários que tinha que preencher, os documentos que tinha que providenciar, as perguntas que tinha que fazer e as incertezas que tinha que eliminar.

Quebrei a complexidade das coisas definindo sprints. Criei uma primeira sprint com as coisas prioritárias para tornavam o processo viáveis. Nessa sprint entraram: visto, cachorro, pedir demissão e vender carro.

Depois fechei uma segunda sprint com as coisas que precisava viabilizar no processo da mudança. Casa, despedidas, onde ficar temporariamente, vôo.

Por último, deixei as coisas que só poderia resolver quando chegasse no outro país como: carro (se ia querer ou não) e alugar casa

O que é interessante é que a partir do momento que você comecei a definir objetivos menores para atingir um objetivo maior, definir atividades concretas e priorizar, a confusão mental decorrente de toda a incerteza existente no processo começou a ser eliminada. Toda a energia que era gasta com ansiedade e dúvida, passou a ser gasta em resolver de fato os problemas. O simples exercício de tomar notas, tirar as coisas da cabeça e torná-las tangíveis num backlog, abriu o espaço necessário para encontrar soluções.

O processo de quebrar em sprints me ajudava a manter o foco. De nada adiantava eu investir esforço no que estava na 2a ou 3a sprint sem resolver os problemas da primeiro. Isso me ajudava a lidar com a procrastinação. Aquelas coisas importantes, porém chatas de resolver, ficavam evidentes.

Isso foi determinante para viabilizar o objetivo de mudar para o exterior. A medida que eu atacava os problemas conforme a prioridade definida e encontrava as próximas atividades para as coisas que não sabia de antemão, mais aprendia sobre o processo e mantinha o controle dos próximos passos. Isso foi gerando um círculo virtuoso.

Em alguns meses, pouco a pouco, todos os obstáculos foram removidos. Quando menos percebi, estava dentro do avião pronto para recomeçar do outro lado do oceano. Meus agradecimentos ao mindset ágil por essa conquista.

E qual a relação de mudar para fora do país com metodologias ágeis no contexto de desenvolvimento de software?

Todo projeto de fazer um novo software é cheio de incertezas. Você precisa entregar algo que não sabe o que é, que provavelmente nunca foi feito antes, com tecnologias que você não conhece direito e com pessoas que nunca trabalhou antes. O primeiro passo é reconhecer claramente tudo isso. Saber o que fazer é provavelmente cerca de 50% do processo.

Quando você encara isso de uma maneira direta, sincera e honesta, move seu cérebro no sentido da solução. Sua cabeça foca em qual é a melhor alternativa que tem em mãos para atacar cada um desses objetivos. Se você simplesmente tentar prever todas as variáveis possíveis até o final do projeto, vai gastar muito mais energia que possui e provavelmente jogar a toalha no meio do caminho. Vai gastar tanto tempo tentando montar um plano infalível que vai acabar não executando nada deste plano por falta de tempo.

Vai ficar o tempo inteiro tentando fazer a realidade se encaixar no seu plano e não planejar de acordo com a as possibilidades existentes.

No final das contas, acho que é isso que as metodologias ágeis me ensinaram: como lidar com incertezas com naturalidade.

Sobre morar e trabalhar no exterior

Pessoal,

Recentemente, comecei uma nova oportunidade profissional, agora em outro país.

Para não misturar assuntos desse blog (profissional, para desenvolvedores) com outros assuntos, criei um blog separado, o “4 malas e o mundo” (4malas.com.br) para compartilhar um pouco das outras experiências de viver aqui (na Inglaterra).

O primeiro post: Como arrumar emprego na Inglaterra já é um que é interessante para os dois blogs. Terão vários cross-posts.

Caso interesse, apareçam por lá! Aproveitem e cliquem bastante nos Ad’s do outro blog para me ajudar a financiar a empreitada!

Abraço,

Eric

TDC 2014

Pessoal,

Novamente fui convidado para palestrar no TDC este ano (The Developers Conference) que será na universidade Anhembi-Morumbi. O evento começa em 06/08/2014 e termina em 09/08/2014.

Estarei palestrando na sexta-feira, dia 08/08 na trilha Arquitetura.NET. Esse ano o tema é “A influência dos processos de desenvolvimento na arquitetura”.

Se estiver no evento, será muito produtivo um bate papo presencial sobre tecnologia ou outros temas abordados aqui no blog.

Até lá!

Open Source – Usar ou não usar?

Introdução

Já faz bastante tempo que software open source existe. Talvez um dos maiores responsáveis por isso tenha sido o sistema operacional Linux que contribuiu para a popularização do modelo.

Apesar disso, ainda vemos muitas empresas e pessoas com certos medos em adotar soluções baseadas em código aberto. Minha idéia com esse post é compartilhar algumas experiências reais que tive com open source no decorrer da carreira.

Para conhecer um pouco mais sobre a história do Open Source, vale a pena ler sobre o Richard Stallman, um dos primeiros “ativistas” sobre o assunto. Aviso antecipadamente: ele é polêmico.

Licenças open-source

Talvez a maior dificuldade em adotar open source esteja relacionada com a licença. Como disponibilizar o código fonte de uma aplicação sem perder os direitos sobre ela?

Para solucionar essa idéia, vieram licenças de código livre, como a GPL – General Public Licence, uma das primeiras e mais polêmicas sobre o assunto. A GPL tem uma idéia que qualquer um pode usar e ter acesso ao código fonte de um software licenciado pela GPL, porém, se modificar o código fonte ou fazer aplicações que se utilizem de qualquer binário licenciado sob a GPL, devem também ser licenciados pela GPL (ou seja, também precisam abrir seu código).

Na prática isso significa que se eu fizer uma aplicação que dependa de uma DLL GPL, minha aplicação também precisa ser licenciada pela GPL. Por essa razão, houve muita crítica a esse caráter viral ou “comunista” da licença GPL.

Por esta razão surgiram licenças menos restritivas como a LGPL, MIT, Apache e outras, que permitem modificações ao código fonte e utilização de binários sem necessidade de royalties.

Quando utiliza-se uma aplicação open-source, como um editor de texto ou um software de controle de versão não há essa preocupação tão restritiva com licenças, visto que pode-se usar gratuitamente o software, mas ao desenvolver uma aplicação é muito importante essa preocupação com qual é a licença do componente que se está utilizando.

O oposto ao licenciamento open-source é o que vemos na maioria das empresas comerciais. No modelo comercial, em geral você não “compra” o produto. Você compra o direito de usá-lo em um computador, por uma pessoa, ou um grupo de pessoas, dependendo do tipo de licença comercial que usa. Se tem algum problema, você entra em contato com o suporte e pede para eles resolverem. No caso do open-source, se você é um desenvolvedor, tem a chance de encontrar e resolver os problemas por conta própria.

Como ganham dinheiro com Open Source?

Apesar de muitos desenvolvedores contribuirem gratuitamente com projetos open-source, por questões de aprendizado ou mesmo alavancagem de carreira, a maioria das empresas que lidam com open-source não vivem de luz. Possuem uma estratégia focada em serviços para conduzirem seus negócios. Alguns exemplos que me vem à cabeça são a CollabNet, que inicialmente começou a desenvolver o Subversion, software de controle de versão gratuíto e open source e vende serviços e outros produtos de cloud, alguns baseados no subversion e outros não e também a SpringSource desenvolvedora do framework Spring, muito popular no mundo Java e um pouco menos no mundo .NET. Além de manter o codigo-fonte vendem serviços de consultoria e suporte comercial.

Outras como a Apache Software Foundation mantenedora do servidor http apache (um dos mais populares e mais usados no mundo), são entidades sem fins lucrativos e recebem doações.

Software open source tem qualidade?

Esse é um dos pontos mais interessantes da discussão. Muita gente questiona como um bando de desenvolvedores malucos que escrevem software no tempo livre podem escrever software melhor do que empresas que remuneram seus desenvolvedores. É um ponto polêmico, mas os fatos podem nos ajudar a chegar a uma conclusão:

  • Servidor http: Segundo esta pesquisa, o servidor web Apache (open source) tem mais de 60% de market share, enquanto o próximo da lista não open-source (IIS, da Microsoft), tem pouco menos de 14%.
  • Em pesquisas sobre controle de versão, como esta, esta e a pesquisa feita neste blog mostram uma preferência esmagadora por ferramentas open-source em detrimento de ferramentas “pagas”
  • Estas estatísticas sobre navegadores de internet, mostram que os de código fechado como Internet Explorer e Safari, tem uma fatia insignificante perto dos open-source

Existem diversas outras ferramentas open-source, desde issue-trackers, editores de texto, ambientes completos de desenvolvimento. Existem tanto ferramentas open sources melhores que pagas quanto o contrário. É o caso da suíte Office, que durante décadas continua sendo a mais usada mesmo existindo alternativas open-source.

Em geral, é muito importante saber quem é a comunidade ou a empresa que está por trás dos projetos open-source, isso é fator determinante na qualidade do produto final (o mesmo critério vale para as pagas!).

Há organização nos projetos open-source?

Depende do projeto, é claro. Este site: Ohloh.net possui muitas estatísticas sobre projetos open-source. É interessante ver projetos com centenas, ou até passando de mil colaboradores e pensar como esse pessoal todo trabalha junto, como garantem a qualidade e o roadmap de melhorias dos produtos.

Muitos destes projetos são hospedados em controles de versão e ferramentas de gestão de projetos hospedados na nuvem como o SourceForge (talvez o mais antigo de todos), o Git Hub ou o BitBucket. A maioria destes hosts utilizam justamente o tamanho e a carga dos projetos open-source que hospedam como argumento para vender serviços de hospedagem para outras empresas e alavancar seus modelos de negócio open-source.

Cada projeto possui uma estratégia de colaboração completamente diferente, mas em geral é muito interessante a organização. Vou citar alguns exemplos práticos de situações que já contribuí.

Projeto Indy

Até me assustei quando encontrei o site do Indy. Pra quem não viveu essa época, eram componentes Delphi para acesso à internet, coisas como http, ftp, e vinham junto com o Delphi, mas eram (ou são?) desenvolvidos por uma comunidade.

Numa dada situação (se me lembro bem, em 2005), precisei de um tipo de request não suportado pelo componente. Fui lá e escrevi a minha classe para resolver o problema e todo feliz e contente fui contribuir com o projeto. Recebi uma negativa polida porque meu código estava totalmente fora do padrão de qualidade deles. Foi frustrante.

SVN::Notify

Em idos de 2006, na minha primeira subida de um servidor Subversion na vida, queria um script para notificação dos commits, bonitinho, igual o cvsnotify que eu já usava a alguns anos. Encontrei o SVN::Notify, feito em Perl e fui todo feliz e contente instalar em Windows. Não funcionava nem com reza brava.

Entrei em contato com o autor e ele me respondeu: Windows? Eu não tenho o menor interesse de fazer o script funcionar em Windows. Se quiser, faça você mesmo.

Foi o que eu fiz. Baixei o fonte, e com toda a minha habilidade de programar em Perl (praticamente nula), corrigi o script. Fiz um “patch”, porque não tinha direito de commit no repositório dele e ele aceitou a modificação. Foi minha primeira contribuição para um projeto open source. Recentemente, instalei um novo servidor SVN e usei novamente o SVN::Notify. Fiquei feliz da vida por saber que ele ainda funcionava em Windows.

Spring.NET

Em 2007, trabalhei num projeto em Spring.NET. Como todo early adopter, tive problema com um bug. Baixei o código-fonte e rapidamente consegui rastrear que era um bug.

Entrei em contato com a lista de discussão dos desenvolvedores e rapidamente o problema foi reconhecido como um bug e registrado no issue tracker. No mesmo dia, recebi um patch com uma correção paliativa do problema e um mês depois a versão oficial foi lançada, incorporando a correção final.

FluentCodeMetrics e MSBuild.Community.Tasks

O FluentCodeMetrics é uma biblioteca .NET para ajudar na extração de métricas de código e o MSBuild.Community.Tasks uma biblioteca de tasks para o MSBuild.

Em ambos os casos foram algumas contribuições bem simples em situações que foi muito mais simples eu contribuir para um projeto já existente do que tentar criar outro e popularizá-lo.

Por serem repositórios hospedados no Git Hub, seguem o fluxo do próprio Git Hub: Você faz uma cópia do repositório para você (Fork), altera o seu repositório, entrega a contribuição no seu repositório no Git Hub (push) e avisa o autor que existe uma contribuição ali e pede pra ele pegar sua contribuição (Pull Request). Se ele quiser, ele incorpora no repositório principal.

Alguns exemplos de pull request: Issue corrigida no FluentCodeMetrics e Nova task GitVersion no MSBuild.Community.Tasks.

Jenkins

Essa é uma contribuição simples e recente, mas que ilustra um pouco do espírito de organização dos times open-source. O Jenkins é um servidor de integração contínua, provavelmente um dos mais populares e mais usados. Por isso provavelmente a melhor organização.

Encontrei um bug num dos seus plugins (build pipeline) que estava me atrapalhando um pouco. Consultando no issue tracker deles, percebi que já existia um bug aberto sobre o assunto.

Eu não sou especialista em Java, mas de nada custava dar uma olhadinha no Bug. Baixei um netbeans, fiz o fork do repositório no git hub, em algo em torno de 2h consegui encontrar o bug e corrigi. Fiz o pull request.

O supreendente é o comentário que veio no pull request: plugins » build-pipeline-plugin #82 SUCCESS. This pull request looks good.

Rapidamente percebi que o meu pull request, disparou um processo de integração contínua, que roda num Jenkins na nuvem. Lá, os testes unitários e de aceitação foram executados e o serviço automaticamente comentou o pull request avisando que ele “parece bom”. Mesmo assim, o pull request não subiu imediatamente para o repositório oficial. Na seqüência um colaborador do time do Jenkins fez o merge.

Como é a organização do seu time?

Conversando com diversos profissionais na área, percebemos que o uso eficiente de uma ferramenta de controle de versão infelizmente é algo ainda raro, integração contínua um desejo e testes unitários e de aceitação um tabu.

É claro que existem times que praticam tudo o que foi visto nesse exemplo do Jenkins assim como existem projetos open-source de uma pessoa só ou abandonados, mas se investigarmos um pouquinho mais, veremos que na maioria dos projetos mais ativos open-source, essas práticas são requisitos básicos para garantir a qualidade do produto final. Isso me faz acreditar, empiricamente, que a organização de times open-source é muito superior que a média, servindo de referência para times grandes, complexos e geograficamente distribuídos.

Mesmo em empresas que diferentes times de desenvolvimento conduzem produtos diferentes e um encontra problemas ou oportunidades de melhoria no código do outro, nunca vi um mecanismo como os pull requests do Git Hub para simplificar o processo de proposta e aceitação da correção ou melhoria.

E o suporte?

Sempre que surge uma discussão sobre adotar ou não open source, esse ponto é colocado na pauta. E o argumento mais utilizado é: Eu prefiro pagar para usar o software porque posso processar alguém se algo der errado.

Já ouvi isso incontáveis vezes. Em todos os exemplos que citei acima, consegui resolver o problema por conta própria. As razões disso são muito simples:

  • Projetos open-source são muito utilizados. A quantidade de informações existentes em blogs, sites de perguntas e respostas com o Stack Overflow é impressionante. Ferramentas pagas, de menor utilização possuem menos material de referência
  • Projetos open-source possuem listas de discussão ativas. Todas as vezes que tive algum problema e o comuniquei de forma respeitosa e com evidências em listas de desenvolvimento, fui prontamente atendido.
  • Ter o código fonte em mãos simplifica a localização e correção de bugs
  • Se tudo mais der errado e o grupo de desenvolvedores sumir, você pode dar continuidade na manutenção do código-fonte e outro grupo provavelmente o fará

Além desses pontos, vale lembrar que muitas ferramentas open-source possuem empresas que dão suporte comercial. Existe também muitas gigantes que embarcam software open-source junto com partes de software comercial. É o caso da IBM que utiliza Eclipse (open source) como base para a interface de diversos de seus produtos (toda a suite Rational por exemplo) e o caso da Oracle que a algum tempo atrás embarcava o servidor http Apache como parte de alguns de seus produtos (não sei ao certo se ainda é assim).

Na contramão, tive duas experiências muito interessantes com suportes comerciais de gigantes de software. Obviamente não vou citar o nome das empresas.

Numa situação, estávamos desenvolvendo uma aplicação em cima de uma API e tivemos problemas na utilização desta API. Acionamos o suporte “gold” que tínhamos direito e após umas duas semanas, o problema escalou para o segundo nível, sem solução. Após um mês, para o terceiro nível. Depois de um mês brigando com o bug, acabei encontrando sozinho a causa raiz dele e uma solução de contorno. Resolvi não comunicar o suporte que tinha encontrado a solução, para ver quanto tempo demorariam para me dar um retorno. Após 3 meses acompanhando a situação sem receber qualquer resposta, desisti de acompanhar o problema.

Numa outra situação, encontrei um bug no driver de um produto. Entrei em contato com o suporte e a primeira reação deles foi tentar desqualificar o bug, dizendo que o driver não fazia parte do produto, logo, não dariam suporte. Após convencê-los que o problema estava numa DLL fornecida no pacote de instalação do cliente do produto, se convenceram. A segunda reação foi argumentar que não era um bug. Após enviar uma boa quantidade de traces que não deixavam qualquer dúvida sobre a existência do problema, continuei não recebendo nenhum bug fix, patch ou correção. Após cada pedido de solução uma nova quantidade de traces era pedida. Desisti de acompanhar o problema após 5 meses de discussão e conseguir uma solução de contorno que não resolve totalmente o problema. Apenas faz com que ele ocorra com uma incidência menor.

Em todas essas situações que vivi, nunca vi qualquer intenção de processar qualquer um dos fornecedores pelos prejuízos causados.

Por outro lado, cada vez mais vemos gigantes que sempre tiveram fama de serem “fechadas” como a Microsoft, com iniciativas estratégicas baseadas em open source. Com o objetivo de aproveitar os feedbacks e contribuições da comunidade de desenvolvedores, a Microsoft abriu o código fonte de alguns de seus projetos, como o Signal R e também o projeto Roslyn. O Roslyn é simplesmente a plataforma de compiladores C# e VB.Net (!).

Conclusão

O modelo de software open-source (com e sem fins lucrativos) está presente e em pleno crescimento. Cada vez mais soluções open-source são adotadas em cenários críticos e não críticos.

Algumas empresas estão visualizando o diferencial competitivo que o modelo oferece, tanto empresas consumidoras de TI, com o objetivo de minimizar custos ou obter melhor valor agregado nos serviços quanto empresas fornecedoras de TI, com o objetivo de acelerar o desenvolvimento (usando componentes) como prestar serviços baseado em plataformas open. Outras empresas continuam resistindo ou mesmo ignorando o modelo. Acredito que a maioria delas por pura falta de conhecimento sobre bons cases de sucesso utilizando ferramentas open e desconhecimento do modelo de operação/desenvolvimento.

Pelas experiências que já passei, recomendo sempre considerar a utilização de ferramentas open, levando em consideração as questões levantadas no post como licença, suporte, “quem está por trás” do projeto e quem utiliza o projeto (cases). Em resumo, ter as mesmas preocupações que temos quando vamos fazer qualquer investimento.

Integrações entre Sistemas – Parte 16 – Consumo de Web Services Multi-Thread

Introdução

Uma das abordagens comumente usadas para diminuir o tempo total na integração é utilizar várias threads no consumo do serviço. O objetivo é compensar a espera por I/O paralelizando o processamento.

O objetivo desta parte da série (que eu nunca imaginava que chegaria na parte 16) é comparar este método com as demais abordagens.

Alterações no código

O servidor utilizado é o mesmo da parte 4, método síncrono normal. No cliente, tivemos algumas alterações:

        public override bool Execute()
        {
            Binding binding;

            if (this.EndpointType == "http")
            {
                binding = new CustomBinding();
                ((CustomBinding)binding).Elements.Add(new TextMessageEncodingBindingElement(MessageVersion.Soap11, Encoding.UTF8));
                ((CustomBinding)binding).SendTimeout = new TimeSpan(0, 50, 0);
                ((CustomBinding)binding).ReceiveTimeout = new TimeSpan(0, 50, 0);
                ((CustomBinding)binding).OpenTimeout = new TimeSpan(0, 50, 0);
                ((CustomBinding)binding).CloseTimeout = new TimeSpan(0, 50, 0);
                HttpTransportBindingElement element = new HttpTransportBindingElement();
                element.MaxReceivedMessageSize = 2048 * 1024;
                element.KeepAliveEnabled = false;
                element.RequestInitializationTimeout = new TimeSpan(1, 0, 0);
                ((CustomBinding)binding).Elements.Add(element);
            }
            else if (this.EndpointType == "nettcp")
            {
                binding = new NetTcpBinding();
                ((NetTcpBinding)binding).MaxReceivedMessageSize = 1024 * 1024;
                ((NetTcpBinding)binding).Security.Mode = SecurityMode.None;
                ((NetTcpBinding)binding).CloseTimeout = new TimeSpan(0, 50, 10);
                ((NetTcpBinding)binding).OpenTimeout = new TimeSpan(0, 50, 10);
                ((NetTcpBinding)binding).ReceiveTimeout = new TimeSpan(0, 50, 10);
                ((NetTcpBinding)binding).SendTimeout = new TimeSpan(0, 50, 10);
            }
            else
                throw new ArgumentException("Invalid value for EndpointType. Expected: http, nettcp");
            EndpointAddress address = new EndpointAddress(new Uri(WebServiceUri));

            IntegrationTestsService.IntegrationTestsServiceClient client = new IntegrationTestsService.IntegrationTestsServiceClient(binding, address);

            Log.LogMessage("Doing " + TotalBatches.ToString() + " batch calls with " + BatchSize.ToString() + " itens each");

            Stopwatch watch = new Stopwatch();
            watch.Start();

            int count = 1;
            ConcurrentQueue<ManualResetEvent> waitObjectQueue = new ConcurrentQueue<ManualResetEvent>();
            Task task = null;
            for (int i = 0; i < TotalBatches; i++)
            {
                int start = count;
                int end = count + (BatchSize - 1);
                count += BatchSize;
                
                if (UseTask)
                {
                    task = Task.Factory.StartNew(() => {
                        ThreadJob(client, waitObjectQueue, start, end);
                    });                    
                }
                else
                {
                    Thread thread = new Thread(() => {
                        ThreadJob(client, waitObjectQueue, start, end);
                    });
                    thread.Start();
                }
            }

            if (task != null)
                task.Wait();

            while (waitObjectQueue.Count > 0){
                ManualResetEvent e;
                if (waitObjectQueue.TryDequeue(out e))
                    e.WaitOne();
            }

            watch.Stop();
            Log.LogMessage("Total processing time: " + watch.Elapsed.TotalSeconds.ToString("0.00") + " seconds");

            return true;
        }

        private void ThreadJob(IntegrationTestsService.IntegrationTestsServiceClient client, ConcurrentQueue<ManualResetEvent> waitObjectQueue, int start, int end)
        {
            ManualResetEvent e = new ManualResetEvent(false);
            waitObjectQueue.Enqueue(e);

            ServiceTable[] stArray = client.GetServiceTables(start, end);
            foreach (ServiceTable t in stArray)
            {

                ServiceTable t2 = new ServiceTable();
                t2.ServiceTableID = t.ServiceTableID;
                t2.DescServiceTable = t.DescServiceTable;
                t2.Value = t.Value;
                t2.CreationDate = t.CreationDate;
                t2.StringField1 = t.StringField1;
                t2.StringField2 = t.StringField2;

                DAO.ProcessServiceTable(ConnString, t2);
            }
            e.Set();
        }

A propriedade UseTask, determina se o trabalho será feito numa Task ou Thread. A diferença entre usar uma task ou uma thread é explicada no post programação paralela – parte 1. Na prática, para este exemplo, vemos que não fará muita diferença na prática.

O objetivo do código é simples. Cada lote de requisições (mesmo cenário utilizado em todas as partes dessa série) é executada numa thread ou task separada. Teremos por um lado o ganho de não esperar a requisição terminar para começar outra e pelo outro o custo da troca de contexto e alocação de memória em threads (explicados na parte 2 e parte 3 da série sobre programação paralela. Outro ponto é a sobrecarga por mais processamento paralelo gerado no servidor.

Resultados

Abaixo seguem os resultados desta abordagem, executada tando em SOAP quanto em NET.TCP. O mesmo método é utilizado para computar os tempos, ou seja, são feitas 10 execuções e o tempo apresentado abaixo é a média deles.

pt16-Comparativo1

pt16-Comparativo2

Como os números mostram, o uso de threads ou tasks não faz praticamente nenhuma diferença neste caso. Minha melhor explicação para isso é que o TaskScheduler utilizado para delegar as tasks abre uma nova thread sempre que identifica que as demais estão em espera (ninguém está consumindo CPU). Como existe muito bloqueio de espera por I/O num cenário de integração destes, a Task Parallel Library acaba abrindo uma nova thread quase sempre.

Os números também mostram que o uso da abordagem async/await (parte 15 da série de integrações e parte 4 da série de programação paralela) é ~53% mais eficiente em SOAP e ~39% mais eficiente em NET.TCP.

Código fonte

O código fonte dos exemplos está atualizado no Git Hub: https://github.com/ericlemes/IntegrationTests

Conclusão

O aproveitamento do tempo de espera por operações de I/O mostra ser a melhor maneira de aumentar o desempenho das aplicações. A implementação do padrão async/await no framework .NET, cada vez mais mostra ser uma forma extremamente simples de atingir este objetivo. Realmente é um trabalho fantástico por parte da Microsoft.

Levantamento de requisitos e SCRUM

Introdução

Um dos posts mais visitados no blog, já bem antigo, é sobre levantamento de requisitos.

Neste post, eu falo um pouco das técnicas que usava para levantar bons requisitos, sempre com uma visão muito focada em metodologias fortemente apoiadas em documentos.

O objetivo deste post é mostrar como a visão ágil me fez pensar de forma diferente em relação a requisitos.

Por que levantamento de requisitos?

Neste ponto, continuo mantendo meu ponto de vista do artigo anterior. Não adianta sair construindo algo que não se sabe exatamente o que é e ainda acredito que a grande maioria dos problemas na área de desenvolvimento de software está em compreender de forma errada os requisitos.

As técnicas de elicitação de requisitos servem para promover o exercício e o entendimento da necessidade do cliente antes de sair construindo.

No meu ponto de vista, nada disso muda nas metodologias ágeis.

As críticas à documentação exaustiva de requisitos

Todas as vezes que eu tentava implementar a filosofia descrita no artigo anterior sobre levantamento de requisitos, sempre sofria algumas críticas. As mais comuns eram:

  • Como você tem certeza que documentou tudo?
  • Como você tem certeza que nada vai mudar?

Minhas respostas mais comuns sempre foram: você não tem certeza que documentou tudo, mas vamos pensar que você conseguiu cobrir 70-80% das necessidades. É bem melhor do que os 0% que tinha antes.

Sobre as mudanças, não existe certeza. A técnica apenas permite melhor rastreabilidade das mudanças. Sempre que um requisito muda, o exercício de replanejar e rediscutir o escopo deve ser realizado.

A receptividade à mudança no modelo Waterfall

Quando trabalhamos no modelo waterfall, geralmente todo o levantamento de requisitos vem antes. No início do projeto, mas após ser dada a data do final do projeto. Sabemos que temos, por exemplo, 2 meses pra levantar requisitos, que o projeto deve ser entregue em 6, mas ainda não fizemos um levantamento exaustivo de requisitos.

Nessa fase, fazemos o levantamento exaustivo e colocamos num grande documento, ou em um grande conjunto de casos de uso e pedimos a validação do cliente. O cliente valida, muitas vezes sem se aprofundar nos documentos e sem ver absolutamente nada construído.

Começamos a fase de construção e geralmente quando começamos a mostrar algo funcionando para o cliente, já estamos próximos do fim da fase de construção, ou no início da fase de homologação.

Não é raro neste momento observamos a reclamação clássica do cliente: “preciso de mudanças, porque quando vemos o software materializado é que começamos a entender o que realmente precisamos”.

Isso gera um tamanho desconforto na equipe. O desconforto ocorre porque o exercício de mudança no modelo cascata é muito grande. Sempre que um requisito muda, deveríamos rever o cronograma e renegociar o prazo. Toda mudança no cronograma deveria passar por esse ciclo de reestimar, reamarrar todas as dependências das atividades e renegociar um prazo, mas tudo isso é tão lento e as mudanças são tão constantes no escopo dos projetos que é muito fácil perder o controle. Acabamos deixando a maioria das coisas registradas como “issues” ou “melhorias” que ou entrarão numa fase 2, ou acabam sendo construídas no meio da fase de teste.

O que acontece é que a data final, cravada em pedra. raramente muda e as mudanças de escopo são absorvidas ao custo de um alto stress e baixa qualidade.

Trabalhando por contrato

O grande risco que se corre ao utilizar uma documentação de requisitos extensa é trabalhar por contrato. Na prática, o cliente pede uma mudança e logo a equipe aponta: Mas nós fizemos o que está no documento e você aprovou.

Na minha opinião, é justo. A equipe fez o trabalho dela, mas o cliente é atendido desta maneira?

Qual é nosso objetivo? Não errar ou atender o cliente?

Incertezas

A grande sacada do SCRUM está em lidar melhor com as incertezas. E existe algo mais incerto do que um projeto de software? A maioria dos novos softwares desenvolvidos são inovações tecnológicas, uso de tecnologias modernas, implementar um novo processo, uma nova forma de trabalho.

No modelo cascata, partimos do princípio que sabemos tudo de antemão. É algo como querer prever o futuro. Uma grande verdade é desprezada durante o decorrer do projeto: As pessoas aprendem sobre o domínio de negócio, sobre o produto durante o projeto.

Se logo durante as primeiras entregas, conseguimos identificar que muitas das premissas tanto de negócio quanto de TI estavam erradas, por que insistimos em continuar pelo mesmo caminho? Por que não aproveitamos esse feedback para corrigirmos a rota?

Como o SCRUM lida com incertezas

Quando fazemos uma estimativa de complexidade (planning poker) para entregar uma estória, não temos lá muitos detalhes sobre o que de fato ela faz, tampouco como construiremos ela.

Quando essa história entra numa sprint, é que começa o trabalho de levantamento de requisitos, porém, ele é específico para aquela história, para aquela funcionalidade. Não é um exercício longo e extenso para todo o projeto. Se nesse momento, observamos que a estória não está madura o suficiente para ser construída, temos a chance de repriorizar, ou mesmo de definir a meta da sprint como um protótipo ou uma prova de conceito para definir uma melhor abordagem para lidar com esse requisito.

Neste momento, as mesmas técnicas utilizadas para a elicitação de requisitos podem ser usadas, porém, o foco é somente para aquela estória.

Muitas pessoas confundem e acham que o modelo ágil significa desprezar toda a técnica e a documentação e sair aplicando um eXtreme Go Horse. Na verdade o que a metodologia propõe é um constante exercício de valor e priorização: O que é mais importante ser feito primeiro? O que retorna mais valor para o cliente?

Se percebemos que o que retorna mais valor para o cliente é o requisito mais incerto, devemos sim começar a construí-lo primeiro, para rapidamente ajudarmos o cliente a materializar a idéia e assim dar o conforto necessário para continuar a construção ou partir para uma abordagem diferente.

Com isso, entrega-se dentro do horizonte de uma sprint um produto funcionando e a melhor materialização dos requisitos existentes, dadas as restrições de prazos e recursos. Para a próxima sprint, qualquer alteração é bem-vinda. Os requisitos são revistos, são aprimorados e o feedback é constantemente utilizado para construir um melhor produto. Dessa forma, o SCRUM aproveita o aprendizado que ocorre durante o projeto.

Que artefatos usar para documentar?

Particularmente eu acho uma documentação de produto mais valiosa do que uma documentação de projeto. Qual a diferença entre as duas coisas?

A documentação de produto, descreve como o software, a aplicação funciona. Ela é mantida e evolui junto com o software. A documentação de projeto, geralmente um caso de uso, representa o que precisa ser feito naquele projeto. Terminou o projeto ela tem pouco valor, porque a linguagem nela utilizada está muito longe de ser uma documentação de sistema.

O ponto é, se os ciclos são extremamente curtos (2 a 4 semanas) pra fazer um produto funcionando, precisamos de uma documentação de projeto?

Muitas vezes documentações simples e rápidas como protótipos feitos à mão, uma descrição da funcionalidade na página wiki é mais que suficiente para atingir o objetivo da sprint.

A prática que acho válida é sempre manter em cada sprint atividades para realizar a documentação de produto, ou seja, pegar as principais abstrações e questões técnicas e documentar e também criar o manual do usuário para a nova funcionalidade construída. A melhor ferramenta pra isso na minha opinião é a Wiki, por sua natureza rápida e colaborativa.

Conclusão

A única certeza que eu tenho em projetos de software é que os requisitos mudam. Continuo achando que as técnicas de elicitação de requisitos são importantíssimas para construir software com melhor assertividade, mas defendo que a documentação não deve ser mais importante do que software funcionando.

A própria filosofia de constante inspeção e receptividade às mudanças ajuda a mitigar o risco dos requisitos mal levantados, da documentação ambígua e da dificuldade de comunicação nos projetos. O principal benefício, na minha opinião, é utiliza o aprendizado que ocorre durante o projeto.

A ausência de “time boxes” na metodologia waterfall e o trabalho por contrato ajudam a perpetuar e insistir em requisitos que já não traduzem a necessidade do usuário, contribuindo para a criação de um ambiente de trabalho de conflitos e desprezando todo o aprendizado que é adquirido durante um projeto.

Slides do TDC 2013

Abaixo segue o link dos slides da minha palestra no TDC 2013: http://www.slideshare.net/ericlemes9/tdc-2013-eric-lemes-integracoes-entre-sistemas2. Obrigado a todos que assistiram, comentaram e contribuiram com a discussão.

Gostaria de aproveitar para compartilhar as experiências sobre o evento:

  • Gostei bastante da palestra do Rafael Barbosa Camargo (@rafajagua). Ele passa por diversos skills que um scrum master deve ter e também uma bela lista de leituras de referência sobre o assunto. Slides: http://www.slideshare.net/mobile/rafajagua/corra-scrum-master-corra-para-saber-mais
  • Outra palestra muito bacana do Victor Hugo Germano (@victorhg). Ele compartilhou experiências práticas de diversos projetos ágeis que vivenciou. Ainda não tenho os slides.
  • Coisas técnicas aos montes: Coisas novas no MVC (do Giovanni Bassi e Victor Cavalcante), bastante coisa sobre REST e Web API (Waldir Felix), Migrations (do Vinicius Hana)

Mas além das palestras, o que vale muito a pena é reencontrar o pessoal, trocar idéias. Conversei com muita gente legal (já mandei diversos agradecimentos pelo tweeter), troquei bastante experiência e voltei com várias idéias na cabeça, assim como bastante coisa nova pra estudar. Senti falta das figurinhas carimbadas Elemar Jr. e Leandro Daniel, mas não faltarão oportunidades.

Fica meu agradecimento especial pra Yara e Vinicius Senger por toda a garra pra organizar esse baita evento. 4 dias de evento não é fácil não. Valeu!

Que venha o próximo!

TDC 2013

É com grande alegria que anuncio que minha palestra foi aceita no TDC 2013!

Estarei palestrando na trilha Arquitetura .NET no dia 10/07. Pretendo também comparecer no sábado, 13/07 para prestigiar outras temas interessantes do evento.

Quem me encontrar por lá e acompanhar o blog, fiquem à vontade para perguntar, trocar idéias, criticar, etc. O objetivo é esse mesmo.

Neste ano, estarei apresentando o tema “Integrações entre Sistemas”, onde abordarei muito do aprendizado que tive realizando esta série aqui no blog e também a correlação deste tema com SOA e arquitetura corporativa.

Espero vocês por lá!!