Asunto: [CORBA-Comp] Más sobre el Implementation Repository
Fecha: Fri Apr 21 12:45:30 2000
De: Diego Sevilla <dsevilla@ditec.um.es>
This is a multi-part message in MIME format.
--------------D05A7B26BA49825D2D4834C1
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: 8bit
Hola a todos:
Hace un tiempo surgió en la lista una discusión sobre el
Implementation Repository. La idea era llegar a comprender completamente
este elemento (ahora importantísimo) de la arquitectura CORBA.
Inicialmente nos centramos en MICO, ya que este ORB poseía este
servicio, y no muchos otros más (queda pendiente estudiar el que lleva
el nuevo ORBacus 4.0beta2).
El caso es que siguiendo con la argumentación, el problema era la
implementación que MICO específicamente hacía del IMR, que, al parecer,
obligaba a activar los servidores antes de que fueran utilizados.
Para comprobar realmente este funcionamiento, modifiqué el ejemplo
que viene con mico en el directorio $MICO/demo/poa/account-3. Lo primero
que me sorprendió es que el ejemplo cambia de la versión de MICO 2.3.0 a
la 2.3.1. En la primera, no se activa implícitamente el servidor
(utilizando imr activate Bank), pero el cliente utiliza un mecanismo no
estándar (la llamada "bind") para ligarse al objeto. Esta llamada activa
implícitamente al servidor, y sólo necesita el interfaz (en forma de
entrada en el Interface Repository, esto es, IDL:Bank:1.0) y la
dirección del IMR:
Bank_var mybank = orb->bind("IDL:Bank:1.0);
Esto no es estándar, y siempre en CORBA se debe buscar seguir el
estándar. La forma estándar es utilizar un servicio de nombres/trading,
etc. ó un IOR.
Modifiqué el ejemplo para que utilizara un IOR en vez de la llamada
"bind" y NO FUNCIONABA, a menos que incluyera la línea "imr activate
Bank", que iniciaba explícitamente el servidor (lo que realmente no
queríamos, ya que queríamos que se iniciara bajo demanda tras la
invocación de un método de "Bank" por un cliente).
Tuve entonces que rastrear el código del imr y del micod, y me di
cuenta de que la llamada "bind" realizaba lo mismo que un "imr
activate": llamaba al método "force_activation" del IMR para el servidor
que implementaba ese tipo de objetos. Este método iniciaba el servidor y
lo dejaba a la escucha. Lo que he hecho es modificar el código de esa
función para RELEGAR LA EJECUCIÓN DEL SERVIDOR A LA PRIMERA INVOCACIÓN
DEL CLIENTE, que es lo que se quería en un principio. El fichero que he
adjuntado (diffs) hace eso en el fichero $MICO/daemon/poamediator.cc, y
se aplica con "patch":
> patch poamediator.cc diffs
El fichero "diffs" lo muestra claro:
--- poamediator.cc.old Fri Apr 21 01:06:39 2000
+++ poamediator.cc Fri Apr 21 02:40:02 2000
@@ -136,8 +136,20 @@
CORBA::Boolean
POAMediatorImpl::force_activation (CORBA::ImplementationDef_ptr impl)
{
- CORBA::String_var svid = impl->name ();
- return create_server (svid);
+
+ CORBA::String_var svid = impl->name ();
+ /* Do not create the server
+ return create_server (svid);
+ */
+ SvInf &inf = svmap[(const char*)svid];
+ // Not needed really (see SvInf's constructor)
+ // Included to avoid the "non used variable" warning
+ inf.state = Inactive;
+
+ /* Note that with this return value, we delay the errors on
+ server execution till the first invocation
+ */
+ return TRUE;
}
/*
Las líneas con "-" indican que se llamaba a la función
"create_server", que efectivamente iniciaba el servidor. Con esto, el
servidor no se iniciará hasta la primera invocación (si se observa el
método "invoke" en este mismo fichero, el servidor se vuelve a lanzar si
"state" es "Inactive").
Así, ahora, aunque se llame a "imr create Bank ...", con el
servidor, y después a "imr activate Bank", el servidor no se iniciará
realmente, sino que se iniciará tras la primera llamada de un cliente.
Así, se podría pensar que la funcionalidad actual de "imr activate"
pasara a "imr create", aunque también se puede argüir en contra.
Sin embargo, tras pensarlo concienzudamente, me doy cuenta de que
esta no es la solución, y de que el mecanismo por defecto de MICO es el
adecuado. Esto es por varias razones: Estamos de acuerdo que lo ideal es
que el servidor se lance bajo demanda. Sin embargo, EL SERVIDOR SE DEBE
LANZAR ANTES QUE CUALQUIER CLIENTE AL MENOS LA PRIMERA VEZ, ya que
tendrá que exportar su referencia a algún servicio de
directorio/naming/trading ó a algún IOR, con lo que la necesidad de
llamar a "imr activate" que siempre estaba presente tiene su lógica.
Además, un servidor con un interfaz bien diseñado siempre posee un
método "shutdown" que indica al servidor que ese cliente en concreto ha
dejado de utilizar el servidor, y por lo tanto, éste puede dejar de
estar en memoria. Por supuesto, cuando otro cliente vuelva a requerir
sus servicios, el IMR se encargará de iniciarlo de nuevo de forma
transparente.
Si el servidor no tiene ese método "shutdown", puede monitorizar a
sus clientes y "desconectarse" (esto es, descargarse de memoria,
terminar) después de un plazo sin recibir invocaciones a sus métodos. De
nuevo el IMR lo lanzará cuando vuelva a ser necesario.
Así, finalmente, la conclusión a la que llego es que la semántica de
la "primera" invocación de un servidor y las "siguientes" (incluso
después de volver a reiniciar la máquina) no es distinta. La "primera"
debe publicar al servidor en los servicios de directorio. Esta
publicación se hará mediante referencias PERSISTENTES, con lo que serán
válidas de por vida para ese servidor. Una vez que se haya realizado
este establecimiento de valores iniciales, las subsecuentes iniciaciones
del servidor se pueden hacer siempre bajo demanda. Por lo tanto, yo
añadiría una nueva entrada en el cliente "imr" para diferenciar estos
dos casos (algo así como un "activateAgain"), que no iniciaría el
servidor. Cuando tenga tiempo lo comentaré en la lista de MICO, a ver lo
que piensan sus creadores.
Estoy seguro de que todo lo que he escrito está tan liado que carece
de valor. Prometo que cuando tenga más tiempo y más claras las ideas lo
mejoraré. No obstante, por favor, preguntad aquello que no os quede
claro.
Saludos.
diego.
--
Diego Sevilla Ruiz -- http://ditec.um.es/~dsevilla -- dsevilla at um dot
es
--------------D05A7B26BA49825D2D4834C1
Content-Type: text/plain; charset=us-ascii;
name="Diffs"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="Diffs"
--- poamediator.cc.old Fri Apr 21 01:06:39 2000
+++ poamediator.cc Fri Apr 21 02:40:02 2000
@@ -136,8 +136,20 @@
CORBA::Boolean
POAMediatorImpl::force_activation (CORBA::ImplementationDef_ptr impl)
{
- CORBA::String_var svid = impl->name ();
- return create_server (svid);
+
+ CORBA::String_var svid = impl->name ();
+ /* Do not create the server
+ return create_server (svid);
+ */
+ SvInf &inf = svmap[(const char*)svid];
+ // Not needed really (see SvInf's constructor)
+ // Included to avoid the "non used variable" warning
+ inf.state = Inactive;
+
+ /* Note that with this return value, we delay the errors on
+ server execution till the first invocation
+ */
+ return TRUE;
}
/*
--------------D05A7B26BA49825D2D4834C1--
--------------------------------------------------------------------------
Esta es la lista de discusión de CORBA y Componentes Software (corba-comp)
--------------------------------------------------------------------------
Suscripcion: Envie un correo a mailto:Majordomo@ditec.um.es?body=subscribe%20corba-comp
Eliminar su suscripcion: mailto:Majordomo@ditec.um.es?body=unsubscribe%20corba-comp
Informacion de la lista: mailto:Majordomo@ditec.um.es?body=info%20corba-comp
Problemas: mailto:corba-comp-owner@ditec.um.es
Indices de la lista: http://www.ditec.um.es/~dsevilla/corba/
--------------------------------------------------------------------------