Windows Phone SDK RTM is here


E' ufficiale, Windows Phone SDK RTM e' disponibile a tutti gratuitamente, http://windowsteamblog.com/windows_phone/b/wpdev/archive/2010/09/16/windows-phone-developer-tools-are-final.aspx.

Insieme all'SDK, tovrerete delle aggiunte come:

Buona programmazione a tutti.

author: Pierre Greborio | posted @ giovedì 16 settembre 2010 06:27 | Feedback (0)

Keyboard


La tastiera e' lo strumento di input principe che ha caratterizzato il PC sin da suo esordio sul mercato. E' quella componente del PC che difficilmente riusciamo a fare a meno. Con l'avvento dell'iPhone molti bloggers e giornalisti hanno iniziato ad immaginare che forse era venuto il momento di fare a meno della tastiera classica, quella fisica con i tasti da premere.

Sebbene una tale valutazione sia criticabile, un fondo di verita' c'e'. Per anni la tastiera ha subito pochissimi miglioramenti, a parte qualche evoluzione ergonomica e di colori. In contrapposizione alla tastiera fisica e' arrivata la tastiera virtuale, la quale puo' essere categorizzata in on-screen oppure proiettata. Ricordo che la tastiera su schermo non e' stata inventata da Apple, ma dall'AT&T nei primi anni 90 (Patent 546704). Il merito di Apple e' stato quello di renderla mainstream! Sebbene Steve Jobs, in una delle sue innumerevoli sortite marketing, decreto' la fine della tastiera fisica, cio' non successe. Il motivo fondamentale e' che la tastiera fisica ha delle caratteristiche che la tastiera virtuale non riesce a soddisfare.

Le piu' importanti sono:

1. Tatto. La mano 'sente' i tasti fisicamente e questo permette di digitare senza guardare i tasti, con un incremento di battiture per minuto decisamente notevole...credo che il Guinness dei primati sia 150 wpm!

2. Ergonomicita'. Le testiere moderne sono decisamente ergonomiche e riducono notevolmente problemi fisici parecchio comuni in passato.

Di contro, il problema principale della tastiera fisica e' la sua staticita'. I simboli sono definiti a priori e cambiarli non e' praticabile. Non e' solo un problema di layout internazionale, ma anche di adattabilita' al contesto applicativo. Questa limitazione e' decisamente uno degli elementi fondamentali a favore della tastiera virtuale, oltre allo spazio.

La soluzione e' quindi passare alla tastiera virtuale? No! La tastiera virtuale e' in un certo senso l'opposto di quella fisica, risolve il problema dei simboli ma crea il problema di ergonomicita' e tatto, rendendola inefficace per la digitazione massiva del testo (30 wpm).

Sebbene questi due mondi sembrino contrapposti, in realta' si stanno ricongiungendo. Da una lato la tastiera sta superando il problema dei simboli, con l'introduzione della tastiera adattiva, dall'altro si trovano gestures che rendono piu' efficiente la digitazione su tastiera virtuale.

In conclusione, il ruolo della tastiera fisica rimane sempre fondamentale per la sua incredibile usabilita' nel contesto della scrivania. Ad accompagnarla, c'e' la testiera virtuale, sempre piu' efficiente e applicabile al contesto fuori dalla scrivania.

author: Pierre Greborio | posted @ lunedì 13 settembre 2010 21:31 | Feedback (0)

CAPTCHA


CAPTCHA (Completely Automated Public Turing test to tell Computers and Humans Apart) e' una tecnica sviluppata qualche anno fa per evitare che un automa possa fare le veci di un umano per compiere operazioni in modo massivo. Viene molto usato nei sistemi di registrazione per evitare che qualche automa si metta a creare milioni di accounts.

Come tutte le storie di guardie e ladri, a seguito di queste tecniche si sono sviluppate tecnologie basate sul riconoscimento dei caratteri (OCR) per cercare di superare questo limite. La risposta e' stata quindi quella di distorcere ulteriormente i caratteri in modo da rendere molto piu' difficile il riconoscimento. Peccato che cosi' facendo anche  l'umano sia sia trovato in grande difficolta'.

Come soluzione (o se preferite pezza), alcuni siti hanno aggiunto un pulsante che permette di sentire l'audio del testo da inserire. Sebbene questo aiuti, in realta' presenta diverse limitazioni, fra cui l'internazionalizzazione.

Recentemente ho trovato una soluzione interessante, risolvere un'operazione algebrica. Ad esempio si chiede all'utente quale e' il risultato di 1 + 2. Se estendiamo il concetto a soluzioni di problemi di matematica o logica, possiamo intravedere un ampissimo spettro di solutioni. Vedo diversi vantaggi immediati in una soluzione di questo tipo:

  1. La lettura, anche con TTS (Text To Speech), e' immediata
  2. Non ci sono problemi di localizzazione
  3. La complessita' del problema puo' variare nel tempo
  4. E' formativo! Un po' di matematica e logica non fa mai male

author: Pierre Greborio | posted @ lunedì 13 settembre 2010 00:54 | Feedback (2)

Natural user Interfaces


Natural user Interfaces, NUI (http://en.wikipedia.org/wiki/Natural_User_Interface), e' un argomento che attrae attenzione di ricercatori, designer e programmatori da quando

e' nato il computer. Molto lavoro e' stato fatto e possiamo dire che gia' oggi si intravedono grandi risultati, ma siamo ancora molto lontano dall'obiettivo finale.

Uno dei principi fondamentali delle NUI consiste nello sfruttare tutte le capacita' umane in base al contesto. Per capacita' umane intendo quelle capaci di interagire con

un dispositivo, qualunque esso sia. Ad esempio:

1. Tastiera
2. Mouse
3. Penna
4. Multi touch
5. Voce
6. Movimenti spaziali
7. Pensiero

Avere a disposizione dispositivi capaci di sfruttare le suddette capacita', in una scala da 1 a 10 direi che siamo a livello 2 nella commercializzazione ed a livello 6

nella ricerca. La ricerca pero' non si sofferma solamente ai dispositivi, va oltre definendo l'iterazione dei suddetti dispositivi con l'uomo nei vari contesti sociali e

storici. Ad esempio la psicologia cognitiva gioca un grande ruolo in questa ricerca.

Per dare una assaggio di quello di cui sto parlando, rimando a questo video, mms://msvcatalog-1.wmod.llnwd.net/a2249/e1/ft/share3/dd69/0/Productivity_Future_Vision.wmv.

author: Pierre Greborio | posted @ lunedì 16 agosto 2010 08:30 | Feedback (0)

Si volta pagina


Questo sarebbe il primo post del 2010 e dato che nel 2009 ne ho scritti ben 8, devo darmi da fare prima di abbassare il mio record negativo :-)

L'inizio del 2009 e' stato parecchio pesante, a maggio abbiamo shippato KIN (http://www.facebook.com/KIN). La parte sulla quale ho lavorato io non aveva nulla a che fare con il cellulare, io mi occupavo del sito Silverlight chiamato KIN Studio (http://studio.vz.kin.com). Dopo aver lavorato in media 12 ore al giorno per 1 anno e mezzo, inclusi parecchi week-end, a giugno mi sono preso un mese di vacanza nella bellissima Calabria :-)

Durante il mio soggiorno vengo a sapere che KIN e' dato per defunto, da un lato perche' le vendite erano basse e dall'altro per focalizzarsi su Windows Phone 7 (http://www.windowsphone7.com/). Quando ho letto la notizia ho lanciato qualche imprecazione, ma poi ho dimenticato tutto con un bel bagno al mare. Non c'e' momento migliore per essere in vacanza!!

Che si fa ora? Il nostro nuovo charter e' sviluppare applicazioni per Windows Phone 7. La buona notizia e' che continuero' a sviluppare con Silverlight, la brutta e' che mi dovro' dimenticare di avere un giga di memoria a disposizione ed uno schermo da 24 pollici.

Sinceramente mi sento molto ottimista con Windows Phone 7. C'e' molto lavoro e la competizione, aka iPhone, Android, Nokia e RIM e' ferocissima, ma stiamo veramente lavorando sodo per cambiare le cose. Sono pronto as commettere che in 2 anni ci riprendiamo il 20% del mercato :-)

author: Pierre Greborio | posted @ martedì 3 agosto 2010 14:39 | Feedback (0)

Sistemi di logging


La mia carriera e' iniziato con lo sviluppo client side, dopo pochi anni sono passato al server side e da circa 1 anno e mezzo sono nei cloud services. E' incredibile vedere quante differenti problematiche si debbano affrontare.

Recentemente abbiamo discusso del sistema di logging. Non tanto in termini di quale tecnologia quali .NET logging, NLog, ETW, o altro, quanto le problematiche da superare nel cloud. Uno dei probemi maggiori e la quantita'. Pensate a Facebook (http://idleprocess.wordpress.com/2009/11/24/presentation-summary-high-performance-at-massive-scale-lessons-learned-at-facebook/) il quale processa 25TB di messaggi al giorno. Solo nel nostro ambiente di test, con circa 300 utenti, generiamo circa 25MB di messaggi al minuto.

Nella discussione abbiamo caratterizzato la problematica in quasti termini:

  • Minimizzare l'impatto sui server di produzione, bufferizzaddo i messaggi di log in memoria e scrivedoli su disco a blocchi
  • Minimizzare l'impatto sui dischi usando un sistema di rotazione dei files
  • Minimizzare l'impatto sulla rete spostando log files non troppo grossi per una successiva processazione
  • Non filtrare per severita' a priori. Il logging serve a capire che cosa e' successo port-mortem, se si filtra si perdono informazioni preziose
  • Arricchire i protocolli di comunicazione fra componenti in modo da permettere la tracciabilita' (correlazione)
  • Accettare perdite di dati (logs)

Nel nostro team usaimo un sistema proprietario (MS) consolidato da altri servizi. Detto cio', credo che siamo ancora abbastanza lontano da una soluzione generalizzata per i cloud services.

 

 

 

author: Pierre Greborio | posted @ lunedì 14 dicembre 2009 07:45 | Feedback (2)

Nuovo attacco alla logica di rinegoziazione TLS


E' notizia di oggi, http://extendedsubset.com/?p=8, che sia stata trovata una falla nella rinegoziazione TLS.

Per sommi capi, l'hacker puo' avviare una negoziazione TLS con il server and successivamente fare da proxy alla negoziazione del client attraverso lo 'stesso' canale. Questo permette all'hacker di iniettare del contenuto arbitrario all'inizio dei dati spediti dal client TLS al server TLS. I server trattera' questi dati come se provenissero dal client. Una volta che l'handshake si e' concluso, l'hacker non puo' fare piu' nulla di utile.

L'hacker non sara' in grado di vedere il contenuto (plaintext) scambiato con il server, ma puo' comunque:

  • Mandare comandi che vengono rispediti al client, ad esempio comandi di autenticazione (incluso quello basato su certificati)
  • Potenzialmente accedere ai dati spediti dal client usando i comandi spediti al punto precedente che implicano l'invio di questi ad un server terzo

La cosa sembra parecchio seria e riproducibile. Non ci sono al momento fix disponibili.


author: Pierre Greborio | posted @ mercoledì 4 novembre 2009 22:55 | Feedback (0)

Storage nel cloud: Partizionamento


Mi sono assentato per in certo periodo in quanto aspettavo un buon momento per poter parlare di SDS (SQL Data Services). Purtroppo, non ne posso ancora parlare e quindi mi invento un'altro argomento, comunque fondamentale.

Una delle caratteristiche peculiari dello storage nel cloud e' quella di poter scalare, potenzialmente scalare indefinitivamente. Fino a qualche anno fa, scalare il database significava aggiungere dischi, e se la potenza di calcolo non era sufficiente, aggiungere nodi al cluster. Non vi e' dubbio che scalare con un cluster, oltre ad incrementare i costi esponenzialmente, presenta comunque un limite fisico oltre al quale non si puo' crescere.

Google, sin dalla sua prima comparsa, ha introdotto il concetto di scalabilita' usando un hardware di basso costo. SDS, cosi' come altre soluzioni, stanno cavalcando la stessa idea. Ma come fanno a scalare un database linearmente mantenendo i costi accettabili.

La soluzione si basa su due aspetti importanti:

  • Partizionamento dei dati
  • Replica

Immaginiamo che un singolo data server (SQL Server) sia in grado di gestire 10GB di dati. Bene, se dovete gestire 25GB di dati vi serviranno 3 data server e farete in modo di spalmare i dati fra i tre server, possibilmente in modo uniforme.

Avere un singolo server, nodo, ci espone di fronte ad un singolo punto di fallimento. Ecco che quindi entra in gioco la replica. In altre parole i dati potranno essere replicati su altri server in modo che se uno di questi fallisce, l'altro compensa.

Questa semplice tecnica permette servizi come Microsoft SDS, Amazon Simple DB ed altri, di poter fornire il servizio del database a basso costo e con grande livello di affidabilita'. Nel caso particolare di SDS, Microsoft garantisce 3 copie dei dati per ogni partizione.

Per ora mi fermo qui, in un prossimo futuro entrero' meglio nei dettagli del partizionamento in quanto ha un impatto diretto su come si scrivono le applicazioni.

author: Pierre Greborio | posted @ lunedì 1 giugno 2009 15:18 | Feedback (0)

Storage nel cloud: latenza, BEB


Nel post dedicato alla latenza, ho illustrato una delle tecniche per mitigare il piu' possibile i problemi legati al timeout. La tecnica si basa sostanzialmente sul riprovare.

L'algoritmo che ho implementato, NRetryPolicy, e' molto primitivo e presenta parecchie imperfezioni, oltre a non risolvere il problema e potenzialmente peggiorarlo. Il lettore attento infatti si sara' accorto che se riproviamo ad intervalli fissi potremmo avere un effetto a valanga generando, involontariamente, un attacco di DOS (Denial Of Service) al servizio stesso. Come?

Immaginiamo di avere un carico costante di chiamate di 100 RPS. Ad un certo punto il 20% di queste vanno in timeout. Queste riproveranno dopo un certo ammontare, che avete definito voi, di tempo. Scattato questo intervallo il servizio dovra' supportare il 20% in piu' di richieste, quindi 120 RPS. La probabilita' che queste vadano ancora in timeout aumenta, e quindi si ripropone il problema al prossimo intervallo. Immaginiamo ora che 40 di queste richieste siano andate in timeout. Al prossimo giro 140 RPS. Avento un limite di tentativi, diciamo 3, non dovremmo superare 160 RPS considerando un errore (timeout) costante del 20%.

Come risolvere il problema? Cambiando il pattern dei tentativi, passando da un sistema costante e statico ad un sistema casuale. Essendo un problema molto comune, anche nelle telecomunicazioni e nelle reti, ci appoggeremo ad un algoritmo ben conosciuto, denominato Binary Exponential Backoff.

L'algoritmo e' semplice, riprova randomicamente sulla base di un intervallo esponenziale (2n - 1). Immaginando che l'unita' di intervallo (delta backoff) sia 1 secondo, al primo fallimento riprova subito, al secondo un tempo random incluso fra 0 e 1 secondo, la seconda volta un tempo random fra 0 e 3 secondi, la terza volta un tempo rando fra 0 e 7 secondi e cosi' via.

L'implementazione e' abbastanza triviale:

 

public class ExponentialNRetryPolicy : RetryPolicy
{
    int numberOfRetries;
    TimeSpan minBackoff;
    TimeSpan maxBackoff;
    TimeSpan deltaBackoff;
    private readonly Random Random = new Random();

    /// <summary>
    /// Policy that retries a specified number of times with a randomized exponential backoff scheme
    /// </summary>
    /// <param name="numberOfRetries">The number of times to retry. Should be a non-negative number.</param>
    /// <param name="deltaBackoff">The multiplier in the exponential backoff scheme</param>
    /// <returns></returns>
    /// <remarks>For this retry policy, the minimum amount of milliseconds between retries is given by the
    /// StandardMinBackoff constant, and the maximum backoff is predefined by the StandardMaxBackoff constant.
    /// Otherwise, the backoff is calculated as random(2^currentRetry) * deltaBackoff.</remarks>
    public ExponentialNRetryPolicy(int numberOfRetries, TimeSpan deltaBackoff)
        : this (numberOfRetries, TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(30), deltaBackoff)
    {           
    }

    /// <summary>
    /// Policy that retries a specified number of times with a randomized exponential backoff scheme
    /// </summary>
    /// <param name="numberOfRetries">The number of times to retry. Should be a non-negative number</param>
    /// <param name="deltaBackoff">The multiplier in the exponential backoff scheme</param>
    /// <param name="minBackoff">The minimum backoff interval</param>
    /// <param name="maxBackoff">The maximum backoff interval</param>
    /// <returns></returns>
    /// <remarks>For this retry policy, the minimum amount of milliseconds between retries is given by the
    /// minBackoff parameter, and the maximum backoff is predefined by the maxBackoff parameter.
    /// Otherwise, the backoff is calculated as random(2^currentRetry) * deltaBackoff.</remarks>
    public ExponentialNRetryPolicy(int numberOfRetries, TimeSpan minBackoff, TimeSpan maxBackoff, TimeSpan deltaBackoff)
    {
        if (minBackoff > maxBackoff)
        {
            throw new ArgumentException("The minimum backoff must not be larger than the maximum backoff period.");
        }
        if (minBackoff < TimeSpan.Zero)
        {
            throw new ArgumentException("The minimum backoff period must not be negative.");
        }

        this.numberOfRetries = numberOfRetries;
        this.minBackoff = minBackoff;
        this.maxBackoff = maxBackoff;
        this.deltaBackoff = deltaBackoff;
    }

    public override void Retry(Action action)
    {
        int totalNumberOfRetries = numberOfRetries;
        int retryCount = numberOfRetries;
        TimeSpan backoff;

        do
        {
            try
            {
                action();
                break;
            }
            catch (RetryException e)
            {
                if (retryCount == 0)
                {
                    throw e.InnerException;
                }
                backoff = CalculateCurrentBackoff(minBackoff, maxBackoff, deltaBackoff, totalNumberOfRetries - retryCount);
                if (backoff > TimeSpan.Zero)
                {
                    Thread.Sleep(backoff);
                }
            }
        }
        while (retryCount-- > 0);
    }

    private TimeSpan CalculateCurrentBackoff(TimeSpan minBackoff, TimeSpan maxBackoff, TimeSpan deltaBackoff, int curRetry)
    {
        long backoff;

        if (curRetry > 30)
        {
            backoff = maxBackoff.Ticks;
        }
        else
        {
            try
            {
                checked
                {
                    // only randomize the multiplier here
                    // it would be as correct to randomize the whole backoff result
                    backoff = Random.Next((1 << curRetry) + 1);
                    backoff *= deltaBackoff.Ticks;
                    backoff += minBackoff.Ticks;
                }
            }
            catch (OverflowException)
            {
                backoff = maxBackoff.Ticks;
            }
            if (backoff > maxBackoff.Ticks)
            {
                backoff = maxBackoff.Ticks;
            }
        }
        return TimeSpan.FromTicks(backoff);
    }
}

 

 

E con questo credo che abbiamo concluso l'argomento di come limitare gli effetti indesiderati della latenza.

author: Pierre Greborio | posted @ giovedì 12 marzo 2009 15:11 | Feedback (0)

Storage nel cloud: le soluzioni in casa Microsoft


Nel primo post dedicato all'argomento, ho elencato due servizi che verranno forniti da Microsoft nei prossimi mesi. Si tratta di Windows Azure Storage e SQL Server Data services (SSDS).

Che differenza c'e' fra questi servizi? Detto che saranno tutti in hosting presso i datacenter di Microsoft, possiamo dire che Windowas Azure Storage fornira' lo storage per blobs, queue e tables (non relazionali), mentre SSDS un database relazionale.

Chi ha avuto modo di guardare a SSDS in passato, si sara' reso conto che di relazionale ha ben poco a che fare, se non il legame fra authority, container ed entity. Bene, quella versione (comunque una CTP) di SSDS sparisce per fare spazio al database relazionale. E' infatti di ieri l'annuncio ufficiale sul blog di SSDS.

I dettagli mancano ancora, io comunque darei un acch'io al prossimo MIX (sessione MIX09-T06F) ;)

author: Pierre Greborio | posted @ martedì 10 marzo 2009 16:48 | Feedback (2)