diff --git a/README.md b/README.md new file mode 100644 index 0000000..14923e9 --- /dev/null +++ b/README.md @@ -0,0 +1,52 @@ +### Feature che vorremmo avere + +* da una persona vogliamo vedere le nostre interazioni passate con questo + * quindi dobbiamo mettere tra gli "streammati" anche gli utenti del servizio +* sto interagendo con un tot, capire chi è che "conta di più" tra di loro + * versione semplice: dato un tot di persone guardo metadati e, in una storia recente, retweet tra di essi + * i metadati si possono prendere con le API + * i retweet probabilmente solo con il crawler +* ricerca frasi: "il primo che l'ha detto" + + +Esistono degli "utenti": essi possono accedere alle nostre API per vedere un "twitter aumentato" + +### Architettura proposta + +#### Schema generale + +Lo schema è complesso, è vero, però abbiamo evitato di usare software troppo strani o di basarci su feature avveniristiche. Il tutto dovrebbe rimanere relativamente semplice da capire/interagirci. + +Abbiamo UN database mongodb; un frontend scritto in Go; dei crawler in linguaggi vari ed eventuali ma con interfacce HTTP ben definite; un Inseritore/Validatore che riceve messaggi dai crawler e li mette su mongo. In realtà i crawler possono anche vivere "dentro" il frontend quando sono particolarmente semplici. +Il frontend accede a Mongo in sola lettura. Il browser/client dell'utente parla SOLO col frontend. Il frontend dovra' quindi ricevere sia richieste che sono semplici interrogazioni, sia richieste che implicheranno la partenza di uno o più crawler. Questi crawler produrranno dei dati. Li passano all'inseritore, che li mette dentro mongo. + +Tutte le interazioni tra programmi diversi avvengono in HTTP. Questo permette di usare librerie semplici; di contattare crawler su altre macchine. La cosa di parlare tra diverse macchine è comoda perché ad esempio si possono mettere più crawler che escono da più IP. + + +#### Inseritore +L'inseritore esiste per "mediare" le scritture su mongo. Il vantaggio di passarli all'inseritore invece di mettere direttamente i dati dentro mongo, è che così possiamo: + +1. validare! possiamo controllare che i dati ci sembrino corretti +2. "riformattare". In particolare volevamo aggiungere un campo "generator" in cui scrivere *quale* crawler ha inserito il dato. In questo modo, in caso di errori di programmazione che comportano l'inquinamento della base dati, li si può ritrovare/cancellare/correggere più facilmente +3. evitare che i crawler abbiano il supporto di libreria a mongodb + + + +#### Frontend + +Il frontend contiene un po' di logica; tipo se l'utente gli chiede "dammi delle informazioni sommarie su Mario" lui allora magari fa partire una query su mongo per vedere cosa sa su mario; vedendo che non c'è molto fa partire 3 crawler, uno per i metadati, uno per gli ultimi 30 tweet, uno boh. +Sarà scritto in Go perché dovrà tenere traccia di queste cose asincrone con un minimo di ordine che in Python ci verrebbe difficile. In altri linguaggi non siamo boni. + +#### Crawler + +I crawler devono essere quindi degli oggetti asincroni, in grado di ricevere richieste HTTP mentre crawlano. Siccome puo' darsi che noi vorremo riciclare programmini di merda, allora facciamo un wrapperino che: + +* fa partire un server web +* quando riceve una richiesta POST, fa partire un programma che prende i dati della POST come stdin + * finche' il programma non termina, mette tutto in coda senza far partire altro + * se il programma termina con exit code 0 allora bene, toglie dalla coda, e prosegue lanciandone un altro + * se il programma termina con exit code non-zero allora rimette in coda e ci riprova tra un po' +* dice al frontend che ha finito + + +Chiaramente si può pure fare che i crawler capiscono l'HTTP da soli; questo è meglio perché il rate limit si può impostare meglio.