Code

This portion of the site is devoted to software code and other topics of interest for a software engineer.

Django on Windows

Category: Code

Posted:

Things are progressing nicely for using Django with Windows. It’s hard to gauge true usage, but it appears to me as if the minuscule minority of Django-Windows users is greatly expanding. At my day job, I started to use Django on Windows five years ago and the site has been in production for almost three.

A few years ago, the most common response to support questions was along the lines of “don’t use Windows”. It’s been a while since I’ve gotten that response. There are a few reasons why I think I no longer get that response. The problems I need help with require an understanding of the Django internals and sometimes are asked in the form of a pull request. Microsoft is a DSF member, PyTools adding Python support to Visual Studio, and Azure providing an easy way of hosting a Django app on a Windows server. All of which contribute to a larger base of developers using and deploying to Windows.

I also like to think that my vocal usage of Windows on production has helped to encourage others to follow suit. At DjangoCon 2012, I gave a lightning talk about running Django on Windows (slides and video). To me, that was the point when I started to notice more people developing Django apps on or for a Windows environment. I’m not sure if I noticed them because I started to look more or if the minority felt a lot less isolated and gained a voice.

A few months after DjangoCon came PyCarolinas. I expanded the lightning talk in to a full presentation (slides and unfortunately no video). In the months between PyCarolinas and today, I know of one other production site that is using Windows and there are an increasing number of downloads of each version of django-mssql I push out. I predict that things will continue to improve!

North Carolina Woodworker Forum Helper Script

Categories: Code, Wood

Posted:

I’ve written a Scriptish script that makes a few UI improvements to the NC Woodworker Forum. The script is tested with the Firefox extension, but may also work with other browsers that have a Scriptish or GreaseMonkey plugin/extension.

Features

  • Convert location text to a Google Maps link. It will detect links in user profiles, classified listings, classified posts, and the thread poster’s location.
  • Auto-collapse maps embedded in a post and provide a link to the map and the ability to expand the embedded map.
  • Remove the “Place Holder” navigation item.

If you’d like the map links to include directions, you can configure the script so that it knows the starting location to use. This location can be any location that Google Maps recognizes; long/lat, intersection, address, city, etc. See the below image on how to find the settings. The green icon at the bottom right of the FireFox window belongs to Scriptish. Clicking it will popup the menu.

How To Install

  1. Install the Scriptish Firefox Extension
  2. Install the NCWW Forum Helper Script
  3. Optionally configure a starting location.
  4. Enjoy the improved UI

GitHub Repo: https://github.com/manfre/scriptish-ncww-forum/

Screenshots

This first image showcases the auto-collapsing of embedded maps and the location text converted to a map link. The screenshot below was taken from the thread New Feature: Insert Google Maps in Posts.

Click to see full size image

Disclaimer

This script is not supported by NCWW. Please don’t contact the NCWW admins or mods with support questions.

My First Bottle Stopper On Etsy

Categories: Code, Wood

Posted:

I’m testing the waters with selling my bottle stoppers on Etsy. The site has the benefit of an existing user base, but my small collection of items (currently only one) is most likely lost among the vast quantities of items. I posted a cherry bottle stopper with a stainless steel base as my first test. There has been almost negligible traffic to the item listing with almost every page hit being sourced from the bit.ly link that I’ve posted in a few places. I plan on posting a few more bottle stoppers up there to site for a while. From what I’ve learned so far, popular stores are somewhat self sustaining, but newer, smaller sellers are all but lost in the void. The $0.20 posting fee is trivial and spending a few dollars to force myself to think about how I can market my woodworking crafts is a worthwhile expense.

An alternative to selling on Etsy is to host my own store. OpenCart is currently in the lead of the free apps. Magento was quickly eliminated as being too large/complicated for a site that would only have a few dozen items for sale. I also couldn’t image being able to turn a client loose on its admin interface to manage their business.

Related to the self hosting, I still have a few shared accounts with Joyent. The uptime has been great and my only complaint is that I didn’t upgrade my lifetime shared hosting when they started offering accelerators. That would have given me more options and capabilities with the hosting. In search of a cheap VPS hosting option, I found LowEndBox.com, a blog that posts sub $7/mo hosting deals. If you set your expectations appropriately and do a little bit of research about the companies providing the offer, then you can find a good deal. I managed to get a dedicated 2gb OpenVZ from ChicagoVPS for $7/mo. For the price, it is exceeding my expectations and I plan on hosting a few personal sites and services that can tolerate some downtime. There hasn’t been any provider caused downtime yet, but my expectations are not set to a level I would need for a production site. My expectations may change with time.

ImportError: No module named os

Category: Code

Posted:

When running Python 2.7 with Apache 2.2 and modwsgi 3.3. Make sure Apache is loading the correct version of modwsgi. I ran in to the following error, which wasted about 15 minutes of my life before realizing the one character typo.


[client 192.168.0.10] mod_wsgi (pid=5800): Exception occurred processing WSGI script 'D:/www/myapp.wsgi'.
Traceback (most recent call last):
  File "D:/www/myapp.wsgi", line 1, in <module>
  ImportError: No module named os

That puzzling error was the result of the following line in the httpd.conf.

LoadModule wsgi_module "@WWWROOT@/modules/mod_wsgi-win32-ap22py26-3.3.so"

See it? The line should be.

LoadModule wsgi_module "@WWWROOT@/modules/mod_wsgi-win32-ap22py27-3.3.so"

Running Python With Apache on Windows

Category: Code

Posted:

My day job has a Windows environment and avoids installing other OSes unless absolutely necessary. Windows is great on the desktop, but has many limitations when tasked with running a web site that relies heavily upon open source languages and products. Its limitations are front and center when trying to host a Python web application. Below are some of the gotchas that I’ve encountered and how I addressed the problem.

The Python GIL

Every Python developer should be familiar with the GIL. If you’re not, follow that link and start reading. TL;DR? Threads of the same process block each other on all IO. By itself, the GIL is an easy beast to tame by spawning more processes, instead of threads. On *nix OSes, processes are relatively light weight and you can fork a process and continue on your merry way. Processes on Windows are heavier and it does not support fork without installing more software. Cygwin and Windows Services for Unix are the two ways of making Windows behave more like *nix for specially compiled programs.

Apache MPM (Multi-Processing Modules)

Apache is a great HTTP server application that provides more functionality than most sites will ever need or use. It is also one of the few options that is designed to run as a service on Windows. The lighter weight options, nginx and lighttpd are usually better for my needs, but both have issues with running as a Windows service.

Apache supports a few different Multi-Processing Modules, prefork is the default for *nix. On Windows, there is only one MPM, mpm_winnt. This MPM works great and follows the Windows idea of spawning threads when you want work done. The GIL makes almost any Python website unusably slow when run on Windows with Apache. Most web applications are a bunch of IO (Network, database, disk, etc.) with a small amount of CPU. This basically turns Apache in to a single threaded web server. The prefork MPM does not experience this problem due to its use of processes instead of threads.

I observed the situation where a page that by itself would take about 1 second to generate, could take tens of seconds to finish if there were more than 2-3 overlapping requests. Each new request (in a thread) would get roughly equal time and slow down all previous threads. It was possible to block the site for minutes with as few as 10 requests.

Faking a Python MPM

There is a way of configuring a Windows server so that it can serve a Python web application and avoid the GIL. A multi-process MPM is conceptual the same as a load balancer sitting in front of several web servers. An incoming request is routed to a individual web server to handle.

Apache as a Balancer

Apache can function as a load balancer if another option is not available. Here’s a configuration snippet that will equally balance requests among three Apache instances running on the same machine as the instance acting as the load balancer (reverse proxy). See mod_proxy documentation for the rest of the configuration directives that you will need to fully configure.

<Proxy balancer://cluster>
	BalancerMember http://192.168.0.10:9001 smax=3 max=10 ttl=120 route=www_1
	BalancerMember http://192.168.0.10:9002 smax=3 max=10 ttl=120 route=www_2
	BalancerMember http://192.168.0.10:9003 smax=3 max=10 ttl=120 route=www_3
</Proxy>

ProxyPass / balancer://cluster/ ProxyPassReverse / balancer://cluster/

Gotchas

This configuration of faking a server farm on a single machine requires some new problems to be resolved. Thankfully, these are not that difficult once you are aware of them.

Lots-O-Logs

Every request will be logged by the load balancing Apache instance and the proxied instance that does the work. This is not necessarily a bad thing by itself. It is useful to know which Apache instance handled a specific request and also get the aggregate view (load balancer logs). Unless steps are taken, this will double the disk IO and space requirements.

The simple resolution is to disable all logging on the worker instances. This can be accomplished by using CustomLog and a conditional environment variable that is never set.

LogFormat " " empty
# Below will never output anything, but it will create an empty file
CustomLog "D:/logs/carme/apache/access-1.log" empty env=NOTHING_IS_LOGGED

Logging has now been reduced to a normal volume, but you will not know which instance handled the request. To regain that bit of information, you can add %{BALANCER_WORKER_ROUTE}e to the LogFormat of the load balancer. This will include whatever value is set for route= in the above BalancerMember configuration. E.g. www_1, www_2, or www_3.

Fixing IPs

The instances behind the load balancer, and application code will see every request as if it is coming from the load balancing instance. This can be resolved with the Apache module mod_rpaf.

« Newer - Older »

Code Repositories

Useful Sites