segunda-feira, 23 de janeiro de 2012

Haja Produtividade

Quando for fazer um projeto pra nuvem, lembre-se de acrescentar no cronograma uma gordurinha extra por conta dos deploys da aplicação. Olha um log de deploy de um projeto Cloud no VS2010:


16:22:27 - Warning: There are package validation warnings.
16:22:28 - Preparing...
16:22:28 - Connecting...
16:22:31 - Uploading...
16:30:31 - Creating...
16:31:41 - Starting...
16:32:16 - Initializing...
16:32:16 - Instance 0 of role _____________ is initializing
16:32:16 - Instance 0 of role _____________ is initializing
16:36:12 - Instance 0 of role _____________ is busy
16:36:12 - Instance 0 of role _____________ is busy
16:37:19 - Instance 0 of role _____________ is ready
16:37:52 - Instance 0 of role _____________ is ready
16:37:54 - Complete.

16:22 pra 16:37... só 15 minutos esperando o deploy :-P Tá me lembrando a época da bolsa de computação gráfica da UnB, que a gente mandava compilar o aplicativo e demorava 5 minutos. Aí testava, corrigia alguma coisa e mais 5 minutos pra compilar. Haja produtividade ;-)

sexta-feira, 20 de janeiro de 2012

"Unable to load the specified metadata resource", ou "Como perder 2 dias por causa de um asterisco"

Mais uma pra pilha "Azure - Mais Um Detalhe De Desenvolvimento". Resolvemos migrar as tabelas de uma aplicação Azure do ATS para o SQL Azure.
OBS1: Se você vai começar seu projeto agora, *não* use o ATS como um banco relacional. A lista de problemas é tão grande que não vou nem colocar aqui.
Bem, fizemos os testes locais e tudo rodou tranquilo.
OBS2: Conselho para desenvolvimento no Azure: "Não escreve muito código sem um deploy e teste na nuvem". Os Compute/Storage Emulators e a nuvem tem vários comportamentos e particularidades diferentes entre si. Desenvolva um trecho, estabilize o suficiente para um teste, e faça um deploy na nuvem para teste lá. Obrigado ao Vitor por emprestar a frase.
Na hora que passamos para a nuvem, no primeiro acesso ao BD no SQL Azure, aparecia uma exceção "Unable to load the specified metada". Resumindo (muito), a estória é a seguinte:

  1. Nossa camada de dados é uma DLL separada (AcessoDados.dll), que contém um modelo Entity Framework apontando para o BD no SQL Azure, e mais um tanto de código customizado.
  2. A aplicação tem um web role e um worker role. Esta DLL é referenciada por ambos, já que ambos manipulam as mesmas tabelas.
  3. A string de conexão ao modelo EF começa assim:
    connectionString="metadata=res://*/Entidades.BDAplicacao.csdl|res://*/Entidades. BDAplicacao .ssdl|res://*/Entidades.BDAplicacao.msl; ...". Estes arquivos são necessários para o Entity Framework realizar o acesso ao banco de dados representado pelo modelo.
  4. O modelo EF tem uma propriedade chamada "Metadata Artifact Processing", que por default vale "Embed in Output Assembly". Isto significa que os 3 arquivos na string de conexão (BDAplicacao.csdl, BDAplicacao.ssdl e BDAplicacao.msl) são incorporados à DLL como recursos durante a compilação.
A mensagem de erro indicava que, na hora que o worker role ia acessa o banco, não encontrava os 3 arquivos necessários para a geração dos comandos de acesso ao banco. Então a exceção "Unable to load the specified metadata resource" ocorria.

A string de conexão no item 3 acima é a string padrão gerado pelo Designer de Modelos Entity Framework do Visual Studio 2010. Basicamente, os asteriscos na string de conexão significam "procure estes arquivos nos recursos de todos os assemblies carregados no momento". Não sei exatamente porque, mas o fato é que o worker role, quando rodando na nuvem, não encontrava os arquivos dentro da DLL (quando rodando no Compute Emulator, tudo funcionava ok). Tivemos então que especificar o nome da DLL em vez dos asteriscos, e a aplicação passou a funcionar também na nuvem. A string de conexão ficou assim:

connectionString="metadata=res://AcessoDados/Entidades.BDAplicacao.csdl|res:// AcessoDados /Entidades. BDAplicacao .ssdl|res://AcessoDados/Entidades.BDAplicacao.msl; ...".

Mais alguns detalhes pra fechar:
  • Repare que colocamos o nome da DLL, mas não sua extensão. Caso você coloque a extensão, será gerada uma exceção "Não foi possível localizar o arquivo ...".
  • O modelo EF se chama "BDAplicacao", e está dentro de um sub-namespace "Entidades". Então veja que o nome dos arquivos não é simplemente o nome do modelo com as extensões .csdl, .ssdl e .msl; o nome dos arquivos é "Entidades.BDAplicacao"; tem que ser acrescentado o namespace ao nome dos arquivos, exceto pela parte "raiz" do namespace - que é o nome da DLL.
E aí? Pouco detalhe, né não?

segunda-feira, 26 de dezembro de 2011

Treinamento Azure: Primeira turma de Azure da Sr Nimbus!

Abrimos nossa primeira turma de treinamento Azure, voltada para o pessoal que deseja ingressar de cabeça no desenvolvimento de soluções Web para o Windows Azure. Modelamos o curso de forma que o aluno veja todos os passos necessários para sair do “File > New > Project” até realizar o deploy da aplicação. E sempre apresentando os conceitos relacionados a cada aspecto do desenvolvimento realizado.

Além desta visão “início-ao-fim”, os laboratórios criam uma aplicação que tem o SQL Azure como base de dados, e usa filas e worker roles para mostrar a escalabilidade de uma aplicação construída para tirar proveito do conceito de computação na nuvem. De quebra, a aplicação exemplo possui uma arquitetura que pode ser usada como referência para as suas primeiras aplicações Azure, de forma que você já possa ser produtivo assim que acabar o curso.

No modelo tradicional de cursos de ferramentas de desenvolvimento você vê as partes mas não o todo. É comum, neste modelo, o “momento E agora???” que o aluno passa após o curso, exatamente pela falta desta visão de um processo contínuo no uso da ferramenta. Nosso objetivo é mudar isto, ao construir uma aplicação do início ao fim e fornecer uma arquitetura simples mas que pode ser usada em aplicações “de verdade”, e não apenas em demonstrações.

A ementa do curso está aqui, e as inscrições já estão abertas!

[]s,

GB

quinta-feira, 22 de dezembro de 2011

Restrições nos nomes de filas no Azure Storage

Recebemos o erro “One of the request inputs is out of range” ao usar uma fila pra implementar comunicação entre web e worker roles rodando no Azure. Depois de revirar a Internet por algum tempo, achei esse artigo: Naming Queues and Metadata. Basicamente as regras de nomenclatura para filas são:

  1. O nome da fila deve começar com letra ou número, e só pode conter letras, números e o caracter “hífen” (-) (não é o “sublinhado”).
  2. O primeiro e o último caracter do nome deve ser letra ou número, não pode ser o hífen. Hífens consecutivos não são permitidos.
  3. Todas as letras devem ser minúsculas. (PQP. Por que não documenta isto no construtor da classe CloudQueueClient? Ou em CloudQueueClient.GetQueueReference() que recebe o nome da fila a acessar? Ou então em CloudQueue.CreateIfNotExists(), já que esse método cria a fila???)
  4. O nome da fila deve ter no mínimo 3 e no máximo 63 caracteres.

domingo, 14 de agosto de 2011

tf rollback: Como voltar os fontes para um determinado ponto do desenvolvimento

Comé que a gente volta o código da nossa aplicação pra um determinado ponto do sistema no TFS?

Bem, a ferramenta dá o suporte, mas você tem que ter processo. Tem várias formas de fazer isto. Uma delas é usando labels. Pra poder voltar em um ponto no tempo, você tem que fazer o seguinte:
  1. Combinar com a equipe. É, porque todo mundo tem que saber dessa combinação, preparar os fontes nos quais estão trabalhando para isto, e fazer checkin.
  2. Aplicar um label aos fontes. Na janela do Solution Explorer, botão direito no diretório no qual estão os fontes desejados, opção "Apply Label".
Esta label vai ser seu "ponto no tempo" para o qual você pode voltar os fontes. Depois de tocar horror no código, pra voltar pro momento no qual você colocou a label, faça o seguinte:
  1. Abra um "Visual Studio 2010 Command Prompt".
  2. (opcional) Use o comando tf labels para listar o nome da label para a qual você quer fazer o rollback:
    tf labels *@$/Projeto /owner:* /collection:http://server:8080/tfs/testcollection
  3. Mude para o diretório aonde estão os itens nos quais você deseja fazer o rollback.
  4. Rode o comando tf rollback para voltar o código para o ponto desejado:
    tf rollback /toversion:L"Solução Criada" HelpDesk /recursive
Este último comando volta os fontes para o estado em que estavam quando a label "Solução Criada" foi aplicada. O diretório atual é o diretório imediatadamente acima do diretório "HelpDesk", no qual estão os fontes do sistema. O utilitário tf faz checkout de todos os arquivos a modificar e retorna os mesmos para o estado da label "Solução Criada". Quando você fizer o checkin agora, a solução estará como estava quando a label "Solução Criada" foi aplicada.

sexta-feira, 12 de agosto de 2011

DSI e SDM

A MS tá investindo num trem chamado DSI - Dynamic Systems Iniciative, que tem como um dos componentes básicos uma linguagem de descrição de sistemas distribuídos: o SDM (System Definition Model), que é basicamente um esquema XML pra descrever sistemas distribuídos, seus componentes, datacenters, e a distribuição dos sistemas em um datacenter. Essa idéia vem pelo menos desde o Windows 2003 - o paper de overview da DSI no site da MS é de 2004, e segue a seguinte idéia: hoje temos o hardware e o software básico - recursos do sistema operacional e suporte nas liguagens de programação - para substituir mainframes por redes de PC's nos datacenters. A visão da MS é poder descrever sistemas e suas subdivisões (ex: executáveis e DLL's), juntamente com datacenters (máquinas, redes, appliances, etc) e a distribuição destes sistemas nos datacenters através de uma linguagem formal. O objetivo é minimizar o esforço de instalação, monitoração e modificação destes ambientes de execução de aplicações (HW + SW), automatizando o máximo possível dessas tarefas. Aí se abre um monte de possibilidades:

  • IDE para o monitorar e modificar sistemas distribuídos.
  • Linguagem de consulta e de modificação destes sistemas.
  • Scripts para automação de deploys.
  • ...

O VS hoje já tem designers para sistemas (system Designer), seus componentes (Application Designer) (EXE, DLL, web services, etc) e para "datacenters lógicos" (Logical Datacenter Designer) (sem os servidores físicos). E faz a junção disto num modelo de deploy (Deplyment Designer) e verifica se há algum problema de configuração e comunicação na arquitetura física da sua aplicação. O uso destes designers na fase de modelagem da aplicação é muito legal porque (a) obriga você, arquiteto da aplicação, a pensar nessas coisas "mundanas" e incluí-las na sua modelagem - pra não dar problemas que só serão detectados quando a aplicação for posta no ambiente de produção, e também porque (b) envolve o pessoal de administração de rede no design da arquitetura, o que é ótimo, porque eles montaram, conhecem e controlam o ambiente de hardware no qual sua aplicação vai rodar, então eles tem que ter uma palavra no assunto.

Imagina só, criar diagramas de sistemas e de datacenters em uma ferramenta, depois apertar um botão "Deploy" e aí a ferramenta pega um monte de ISO a partir de uma "biblioteca de VM's", cria as VM's no Hyper-V, configura a comunicação entre elas, configura os serviços, e instala os componentes do sistema em cada uma delas. Pronto. Um ambiente de produção instalado e funcionando em o que? meia hora? uma hora?Tamo rapidamente caminhando pra isso... Dá uma olhada no TFS Lab Manager!

[]s,
GB

quarta-feira, 20 de julho de 2011

ReportViewer: Outra Razão Para “Sys.ArgumentNullException: Value cannot be null. Parameter name: panelsCreated[…]”

ponte-que-partiu-1 
Ponte Que Partiu

CARVALHO. PONTE QUE PARTIU!!! Perdemos uma manhã inteira caçando o erro “Sys.ArgumentNullException: Value cannot be null. Parameter name: panelsCreated[1]” que era gerado em um web form que tinha um controle ReportViewer pra mostrar relatórios na nossa aplicação. A nossa “preguiça” me parece ser um jeito bem fácil de este erro aparecer: copiar um relatório já existente para fazer um novo. Nós criamos uma cópia de um relatório já existente pra reaproveitar o trabalho de layout já feito para o relatório original. Só que a página com o relatório original funcionava ok, mas na página com o novo relatório, o controle ReportViewer mostrava um painel em branco, e o IE mostrava o seguinte erro de JavaScript:

sheila-carvalho
Sheila Carvalho

Sys.ArgumentNullException: Value cannot be null. Parameter name: panelsCreated[1]

O problema foi gerado porque o relatório original tinha 4 parâmetros, e no segunda relatório só usamos 3. O quarto parâmetro não era usado, e não tinha um valor default. E, conforme descobrimos, parâmetros para os quais não são fornecidos um valor provocam o erro acima na renderização do ReportViewer. Bastou retirar a definição do parâmetro no arquivo RDLC e o relatório foi renderizado corretamente.