marzo
28

Minimizar consultas SQL repetidas en CakePHP

Posted In: CakePHP by Mauro Zadunaisky

Trabajando en optimización de performance de una aplicación CakePHP noté que una consulta SQL se estaba ejecutando más de una vez, siempre igual y devolviendo el mismo resultado.

El método del modelo que generaba la consulta era más o menos así

/**
 * Determina si un producto está habilitado
 *
 * @param int $id Id del producto en base de datos
 * @return boolean
 * @access public
 */
public function isEnabled($id) {
	$product = $this->find('first', array(
		'conditions' => array('Product.id' => $id),
		'fields' => array('enabled')
	));
	if (empty($product)) {
		$out = false;
	} else {
		$out = !empty($product['Product']['enabled']);
	}
	return $out;
}

En algunos casos, al momento de llamar a isEnabled ya teníamos disponible el array con los datos del producto porque habíamos ejecutado un find previamente, así que el método se podría reescribir pasándole el array con todos los datos en vez del id, y con eso ya nos ahorraríamos consultas SQL repetidas

/**
 * Determina si un producto está habilitado
 *
 * @param array $product Array del producto retornado por un find()
 * @return boolean
 * @access public
 */
public function isEnabled($product) {
	return !empty($product['Product']['enabled']);
}

Sin embargo, esto hizo fallar algunos casos de testing porque en otros lugares de la aplicación el método necesitaba recibir el id el producto y todavía no se había leído el producto desde base de datos como para pasar el array.

La refactorización final quedó así:

/**
 * Determina si un producto está habilitado
 *
 * @param mixed $product Array del producto retornado por un find() o id del producto
 * @return boolean
 * @access public
 */
public function isEnabled($product) {
	if (!is_array($product) or empty($product['Product']['enabled'])) {
		$product = $this->find('first', array(
			'conditions' => array('Product.id' => $product),
			'fields' => array('enabled')
		));
	}
	if (empty($product)) {
		$out = false;
	} else {
		$out = !empty($product['Product']['enabled']);
	}
	return $out;
}
marzo
25

Cómo reportar errores de programación

Posted In: Opinión by Mauro Zadunaisky

Siempre hacemos un esfuerzo muy grande por evitar cometer errores, pero a veces no es suficiente y es posible que algo se nos escape. Cuando esto sucede los clientes (en nuestro caso las agencias) nos avisarán de los bugs encontrados para que podamos corregirlos. Sin embargo, a veces los reportes no están lo suficientemente completos como para que podamos rastrear el error y encontrar el problema para poder solucionarlo.

En proyectos grandes y a largo plazo lo ideal es tener un sistema de bug tracking, pero para trabajos medianos o pequeños consideramos que un sistema de este tipo genera más problemas que beneficios y con un simple correo electrónico es suficiente. Sin embargo, esto no quita que el reporte de error deba estar completo.

Qué debe contener un reporte de bug

Todo reporte de error debe estar lo suficientemente detallado como para que los programadores podamos reproducirlo en igualdad de condiciones. No es suficiente con avisarnos que algo no funciona, debemos saber exactamente qué es lo que no funciona y por qué se considera que es un error, ya que muchas veces no se trata de un error sino de una mala interpretación sobre la forma en que debería estar funcionando el programa.

Un reporte de error debería responder al menos estas 4 preguntas:

  1. Cuáles son los pasos a seguir para producir el error
  2. Qué resultado esperaba conseguir el usuario al ejecutar estos pasos
  3. Qué resultado se obtuvo en lugar del esperado
  4. Bajo qué condiciones se ejecutó la prueba: sistema operativo usado, versión del navegador o teléfono móvil, resolución de pantalla, etc.

También resulta de mucha ayuda incluir capturas de pantallas, archivos adjuntos o imágenes que se hayan utilizado, copias completas de direcciones de acceso (URL), datos que se usaron para completar formularios, etc.

Si los reportes de errores están completos ahorraremos mucho tiempo en idas y vueltas de emails y lograremos entregar los trabajos con mayor anticipación.

noviembre
30

Cada vez que CakePHP lanza una nueva versión basta con actualizar el directorio cake con los nuevos archivos y (por lo general) todo funciona correctamente. Sin embargo, hay veces en que se producen algunos errores que pueden pasar desapercibidos para los casos de testing y lamentablemente estos bugs llegan a producción. Cuando esto sucede deberemos volver a volver a una versión anterior de CakePHP, hasta tanto encontremos el error y lo solucionemos. Este proceso de rollback puede ser un problema, ya que volver a reemplazar el directorio cake lleva tiempo y los bugs siguen en producción.

Primer intento de solución

Tener varios directorios con el framework, uno llamado cake con la versión actual (que será la que use nuestra aplicación) y otros directorios con las versiones anteriores, por ejemplo cake-1.2.5, cake-1.3.2, etc. De este modo, cada vez que se necesite volver a una versión anterior simplemente se renombran dos directorios.

Esta solución tiene algunos problemas

  • Renombrar los directorios es una tarea que tenemos que hacer manualmente, por fuera del proceso de deploy automatizado.
  • El core de Cake no es código mantenido por nosotros y por lo general se lo deja fuera del repositorio de nuestra app. Por lo tanto, cada vez que se modifica el directorio cake, tenemos que avisar a todos los miembros de nuestro equipo que hagan lo mismo para que todos trabajemos en iguales condiciones.
  • Debemos mantener actualizado nuestro archivo .gitignore para que las nuevas versiones de cake no formen parte del repositorio de Git (o el sistema de versionado que utilicemos).
  • Si alguien realiza un checkout de nuestra aplicación no encontrará en el código información acerca de cuál es la versión de CakePHP que necesita para funcionar.

Solución

Crearemos la siguiente estructura de directorios

  • app
  • cakeversions
    • 1.2.5
      • cake
    • 1.3.2
      • cake

El directorio cakeversions contendrá todas las versiones del core que alguna vez necesitó nuestra aplicación y será ignorada por Git. Los directorios cake dentro de cada número de versión son necesarios ya que el framework requiere que todo el core esté dentro de un directorio llamado exactamente cake.

Después tendremos que modificar el archivo app/webroot/index.php para que tome la nueva ubicación del core. La siguiente línea:

define('CAKE_CORE_INCLUDE_PATH', ROOT);

Debe ser reemplazada por esta:

define('CAKE_CORE_INCLUDE_PATH', ROOT . DS . 'cakeversions' . DS . '1.3.6');

De este modo, cada vez que necesitemos cambiar la versión de cake sólo deberemos modificar el número en esta línea. Los cambios que hagamos se implementarán en producción en el próximo deploy y como el archivo app/webroot/index.php forma parte del repositorio en Git, el resto del equipo lo tendrá actualizado en el próximo fetch o pull que realicen.

octubre
8

Libro “Desarrollo web profesional”

Posted In: Libros by Mauro Zadunaisky

_desarrollo-web-profesional

Desarrollo Web profesional es un libro que intenta reunir en una sola obra muchos temas relacionados al desarrollo web de la actualidad, y lo consigue con bastante éxito. Resulta complicado escribir una revisión del libro en su conjunto, ya que en él se encuentran temas variados, que van desde cuestiones básicas de XHTML, CSS y Javascript, hasta herramientas avanzadas como Firebug y Web Developer, pasando por teoría de los archivos de imágenes, funcionamiento de HTPP, configuración de .htaccess y algo de SEO. Parece más un compendio de artículos sueltos que un libro, si bien todos los capítulos resultan muy interesantes y útiles.
Read More