Arquivo para categoria Desenvolvimento

How to configure wsgid and mongrel2 to handle arbitrary sized requests

Intro

Wsgid is a generic handler for the mongrel2 web server. It acts as a bridge between WSGI and mongrel2 and makes it possible to run any WSGI python application using mongrel2 as the front end. To know more about both projects visit their official websites at: http://wsgid.com and http://mongrel2.org

In this post we will see how to configure mongrel2 and wsgid so your application will be able to handle arbitrary sized requests very easily and with a low memory usage.

Why?

The problem of receiving big requests is that depending on how your front end server deals with it, you can easily become out of resources and in a worst case scenario your application can stop responding for a while. If your application exposes any POST endpoint, then you should be prepared to handle some big requests along the way.

The big picture

Mongrel2 has a very clever way to handle big requests without consuming all your server’s resources, in fact without consuming almost nothing, only bandwidth. Basically what it does is to dump the entire request to disk, using almost none additional memory. Here is how it works:

When the request comes in, mongrel2 sends a special message to the back-end handler containing only the original headers. This message notifies the start of this request. It’s up to the handler to accept or deny it. To accept the request, your handler just do nothing. If you want to deny the request, your handler must send a 0-length message back to mongrel2. Due to mongrel2 async model, you can send this deny message at any time, does not need to be imediatelly after receiving the request start message.

If you happen to be using wsgid (I hope you are!) this happens without your WSGI application ever knowing. All your application will see (if at all) is the wsgi.input attribute of the WSGI environ (if you happen to write a WSGI framework) or just request.POST (or something similar depending on what framework you’re using). It’s all transparent.

After the request is completely dumped, mongrel2 sends another message notifying the end of the upload and that’s when wsgid will actually call your application. During all the upload process, your application does not even know that a new request has come and was being handled.

All this happens while mongrel2 is already dumping the request content to disk. If your handler happen to deny the request, mongrel2 will close the connection and remove the temporary file. To know more about how mongrel2 notifies the handlers, you can read the on-line manual: http://mongrel2.org/static/mongrel2-manual.html.

Configuring mongrel2 to handle big requests

The configuration of the server is extremely simple. All you have to do is tell it where to dump any big request that may arrive. You may ask: How big a request must be to be dumped to disk? The truth is that you decide this and tell mongrel2 about it.

To tell it where to dump the request you must set the option upload.temp_store to the correct path. This path must include the filename template. An example could be: /uploads/m2.XXXXXX. This must be a mkstemp(3) compatible template. See the manpage for more details.

The size of the request is set with the limits.content_length. This sets the biggest request mongrel2 will handle without dumping to disk. This size is set in bytes.

Configuring wsgid to understand what mongrel2 is saying

Since mongrel is saving requests on disk wsgid must be able to open these files and pass its contents to the application being run. It’s important to note that the path chosen on the upload.temp_store is always relative to where your mongrel2 is chrooted, so somehow we must tell wsgid where this is.

Fortunately this new release of wsgid comes with a new command line option: --mongrel2-chroot. You just have to pass this to your wsgid instance to be able to handle big requests.

Alternatively you can add this options to your wsgid.json configuration file if you want. This can be complished with a simple command:

$ wsgid config --app-path=/path/to/your/wsgid-app --mongrel2-chroot=/path/to/mongrel2/chroot

This will save this new option on your config file. Just restart your wsgid instance and it will re-read the config file.

Working without knowing where mongrel2 is chrooted

There is another way to handle these big requests. In this approach your don’t need to pass --mongrel2-chroot to all your wsgid instances. The trick here is to mount the same device on many different places. The easiest way to do this is to have mongrel2’s temp_store in a separated partition (or logical volume if you are using LVM). Let’s see an example:

Suppose we have mongrel2 chrooted at /var/mongrel2/ and configured this way:

upload.temp_store = '/uploads/m2.XXXXXX'

Since mongrel2 assumes /uploads is relative to its chroot we must mount this device ate the right place.

# mount /dev/vg01/uploads /var/mongrel2/uploads

Now our logical volume is mounted at /var/mongrel2/uploads. There is one last setp so we can start serving big requests with wsgid. When mongrel2 sends the upload started message to wsgid, which contains the path of the temporary file, the path received by wsgid is the same we put on mongrel2’s config. So wsgid will try to read /uploads/m2.384Tdg (for example) and obviously will fail. So we need a way to make /uploas/ also available to wsgid (that normally is not chrooted anywhere) and the trick to do this is to re-mount the same device at a different place. And this is how we do it:

# mount /dev/vg01/uploads /uploads

So now we have the same device mongrel2 writes the temporary files available to all wsgid processes that need to read them. Remember that mongrel2 does not remove any of these file because obviously it does not know when your app is done. So it’s up to you to clean them.

If your /upload directory is part of a bigger volume or is not on a separated one, you still can accomplish this multi-mount approach. Just use the --bind. This way you can re-mount any directory at another place. Read the mount man page for more details.

Conclusion

This is another cool mongrel2 feature that the latest wsgid release (0.5.0) already supports. So now wsgid supports all major features mongrel2 provides and is starting to be more mature, trying to find its way into a production-ready tool.

This release complete changelog is available at wsgid.com/changelog and you can grab your wsgid copy at wsgid.com.

Thanks for reading and enjoy!

, , ,

Deixe um comentário

Deploying your django application with mongrel2 and wsgid

Some time ago when people talked about webapp deployment they were probably talking about the LAMP stack. Since the appearance of the nginx webserver this has changed quite a bit. In this post you will know another stack, that does not use neither apache nor nginx but that is equally interesting and quite scalable too. We will be talking about mongrel2 for the frontend and wsgid for the backend worker processes.

TL;DR

In this post you will learn how to configure mongrel2 and wsgid to run your WSGI appalication. If you are interested in web servers, web application deployment and system administration, read on!

Leia o resto deste post »

, , ,

Deixe um comentário

How I’m planning to test one of my projects by writing another one

The purpose

Some time ago, I started writing wsgid. It is a project that brings to you the ability to run any WSGI application with mongrel2 web server. Some time ago I had this idea of writing a web application that could help me test wsgid on a real production environment. Both wsgid’ official website and my personal website are hosted using wsgid and mongrel2 as the backend, but none of them even uses a database (and maybe won’t for a long time) and since they are very simple and low traffic websites, I think they aren’t good enough to test wsgid.

I thought about some type of applications that would be better to test wsgid and end up with the decision to write my own blog engine. This same engine will soon power my own blog, self hosted and managed by me.

Wait, another blog engine? Why?

Yes, it will be a blog engine, another one! =) Before you think about NIH, I will try to explain why I decided to start this project. The very first thing I did when I thought about writing one more blog engine was to find some existing ones. But it could not be any blog engine, they must obey some rules:

  • Written in python
  • Used a WSGI framework
  • Bonus points for engines written in Django

These rules are obvious. If I’m trying to test wsgid (that is a WSGI gateway) the application must be written in Python and be compliant to the WSGI specification. The last one was a bonus point because I’m currently learning Django. I found that are there plenty of Django blog engines, but one decision made me not choose any of them: I want to learn something new, and I think the best way to do this is having a project. And not any one, but one that you will really use. And writing the code of my own blog is a good way to maintain the project alive, evolving and getting better and better.

Another point that helped me on this decision was the willing to self host my applications. This will give me very important knowledge and experience on system administration, servers, deployment, clusters and may more. Recently I had two amazing opportunities to work with these topics and I’m sure that if I were already managing my own infra-structure for a while I could have done much better on these two interviews.

Until the day of witting this blog post, my blog is still hosted on wordpress.com. I  plan to migrate to my own servers as soon as this new project becomes minimally usable. This will be good for many reasons that I already said and one more is that I will be able to have my own domain name and not pay any more money for this, since I already own daltonmatos.com.

Wish me luck

Starting a new project is always a great responsibility, first with yourself, second with the people that follow your projects and more important: with who uses your project. So today I decided to start this new project: The blog engine. It has no name yet, the only certainty is that I will create this project and host my own blog. The code will be hosted on github, where I publish all my codes. So if you are intersted follow me there and stay tuned!

Thank you for reading!

, ,

Deixe um comentário

O que aprendi desenvolvendo projetos de código aberto

Nesse post vou escrever um pouco sobre minha primeira experiência no desenvolvimento de projetos de código aberto.

O interesse por software de código aberto

Desde muito tempo tive interesse no desenvolvimento de software, especialmente em softwares de código aberto. Um interesse especial é o fato de você ter a oportunidade de ver códigos escritos por outras pessoas. Ler código de outras pessoas nos faz aprender muito, pois vemos abordagens diferentes para um mesmo problema e podemos aprender hacks que não fazíamos idéia que seriam possíveis.

Sempre publiquei meus códigos para quem quisesse ver e defendo a idéia de que as pessoas deveriam também sempre publicar seus códigos. A unica situação em que faz sentido não publicar algum código é quando esse código é crucial para um negócio qualquer. Nesse caso não faz sentido entregar o ouro, claro.

Primeiras contribuições

O primeiro passo para ter seu projeto de código aberto é fazer parte de algum outro projeto. Fazendo isso você pode ter contato com outros desenvolvedores, aprender como funciona o projeto especificamente, como é o processo para que você possa contribuir, além de ganhar experiência para que um dia possa tocar seu próprio projeto de código aberto.

Minha participação em projetos de código aberto teve início quando comecei a estudar python, há pouco mais de um ano atrás.  Antes de escrever código em python, lia bastante sobre a linguagem. Aprendi lendo o próprio site da linguagem e sempre que tinha alguma dúvida específica sobre alguma sintaxe, ia direto ler a gramática. Acho essa forma mais eficiente do que ler hello worlds por aí.

Em uma dessas pesquisas, estava tentando encontrar um framework web que fosse bem simples de entender, afinal eu estava começando a estudar a linguagem. Apesar de já ter experiência com sistemas web, conhecer sobre HTTP, requisições e etc. Web + python era, naquela época, algo novo.

Foi então que encontrei um framework chamado pyroutes. Pois bem, desde o início gostei da implementação pois ela faz uso dos decorators, que é uma coisa que acho fantástica na linguagem. Então comecei a estudar o código desse projeto, fiz meu fork no github e comecei a enviar pull requests. Comecei simples, apenas corrigindo erros triviais nos testes automatizados: 2d921fa9122a3211. Pouco depois, já estava corrigindo bugs e fazendo implementações menos triviais: 44d1708.

O que ganhei com tudo isso? Bastante experiência! Contato com pessoas de outras nacionalidades, conhecimento na linguagem que estava aprendendo e o mais importante: A oportunidade de outras pessoas me conhecerem e saberem das minhas habilidades e conhecimentos. Nesse projeto especificamente ganhei outra coisa também muito impotante: permissão de commit no repositório oficial!

A hora de começar meu próprio projeto

Depois de ter colaborado por algum tempo com esse projeto decidi que tinha chegado a hora de tentar uma nova empreitada: Tocar meu próprio projeto de código aberto. A idéia desse projeto apareceu ainda quando estava estudando sobre a linguagem. Como já disse aqui, acho muito importante ler código de outras pessoas e foi lendo o código do Trac que tive a idéia para o meu primeiro projeto: plugnplay.

O desenvolvimento desse projeto foi bem legal, foi meu primeiro código publicado que realmente tinha chance de ser útil para alguém além de mim, e isso é fantástico. Foi desenvolvido em apenas uma semana (de acordo com o histórico de commits).

O projeto é bem pequeno e fiquei bem feliz quando vi que ele já tinha 3 watchers!

O Segundo projeto

É claro que não parei por aí! Continuei com minhas pesquisas até que surgiu a idéia para o segundo projeto: wsgid. Essa idéia surgiu quando me deparei com um outro projeto: mongrel2. O objetivo do wsgid é me ajudar a ter uma infra-estrutura totalmente automatizada para fazer o deploy de minhas aplicações, e esse é o primeiro passo para que consiga chegar a esse objetivo.

Ao contráio do plugnplay, para esse projeto fiz um website, uma documentação completa e até comprei o domínio (wsgid.com), ou seja, coisa séria! =) E isso se mostrou muito importante. Querendo ou não, um projeto que apresenta um site oficial e uma documentação completa de suas funcionalidades atrai muito mais a atenção das pessoas, pois passa uma credibilidade maior. Uma coisa interessante é que o site oficial do wsgid roda usando o próprio wsgid!

A questão da documentação é especialmente importante pois temos que lembrar que nem todo mundo (mesmo desenvolvedores) terá curiosidade suficiente para ler o código-fonte para poder aprender a usar seu projeto, então ter uma forma fácil de começar a usar o projeto se mostra muito importante.

Visibilidade do projeto

O projeto wsgid teve uma visibilidade muito maior do que o plugnplay, e acho que isso se deve a alguns fatores. Em primeiro lugar ele é um projeto satélite de um projeto grande, o mongrel2. Só isso já te dá mais visibilidade. Outra coisa é que como eu estava participando da lista de desenvolvimento do mongrel2, mandei emails para essa lista divulgando o projeto e recebi feedbacks importantes. O fato da URL do site oficial estar na assinatura de todos os meus emails também ajuda. Novamente, isso só é possível pois o projeto possui um website.

Durante o desenvolvimento do projeto (até hoje, na verdade) ainda recebo notificações por email quando o projeto ganha mais um watcher em seu repositório. Hoje o projeto está com 13 watchers, o que é fantástico! Esse tipo de coisa te dá mais gás para continuar escrevendo o código, pois você vê que existem pessoas que acharam seu projeto interessante a ponto de decidirem acompanhar sua evolução. E isso é muito bom! Outra coisa ainda melhor é o número de forks que o projeto recebeu, até agora já são 5 em 6 meses de projeto.

Novamente, durante o desenvolvimento desse projeto tive a oportunidade de me comunicar com outras pessoas. Como já disse, entrei para a lista de desenvolveores do projeto mongrel2 e novamente comecei a submeter patches com pequenas correções. Depois, quando já estava com um domínio maior sobre o código já comecei a enviar códigos menos triviais, participei de várias discussões na lista até que, novamente, ganhei permissões de commit no repositório oficial. Essa é a lista de commits que fiz no repositório oficial, até o momento.

Conclusão

Minha conclusão disso tudo é que é muito divertido contribuir com algum projeto, melhor ainda é ter seus próprios e receber contribuições de outras pessoas  (já recebi um patch para o wsgid). Ter um side-project te dá mais conhecimento, faz com que as pessoas possam te conhecer (e isso é muito importante!) e te permite aprimorar suas habilidades.

Se você ainda não posui um projeto, comece um! Os dois que tenho surgiram para resolver problemas que eu tinha no dia-a-dia, tenho certeza que você também já viveu situações onde um programa poderia te ajudar ou até mesmo resolver seu problema. Pense que outras pessoas certamente já tiveram o mesmo problema e também poderiam ser ajudadas pelo seu projeto.

2 Comentários

Plug n’ Play: um sistema de plugins genérico para python

Nesse post veremos um projeto open source chamado Plug n’ Play. É um sistema de plugins genérico para python. Isso significa que com esse projeto é possível desenvolver de forma modular e também adaptar códigos existentes para que, a partir de então, seja possível adicionar novas funcionalidades sem modificar o código principal do programa.

Leia o resto deste post »

2 Comentários