Re: [Python] django e strutture dati permanenti

2012-10-13 Per discussione Riccardo Lemmi
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

2012-10-11 Per discussione Riccardo Lemmi
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

2012-10-11 Per discussione Manlio Perillo
-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

2012-10-11 Per discussione Roberto De Ioris

 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

2012-10-11 Per discussione Giovanni Porcari

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

2012-10-11 Per discussione Nicola Larosa
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

2012-10-10 Per discussione Marco De Paoli
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 Per discussione Marco Beri
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

2012-10-10 Per discussione Marco De Paoli
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

2012-10-10 Per discussione Daniele Varrazzo

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 Per discussione Marco Beri
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

2012-10-10 Per discussione Daniele Varrazzo

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

2012-10-10 Per discussione Balan Victor
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 Per discussione Marco Beri
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

2012-10-10 Per discussione Daniele Varrazzo

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-10 Per discussione Marco Beri
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