librelist archives

« back to archive

Re: [erlar] Closures a través de reloads

Re: [erlar] Closures a través de reloads

From:
Bartłomiej Puzoń
Date:
2010-07-05 @ 07:19
Hola,

Has comprobado, si el comportamiento se puede explicar con esto:
http://www.erlang.org/doc/reference_manual/code_loading.html?


Saludos,
BP

----- "Nahuel Greco" <ngreco@gmail.com> escribió:

> Encontré un comportamiento un poco extraño, sobre el que no vi nada de
> documentación:
> 
> 0- Cargo un módulo m.
> 1- Arranco un proceso definido en m que crea una closure, que utiliza
> una función de ese mismo módulo.
> 2- La ejecuto y queda en memoria.
> 3- Hago ciertas modificaciones al source de m.
> 4- Recargo m.
> 5- La vuelvo a ejecutar (la misma que fue creada en el paso 1)
> 
> Aquí lo que observo es que, dependiendo de qué modificaciones haya
> hecho en el paso 3, la closure en el paso 5 va a apuntar a funciones
> de la versión vieja _o_ nueva del módulo. También observé que se
> pueden cambiar los bindings de la closure en el paso 3. Detallando:
> 
> Test 2: Si se cambia el body de una función de m, usada por la
> closure, la closure utilizara la _nueva_ versión de m.
> Test 3: Si se redefine el nombre de esa función, redefiniendo el body
> de la closure, la closure utilizará la _vieja_ versión de m
> Test 4: Si se cambia un literal dentro de la closure, la closure
> utiliza la _vieja_ versión de m
> Test 5: Si se cambia el valor asignado a una variable bindeada desde
> la closure, la closure utiliza la _nueva_ versión de m _con el nuevo
> valor definido_.
> 
> No encuentro una sémantica clara, y tampoco la vi documentada. Qué
> piensan?
> 
> Adjunto un test.erl que va compilando y cargando/recargando las
> diferentes versiones de m, realizando los tests 2 a 5 que detallé
> antes. La versión original del módulo que siempre carga en el paso 0
> es m__base.erl, y la que carga en el paso 4 es m__[2-5].erl
> alternativamente.
> 
> Output:
> 
> Erlang R13B04 (erts-5.7.5) [source] [smp:2:2] [rq:2] [async-threads:0]
> [kernel-poll:false]
> Eshell V5.7.5  (abort with ^G)
> 1> c(test).
> {ok,test}
> 2> test:start().
> 
> - Unloading m old and current
> - Loading m__base and starting process
> Started a() from version 1
> From closure, version() -> 1, B -> first
> - Loaded m__2 , differences with base: Increments the version
> - Continuing process
> From closure, version() -> 2, B -> first
> 
> - Unloading m old and current
> - Loading m__base and starting process
> Started a() from version 1
> From closure, version() -> 1, B -> first
> - Loaded m__3 , differences with base: Increments the version,
> version/0 changed to another_version/0
> - Continuing process
> From closure, version() -> 1, B -> first
> 
> - Unloading m old and current
> - Loading m__base and starting process
> Started a() from version 1
> From closure, version() -> 1, B -> first
> - Loaded m__4 , differences with base: Increments the version, changed
> text literal in closure
> - Continuing process
> From closure, version() -> 1, B -> first
> 
> - Unloading m old and current
> - Loading m__base and starting process
> Started a() from version 1
> From closure, version() -> 1, B -> first
> - Loaded m__5 , differences with base: Increments the version, changed
> B assigned atom to 'second'
> - Continuing process
> From closure, version() -> 2, B -> second
> [undef,undef,undef,undef]
> 3>
> 
> 
> 
> Saludos,
> Nahuel Greco.

-- 
Bartłomiej Puzoń
Erlang Solutions
bartlomiej.puzon@erlang-solutions.com

Re: [erlar] Closures a través de reloads

From:
Nahuel Greco
Date:
2010-07-05 @ 12:54
> Has comprobado, si el comportamiento se puede explicar con esto:
> http://www.erlang.org/doc/reference_manual/code_loading.html?
>

Si, pero en esa documentación nada dice acerca de que sucede con las
closures. Extrapolando la semántica definida en esa doc y en otras
sobre code reloading, lo que uno tiende a pensar es que la closure
queda asociada a la versión de módulo en la que se creo, ya que dentro
de la closure (en este ejemplo) se hacen llamadas directas (y no fully
qualified) a funciones de ese módulo. Por lo que en el proceso de
purga un proceso que contuviera en su heap una closure haciendo
referencia al viejo módulo, sería tratado de forma similar a la de un
proceso que en la call stack contuviera una referencia a una función
del viejo módulo. En el testito que hice se ve claramente que no es
así. Notar que cuando se purga un módulo hay un scan del heap y de la
call stack de todos los procesos (ver do_purge/1 de code_server.erl y
check_process_code() de beam_bif_load.c).


Saludos,
Nahuel Greco.

Re: [erlar] Closures a través de reloads

From:
Nahuel Greco
Date:
2010-08-12 @ 20:24
Al final parece que le pegué a un bug reportado en el 2007, todavía
abierto. El tema siguió por aquí:

http://thread.gmane.org/gmane.comp.lang.erlang.general/47310

Saludos,
Nahuel Greco.



2010/7/5 Nahuel Greco <ngreco@gmail.com>:
>> Has comprobado, si el comportamiento se puede explicar con esto:
>> http://www.erlang.org/doc/reference_manual/code_loading.html?
>>
>
> Si, pero en esa documentación nada dice acerca de que sucede con las
> closures. Extrapolando la semántica definida en esa doc y en otras
> sobre code reloading, lo que uno tiende a pensar es que la closure
> queda asociada a la versión de módulo en la que se creo, ya que dentro
> de la closure (en este ejemplo) se hacen llamadas directas (y no fully
> qualified) a funciones de ese módulo. Por lo que en el proceso de
> purga un proceso que contuviera en su heap una closure haciendo
> referencia al viejo módulo, sería tratado de forma similar a la de un
> proceso que en la call stack contuviera una referencia a una función
> del viejo módulo. En el testito que hice se ve claramente que no es
> así. Notar que cuando se purga un módulo hay un scan del heap y de la
> call stack de todos los procesos (ver do_purge/1 de code_server.erl y
> check_process_code() de beam_bif_load.c).
>
>
> Saludos,
> Nahuel Greco.
>