Etichette

venerdì 18 marzo 2011

Riflettendo...

Ci vogliono tante lezioni per imparare a cavalcare le onde.
Succede la stessa cosa nella vita: devi aspettare parecchio tempo per raggiungere i tuoi scopi o per realizzare che le cose migliori nella vita sono gratuite. 

 
° S.Bambaren - Il vento dell'Oceano °



Come al solito ritengo importante dare senso alle parole..... e navigando in internet, trovo cose interessanti


.

martedì 15 marzo 2011

Nucleare e altro ancora

Scusate ma sono stanco,  sono stanco di sentire questi falsi moralisti italiani, che dicono che noi anti nuclearisti stiamo prendendo spunto dall'immane tragedia giapponese per appoggiare la nostra tesi.

Stanco di sentire sputare cavolate,  sentire parlare  ministri che non ne sanno niente di nucleare,  parlare di falsi all'allarmismo, non voglio sentire voi, voglio sentire gli esperti, quei ricercatori di fisica, Ingeneri Nucleari,  insomma facciamo parlare l'università, insomma paghiamo i nostri soldi per avere un università statale dove la gente dovrebbe studiare queste cose, e non la facciamo parlare?
A scusate è vero... dopo l'ultima riforma parlare di università statale è veramente angosciante,  pensare che dopo aver tagliato l'impossibile ci sia ancora qualche "TESTA" in italia è veramente dura, avete ragione!

Allora parlo io e da ignorante (quasi ignorante, qualche pezzo di carta l'ho preso anche io), e mi domando perché se uno tsunami devasta un campo eolico, o un campo solare non mi devo preoccupare e l'unico che si deve preoccupare è il proprietario se non lo ha assicurato  per eventi catastrofici?
Perchè se  un fulmine colpisce una centrale idroelettrica, la mia preoccupazione sarà quella di procurarmi delle candele e pensare che forse staserà non potrò vedere "Amici" (quel programma bellissimo della defilippis?), mentre se per caso esplode una centrale nucleare la mia preoccupazione  principale  sarà:
"Cavolo fra poco sarò io ad illuminarmi come una lampadina!!! e probabilmente come lampadina durerò anche poco!"


Rimango male, quando  dicono che eventi come quello giapponese in italia non avverranno, e poi penso ma come mai in Giappone i palazzi sono ancora tutti in piedi, mentre all'aquila sono tutti stati rasi al suolo o resi inagibili??
Perché la casa dello studente dell'aquila  si è sbriciolata come un grissino, e una scuola elementare del Giappone è ancora intatta, e la maestra mentre succedeva il terremoto , ha fatto mettere tutti i bambini in fila e li ha fatti  salire ordinatamente sul terrazzo?

E chiudo con un ultima riflessione:
Dove li dovremmo prendere questi trenta miliardi che servono per il nucleare???
Preferisco lavare i piatti, scrivere il mio blog solo se c'è il sole, che pensare che un giorno mio figlio andrà in una scuola senza futuro, senza cultura, senza ricerca... in cui imparerà a rispondere ai quiz ma non imparerà a pensare....

domenica 6 marzo 2011

Kuan Kun

Chi è Kuan Kun?
questa domanda ha risuonato, per un periodo non ben definito nella mia mente.... perché?
Perchè la mia scuola di Kung Fu è una scuola tradizionale, che oltre ad insegnare le tecniche dell'arte Marziale, da anche una serie di informazioni teoriche, sulla cultura cinese e in particolar modo sull'arte marziale cinese....
Per cui mentre ci alleniamo, molto spesso, vengono fatte delle domande di teoria, che non riguardano solo le tecniche ma anche la cultura cinese.
E cosi, come potete ben immaginare quella volta  è toccato a me: "Chi era Kuan KUN?"
ovviamente la risposta fu il silenzio, meglio non tirare ad indovinare!

Kuan Kun è un guerriero mitico o mitologico dell'antica cina, si fa risalire la sua morte al 220 d.c.,  la sua miticità  lo ha portato oggi ad essere  considerato il protettore  dei combattenti.
Gia da bambino, educato da sua madre, si vide costretto ad uccidere un uomo malvagio, che aveva  preso di mira i suoi concittadini, e da li inizia il suo pellegrinaggio.
OLtre ad essere stato un valoroso combattente, oggi lui incarna l'idea della persona giusta, non solo rappresenta la forza, l'agilità, la destrezza, ma rappresenta la giustizia, il retto comportamento.
Insomma noi siamo vissuti pensando che Superman fosse  il guerriero valoroso, mentre oggi scopro che c'era qualcuno più "forte" di lui. La cosa buffa è che superman era un extratterrestre, e in piu con super poteri, Kuan Kun noooo! Kuan Kun era un guerriero valoroso, che acuisito le suo abilità con il tempo e l'esercizio e il sacrificio.... Cavolo Super Man c'è nato!! che sforzo ha fatto per essere lui!
Senza essere demagogici,  oggi come oggi  c'è proprio questo tipo di cultura,  quella della via facile, quella della speranza di avere i super poteri,  e di poter fare di conseguenza il bene per noi stessi, esempio classico, speriamo di nascere gnocca e  se nasco uomo speriamo di essere fico.... sicuramente un posto in qualche consiglio regionale se so gnocca e disposta al Bunga Bunga lo trovo, altrimenti da uomo  posso andare a fare il tronista da maria de filippis, oppure mi affido a lele mora!!!! sempre meglio di niente.....
(epilogo progmaticamente triste)

sabato 5 marzo 2011

Creare una cache locale

Nel l'ultimo periodo mi sono imbattuto nel tentare di ottimizzare e velocizzare le prestazioni di un software, con architettura client - server.

Premesso che:

  • Il software non lo avevo ne progettato ne realizzato io, per cui non conoscevo molto della sua struttura.
  • Che non c'era documentazione (grave errore) a mia disposizione (ovviamente come nella maggior parte delle situazioni in cui mi sono trovato, mi pare che sia un po un vizio degli  sviluppatori non lasciare mai traccia).
  • Che avevo i sorgenti a disposizione, ma che purtroppo non c'era un briciolo di commento su nessun file, neanche in testa, sai quelle cose del tipo:"questa classe ha questo compito", insomma un milione o forse piu di righe di c# (non le ho contate) 
  • Che avevo  poco tempo per inventarmi qualcosa per far velocizzare il software.

Possiamo proseguire....

Aggiungo  al tutto, a mo' di sale nell'insalata mista,  che Il software salvava i propri dati  in una base dati MSSQLSERVER 2005.

Vi dico con sincerità che Il mio  approccio fu quello di dire:
"Cavolo ho i sorgenti! per cui sono come DIO quando creò l'uomo e la donna", ma avrei dovuto capire subito che non era la strada corretta, non tanto per l'essere o non essere DIO, quanto al fatto che mi pare che anche a DIO con l'uomo e la donna non abbia fatto proprio un bel lavoro!!

Comunque ho iniziato a cercare nel codice, ma da subito ho capito che era una via poco percorribile, allora come si dice:" ho attaccato il profiler" ( cioè si avvia un software che monitorizza le attività del server sql mostrandoti eventuali query o istruzioni che possono causare rallentamenti).
Della serie, non si sa mai quale sia la via corretta!

Dopo un po  di analisi ho pensato che quella era la strada giusta, le query erano molte e si ripetevano inspiegabilmente decine di volte, sempre le stesse, e alcune query di queste erano particolarmente pesanti.
L'idea mi ronzava nella testa:
"Poter creare uno strato di cache su SQL in modo, da evitare il ripetersi delle query, e evitare di ripetere oltre tutto le query molto lunghe".


Il problema era sicuramente come incastrare uno strato di cache sql dentro un programma, in modo piu o meno  trasparente, e piu o meno indolore.

Una bella sfida!

L'idea è arrivata, dovevo creare una classe, che fungesse da cache, in cui mettere  tutti gli oggetti che volevo  in una tabella di  HASH, per avere  il massimo nella ricerca, e nella flessibilità.
In aggiunta potevo utilizzare i GENERICS, per rendere totalmente astratta la tabella, e in piu utilizzando il PATTERN SINGLETON, potevo rendere la mia classe persistente per tutto il ciclo di vita del software.
l'idea era veramente buona (melo dico pure da solo)
La cosa importante era che potevo inserire in cache qualsiasi cosa, e riutilizzarla in qualsiasi momento   nel programma in esecuzioni, ma ci sono dei MA.
MA - PERO'
Ovviamente ci sono anche i ma e i però da considerare, in modo da mettervi in alert nel caso vogliate fare anche voi questa scelta.
Il primo e più importante di tutti è che qui ci giochiamo la nostra esperienza nella conoscenza della programmazione ad oggetti, nel classico diatriba di cosa fa l'assegnazione di un oggetto ad un altro: nel 99,99% dei casi assegnare un oggetto ad un altro vuol dire passare il riferimento a quell'oggetto e non copiare un oggetto in un altro, questo è fondamentale perché se noi assegniamo un oggetto ad una tabella HASH stiamo dicendo che con un KEY, possiamo recuperare il riferimento a quell'oggetto e non l'oggetto stesso, percui se qualche altro oggetto al di fuori della nostra cache  modifica l'oggetto, modificherà anche l'oggetto che ho messo in cache...
Facciamo un metafora culinaria:
Io ho un piatto di pasta, e vorrei metterlo in cache perche dopo potrei averne bisogno, il piatto si trova  in frigorifero. Assegnando il piatto di  pasta alla cache, io non faccio altro che scrivere  in un mio block note che il piatto di pasta è in frigorifero, ma purtroppo il frigorifero lo condivido con mi moglie, presa da un attacco di fame, aperto il frigorifero si magia tutta la pasta, lasciando il piatto vuoto. Quando a me verrà fame, prenderò il mio taccuino (cache) e cercherò piatto di pasta, e troverò scritto si trova in frigorifero, aprendo in frigorifero troverò il piatto vuoto!!!
Questo problema è risolvibile in informatica, poichè è possibile, prima di inserire in cache un qualsiasi oggetto, clonare l'oggetto stesso, purtroppo clonare un piatto di pasta è un pochino piu complesso!!!
Altro Però, da mettere in risalto, è che  sarebbe stato bello mettere in cache l'oggetto DATAREADER
 ma purtroppo non è possibile, ne metterlo in cache come reference, ne si può clonare (come la pasta alcuni oggetti in informatica non si possono clonare), ma dei dettagli tecnici ne parleremo in un altro post.
Adesso mettiamo giu un po di codice, cosi potete vedere se vi piace:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Text;
using System.Reflection;
using System.Reflection.Emit;
using System.Threading;
using System.IO;
using System.Xml;


namespace XXXXXX.Common
{
    public delegate TResult Func<T1, TResult>(T1 arg1);


    public sealed class AOCache<T>
    {
        
#region Cache cleaner parameters


//Default: 15 minuti
private int cc_interval = 15;
private string cc_intervalType = "M";
private DateTime lastCacheCleaning;


#endregion


private static volatile AOCache<T> instance;
                private static object syncRoot = new Object();
                public  Dictionary<string,T> cache;



   //FUNZIONE MADRE con questo istanzio la cache  in singleton
        public static AOCache<T> Instance
        {
            get
            {
                if (instance == null)
                {
                    lock (syncRoot)
                    {
                        if (instance == null)
                            instance = new AOCache<T>();
                    }
                }

instance.checkCache_toClean();

                return instance;
            }
        }


/// <summary>
/// Legge le impostazioni sul file di configurazione e setta il timeout per il CC
/// </summary>
private void settaCacheCleaner()
{
string config_path =Path.Combine(AppDomain.CurrentDomain.BaseDirectory,"program.config");
XmlDocument doc = new XmlDocument();
try
{
doc.Load(config_path);


XmlNode CC = doc.DocumentElement.SelectSingleNode("cacheCleaner");


this.cc_interval = int.Parse(CC.InnerText);
this.cc_intervalType = CC.Attributes["type"].Value;
}
catch
{
//lasciamo i parametri di default
}
}


/// <summary>
/// Puliamo la cache se abbiamo oltrepassato il limite di tempo
/// </summary>
private void checkCache_toClean()
{
DateTime limit;
try
{
if (this.cc_interval == 0) //Non svuotare mai la cache
throw new Exception();


switch (this.cc_intervalType)
{
case "S": //Secondi
limit = this.lastCacheCleaning.AddSeconds(this.cc_interval);
break;
case "M": //Minuti
limit = this.lastCacheCleaning.AddMinutes(this.cc_interval);
break;
case "H": //Ore
limit = this.lastCacheCleaning.AddHours(this.cc_interval);
break;
default: //Nessuno dei tre caratteri ammessi: non svuotiamo la cache
throw new Exception();
}
                System.Reflection.Assembly a = System.Reflection.Assembly.GetEntryAssembly();


                if (DateTime.Compare(DateTime.Now, limit) > 0 || a.FullName.Contains("program2"))
cache.Clear();
}
catch
{
// Non interveniamo sulla cache
}
}
        
        private AOCache()
        {
            cache =new Dictionary<string,T>();
            ok = utlizzoCache();
this.lastCacheCleaning = DateTime.Now;


AOCacheManager.Manager.Add(this);
        }
        
        //Leggo il file di configurazione per verificare se la cache è gestita
        private bool utlizzoCache()
        {
            return true;
        }


    
        public void add(string Key, T value) {


                if (cache.ContainsKey(Key))
                    cache.Remove(Key);
                cache.Add(Key, value);
        }


public void remove(string Key)
{
if (cache.ContainsKey(Key))
cache.Remove(Key);
}


public void clear()
{
cache.Clear();
this.lastCacheCleaning = DateTime.Now;
}


        public bool TryGetValue(string key,out T value)
        {


            if (ok)
            {


                return cache.TryGetValue(key, out value);


            }
            else
            {
                value = default(T);
                return ok;
            }


        }


Quella in grassetto è la funzione madre, che istanzia l'oggetto cache e in cui si vede applicato il Singleton, le altre sono funzioni a corredo.
Ringrazio ufficialmente il mio collega JO (detto Jocondo) che mi ha aiutato  nel completare e debbuggare le funzionalità.