Blog de Francisco Velázquez

otro blog personal

Archive for July 2011

Simple cache para BusinessObjects

leave a comment »

Debido a la naturaleza de mi trabajo, aplicaciones multitenant, y servicios M2M, para mejorar el rendimiento suelo cachear muchos objectos que tienen un tasa de lectura muy alta y de cambios muy muy pequeño. Así que para facilitar el trabajo, me he decido crear una pequeña utilidad.

    /// <summary>
    /// Concurrent cache for BusinessObject.  It doesn´t clean cache, useful for small data.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class BusinessObjectCache<T>
        where T : BusinessObject<T>
    {
        static ReaderWriterLockSlim Locker = new ReaderWriterLockSlim();
        static volatile Dictionary<object, T> storage;

        static BusinessObjectCache()
        {
            Locker.EnterWriteLock();
            try
            {
                storage = new Dictionary<object, T>();
            }
            finally { Locker.ExitWriteLock(); }
        }

        public T Get(object id)
        {
            T o = null;
            Locker.EnterReadLock();
            try
            {
                if (storage.ContainsKey(id))
                {
                    o = storage[id];
                    return o;
                }
            }
            finally { Locker.ExitReadLock(); }

            if (o == null)
            {
                Locker.EnterUpgradeableReadLock();
                try
                {
                    if (!storage.ContainsKey(id))
                        o = BusinessObject<T>.Retrieve(id);

                    if (o != null)
                    {
                        Locker.EnterWriteLock();
                        try
                        {
                            storage[id] = o;
                        }
                        finally { Locker.ExitWriteLock(); }
                    }
                }
                finally { Locker.ExitUpgradeableReadLock(); }
            }

            return o;
        }
    }

A ver si me lo curro y la hago LRU.

Advertisements

Written by fravelgue

July 21, 2011 at 5:44 pm

Posted in development

Tagged with , ,

Simple HTTP GET en C#

leave a comment »

La verdad es que, a veces, cosas sencillas se hacen  complicadas en .NET y en mi opinión esta es una de ellas. Nada que objetar a que un framework tiene que ser lo menos restrictivo posible, pero en este caso no encuentro el sentido de que un error HTTP tenga que lanzar una excepción, yo personalmente la definiría como excepción vexing. Y bueno como estamos para ayudar pues con esta pequeña función todo será un poco más sencillo.

        public static int Get(string uri, int timeout, out string response)
        {
            int statusCode = -1;
            response = string.Empty;

            HttpWebRequest request = WebRequest.Create(uri) as HttpWebRequest;
            request.KeepAlive = false;
            request.Timeout = timeout;

            try
            {
                using (HttpWebResponse res = (HttpWebResponse)request.GetResponse() as HttpWebResponse)
                {
                    statusCode = (int)res.StatusCode;
                    using (Stream dataStream = res.GetResponseStream())
                    {
                        using (StreamReader reader = new StreamReader(dataStream))
                        {
                            response = reader.ReadToEnd();
                        }
                    }
                }
            }
            catch (WebException wex)
            {
                //http://msdn.microsoft.com/en-us/library/es54hw8e.aspx
                if (wex.Status == WebExceptionStatus.ProtocolError)
                {
                    // If status is WebExceptionStatus.ProtocolError,
                    // there has been a protocol error and a WebResponse
                    // should exist. Display the protocol error.
                    using (HttpWebResponse res = wex.Response as HttpWebResponse)
                    {
                        if (res != null)
                        {
                            statusCode = (int)res.StatusCode;

                            using (Stream s = wex.Response.GetResponseStream())
                            using (StreamReader reader = new StreamReader(s))
                            {
                                response = reader.ReadToEnd();
                            }
                        }
                        else
                        {   // no http status code available
                            throw wex;
                        }
                    }
                }
                else
                {   // no http status code available
                    throw wex;
                }
            }

            return statusCode;
        }

Cuanto más veo ese código, menos me gusta como está diseñado.
Un par de enlaces.

Written by fravelgue

July 19, 2011 at 7:27 pm

Posted in development

Tagged with , , , , ,