Delucidazione extender + instance_eval + dcell

Ciao a tutti, qualcuno sarebbe cosi gentile da portermi aiutare a capire
cosa fa una parte di codice che ho visto su questo file:

Il file in questione è un modulo scritto da Tenderlove per gestire le
notifiche tra processi in Drb.

La parte che non mi è chiara e la seguente:

def self.extended klass
super

klass.instance_eval do
   @bus = DRbObject.new_with_uri uri
   @observer_state = false
   @subscribers      = {}
end

end

Da quello che ho capito googlerando è che instance_eval serve per
aggiungere metodi di classe, klass è un nome che si è scelto di dare ad
una metodo visto che il metodo class è gia usato da Object.

Ma ciò che non mi è chiaro è cosa effetivamente fa questa parte di
codice.

Inoltre vorrei approffitarne per chiedervi se qualcuno di voi conosce un
modo per gestire le notifiche tra processi in Drb, sono riuscito a farlo
attravero questo modulo, ma vorrei sapere se ci sono già dei sistemi
inclusi nelle libreria standar di Ruby o qualche altra gemma che
gestisca le notifiche tra processi distribuiti in una rete.

Ho provato ad usare Dcell (che gestisce anche le notifiche), ma qualcosa
non mi convinceva sulla performance, ho realizzato un programma che
lancia 2 processi CPU bound in parallelo, in modo asyncrono utlizzando
il metodo future di celluloid, e prendendo il valore di ritorno con il
metodo value

server1 = DCell::Node[“server1”]
server2 = DCell::Node[“server2”]

long_process1 = server1[:process_1].future.long_process1(2)
long_process2 = server2[:process_2].future.long_process2(10)

while 1
sleep 0.2
if long_process1.ready? and long_process2.ready?
p long_process1.value
p long_process2.value
break
end
end

Facendo la stessa cosa con Drb ho visto che ci impiega quasi metà del
tempo. Per cui mi sono deciso di affidarmi a Drb, che mi sembra molto
più completo di Dcell, anche se leggendo nel wiki di dcell, Drb è
intrinsecamente sincrono, e ciò fa desumere che non sia performante
quanto celluloid.
Comparison to DRb · celluloid/dcell Wiki · GitHub.

Ah domenticavo i miei test sono stati effetuati con ruby 2.0.0p451, lo
so che sarebee meglio jruby per usare celluloid visto che gestisce
meglio i thread, ma al momento non posso usare jruby perche ci sono
alcune gemme che non mi funzionano.

Grazie a tutti.

2014-04-13 1:19 GMT+02:00 michele boscolo [email protected]:

Ma ci che non mi chiaro cosa effetivamente fa questa parte di
codice.

Assuemendo che tu abbia una classe Klass, #extended viene invocato
quando
fai Klass.extend(ThisModule),
questo #instance_eval non fa altro che impostare delle variabili
nell’oggetto klass (che incidentalmente una classe)

Ovvero, se vai a fare

 Klass.instance_variable_get('@bus')

ti dovrebbe dare quelle cose l (ricordati che le classi sono oggetti
come
gli altri, e possono avere variabili d’istanza).

Occhio a non confondere class_eval e instance_eval.

instance_eval semplicemente come se quel pezzo di codice venisse
eseguito
dentro l’oggetto, cio, se immagini che “self” sia una variabile
normale,
come se

something.instance_eval do
    foobar
end

fosse

old_self = self
self = something
foobar
self = old_self

mentre #class_eval come se facesse “class X… end”

Probabilmente l’idea che per ogni singola classe ci sia un DrbObject,
ma
sia accessibile direttamente solo alla Classe stessa. (altrimenti si
potevano usare variabili di classe @@bus)

Non avendo la minima idea di quale sia il tuo use case, non son sicuro
del
perch ti serva questo modulo, DRb gi ha dei meccanismi per le notifiche
(che sono infatti usati da questo modulo).

Senn nella stdlib c’ anche Rinda (Linda/TupleSpace sopra DRb) che
funzionava ok l’ultima volta che l’ho provato (i.e. un decennio fa), e
magari ha un modello di programmazione che preferisci.
Anche Rinda permette di notificare client di cambiamenti nel tuplespace,
ma
documentato un po’ a minchia.


twitter: @riffraff
blog (en, it): www.riffraff.info
work: circleme.com