Re: [Python] django e strutture dati permanenti
Riccardo Lemmi wrote: Balan Victor wrote: idee? :) Il giorno 10 ottobre 2012 14:01, Balan Victor balan.vict...@gmail.com ha scritto: quello che devo fare è questo: in fase di inizializzazione devo caricare in memoria un grafo(networkx) di dimensioni consistenti: 60.000 nodi e più di 100.000 connessioni. PER ADESSO dovrebbe essere in sola lettura e se devo fare delle modifiche posso permettermi di stoppare tutto, fare le modifiche e rilanciare l'applicazione. Poi in base alle richieste che vengono effettuate devo andare a leggere le informazioni che mi servono dal grafo, elaborarle e restituirle all'utente. ... Non sarebbe meglio fare il pickle della struttura dati creata in memoria da networkx invece di ricreare il grafo ogni volta dal DB? Ovviamente perchè sia fattibile bisogna controllare che gli oggetti di NetworkX siano effettivamente serializzabili, inoltre tenere allineati il DB e il grafo richiede sicuramente del codice specifico per evitare di buttare via tutto e ricreare da 0 ogni volta che cambia qualcosa. Potrei anche arrivare a suggerire di provare a derivare (o patchare) le classi di NetworxX da Persistent dello ZODB per semplificare la serializzazione ed eliminare il DB relazionale... Una prova fatta velocemente, ma sembra funzionare. # store a networkx graph in a ZODB # depends on # networkx # matplotlib # ZODB3 import sys import networkx as nx import matplotlib.pyplot as plt from persistent import Persistent from persistent.list import PersistentList from persistent.dict import PersistentDict from ZODB import FileStorage, DB import transaction # root = None storage = None db = None connection = None def init_db(): global root, storage, db, connection if root is None: storage = FileStorage.FileStorage('./g1.fs') db = DB(storage) connection = db.open() root = connection.root() # class PersistentGraph(Persistent, nx.Graph): def __init__(self, data=None, **attr): nx.Graph.__init__(self, data=None, **attr) self.graph = PersistentDict() # dictionary for graph attributes self.node = PersistentDict()# empty node dict (created before convert) self.adj = PersistentDict() # empty adjacency dict class Person(Persistent): def __init__(self, name): self.name = name def __repr__(self): return Person: %s%(self.name) # if __name__ == '__main__': init_db() if G not in root.keys(): print Adding some Person(s) G = root[G] = PersistentGraph() f = Person(Father) m = Person(Mother) c = Person(Child) G.add_edge(f, c) G.add_edge(m,c) transaction.commit() else: G = root[G] if 'addWN' in sys.argv: print Adding wife and son of Child # these are not permanents until commit w = Person(Wife) n = Person(Nephew) c = [p for p in G.nodes() if p.name==Child][0] # can be done better G.add_edge(n, w) G.add_edge(n, c) transaction.commit() if 'rmW' in sys.argv: res = [p for p in G.nodes() if p.name==Wife][0] if len(res)0: print Removing Wife G.remove_node(res[0]) transaction.commit() print Showing for n in G: print n nx.draw(G) plt.show() -- Riccardo Lemmi ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] django e strutture dati permanenti
Balan Victor wrote: idee? :) Il giorno 10 ottobre 2012 14:01, Balan Victor balan.vict...@gmail.com ha scritto: quello che devo fare è questo: in fase di inizializzazione devo caricare in memoria un grafo(networkx) di dimensioni consistenti: 60.000 nodi e più di 100.000 connessioni. PER ADESSO dovrebbe essere in sola lettura e se devo fare delle modifiche posso permettermi di stoppare tutto, fare le modifiche e rilanciare l'applicazione. Poi in base alle richieste che vengono effettuate devo andare a leggere le informazioni che mi servono dal grafo, elaborarle e restituirle all'utente. ... Non sarebbe meglio fare il pickle della struttura dati creata in memoria da networkx invece di ricreare il grafo ogni volta dal DB? Ovviamente perchè sia fattibile bisogna controllare che gli oggetti di NetworkX siano effettivamente serializzabili, inoltre tenere allineati il DB e il grafo richiede sicuramente del codice specifico per evitare di buttare via tutto e ricreare da 0 ogni volta che cambia qualcosa. Potrei anche arrivare a suggerire di provare a derivare (o patchare) le classi di NetworxX da Persistent dello ZODB per semplificare la serializzazione ed eliminare il DB relazionale... -- Riccardo Lemmi ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] django e strutture dati permanenti
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 Il 11/10/2012 01:48, Daniele Varrazzo ha scritto: On 2012-10-10 19:06, Marco Beri wrote: 2012/10/10 Balan Victor balan.vict...@gmail.com quello che devo fare è questo: in fase di inizializzazione devo caricare in memoria un grafo(networkx) di dimensioni consistenti: 60.000 nodi e più di 100.000 connessioni. [...] Leggendo il post originale, la preoccupazione di Victor mi sembra sia che, col server di sviluppo, ogni volta che cambia una riga tutto il grafo viene ricaricato, presumibilmente mettendoci troppi secondi per essere divertente. [...] Altra possibile soluzione, se usi un web server con architettura master/workers, è quella di caricare in memoria il grafo nel processo master, in modo che i worker (essendo figli del master) vi possano accedere. Se accedi in sola lettura la cosa dovrebbe essere molto efficiente (su sistemi che supportano il copy on write), ma su questo non ne sono sicuro, dovrei fare qualche test. Ciao Manlio -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.10 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEUEARECAAYFAlB2h7sACgkQscQJ24LbaUSUcgCfYf605N5vhSS2hLnDY18prZkQ eisAmKFV3+vX3yukXb8HRfy1F6bin/Y= =vrHS -END PGP SIGNATURE- ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] django e strutture dati permanenti
idee? :) Guarda, e' un problema risolvibile abbastanza semplicemente con uWSGI. Fondamentalmente 1) carichi python 2) carichi il modulo con il grafo 3) fork() n volte 4) carichi l'applicazione in ogni 'worker' quando fai modifiche al codice riavvii solo i worker che ripartiranno dal punto 3 (quindi con gia' il grafo in memoria). Ovviamente funziona in sola lettura. Una configurazione per lo sviluppo (con 8 processi) potrebbe essere: [uwsgi] http = :8080 shared-import = modulografo.py module = yourapp.wsgi processes = 8 master = true py-auto-reload = 2 lazy = true i parametri chiave sono shared-import che importa un modulo prima di fork() e lazy che carica l'applicazione in ogni worker a quando il codice cambia vengono riavviati solo i worker anziche' tutto lo stack. Se non conosci il progetto probabilmente il tutto ti risultera' criptico, purtroppo non posso essere piu' prolisso perche' sono all'italian perl workshop e non voglio farmi beccare a pythoneggiare ;) In caso mandami una mail in privato -- Roberto De Ioris http://unbit.it ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] django e strutture dati permanenti
Il giorno 11/ott/2012, alle ore 01:48, Daniele Varrazzo p...@develer.com ha scritto: L'errore secondo me è caricare tutto il grafo: per lo sviluppo dovresti averne una versione semplificata, oppure avere un oggetto stub che ne simuli l'interfaccia e sviluppare l'app django con quello. La soluzione che userei (e che uso in situazioni come questa) è di avere oggetti che siano in grado di caricarsi al momento in cui vengono richiesti. Ovvero ho una radice e quando devo prendere l'elemento X la struttura verifica se l'ha e me lo rende se no carica l'elemento e i figli non risolti. Poi quando cerco x.y viene caricato x.y e i figli non risolti e via dicendo. In pratica il caricamento è incrementale e lazy. Se si applica al tuo caso poterebbe essere comodo. G ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] django e strutture dati permanenti
Roberto De Ioris wrote: purtroppo non posso essere piu' prolisso perche' sono all'italian perl workshop e non voglio farmi beccare a pythoneggiare ;) E ti fai beccare qui a pirlare? Ma allora! :-P -- Nicola Larosa - http://www.tekNico.net/ Art and storytelling are worthy in their own right, and we need a cult- ural response to the collapse of our world, if for no other reason than my personal desire to have an honest story to tell my children about how we destroyed beauty for money and called it ‘development’. - Paul Kingsnorth, quoted by Dave Pollard, April 2012 ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] django e strutture dati permanenti
Il giorno 10 ottobre 2012 09:59, Balan Victor balan.vict...@gmail.com ha scritto: ciao a tutti, stavo leggendo il tutorial di django e mi è venuto un dubbio: come faccio a creare degli oggetti in memoria che restino in vita da quando faccio runserver a quando faccio ctrl-c e siano visibili in tutti i moduli della mia applicazione? gli attributi di classe sono visibili/modificabili in tutti i moduli che importino il modulo contenente la classe prova a vedere se fanno al caso tuo Inoltre può esserti d'aiuto anche un occhiata al pattern Borg di Alex Martelli Marco ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] django e strutture dati permanenti
2012/10/10 Marco De Paoli depao...@gmail.com Il giorno 10 ottobre 2012 09:59, Balan Victor balan.vict...@gmail.comha scritto: ciao a tutti, stavo leggendo il tutorial di django e mi è venuto un dubbio: come faccio a creare degli oggetti in memoria che restino in vita da quando faccio runserver a quando faccio ctrl-c e siano visibili in tutti i moduli della mia applicazione? gli attributi di classe sono visibili/modificabili in tutti i moduli che importino il modulo contenente la classe prova a vedere se fanno al caso tuo Inoltre può esserti d'aiuto anche un occhiata al pattern Borg di Alex Martelli Attenzione però: se si usano più processi (per esempio i worker di uwsgi) i dati dei moduli non sono condivisi. Io userei memcached. Ciao. Marco. -- http://beri.it/ - Un blog http://beri.it/i-miei-libri/ - Qualche libro ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] django e strutture dati permanenti
Il giorno 10 ottobre 2012 11:14, Marco Beri marcob...@gmail.com ha scritto: 2012/10/10 Marco De Paoli depao...@gmail.com Attenzione però: se si usano più processi (per esempio i worker di uwsgi) i dati dei moduli non sono condivisi. ...e se invece sono condivisi c'è il problema degli accessi concorrenti per cui, o sono valori base e in sola lettura e allora puoi metterli nei settings, oppure Io userei memcached. ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] django e strutture dati permanenti
On 2012-10-10 09:03, Marco De Paoli wrote: Inoltre può esserti d'aiuto anche un occhiata al pattern Borg di Alex Martelli Devo a questo cosiddetto pattern (è un'implementazione) le migliori ore della mia vita buttate in debug. Da non toccare neanche con una pertica. -- Daniele Varrazzo - Develer S.r.l. http://www.develer.com ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] django e strutture dati permanenti
2012/10/10 Daniele Varrazzo p...@develer.com On 2012-10-10 09:03, Marco De Paoli wrote: Inoltre può esserti d'aiuto anche un occhiata al pattern Borg di Alex Martelli Devo a questo cosiddetto pattern (è un'implementazione) le migliori ore della mia vita buttate in debug. Da non toccare neanche con una pertica. :-)) Cosa era successo? Più processi attivi? Race condition? Ciao. Marco. -- http://beri.it/ - Un blog http://beri.it/i-miei-libri/ - Qualche libro ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] django e strutture dati permanenti
On 2012-10-10 11:03, Marco Beri wrote: 2012/10/10 Daniele Varrazzo p...@develer.com On 2012-10-10 09:03, Marco De Paoli wrote: Inoltre può esserti d'aiuto anche un occhiata al pattern Borg di Alex Martelli Devo a questo cosiddetto pattern (è un'implementazione) le migliori ore della mia vita buttate in debug. Da non toccare neanche con una pertica. :-)) Cosa era successo? Più processi attivi? Race condition? Cosa deve succedere? Quello per cui è progettato: tu hai l'istanza di un oggetto, chiami qualche funzione apparentemente non correlata e alla riga dopo quell'istanza si comporta in maniera inconsistente da due righe prima. Anche un programma single-thread diventa imprevedibile. È solo una variabile globale glorificata, ma col rischio che nasconde il fatto di esserla. Molto meglio un singleton (il vero pattern di cui il borg è un'implementazione): almeno è esplicito che tutti ci possono mettere le mani e non fai assunzioni fuori luogo che sia una variabile locale. Per la storia, il programma in questione era Epydoc. Aggiungi il fatto che lo stato di questi oggetti veniva modificato in maniera casuale tra un run e l'altro, a seconda di che ordine venivano letti i sorgenti... È stato probabilmente il bug più ''.join(unsorted('aaacccozz')) che abbia mai trattato. Semplicemente perché un'istanza ammalata di borg non si comporta come un regolare oggetto Python: a is b == False, eppure cambi a e ti cambia anche b: un comportamento del tutto prevedibile no? -- Daniele Varrazzo - Develer S.r.l. http://www.develer.com ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] django e strutture dati permanenti
quello che devo fare è questo: in fase di inizializzazione devo caricare in memoria un grafo(networkx) di dimensioni consistenti: 60.000 nodi e più di 100.000 connessioni. PER ADESSO dovrebbe essere in sola lettura e se devo fare delle modifiche posso permettermi di stoppare tutto, fare le modifiche e rilanciare l'applicazione. Poi in base alle richieste che vengono effettuate devo andare a leggere le informazioni che mi servono dal grafo, elaborarle e restituirle all'utente. Il giorno 10 ottobre 2012 12:46, Daniele Varrazzo p...@develer.com ha scritto: On 2012-10-10 11:03, Marco Beri wrote: 2012/10/10 Daniele Varrazzo p...@develer.com On 2012-10-10 09:03, Marco De Paoli wrote: Inoltre può esserti d'aiuto anche un occhiata al pattern Borg di Alex Martelli Devo a questo cosiddetto pattern (è un'implementazione) le migliori ore della mia vita buttate in debug. Da non toccare neanche con una pertica. :-)) Cosa era successo? Più processi attivi? Race condition? Cosa deve succedere? Quello per cui è progettato: tu hai l'istanza di un oggetto, chiami qualche funzione apparentemente non correlata e alla riga dopo quell'istanza si comporta in maniera inconsistente da due righe prima. Anche un programma single-thread diventa imprevedibile. È solo una variabile globale glorificata, ma col rischio che nasconde il fatto di esserla. Molto meglio un singleton (il vero pattern di cui il borg è un'implementazione): almeno è esplicito che tutti ci possono mettere le mani e non fai assunzioni fuori luogo che sia una variabile locale. Per la storia, il programma in questione era Epydoc. Aggiungi il fatto che lo stato di questi oggetti veniva modificato in maniera casuale tra un run e l'altro, a seconda di che ordine venivano letti i sorgenti... È stato probabilmente il bug più ''.join(unsorted('aaacccozz')) che abbia mai trattato. Semplicemente perché un'istanza ammalata di borg non si comporta come un regolare oggetto Python: a is b == False, eppure cambi a e ti cambia anche b: un comportamento del tutto prevedibile no? -- Daniele Varrazzo - Develer S.r.l. http://www.develer.com __**_ Python mailing list Python@lists.python.it http://lists.python.it/**mailman/listinfo/pythonhttp://lists.python.it/mailman/listinfo/python ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] django e strutture dati permanenti
2012/10/10 Balan Victor balan.vict...@gmail.com quello che devo fare è questo: in fase di inizializzazione devo caricare in memoria un grafo(networkx) di dimensioni consistenti: 60.000 nodi e più di 100.000 connessioni. PER ADESSO dovrebbe essere in sola lettura e se devo fare delle modifiche posso permettermi di stoppare tutto, fare le modifiche e rilanciare l'applicazione. Poi in base alle richieste che vengono effettuate devo andare a leggere le informazioni che mi servono dal grafo, elaborarle e restituirle all'utente. E questo cosa c'entra con una variabile globale? PER ADESSO fai un modulo che carica tutto e che si salva in memoria la cosa. Per esempio grafo_enorme.py: # -*- coding: utf-8 -*- class GrafoEnorme(): def __init__(self): self.carica_il_grafo_enorme() def get_informazioni_su_utente(self, utente): return informazioni grafo = GrafoEnorme() E dalle altre parti: import grafo_enorme grafo_enorme.grafo.get_informazioni_su_utente(pippo) Ciao. Marco. -- http://beri.it/ - Un blog http://beri.it/i-miei-libri/ - Qualche libro ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] django e strutture dati permanenti
On 2012-10-10 19:06, Marco Beri wrote: 2012/10/10 Balan Victor balan.vict...@gmail.com quello che devo fare è questo: in fase di inizializzazione devo caricare in memoria un grafo(networkx) di dimensioni consistenti: 60.000 nodi e più di 100.000 connessioni. PER ADESSO dovrebbe essere in sola lettura e se devo fare delle modifiche posso permettermi di stoppare tutto, fare le modifiche e rilanciare l'applicazione. Poi in base alle richieste che vengono effettuate devo andare a leggere le informazioni che mi servono dal grafo, elaborarle e restituirle all'utente. E questo cosa c'entra con una variabile globale? PER ADESSO fai un modulo che carica tutto e che si salva in memoria la cosa. Leggendo il post originale, la preoccupazione di Victor mi sembra sia che, col server di sviluppo, ogni volta che cambia una riga tutto il grafo viene ricaricato, presumibilmente mettendoci troppi secondi per essere divertente. Puoi disabilitare il reload automatico del server di sviluppo e riavviarlo quando ti serve: c'è un parametro di riga di comando IIRC. Non è una grande consolazione. Ma il problema non è diverso da altri modelli di sviluppo. L'errore secondo me è caricare tutto il grafo: per lo sviluppo dovresti averne una versione semplificata, oppure avere un oggetto stub che ne simuli l'interfaccia e sviluppare l'app django con quello. -- Daniele Varrazzo - Develer S.r.l. http://www.develer.com ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] django e strutture dati permanenti
2012/10/11 Daniele Varrazzo p...@develer.com Leggendo il post originale, la preoccupazione di Victor mi sembra sia che, col server di sviluppo, ogni volta che cambia una riga tutto il grafo viene ricaricato, presumibilmente mettendoci troppi secondi per essere divertente. E c'hai ragione c'hai... Scusami Victor. -- http://beri.it/ - Un blog http://beri.it/i-miei-libri/ - Qualche libro ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python