sábado, 20 de noviembre de 2010
Reflexión sobre el amor
Amando a aquel que me hizo mal,
Haciendo lo que digo ser:
Si soy listo, usar la cabeza,
Si soy capaz, cumplir mis metas,
Si soy curioso, conocer.
Si quiero que cualquier ser
Mis faltas deje en el olvido
Lo mismo haré con los demás,
Echando el orgullo atrás,
Disfrutando lo vivido.
Porqué reprimo algo tan grande,
Si no tengo amor nada soy,
En cualquier tiempo, incluso hoy,
Puedo honrar al que dio su sangre.
Y que el amor no se confunda,
Pon atención a esta pregunta:
Si te necesito para ser feliz,
Y dejar atrás de un día lo gris,
Se ha despertado un mal dormido:
La carencia ha florecido.
Porqué somos tan egoístas
Privando al mundo de sonrisas,
Esto ayuda al desdichado;
Y no es para nada errado,
Ayudar al que está a mi lado,
Hacerle ver que al caer
Digno es de admiración
Levantarse sin roer
Y aprender una lección;
También hay que ser capaz
Como dijo una doncella
De amar hasta que duela
Y cuando duela amar más.
RZM
miércoles, 28 de abril de 2010
Un poco de usuarios y permisos
System.Threading.Thread.CurrentPrincipal.Identity.Name, el usuario del contexto de seguridad, por lo general es el que va a tener acceso a algunos recursos, esta se puede ver a través de:
System.Security.Principal.WindowsIdentity.GetCurrent().Name, y el usuario encargado de correr el proceso.
El usuario autenticado prácticamente puede tener cualquier cosa desde “vacío” en el caso de que se utilice autenticación anónima en el IIS o la aplicación esté configurada para no utilizar autenticación del todo (
Otro punto importante es la impersonificación (Impersonate). Si a través del web.config habilitamos la impersonificación (
En ambientes con IIS 6 o superior todo sitio Web se ejecuta bajo un aplication pool, el default application pool tiene asignada la cuenta de NETWORK SERVICE, es por esto que esta es la cuenta que corre el proceso por defecto, así las cosas, otra opción para resolver el problema anterior podría ser utilizar un pool customizado con una cuenta específica.
También hay situaciones en las que el acceso al recurso específico es por usuario, pero como medida de seguridad, no se desea impersonificar siempre, en estos casos se podría llevar a cabo una impersonificación temporal a través del objeto WindowsImpersonationContext, esto se ilustra en el siguiente ejemplo, accesando un WebService:
localhost.Service proxy = new localhost.Service();
IPrincipal p = this.User;
WindowsIdentity wi = (WindowsIdentity)p.Identity;
WindowsImpersonationContext wic = wi.Impersonate();
try
{
// Recurso que requiere cierto permisos
proxy.Credentials = CredentialCache.DefaultCredentials;
retorno = proxy.HelloWorld();
}
finally
{
wic.Undo();
}Y ya que estamos con un ejemplo de acceso a un WebService cabe destacar que al accesar un WebService desde un sitio Web el usuario del contexto de seguridad, pasaría a ser el usuario autenticado dentro del mismo, por ejemplo si el usuario autenticado es “rzumbado” y el usuario del contexto de seguridad es ASPNET, al llamar al servicio Web, dentro del contexto del mismo, ASPNET pasaría a ser el usuario autenticado, siempre y cuando se utilice la sentencia se asignen las DefaultCredentials a las credenciales del proxy (proxy.Credentials = CredentialCache.DefaultCredentials;). De no asignarse las credenciales, el servicio Web se estaría accesando de forma anónima.
Una vez explicado esto se puede entender porqué, un WebService sin autenticación anónima por lo general da un error de acceso denegado si no se setean las credenciales y porqué en un WebService sobre el que no tiene acceso ASPNET o NETWORK SERVICE hay que impersonificar temporal o permanente o utilizar un usuario customizado a través de un aplication pool en IIS 6.
martes, 20 de abril de 2010
Sobre Cursores y Tablas Temporales
La prueba consistió en lo siguiente, creé una tabla con cuatro columnas, nada especial, de hecho tomé una tabla de pruebas que ya existía en la base de datos:
CREATE TABLE Test(
Col1 int NULL,
Col2 int NULL,
Col3 numeric(16, 2) NULL,
Col4 int NULL
) ON PRIMARYE inserté ciertos valores, probé con cantidades tan variadas como 10.000 o 700.000 registros
DECLARE @i decimal(8), @j decimal(8)
SET @i = 1
SET @j = 300000
WHILE @i <= @j
BEGIN
INSERT INTO Test(Col1, Col2, Col3, Col4) VALUES(1,10,500,8)
SET @i = @i + 1
ENDLa prueba básica consistió en realizar lo que más comúnmente hacemos con este tipo de objetos, que es crear la estructura, llenarla y procesarla obteniendo la información de la misma.
Primero hice pruebas con tablas temporales y variables tipo tabla, en teoría lo recomendable es utilizar variables tipo tabla con cantidades pequeñas de registros y tablas temporales con cantidades más grandes, me sorprendió que en todos los casos fue más veloz el uso de tablas temporales, en el peor de los casos duró 22 seguros, mientras que el uso de variables tipo tabla duró 29. Si bien es cierto la diferencia no es mucha comparativamente hablando, si fue un comportamiento que siempre se dio:
-- 22
SELECT * INTO #Test FROM Test
SELECT * FROM #Test
DROP table #Test-- 29
DECLARE @Test TABLE (
Col1 int NULL,
Col2 int NULL,
Col3 numeric(16, 2) NULL,
Col4 int NULL)
INSERT @Test SELECT * FROM Test
SELECT * FROM @TestPara constatar que no estubiera afectando el hecho de que con el uso de tablas temporales se estaba omitiendo la creación explícita de la misma, además de la forma de llenado, también hice las mismas pruebas con un tabla temporal, pero creándola explícitamente y llenándola con una cláusula INSERT-SELECT en vez del SELECT-INTO, utilizado en el ejemplo anterior. En este caso los tiempos de respuesta fueron prácticamente iguales que los arrojados con la prueba de la variable tipo tabla
-- 29
CREATE TABLE #Test (
Col1 int NULL,
Col2 int NULL,
Col3 numeric(16, 2) NULL,
Col4 int NULL)
INSERT #Test SELECT * FROM Test
SELECT * FROM #Test
DROP table #TestPara enriquecer aun más la prueba, hice lo mismo con tablas permanentes. En este caso, el peor escenario duró más que el procesamiento de la tabla temporal (42 segundos), pero le di el beneficio de la duda al haberse creado en la base de datos actual, misma que para este efecto en particular estaba más saturada que TempDB, que es donde se almacenan las tablas temporales, por lo que hice otra prueba en donde creaba la tabla permanente en la misma base de datos de las tablas temporales y el comportamiento fue básicamente el mismo de estas con un tiempo en el peor caso de 30 segundos:
-- 42
CREATE TABLE Test2 (
Col1 int NULL,
Col2 int NULL,
Col3 numeric(16, 2) NULL,
Col4 int NULL)
INSERT Test2 SELECT * FROM Test
SELECT * FROM Test2
DROP table Test2-- 30
CREATE TABLE tempdb.dbo.Test2 (
Col1 int NULL,
Col2 int NULL,
Col3 numeric(16, 2) NULL,
Col4 int NULL)
INSERT tempdb.dbo.Test2 SELECT * FROM Test
SELECT * FROM tempdb.dbo.Test2
DROP table tempdb.dbo.Test2Este conviene traer a la reflexión lo que muchas veces pasa con las tablas temporales, como ya se mencionó se almacenan en TempDB, demás de otros objetos, como variables, cursores, objetos internos del motor, versiones de filas generadas por las transacciones, etc. En la medida en que se utilicen en exceso este tipo de objetos, dicha base de datos puede ver afectado su rendimiento, en el ejemplo que hice pasó lo inverso, porque en dicho servidor se utiliza muy poco la base de datos TempDB, pero la base de datos del sistema si tendía a sobrecargarse. Muchas veces se sataniza el uso de tablas temporales, pero al igual que todo, es cuestión de moderación.
Para terminar la prueba faltaba el caso de los recorridos, los cursores siempre han sido muy criticados por causar latencia, esto es cierto por lo que en la manera de los posible hay que evitar su uso, lamentablemente no siempre es ta sencillo evitar usarlos, por ejemplo en casos en que hay que realizar algún tipo de cálculo por cada registro. Las pruebas se realizaron con los mismos escenarios de las anteriores y por lo general rondó el doble o más de que tardaba el proceso con tablas temporales, en el peor escenario duró 61 segundos:
-- 61
DECLARE @Col1 int, @Col2 int, @Col3 numeric(16, 2), @Col4 int
DECLARE cursor_test CURSOR FOR
SELECT *
FROM Test
OPEN cursor_test
FETCH NEXT FROM cursor_test INTO @Col1, @Col2, @Col3, @Col4
WHILE @@FETCH_STATUS = 0
BEGIN
FETCH NEXT FROM cursor_test INTO @Col1, @Col2, @Col3, @Col4
END
CLOSE cursor_test
DEALLOCATE cursor_testPara mostrar la alternativa a los cursores realicé otro caso con un recorrido a una variable de tipo tabla, a través de una lógica que me encontré en más de un sitio, a razón de ser sincero al ver dicho código no me parecía que fuera muy eficiente, de hecho esperaba una forma menos artesanal de llevar a cabo dicha labor, pero no encontré ninguna, sin embargo viendo un poco los comentarios de los artículos esperaba alguna sorpresa, sin embargo no fue así, de hecho no puedo decir cuánto duró el peor escenario porque no tuve la paciencia de esperar, pero tardó más de 6 minutos. Para poder ver resultados, con el fin de constatar que la lógica estubiera bien tuve que probar con 10.000 registros arrojando una duración de desesperantes 15 segundos, contra un tiempo menor a un segundo con los clásicos cursores.
-- > 300
DECLARE @rowId int, @maxRowId int
DECLARE @Col1 int, @Col2 int, @Col3 numeric(16, 2), @Col4 int
DECLARE @Test2 TABLE (
rowId int identity(1,1),
Col1 int NULL,
Col2 int NULL,
Col3 numeric(16, 2) NULL,
Col4 int NULL)
INSERT @Test2 SELECT * FROM Test
SELECT
@rowId = min(RowId),
@MaxRowId = max(RowId)
FROM @Test2
WHILE @RowId <= @MaxRowId BEGIN
SELECT @Col1 = Col1, @Col2 = Col2,
@Col3 = Col3, @Col4 = Col4
FROM @Test2
WHERE RowId = @RowId
SET @RowId = @RowId + 1
END
sábado, 9 de enero de 2010
Sobre Elecciones 2010 Costa Rica
Candidato: Laura Chinchilla
Partido: Partido Liberación Nacional, PLN
Plan de Gobierno: http://www.pln.or.cr/docs/plangobierno2010_2014.pdf
Página Web: http://www.pln.or.cr, http://www.laurachinchilla.com
Candidato: Otto Guevara
Partido: Movimiento Libertario, ML
Plan de Gobierno: En su sitio Web informa que el plan se presentará públicamente hasta el 12 de enero del 2010, http://www.movimientolibertario.net/presentacion-de-plan-de-gobierno
Página Web: http://www.movimientolibertario.net, http://www.ottoguevara2010.com
Candidato: Ottón Solís
Partido: Partido Acción Ciudadana, PAC
Plan de Gobierno: http://otton.cr/downloads/ConvocatoriaCiudadana.pdf
Página Web: http://pac.cr/, http://otton.cr
Candidato: Luis Fishman
Partido: Partido Unidad Social Cristiana, PUSC
Plan de Gobierno: http://www.fishman.co.cr/files/Resumen-ejecutivo.pdf
Página Web: http://www.partidounidadsocialcristiana.com, http://www.fishman.co.cr
Candidato: Rolando Araya
Partido: Alianza Patriótica, AP
Plan de Gobierno: http://www.araya2010.com/files/PROGRAMA_AP.pdf
Página Web: http://www.ap.cr, http://www.araya2010.com
Candidato: Oscar López
Partido: Partido Accesibilidad Sin Exclusión, PASE
Plan de Gobierno: http://oscarlopez.net/cms2/images/stories/propuestapase.pdf
Página Web: http://oscarlopez.net
Candidato: Eugenio Trejos
Partido: Frente Amplio, FA
Plan de Gobierno: http://www.frenteamplio.org/wp-content/uploads/2009/12/programa12puntos.pdf
Página Web: http://www.frenteamplio.org
Candidato: Walter Muñoz
Partido: Partido Integración Nacional, PIN
Plan de Gobierno: No encontré un plan de gobierno en su sitio Web, aunque aquí vienen algunas propuestas, http://www.pin.freeservers.com/propuestas.html
Página Web: http://www.pin.freeservers.com, en este mismo sitio dice que su página nueva es http://www.pin.co.cr, pero actualmente está caída.
Candidato: Mayra González
Partido: Partido Renovación Costarricense
Plan de Gobierno: http://www.partidorenovacioncostarricense.com/PlanGobierno2010.pdf
Página Web: http://www.partidorenovacioncostarricense.com
domingo, 29 de noviembre de 2009
Martial Arts - Part Two, Internal Kung Fu
Martial Arts
The word "martial", it's originated from Mars, the god of the war in Roman mythology. The term "Martial Art" for itself, it means the artistic expression of the combat, without losing the application of martial laws and principles. Although at the present time India hasn't any recognized modern martial art, in that country was originated the Hindu martial art "Varajmushti", the father of all the Chinese systems, and consequently of the rest of them.
The modern martial arts are mostly from the oriental region of the planet, and more specifically from China, Japan and Korea. Nowadays, the most popular and traditional China method it's the "Kung Fu" that it means "Ability", and whose origin dates from the sixth century BC, the Kung Fu has been also defined as any technique or martial art with Chinese origin, an example is "Wing Chun", created in the XVII century, which was practiced by the legendary Bruce Lee. Lee also created his own martial art, "Jeet Kune Do" or "way of the interceptor fist", which gathers philosophies of Wing Chun, such as to defend and to attack simultaneously, according Bruce Lee, the purpose of Jeet Kune Do was more philosophical than physical and it gathered the useful things of the other martial arts discarding the useless things. The main purpose was defeating the enemy with the minimum effort. On the other hand, Japan has developed great quantity of methods, "Sumo" is the traditional Japanese sport, This technique was probably originated before the Christian era; "Kendo" that literally means "Via of the sable", and it is also known as the Japanese fencing; "Kenpo" that means in Japanese language "Law of the fist", this refers to any kind of combat originated in China developed in Japan; Nin Jitsu, that used to be used by the old Ninjas and Samurais, this method taught its practitioners, how to exist or survive in any place or situation. Another Japanese method is the "Jiu Jitsu" this became the samurai's ideal defense method. Due to its complexity, another martial arts was created to be focused in specific areas. Some of them are "Karate Do" that means "Empty Hand" and was originated in the VI century at Okinawa city, Jigoro Kano's "Judo", which is characterized by the use of locks, and the Moriei Ueshiba's Aikido, which consists on a synthesis of the Karate, Judo and Jiu Jitsu. Aikido means "Method of the union or harmonization of the energy". These last two arts were originated respectively in the last two centuries. Maybe the most famous Korean martial art in the western region is "Tae Kwon Do", created by Lieutenant Choi to developing an own national martial art more superior in technical as in spirit than the Japanese Karate. This martial art began to be developed since the year 1946 until 1954. April eleventh 1955 this method took the name of Tae Kwon do, that means "Method of blocking kicking"; other Korean martial arts are "Sipa Ki Do", which has official registrations since 1.392, this consists on teaching as quick as possible to any person; "Han Mu Do" that means "The way of the Korean martial arts", this technique was created by Dr. He-Young Kimm in 1989, this is another empty hand technique; "Hap Ki Do" that is the art of the Korean personal defense, it was founded by the Great Master Ji Han Jae in the year 1.959, this uses all type of techniques to survive in a dangerous situation; and "Tang Su Do" that means "China hand way", this martial art was created by the great master Hwang Kee. This name was also used in Korea to make reference to any martial art. The North American actor Chuck Norris is an exponent of this sport.
Although the previously mentioned techniques was originated at the oriental area of Asia, the martial arts have been developed around the world, in countries like Brazil, United States, Israel, Malaysia, Thailand, Russia, Vietnam and France. Important arts developed in this other places are "Muay Thai" or "Thai boxing"; the recently developed American arts as the Kickboxing and the Full Contact, which starts since 1968; and Brazilian techniques like "Brazilian Jiu Jitsu" which is well-known by the effectiveness of their techniques in real fights, "Vale Tudo" and "Capoeira", although for some people the last one isn't a real martial art.
viernes, 27 de noviembre de 2009
Load Balancing
Uno de los grandes temas cuando se habla de balanceo de carga en aplicaciones Web, es lo concerniente al manejo del estado, como es bien sabido, un sitio Web es una aplicación Stateless (o sea que no mantiene información de estado por sí sola), para esto han existido innumerables técnicas ya sean desde el lado del cliente o el servidor, donde podríamos decir que la más popular es una técnica de servidor denominada Session State. El Session State consiste el almacenar en la memoria del servidor Web información de estado por cada cliente. En un ambiente de granjas esto puede acarrear inconvenientes, debido a que si un cliente hizo una solicitud al sitio que se procesó por el Nodo X, puede ser que la siguiente solicitud se haya procesado por el Nodo Y, y al ser estos dos nodos servidores diferentes, cada uno con su memoria propia, es imposible para ellos compartir dicha información, por lo que se perdería. Algunas de las técnicas utilizadas para solventar esto es la Persistencia, que consiste en que una vez que se ha creado una sesión para un cliente, el balanceador debe ser responsable de manejar los siguientes requests en el mismo servidor que lo atendió hasta que la sesión del mismo haya expirado. Talvez los dos principales inconvenientes achacados a esta técnica son las siguientes: primero, que si el servidor que estuvo atendiendo al cliente, falla, toda la información del mismo se perdería; y segundo, que no se estaría explotando el concepto de balanceo, sobre todo en aplicaciones que manejen pocos usuario que realizan muchos requests, aunque este último caso conformarían un escenario realmente atípico. Volviendo al primer inconveniente, igualmente en un ambiente en el que no existiese balanceo de carga, el problema de pérdida de sesión en caso de fallo se daría, por lo que esta situación no es achacable al uso de un balanceador. Una técnica de balanceo muy conocida que es propietaria de Microsoft es el NLBS (Network Load Balancing Service), esta técnica es por software y maneja persistencia a través del concepto de Afinidad del Cliente (Client Affinity), la cual se puede manejar por cliente (Para Intranet) o por dirección IP de clase C (para Internet).
Otra opción para evitar el problema de pérdida de información de estado, es almacenar dicha información en un servidor dedicado; ya sea este una base de datos, otro servidor Web, o un servidor con algún tipo de servicio o demonio, accesado a través de un puerto. Principalmente con la solución de base de datos se resuelve el problema de la pérdida de información en caso de fallo. Con las otras técnicas la caída de un servidor Web no acarrearía la pérdida de información, pero sí la caída del servidor dedicado, a no ser que dicha información no se almacene en memoria, si no en algún repositorio de información persistente como un archivo o una base de datos.
Un tema interesante al que se le puede seguir el rastro es el concepto de Application Delivery Controller, que ha sido nombrado Next Generation Load Balancer (balanceador de carga de la siguiente generación), el cual consiste en un dispositivo de red que a la hora de asignar un servidor busca el servidor más rápido que esté disponible y maneja aspectos tales como caché y seguridad.