<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">Il giorno 22 aprile 2015 18:58, enrico franchi <span dir="ltr"><<a href="mailto:enrico.franchi@gmail.com" target="_blank">enrico.franchi@gmail.com</a>></span> ha scritto:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span class=""></span><span class=""></span><span class=""><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div></div><div>l'ultimo in ordine di tempo mi è successo con djangorestframework: in base ad un parametro many=True mi istanziava "a mia insaputa" una classe wrapper che conteneva la mia<br></div><div>Questo significava che non avevo alcun modo semplice per fare l'override/plug<br></div><div>Insomma, mi sono convinto che il principio stesso che "può succedere di chiamare il costruttore di una classe ma qualcuno (presumibilmente per il tuo bene) decide di restituirtene un altra", beh, non mi piace granchè<br></div></div></div></div></blockquote><div><br></div></span><div>Ma non e' che tu parli semplicemente di definire __new__? Per quello io ho diversi use-case interessante.</div></div></div></div></blockquote><div><br></div><div>cavolo, hai ragione, bastava __new__<br></div><div>ora, calma, aspetta un momento, io ricordo distintamente che usavano una metaclasse ...<br></div><div>o io ho citato a casaccio oppure loro facevano un overkill<br></div><div><br>in realtà ricordo solo che volevo uscirne il prima possibile perchè mi ci ero imbattuto solo per riuscire a far andare come volevo io le browsable api in un caso particolare<br></div><div>insomma, come dire che mi trovavo con il motore a posto e stavo perdendo tempo sul tappino degli pneumatici<br></div><div>ricordo vagamente di aver dato qualche martellata e aver fissato in qualche modo quel disgraziato di tappino<br></div><div>e centrava una metaclasse, giuro<br></div><div><br></div><div>se posso domani ci guardo<br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span class=""><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div></div><div>In questi casi tendo ad usare una funzione che faccia da Factory<br></div><div>Sarò pure meno cool, ma preferisco essere più esplicito e comprensibile<br></div></div></div></div></blockquote><div><br></div></span><div>Il problema e' che c'e' sempre prima o poi il pistola che non la chiama e fa a mano. Statistico. E la volta che succede e la cr non passa per le mie mani... Il che vuole dire che se e' un nice to have, va bene. Se instanziare direttamente rompe la semantica della classe, niente, vai di __new__, mi prendo lo sbattimento io, ma almeno non verro' svegliato alle quattro di notte.</div><div><br>Si, ok... potrei sempre avere la famosa _Classe. In questi casi di solito basta. </div><span class=""><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><span><br></span></div><div><span>Al momento non alcun motivo valido per scomodare Tornado nei miei progetti: Django con i worker uWSGI mi vanno benissimo<br></span></div></div></div></div></blockquote><div><br></div></span><div>A me Django sta molto stretto. Non amo particolarmente il fatto che se devo fare qualche API call dentro Django rischia di andare in timeout il tutto.</div></div></div></div></blockquote><div><br></div><div>api http, intendi? ok, capisco<br></div><div>l'altro timeout sarebbe il caso di client websockets o comet o roba simile...<br><br></div><div>beh, certo, in particolare per il secondo caso django non reggerebbe<br></div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div>Si, certo... dovrei spostare tutta sta roba in Javascript e tanti saluti. </div></div></div></div></blockquote><div><br></div><div>ok, lasciamo perdere le websockets per il momento, ma se hai solo il problema di operazioni potenzialmente lunghe (es. le api che si diceva)<br></div><div>allora perchè Javascript? basta delegare ad una batteria di processi di backend<br></div><div>un po' di risorse in più e passa la paura<br>... oddio, poi cosa si intenda con "un po' di risorse in più" dipende dalla scala del problema!<br></div><div>(ogni riferimento al committente di qualcuno di noi è puramente causale :-) )<br></div><div><br></div><div>ok, introducendo i back-end, l'architettura si incasina: no doubt<br><br>ci vorranno come minimo...<br>coda (redis?) per passaggio parametri fra front-end e backend, supervisor dei backend (dovrai pur monitorare lo stato dei processi), staging area per i risultati (su db, ehm, dipende...), notifiche differite all'utente, gestione delle transazioni db e gestione delle eccezioni (già, perchè se qualcosa va storto qualcuno presumibilmente lo deve venire a sapere, e magari senza necessariamente doversi tenere davanti il tail -f di un log del server)<br><br></div><div>insomma, ti tieni il buon vecchio sequenziale ma il tuo bel flusso request/response http e ormai poco più che un "vissero felici e contenti" quando ormai le fiabe sei tu a leggerle ad altri<br><br></div><div>ma so che sto dicendo cose note, diciamo che me le ripeto per convincermi che sto facendo la scelta giusta<br><br></div><div>la mia situazione è che, sebbene continui ad essere alla ricerca dell' "architettura di backend pulita definitiva" e non sia riuscito a trovarla, tuttavia l'asincrono (o event driven o callback che dir si voglia) sono riuscito totalmente ad evitarlo<br><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span class=""><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><span></span></div><div>Diciamo che ho risentito parlare di Tornado con asyncio e la prima domanda da nerd è "datemi un occasione per giocarci, se non me la date me la invento!"<br></div></div></div></div></blockquote><div><br></div></span><div>Caruccio, si. Poi detto fra noi... Asyncio non e' che mi abbia colpito troppo.</div></div></div></div></blockquote><div><br></div><div>ah, si? cosa non ti convince?<br></div><div><br></div><div>per quanto mi riguarda io ho perso un po' il treno (per mia fortuna, credo) di dovermi scontrare con gevent, callback, greenlet, stackless-python, twisted e compagnia cantante<br></div><div>mi aveva pigliato molto erlang ma alla fine non ho avuto bisogno neanche di quello <br><br></div><div>per cui a questo punto spero che asyncio sia il "preferably one and only one method" che dovrò veramente studiarmi<br><br></div><div>arriva un po' tardi? forse<br></div><div><br></div><div>beh, io lo spero che sia "one and only one"</div><div>e se lo fosse, beh... meglio tardi che mai<br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span class=""><div class="gmail_quote"> <br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div>5. etc. etc. etc.<br></div></blockquote><div>In Python 3 puoi scrivere ...</div><div>E' sintassi valida.</div></div></span><span class=""><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span><div><br></div></span><div>uhm, questa temo di non averla capita ...<br></div></div></div></div></blockquote><div><br></div></span><div>Eh, non ho un python 3 per fare lo snob.</div><div>Essenzialmente ... e' sintassi valida di Python 3. Presente quando si scrive</div><div><br></div><div>class Foo(Bar):</div><div>    ...</div><div><br></div><div>per intendere che poi ci metti quello che ti pare? Ecco, e' Python 3 valido.</div></div></div></div></blockquote><div><br></div><div>ma dai!<br>non si finisce mai di imparare<br><br>per dirlo in modo idiomatico (delle mia parti)<br>Ogni mês si fâs la lune, ogni dì s'impare une<br><br><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span class=""><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div>ma dato che i miei progetti sono soprattutto DB-bound (si può dire?) guadagnare sul CPU-time lato pure-python sarebbe più o meno inifluente<br></div></div></div></div></blockquote><div><br></div></span><div>1. mi piace un sacco la definizione db-bound. Proprio perche' in effetti, in linguaggi come Python la differenza di performance fra db e python e' talmente tanta che roba che logicamente dovrebbe essere I/O bound in effetti potrebbe essere CPU bound. No shit.</div><div>2. Quindi no, altro che ininfluente. Io mi aspetto che le cose migliorino parecchio. </div><div><br></div><div>Se il tuo db e' veloce e la tua query e' scritta bene, c'e' proprio il caso che il collo di bottiglia sia il python che ti porta i risultati nel mondo Python. E potrebbe anche essere piu' vero se hai un ORM che ti crea oggetti complessi (ma non ho dati su questo).</div><div> </div></div><div>Poi con gli ORM e' difficile da dire: magari sotto sta facendo tante di quelle query insensate che il db non puo' fare miracoli.</div></div></div></blockquote><div><br></div><div>io ho in realtà un approccio di ottimizzazione piuttosto banale che seguo spesso<br></div><div>vado effettivamente lento? misurare, misurare, misurare, Ora e ad ogni passo successivo<br></div><div>ok, eliminiamo le cause più stupide (es. manca un indice)<br></div><div>non basta? andiamo a vedere quante "query insensate" sta facendo l'orm, e spalmiano un po' di hint (select_related, values, iterator, etc.)<br></div><div>non basta? sql-diretto, mi riscrivo io la query sql. Punto (in realtà "punto" un cavolo, perchè, mannaggia, va a finire che mi devo reimplementare una parte della logica applicativa di aggregazione scrivendola in sql)<br></div><div><br></div><div>poi, per carità, qui io l'ho fatta lineare mentre in realtà ad ogni passo mi chiedo se avrebbe senso usare memcache per qualcosa, oppure se lo schema dei dati è fallato perchè eccessivamente normalizzato (o stupidamente denormalizzato), poi ci sono anche frequenti casi in cui mi chiedo se ho sbagliato lavoro<br><br></div><div>ma va beh, alla fine della fiera mi ritrovo con una bella query che... mi fa aspettare<br><br></div><div>... e sono al db-bound come lo intendevo io: python ormai l'ho scarnificato e pesa poco, e mi ritrovo che il mio worker tende ad aspettare il db<br></div><div>se i tempi ottenuti sono sufficienti, bene, altrimenti si inizia a scavare sotto il fondo del barile del mio applicativo e si finisce su partitioning / materialized-views e altre amenità del db<br><br></div><div>se invece i tempi restano lunghi allora, ammesso sia accettabile per l'utente (più spesso di quanto si creda, in realtà. E io tendo a remare molto in questa direzione) allora risposta differita e via pedalare: l'utente mi mette i criteri e poi l'elaborazione gli arriva in un bel xlsx (tanto per recuperare il contesto dell'op question) da scaricare tramite apposita pagina del sito<br></div><div><br></div><div>M.<br><br></div></div></div></div>