Categories
Artí­culos

TortoiseSVN: Reducir la actividad en el disco

TortoiseSVN es un cliente gráfico para Subversion que se integra con el shell de Windows, gracias a esta integración es posible que los cambios hechos sobre un proyecto se diferencien a través de los íconos que se asignan de acuerdo a diferentes estados que puede tener un archivo.

TortoiseSVN icon overlays

Pero como todo en la vida, nada viene gratis 🙂 , puesto que ésta característica puede funcionar de dos formas:

Por omisión

Se almacena el caché de estado en un proceso separado (TSVNCache.exe). Este proceso está al tanto de los cambios que se realizan en todas las particiones.

Shell

El cacheo se realiza directamente dentro de la dll de la extensión del shell, pero sólo para la carpeta actualmente visible. Cada vez que navega a otra carpeta, se obtiene de nuevo la información de estado.

TortoiseSVN Icon Overlays Settings

Retomando el punto, para reducir la actividad en disco que realiza el proceso TSVNCache.exe se tiene que hacer uso de las opciones Exclude/Include paths de modo que sólo se limite la verificación de cambios al directorio donde están ubicados nuestros proyectos. Un ejemplo para un disco con tres particiones podría ser:

code:

Exclude paths:
C:\*
D:\*
E:\*

Include paths:
D:\SVN\*

Con estos cambios seguramente reduciran muchos eventos que se realizan sobre archivos o carpetas, que dicho sea de paso, pueden verlo con FileMon.

Categories
Web WordPress

Beta1 de WordPress 2.3.1

Actualización: Ya está disponible la versión final de WordPress 2.3.1.

Acaban de anunciar la liberación de la primera versión menor de la rama WordPress 2.3, que entre otras cosas trae las siguientes mejoras y correcciones a fallas:

  • Soporte nativo para agregar tags desde Windows Live Writer.
  • Mejora de rendimiento para realizar las intersecciones de tags y categorías.
  • Corrección de un bug en la edición y creación de páginas (no se escapaba el HTML).
  • Corrección a la vulnerabilidad -- que algunos la consideran erróneamente "grave" -- que permite a usuarios registrados agregar enlaces al blogroll, para blogs donde el registro de usuarios no está habilitado este problema es inofensivo.

Pueden ver una lista más completa de problemas solucionados en la página de registro de bugs.

Descargas

Categories
WordPress

¿Cómo reducir el consumo de memoria de algunos plugins de WordPress?

Uno de los problemas derivados del uso de plugins en WordPress es el consumo de memoria, el cual es proporcional al número de plugins activos o más específicamente al número de líneas de código que el interprete de PHP tiene que cargar y ejecutar en cada petición.

Una forma para lidiar con este problema en determinados plugins es separar la definición de éstos (añadir filtros, acciones, etc) del código que implementa su funcionalidad, de este modo podemos cargar el código sólo si se cumplen ciertas condiciones.

Como ejemplo, voy a tomar el popular Google XML Sitemaps que con sólo activarlo aumenta unos 600 KB el consumo de memoria anterior y dada las características de este plugin, solamente debería ejecutarse cuando se genera o modifica contenido. Este proceso es relativamente sencillo:

  • Crear un nuevo archivo en el mismo directorio del plugin anterior. Para el ejemplo lo llamaremos sitemap_plugin.php.
  • Ubicar y mover los metadatos (nombre y datos del autor) del plugin al nuevo archivo. Para el ejemplo movemos las líneas 30 a 37 de sitemap.php:
    php:

    <?php
    /*
     Plugin Name: Google XML Sitemaps
     Plugin URI: http://www.arnebrachhold.de/redir/sitemap-home/
     Description: This plugin will generate a sitemaps.org compatible sitemap of your WordPress blog which is supported by Ask.com, Google, MSN Search and YAHOO. <a href="options-general.php?page=sitemap.php">Configuration Page</a>
     Version: 3.0
     Author: Arne Brachhold
     Author URI: http://www.arnebrachhold.de/
     */

    ?>
  • A continuación se debe indentificar y mover la parde donde se "registran" los filtros y acciones (add_filter, add_action, etc.) que hacen que el plugin sea invocado. Para el ejemplo, esta parte se encuentra en las líneas 3652 a 3656 de sitemap.php, lugar donde se invoca al método Enable de la clase GoogleSitemapGenerator:
    php:

    <?php
    /*
     Plugin Name: Google XML Sitemaps
     Plugin URI: http://www.arnebrachhold.de/redir/sitemap-home/
     Description: This plugin will generate a sitemaps.org compatible sitemap of your WordPress blog which is supported by Ask.com, Google, MSN Search and YAHOO. <a href="options-general.php?page=sitemap.php">Configuration Page</a>
     Version: 3.0
     Author: Arne Brachhold
     Author URI: http://www.arnebrachhold.de/
     */

    if(defined('ABSPATH') && defined('WPINC')) {   
            if ( is_admin() || defined('XMLRPC_REQUEST') && constant('XMLRPC_REQUEST') && !empty($HTTP_RAW_POST_DATA) ) {
                    require_once(dirname(__FILE__) . '/sitemap.php');
                    add_action("init", array("GoogleSitemapGenerator","Enable"), 1000,0);
            }
    }
    ?>

    La condición de la línea 12 sirve para filtrar el tipo de peticiones que llegan al blog, en otras palabras el plugin sólo se cargará si entramos a la parte de administración* o se hace una petición a través de XMLRPC.

  • Desactivar y volver a activar el plugin una vez hecho los cambios.

Con este simple cambio hecho sobre el plugin Google XML Sitemaps se reduce el consumo de memoria para la mayoría de peticiones que se realizan sobre un blog, sin embargo, sacrificando un poco de funcionalidad todavía se puede optimizar un poco más usando WP-Cron.

*: En realidad el método is_admin() sólo verifica que la URL contenga wp-admin/, no necesariamente significa que estamos en el panel de administración.

Categories
Desarrollo de Software Miniposts WordPress

Enlaces varios

Algunos enlaces que posiblemente les resulten interesantes:

  • Descarga gratuita del libro Domain Driven Design Quickly: Un libro de introducción para DDD, incluye los siguientes capítulos:
    1. Building Domain Knowledge
    2. The Ubiquitous Language
    3. Model Driven Design
    4. Refactoring Toward Deeper Insight
    5. Preserving Model Integrity
    6. Interview with Eric Evans on why DDD matters today
  • Screencast: Test-Driven Domain Model: un screencast (idioma: inglés, duración: 50 minutos, lenguaje: C#) que muestra un ejemplo introductorio sobre el desarrollo orientado a pruebas.
  • C# Intellisense Test: comentan como realizan las pruebas que se hacen sobre el intellisense para C#.
  • Historial de funciones de WordPress: herramienta útil para los que desarrollan plugins de WordPress y quieren mantener la compatibilidad con versiones anteriores.
Categories
.NET MySQL

Generar backups de bases de datos MySQL desde .NET

En general prefiero realizar los backups desde scripts, pero muchas veces esta tarea se debe realizar desde la misma aplicación. Algo a tomar muy en cuenta si opta por este camino, es que los backups -- en lo posible -- deben ser generados con las herramientas que el motor de base de datos trae para este fin.

En los ejemplos se muestra el uso de mysqldump y la clase Process, que según MSDN proporciona acceso a procesos locales y remotos, y permite iniciar y detener procesos del sistema local:

csharp:

public void Backup(string  args)
{
        ProcessStartInfo psi = new ProcessStartInfo(ConfigurationManager.AppSettings["MysqlDump"], args);
        string filename = Path.Combine(workingDir, DateTime.Now.ToString(@"yyyy-MM-dd.\sql"));
       
        using (StreamWriter writer = new StreamWriter(filename, false, Encoding.UTF8))
        {
                using(Process process = new Process())
                {
                        psi.CreateNoWindow = true; // Evita que el proceso se inicie en una nueva ventana.
                        psi.UseShellExecute = false; // Evita que se use el shell del sistema operativo para iniciar el proceso.
                        psi.RedirectStandardOutput = true; // Escribir la salida en Process.StandarOuput
                        psi.StandardOutputEncoding = Encoding.UTF8; // Codificación de los datos de salida
       
                        process.StartInfo = psi;
                        process.OutputDataReceived += delegate(object sender, DataReceivedEventArgs e)
                        {
                                writer.WriteLine(e.Data);
                        };
       
                        process.Start();
                        process.BeginOutputReadLine(); // Lectura asincrónica del stream de salida
                        process.WaitForExit(); // Esperar a que el proceso termine.
                }
        }
}

Aunque en el código mostrado es más sencillo realizar algún proceso sobre los datos generados, hay que tener muy en cuenta la codificación de los datos en los backups, puesto que por un descuido se puede generar fácilmente basura.

Si se quiere evitar estos problemas de codificación, se podría usar algo como:

csharp:

public void Backup(string args)
{
    string filename = Path.Combine(workingDir, DateTime.Now.ToString(@"yyyy-MM-dd.\sql"));
    ProcessStartInfo psi = new ProcessStartInfo("cmd.exe",
                                                string.Format("/c \"\"{0}\" {1} > \"{2}\"\"",
                                                              ConfigurationManager.AppSettings["MysqlDump"], args,
                                                              filename));

    psi.CreateNoWindow = true;
    psi.UseShellExecute = false;

    using (Process process = new Process())
    {
        process.StartInfo = psi;
        process.Start();
        process.WaitForExit();
    }
}

En fin, usar uno u otro método va a depender de los requerimientos de la aplicación.