Bug no cliente FTP do Windows

2007-11-29

Dizem que uma imagem vale mais que mil palavras, então vejam esta:

Pra quem não se deu ao trabalho de entender, o enredo é o seguinte. Estou numa janela de comandos do Windows e num diretório que contém um arquivo chamado file.txt contendo oito bytes. Daí eu invoco o comando de linha “ftp” e me conecto a um servidor remoto. Verifico que não existe no servidor FTP um arquivo com o mesmo nome e me engano usando o comando “get file.txt” ao invés do “put file.txt”.

A mensagem de erro “550 file.txt: No such file or directory” é bastante clara e indica exatamente o que eu fiz de errado. Mas… ao sair do comando ftp e listar o conteúdo do diretório local sou surpreendido ao ver que o arquivo file.txt foi truncado e está com zero bytes!

Parece que quando fazemos um “get” no ftp do Windows ele abre o arquivo pra escrita antes de verificar se o arquivo existe no servidor FTP. Nesse caso, a abertura pra escrita trunca o arquivo local e o deixa com tamanho 0.

Um colega me disse que no Windows 98 e no Windows 2000 o arquivo local é removido do diretório. O exemplo acima foi executado num Windows XP, que não remove o arquivo mas o deixa vazio. Parece que eles estão melhorando… alguém pode testar no Windows Vista pra ver se já está corrigido? 🙂

Em tempo, testei na minha máquina Linux (Kubuntu 7.04) e o problema não ocorre.

Anúncios

O Futuro é Wiki

2007-11-29
É o título de um artigo muito interessante do professor Milton Campanário da FEA-USP.

Ele comenta os assuntos tratados em dois best-sellers recentes: Wikinomics e The Wealth of Networks. Quem se interessa por economia, inovação, software livre, propriedade intelectual ou produção colaborativa, vale a pena conferir.


Ruby on Rails

2007-11-22
Assisti ontem a uma palestra excelente sobre Ruby on Rails. É a terceira ou quarta palestra sobre RoR a que eu assisto. Descontando a do próprio David Hansson a que eu assisti no FISL 6.0 esta foi a mais detalhada e interessante. A impressão que eu tive depois de conversar com algumas das 30 pessoas que estavam lá é que o Bill Coutinho da Dextra conseguiu entusiasmar várias delas.

Além dos tutoriais tradicionais e da geração automática de código (scaffold!) o Bill apresentou uma perspectiva mais atual e mais madura sobre a utilização do framework. Alguns pontos que o Bill ressaltou na palestra:

  • A Dextra mediu um incremento de 100% na produtividade nos primeiros projetos RoR executados por programadores com experiência em Java.
  • Programadores Java têm pouca dificuldade em aprender Ruby e RoR.
  • O JRuby permite rodar
    aplicações RoR dentro de servidores de aplicação Java como o Tomcat e o
    JBoss, o que possibilita a integração de uma interface web RoR com
    bibliotecas Java.
  • RoR é ótimo para desenvolver aplicações web baseadas em bancos de dados. Fora disso, use outra coisa.
  • Programar em Ruby é muito mais legal que programar em Java. 🙂

Google Android

2007-11-13
Há um artigo interessante sobre lançamento do SDK do projeto Android do Google. Pra quem ainda não viu, o Android é uma plataforma aberta para dispositivos móveis baseada em Linux e Java.

O Google junto com outras 34 empresas formaram o Open Handset Alliance pra desenvolver esta tecnologia que parece que vai estar disponível comercialmente no segundo semestre de 2008.

O autor do artigo já está chamando o Android de tecnologia de ruptura. Será?


SGBDs orientados a colunas

2007-11-12
Semana passada assisti a uma palestra do Eduardo Sato da Sybase na qual ele explicou a tecnologia por trás do Sybase IQ, um banco de dados relacional usado em ambientes analíticos, como data warehousing e aplicações de Business Intelligence em geral.

A tecnologia em questão se chama column-oriented DBMS e é essencialmente uma forma não-tradicional de armazenar os dados das tabelas em disco. Normalmente, os dados de uma tabelas são armazenadas por linhas, i.e., todos os campos de uma linha são armazenados de maneira contígua no disco. Já num SGBD orientado a colunas os dados de uma tabela são armazenados por coluna, i.e., todos os campos de uma coluna da tabela são armazenados de maneira contígua.

Essa diferença aparentemente trivial modifica totalmente as características de desempenho do banco de dados. O armazenamento por linhas é ideal para acessos de linha inteira. Pense num insert ou num update que modifique todos os campos da linha. Ou mesmo, num select *. De fato, a forma de armazenamento por linha é a que garante melhor desempenho para a maioria das aplicações transacionais.

Agora pense num ambiente analítico, no qual os inserts e updates são quase inexistentes e a maioria absoluta das consultas são de selects. Normalmente, as tabelas usadas nestes ambientes são “tabelões”, com um grande número de colunas, resultado da agregação de várias tabelas extraídas de sistemas transacionais, planilhas e arquivos texto. Além disso, em ambientes analíticos é comum ocorrerem consultas ad hoc para as quais não se pode planejar a manutenção de índices e que acabam resultando muitas vezes na necessidade de full scans nas tabelas para executar a consulta.

O exemplo concreto que o Eduardo Sato usou na palestra pra explicar os ganhos que podem ser obtidos envolvia uma tabela com 10 milhões de linhas de 800 bytes cada uma. Considerando uma representação em disco usando páginas de 16KB, pra fazer um full scan nesta tabela seriam necessários 500 mil I/Os. Se esse full scan tivesse sido motivado por um select envolvendo apenas três colunas da tabela, usando uma representação em colunas poderia reduzir o número de I/Os para apenas 234. (Não é 234 mil. É 234 unidades!)

Além do ganho de eficiência nos selects, a representação em colunas também consegue ser mais compacta que a representação em linhas. Uma razão é que os campos NULL podem ser indicados pela mera ausência, ao passo que na representação em linhas eles precisam ser indicados por um código explícito. Outra razão é que é muito mais fácil compactar dados de um tipo único que dados de múltiplos tipos, como ocorre na representação em linhas.

Ainda outra vantagem da representação em colunas é que as alterações de esquema são muito mais fáceis e rápidas. Afinal é muito mais fácil inserir, remover ou alterar uma coluna quando ela está armazenada de forma contígua que quando seus dados estão “espalhados” pelas linhas da tabela.

O Sybase IQ não é a única implementação desta tecnologia. A página da wikipedia mostra uma lista de implementações concorrentes. Achei duas promissoras: o MonetDB e o Vertica.


Evidence Based Scheduling

2007-11-08

Eu não acredito em cronogramas, mas que eles existem, existem. Bem, nem todo cronograma é furado… os ferroviários ingleses que o digam. 🙂

O Joel Spolsky, que é um cara inteligente e experiente, diz que os desenvolvedores de software em geral não gostam de fazer cronogramas por duas razões. Primeiro, porque é um saco. Segundo, porque ninguém acredita mesmo que o cronograma seja realístico.

Mas, como dono de uma empresa de software, o Joel deve ter seu “lado administrador” sempre procurando encontrar uma forma de “controlar as coisas”. Sabe como é: planejamento, planilhas, cronogramas…

O fato é que ele bolou um novo método de produzir cronogramas baseado no método de Monte Carlo e conseguiu me fazer acreditar que funcione. Ele chamou o método Evidence Based Scheduling, ou EBS, que parece bastante apropriado.

Para os que gostam (e principalmente para os que, como eu, não gostam) de cronogramas, eu sugiro a leitura do artigo em que o Joel explica detalhadamente o método. Para os demais (hã?) aqui vai um resumo:

O início não tem novidade. O grupo de desenvolvedores que vai trabalhar num projeto faz uma WBS detalhada do mesmo, quebrando-o em atividades de, no máximo, 16 horas. Cada atividade é atribuída a um desenvolvedor e é ele quem decide o tempo que vai levar para executá-la.

Todas as estimativas devem ser registradas e associadas ao desenvolvedor que as fez. É importantíssimo que cada desenvolvedor registre também o tempo que ele efetivamente gastou na execução das tarefas. Deste modo, ao longo do tempo, vai-se acumulando informações sobre a capacidade de “estimação” de cada desenvolvedor.

Depois de algum tempo, é possível plotar um gráfico para cada desenvolvedor, correlacionando suas estimativas com suas respectivas execuções. A idéia é que “estimadores” experientes tendem a cometer sempre os mesmos erros. Já estimadores inexperientes tendem a variar bastante nos seus erros.


De posse desse histórico e do conjunto de estimativas da WBS do novo projeto, o sistema gera 100 simulações diferentes usando, cada vez, um valor aleatório do histórico de erros passados de cada desenvolvedor para projetar o tempo de execução efetivo de cada atividade. O resultado dessas 100 simulações é um gráfico mostrando a probabilidade de que o projeto termine em um intervalo de datas dentro do qual caíram todas as 100 simulações.


O que é bacana neste método é que ele não determina uma data mágica, mas sim um intervalo de datas com probabilidades geradas a partir do histórico de sucesso de cada desenvolvedor individualmente.

O artigo original mostra várias outras vantagens do método e sugere algumas técnicas gerais para tornar o exercício mais previsível. Vale realmente a pena lê-lo.

Eu estou convencido de que o método tem mérito, mas isso não quer dizer que ele funcione. É óbvio que ele depende fortemente de que os desenvolvedores registrem suas estimativas e suas execuções o mais fielmente possível e também que produzam muitas estimativas pra aumentar a qualidade do histórico. Mas mais que tudo, o método supõe que a capacidade de estimativa dos desenvolvedores tenda a se estabilizar à medida em que eles ganham experiência. Isso parece fazer sentido, mas não conheço estudos empíricos que validem esta suposição.

Outra coisa importante é que não dá pra fazer as simulações na mão. É preciso usar um sistema que automatize o processo. Mas o Joel cuidou disso também. Ele adicionou um módulo de EBS no FogBugz 6.0, a nova versão da sua ferramenta de gestão de projetos. 🙂


Banda e latência

2007-11-08
Uma colega me procurou dizendo que alguns usuários estão enfrentando um sério problema de lentidão no acesso a um sistema web remoto. Cada transação neste sistema, desde o login até o logout, está demorando da ordem de 50 segundos. A reclamação já foi submetida aos administradores do sistema remoto que fizeram seus testes e disseram que os clientes locais conseguem executar as mesmas transações em dois segundos. Parece óbvio que se trata de um “problema de rede”. Mas, a sugestão imediata dos administradores, de “aumentar a banda” do nosso acesso à Internet, pode não resolver o problema.

Como este é um problema comum, resolvi registrar aqui o email que enviei pra colega, pra poder reutilizá-lo no futuro quando outro problema semelhante aparecer. (Personagens e cenários foram modificados para proteger os inocentes. 🙂

De fato, o aumento no tempo de acesso parece ser devido às diferentes situações de conectividade de rede entre o cliente e o servidor do sistema. Contudo, nem sempre um aumento de banda resolve esse tipo de problema.

Há duas características de rede que podem influenciar o tempo de resposta de uma transação: banda e latência. Banda é a quantidade de informação que a rede pode transportar por unidade de tempo e latência é o tempo que uma unidade de informação leva pra transitar pela rede de um ponto a outro.

Numa rede local trabalhamos com bandas da ordem de 100Mb/s à 1000Mb/s e latências da ordem de 1ms. Quando trabalhamos com a Internet, tratamos de bandas da ordem de 1Mb/s a 10Mb/s e latências da ordem de 100ms. Ou seja, a banda que temos pra acessar a Internet é 100 vezes menor que a banda de uma rede local e a latência é 100 vezes maior.

Essas duas características influenciam as transações de um sistema de modos diferentes. Há sistemas em que as transações são demoradas e transportam grandes volumes de dados. Imagine um repositório FTP em que as transações são o envio e a recepção de arquivos. Este tipo de sistema é bastante afetado pela banda disponível mas muito pouco afetado pela latência. Pra baixar um arquivo de 1GB da Internet leva mais de duas horas enquanto pra baixá-lo de um servidor local leva só dois minutos.

Outros sistemas são mais afetados pela latência. Imagine que ao invés de o cliente FTP fazer uma requisição para o arquivo inteiro ele precisasse fazer uma requisição para cada bloco de 1MB de dados. O mesmo arquivo de 1GB teria que ser solicitado em 1000 pedacinhos. Imagine também que cada pedaço tivesse que ser recebido antes que o próximo pudesse ser solicitado. Nesse caso, a latência passa a ser mais importante. Se numa rede local com o FTP normal o arquivo pode ser baixado em dois minutos, numa rede com a mesma banda mas com uma latência de 100ms, como ocorre na Internet, a transferência do arquivo levaria 100 segundos a mais devido ao tempo necessário para cada uma das 1000 solicitações de 100ms cada.

Tendo isso em mente é importante analisar o padrão de comunicação do sistema pra determinarmos se a lentidão quando o acesso é via Internet é determinado pela redução de banda ou pelo aumento da latência da rede. Se o padrão de comunicação for determinado por poucas requisições com grande transferência de dados então realmente o aumento na banda pode melhorar a situação. Mas se o padrão for determinado por muitas requisições pequenas, então o aumento de banda não deverá ter efeito significativo.

O ruim nisso tudo é que as soluções na camada de rede ou são caras (aumento de banda) ou inexistentes (não há como reduzir significativamente a latência na comunicação a longa distância).

Eu gostaria de simular o acesso ao sistema pra poder capturar os pacotes de rede e analisá-los pra poder verificar o padrão de comunicação. Parece-me pouco provável que uma aplicação destas tenha grandes volumes de dados trafegando entre cliente e servidor. Não conheço o sistema, mas as aplicações web mais modernas têm incorporado uma série de melhorias na interface utilizando uma tecnologia chamada AJAX. Com ela é possível que entre um clique explícito e outro do usuário o navegador dispare um grande número de requisições HTTP implícitas, o que pode tornar estas aplicações mais sensíveis a um aumento da latência da rede.

Mas isso é apenas conjectura. Se você conseguir um acesso ao sistema e um roteiro de teste eu posso tentar analisar seu padrão de comunicação pra ver se identificamos mais exatamente o problema.

Eu me lembro de ter lido um artigo muito bom sobre isso numa edição antiga da ;login:. Não consegui encontrá-lo, mas achei um outro artigo interessante do Brent Chapman sobre isso. O mais engraçado é que ele resolveu postá-lo exatamente pra poder reutilizá-lo quando tivesse que explicar o mesmo problema no futuro. 🙂