El Blog de Trespams

Blog personal sobre tecnologia, gestió de projectes i coses que se me passen pel cap

Caçant bubotes

Poc a poc hem anat evolucionant la nostra arquitectura d'aplicacions des de aplicacions monolítiques fetes amb J2EE cap a aplicacions on la capa de serveis està en Java (per ara!) i aquests es consumeixen amb Python, utilitzant Django com a bastiment web.

Per a consumir serveis SOAP feim servir una llibreria anomenada ZSI que ens permet generar les classes Python a partir el WSDL dels serveis.

ZSI és un projecte que avança molt a poc a poc, veus que no està mort, que funcina, però la versió 2.1 fa estona que està en alfa. Tot i això, la versió 2.0 funciona prou bé com per poder consumir els serveis sense problemes.

L'altra dia però, ens vàrem trobar amb un problema d'aquests que classific com a "bubota". Atacàvem al servei que tenim de Transfers i tot anava com a la seda, atacàvem al d'excursions i el mateix. Atacàvem als dos dins la mateixa aplicació i l'espai de noms es feia un embolic, de manera que ens posava l'espai de noms del primer servei que s'executava.

Ho va descobrir en Juanjo i jo li deia que no podia ser fins que vaig fer un petit test de manera independent de l'aplicació que estam fent i ho vaig tocar amb les mans. Hi havia un problema i ara el problema era poder identificar a on, al webservice (poc probable), a la capa de servei que cosumia el SOAP (probable), al mapeig del ZSI (menys probable) o al ZSI en si (encara menys probable).

Quan un es troba amb un problema així, el primer és anar de més probabilitat a menys i anar descartant coses. La idea a més és aprofitar que hom està fent la depuració per a refactoritzar el codi, de manera que la feina de depuració serveixi a més per deixar un codi més clar i per tant més fàcil de depurar (recordau la primera regla de la refactorització: l'aplicació ha de funcionar exactament com funcionava abans, no introduïm nova funcionalitat).

Així doncs va començar un procés de refactorització de la primera capa, la que consumia el servei mapejat amb ZSI. Vaig organitzar millor el codi en paquets, vaig eliminar importacions innecesàries i vaig aillar totalment la part de transfers de la part d'excursions. Els tests però treien sempre el mateix, error quan atacàvem als dos serveis a l'hora.

La següent passa va ser anar a veure el codi generat pel ZSI (amb wsdl2py). Els generador de codi van molt bé, però sovint són massa genèrics. Així que també vaig fer-ne la refactorització. Eliminar totes les importacións amb arterisc, canviar nom comuns als dos paquets de transfers i excursions, i passar la part de defnició de tipus Soap a un arxiu independent, de manera que sols importàssim els realment necessaris. Tampoc! Els tests seguian donant el mateix... Bé al manco la refactorització era conseqüent...

Ara ja sols quedava la passa de la depuració línia a línea, fins i tot anant al codi del ZSI. Per això vaig començar amb un depurador senzillet comp el pdb (amb la seva versió d'ipdb) i vaig poder identificar a quin punt hi havia el problema. Pareixia estar en les cridades que feia el codi generat cap el ZSI. Per a facilitar la depuració en aquest punt ja vaig passar a un depurador gràfic, el winpdb, ja que permet veure d'una ullada totes les variables locals i globals.

Entrant al ZSI vaig descobrir la bubota. El ZSI cacheja els tipus d'objectes generats, però de tal manera que ho fa de manera global a l'aplicació, per tant, si dos objectes tenenen el mateix nom (com era el nostre cas), retorna el primer nom generat amb el seus espai de noms (cagada del ZSI al meu entendre). Potser és poc comú el que feim, però crec que és un cas típic d'optimització prematura. Es cachegen els tipus generats potser sense importar-hi.

La solució doncs va ser llevar les cachés, fes que generàs el tipus cada cop. Esperava pot ser una pèrdua de rendiment, però no és així, pareix que fins i tot posar i treure de la caché és comparable al temps d'execució a la genereació del tipus. He d'afinar un poc més amb aquesta apreciació, però el que està clar és que per al consum que es fa del servei, la diferència de temps no és significativa a l'ordre dels milisegons, i del tot menyspreable si ho comparam amb el *lag * produït per les línees de comunicació. Amb la caché activada 1 segon, i sense 1 segon igual.

La bubota està caçada, els fantasmes desapareixen quan es fa la llum i amb tot el procés he après molt millor com funciona el ZSI per dintre.

blog comments powered by Disqus