The Ultimate ASP.NET Session State Debugging Tool

Do you use ASP.NET? ASP.NET MVC? Any kind of Session storage? Any kind of Out-of-Proc storage (like State Server, or SQL Server Session Storage) for web servers in a web farm?

Do you have problems with it? Yes, you do. Microsoft makes it painful. You must make MachineKey match. You must make the IIS W3SVC ID match. You must pray it doesn’t break when you restore your metabase config. You realize some virtual directories work, while others don’t. Some servers, browsers, load balancers, work while others don’t.

Now, do yourself a favor, stop hammering your sysadmin, and get the code below. Paste into a testSession.aspx page in every machine and every virtual directory affected. You’ll get something similar to the shot below. Run it individually and through the load balancer. Check for “AppDomainAppId” mismatches (even the tinyest difference in upper/lowercase makes a difference). Check for “MachineKey” hash. Make sure everything match between servers in the farm (by hand-editing the metabase, machine.config, etc) in every virtual directory (I’ve seen uppercase/lowercase mismatches in the /LM/W2SVC/1/ROOT/VirtualDir AppDomainId string that happen on one Vdir while others are okay).

So simple, isn't it?

Here goes the entire code. Attention: remove this from the server after you’re done. You never know what evil people will use it for…

<%@ Page Language="C#" ValidateRequest="false" %>

Current DataTime: <%= DateTime.Now %><br/>
Current Session Mode: <b><%= Session.Mode %></b><br/>
HttpRuntime.AppDomainAppId: <b><%= HttpRuntime.AppDomainAppId %></b><br/>

<%@ Import Namespace="System.Web.Configuration" %>
<%@ Import Namespace="System.Reflection" %>

<%
MethodInfo _encOrDecData;
MethodInfo _hexStringToByteArray;
MethodInfo _byteArrayToHexString;
MethodInfo _HashAndBase64EncodeString;

MachineKeySection  config = (MachineKeySection)ConfigurationManager.GetSection("system.web/machineKey");
Type machineKeyType = config.GetType().Assembly.GetType("System.Web.Configuration.MachineKeySection");

BindingFlags bf = BindingFlags.NonPublic | BindingFlags.Static;

_HashAndBase64EncodeString = machineKeyType.GetMethod("HashAndBase64EncodeString", bf);

if (_HashAndBase64EncodeString == null)
{
	throw new InvalidOperationException("Unable to get the HashAndBase64EncodeString to invoke.");
}
String str = HttpRuntime.AppDomainAppId;
var HashedPiko = (String)_HashAndBase64EncodeString.Invoke(null, new object[] { str });

%>

Hashed with the MachineKey: <b><%= HashedPiko %></b><br/>

Local Machine Name: <b><%= Request.ServerVariables["LOCAL_ADDR"] %></b><br/>

Current Session ID: <b><%= Session.SessionID %></b><br/>

<%
String pikoNaSession = (String)Session["SESSION_TEST_VALUE"];
if (String.IsNullOrEmpty(pikoNaSession)) {
	Session["SESSION_TEST_VALUE"] = "Test Value, set on " + Request.ServerVariables["LOCAL_ADDR"] + " " + " at " + DateTime.Now ;
}
%>

Current value in Session: <b><%= pikoNaSession %></b><br/>

TortoiseCVS and TortoiseSVN on Vista and Windows 7 x64 – Overlay Icons

For more than a year, getting icon overlays to work with both TortoiseCVS and TortoiseSVN on x64 has been a nightmare.

Not anymore.

First, install the latest stable TortoiseSVN.

Then install my custom build of TortoiseCVS, TortoiseCVS-1.11.6-pardini.exe. It is a custom built CVS-HEAD checkout, without many changes.

Please note that apparently TCVS is the one that decides the icons to use (both TSVN and TCVS will use the same icons), but they all work.

If it’s not working for you, uninstall all TortoiseSVN, TortoiseCVS and TortoiseOverlays you may have installed.

Also delete the registry key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers.

Then reinstall in the order I suggested above.

Atualização do Boot Camp para 2.1 (Brazilian Portuguese)

Para algum infeliz, brasileiro, que tenha um Mac, rodando Boot Camp (Windows), que tente atualizar o Boot Camp do 2.0 para o 2.1. Acho que sou só eu no mundo todo. Se o Windows instalado for em inglês, mas com preferências/teclado/regional settings como Brazil, a instalação do Boot Camp 2.0 faz uma cagada federal, e localiza o nome do produto no registro do Windows. Resultado, o update para o 2.1 não consegue atualizar, devido a algo esotérico do tipo ”Error applying transforms. Verify that the specified transform paths are valid.” Muito informativo, parabéns Apple. A Apple também resolveu ignorar o problema, apesar de centenas de usuários com problemas (com certeza são todos estrangeiros, então fodam-se). A ajuda veio de um outro cara que fala Português (de PT). Porém, para máquinas em pt_BR, a chave de registro é diferente. Convém procurar por “Serviços do Boot Camp”. No meu caso resultou na chave HKEY_CLASSES_ROOT\Installer\Products\82654E0F812156845A61E8A84572A2CD. Altere a chave “Language” para 1033 (em decimal). Boot. Reinstale o update e voilá.

Flash is Single Threaded: RPC and AsyncToken behavior

So in Flex you can invoke a service (like a WebService method, or HTTPService.send()), which returns a token (mx.rpc.AsyncToken). After that, you set a responder on the token. When the results come back, the responder is called. Calling the send() method actually sends the request, so the whole construct looks bizarre, since you’re setting a responder/handler AFTER the call has been sent. This is a very common pattern in Cairngorm applications.

The fact is that this never fails, and I wondered why, because it looks possible (although unlikely) for an RPC call to return data before the responder is set. After thinking for a while, I remembered one of my first problems with Flash, years ago: it’s single threaded. After investigating on the web, I found out this is really what makes this (and a whole host of other async stuff) work in Flash/Flex. The call may return data, but since it’s single threaded, your method will surely be able to continue, and set the responder, before the result handler is called. Uncommon, to say the least.

Ultimate Debian Etch VMWare Server setup (16Gb Dual Quad Core Dell 2950 with OMSA)

With assistance from the helpful folks at the VMWare Discussion Forum, I came up with what I think is the ultimate VMWare Server setup. It’s essentially Debian Etch (4.0) x86 running on a Dell 2950, with dual Xeon E5310 (Quad-Core) and 16Gb RAM. The focus here is on cleanliness: no hacks, no bizarre compat libraries, no patches. Just plain Debian-Dell-VMWare fun.
First, a word about x64. Since I have a lot of RAM, the initial tests were with the amd64 port of Debian. Unfortunately, and not being Debian’s fault, a lot has conspired against x64. First, VMWare not being a native 64-bit application, a lot of compat libraries would be involved. Also, a lot of trouble arises with Dell OMSA. Finally, most people agree that there’s some performance penalty for VMWare on x64, quirks aside. If we had native VMWare and OMSA, I’d go with amd64. The best option I’ve found (and recommended on the forums) is installing standard x86 Debian, and then switching kernel to a ‘bigmem’ one. More on that later.
So lets head on to the method:

1) Prepare the RAID setup for initial install. Dell does not support Debian, so you need a way to configure your RAID volumes beforehand (at the very least, the volume where you will install Debian, but I just go ahead and configure all my volumes). For this purpose I’ve found the excellent “CentOS Dell OMSA 5.1 Live CD”. Just burn the ISO, boot from it, set the root password, wait a lot, and you can get into the Web Interface for OMSA where you can set up the storage. I’ve set “Adaptive Read Ahead”, “Write back” and other performance-enabling RAID options.

2) Install Debian Etch (x86). I used a 3-in-1 CD, which has a i486, amd64 and power installer, and with that it was a little tricky to force i386/i486 instead of amd64 (it seems to auto-detect). The Dell PERC controller and NICs were all detected, even though it seems the (Gigabit) Ethernet ports were reversed (port 1 was eth1 and port 2 was eth0 – I’ve seen this reported before). Proceeded with standard install, I went with straight ext3 filesystems. You may want LVM or other fancy stuff, but I didn’t bother. I took care of unchecking the “Standard system” install option, which would install a lot of uneeded stuff like NFS, and results in a very, very minimal Debian install. Complete install, set root password, apt sources etc, and boot into the new system.

3) New kernel and packages. “aptitude update” and install SSH and the new kernel “aptitude install ssh linux-image-2.6-686-bigmem”. This should be all handled automatically, including the new kernel being setup in grub. Reboot. Once the system is back up, check /proc/cpuinfo, /proc/meminfo and “top” for correct 8-logical-CPU and 16635720 kB MemTotal. You may want to do a “aptitude upgrade” too to update everything with security updates. I also like ntpdate, tz-brasil and ntp-server for keeping the clock right.

4) Install Dell OMSA. The nice folks at sara.nl offer some excellent pre-packaged Dell OMSA install for Debian (it’s version 5.2, so it just plain works, without the “storage not found” problem). Thanks to them, you can just add “deb http://ftp.sara.nl/pub/sara-omsa dell sara” to /etc/apt/sources.list (ftp:// also works), do “aptitude update”, and “aptitude install dellomsa” and it’s quite ready. It’s a large package, around 100mb, but installs perfectly. After the install, run “update-rc.d dsm_om_connsvc defaults” and “/etc/init.d/dsm_om_connsvc start”. You can then go to “https://x.y.z.w:1311″ (on another machine) and get to the OMSA web interface. Log-in as “root” with root’s shell password. It’s just that sweet. Dell’s own install system on supported OSes are not even close. I will post about SNMP support for OMSA later.

5) Install VMWare prerequisites. VMWare Server links dynamically to a lot of stuff. I got a few pointers from other sites, but ultimately “ldd” and “apt-cache search” were my best friends. The best indication you’re missing libraries is the VMWare install program complaining about them, or even rejecting your VMWare serial number, or vmware-mui telling you vmware isn’t installed. Anyway, this is the final aptitude line for install all the dependencies I found: “aptitude install libx11-6 libx11-dev libxtst6 xinetd wget linux-headers-`uname -r` build-essential gcc g++ psmisc libxt6 libxrender1 libxi6″.

6) Install VMWare Server and VMWare Management Interface. You get these from vmware.com after registering. Don’t forget to request your free serial number from them too. You should download the latest version (I got 1.0.3) in .tar.gz format. Just “tar xzvf” them, and run the installer script as per the manual. Everything should go smooth – VMWare will say you’ll need to compile the modules, and that should go just fine (no need for any-to-any patches). Do the same install routine for vmware-mui. Once it’s installed you can get to the nice VMWare web interface via “https://x.y.z.w:8333″. You will also connect via VMWare Console (I run that on Windows…) on x.y.z.w port 902. VMWare is able to see around 14.5Gb of RAM, which is excellent for my needs. Any given VM is limited to 3600mb, as usual.

Burrocracia NET/Virtua chega a novos extremos

Apesar do serviço ser excelente (e caro), a NET/Virtua me surpreendeu com a burocracia na semana passada. Quando fomos morar no antigo apartamento da minha avó, reativei a assinatura NET que meu pai tinha feito para minha avó. Com isso passei a pagar R$69/mês para ver enlatados americanos, e nenhum canal de filme. Além disso, fiz um pacote ‘fidelidade’ (você não paga assinatura, nem instalação, mas tem que ficar 12 meses senão paga multa) de um Vírtua 600kps, pagando $89/mês. Aqui no escritório temos um Vírtua 1200/600kbps, pagando R$140, então não achei ruim.
Agora, cinco meses depois, estamos nos mudando (pergunte a Dine sobre os detalhes, e sobre o coletivo, ok? isso aqui é blog de nerd) e preciso transferir tudo (TV e Virtua) para um novo endereço. Liga na ‘central de emburrecimento’ e olha que fácil: “Isso não é possível, senhor”. Pergunto a razão. “O contrato NET que o senhor possui, senhor, é vinculado ao condomínio, senhor, e não pode ser transferido, senhor”. 3 horas depois: “a nossa sugestão, senhor, é que o senhor faça uma nova assinatura no novo endereço, senhor, e depois cancele a antiga, senhor”. Mas é o plano ‘fidelidade’? “Nesse caso, senhor, o senhor estará pagando uma multa de R$240, senhor. Afinal o senhor está cancelando o serviço, senhor”. É o fim…
Depois de cinco horas (sério!!!) no telefone com os infelizes, um supervisor me indica a solução mágica: “Basta fazer uma nova assinatura NET/TV no novo endereço, senhor, com a mesma titularidade, que será possível transferir o Virtua/fidelidade para o novo endereço”. Trouxa eu que fiz isso, e agora estou a 6 dias tentando convencer algum outro infeliz, na área de PJ, ou via FAX, ou sinal de fumaça, “senhores”, que fiz o que mandaram, e que se não transferirem isso rapidinho, vou meter todo mundo no PROCOM, e cancelar todos os elogios jamais feitos ao Virtua. Fim do mundo!

Obs: já mandei mais de 50 faxes, e perdi nada menos do que 7 horas e quinze minutos no telefone, contadinhos, com esses infelizes. Anda logo, vai.

PS. Consegui finalmente esvaziar meu gmail, via POP/SSL. O POP deles só manda 600 mails de cada vez, é um inferno. Agora colocarei a conta do gmail via fetchmail na minha conta principal, tornando a menos inútil e mais verificada.