ZeroC Ice: Tareas periódicas en un servidor

IceArco

Cómo ejecutar una (o varias) funciones periódicas en un servidor Ice.

Crear un servidor Ice es muy fácil con ayuda de la clase Ice.Application. El communicator() corre en un hilo distinto dejando libre el flujo actual para realizar otras tareas. Lo habitual después de configurar el adaptador y arrancar el comunicador, es invocar el método waitForShutdown() en espera de que el servidor acabe. Este es un servidor mínimo en Python aplicando esa idea:

import sys, Ice
 
class Hello(Ice.Object):
    def ice_ping(self, current=None):
        print "ping()"
 
class Server(Ice.Application):
    def run(self, argv):
        adapter = self.communicator().\
                  createObjectAdapterWithEndpoints("Server", "default -p 9999")
 
        adapter.add(Hello(), Ice.stringToIdentity("Hello"))
        adapter.activate()
 
        self.shutdownOnInterrupt()
        self.communicator().waitForShutdown()            
        return 0
 
sys.exit(Server().main(sys.argv))

A efectos de pruebas, el cliente sería:

import sys, Ice
 
class Client (Ice.Application):
    def run(self, argv):
        base = self.communicator().stringToProxy("Hello:default -p 9999")
        base.ice_ping()
        return 0
 
sys.exit(Client().main(sys.argv))

Ahora imagina que, en el servidor, necesitas ejecutar un método cada 2 segundos. Una forma sencilla es utilizar el bucle de eventos de gobject, es decir, algo como lo siguiente (sólo pongo la clase Server):

class Server(Ice.Application):
    def run(self, argv):
        adapter = self.communicator().\
                  createObjectAdapterWithEndpoints("Server", "default -p 9999")
 
        adapter.add(HelloI(), Ice.stringToIdentity("Hello"))
        adapter.activate()
 
        self.shutdownOnInterrupt()
 
        gobject.threads_init()
        gobject.timeout_add(2000, self.event)
        self.loop = gobject.MainLoop()
        self.loop.run()
 
        return 0
 
    def event(self):
        print 'Event!'
        return True

Y esto funciona bien salvo por una pequeña pero desesperante cuestión: el programa no se cierra al pulsar Ctrl-C. Para arreglarlo, parece que lo más sencillo es usar otro método de Ice.Applicacion llamado callbackOnInterrupt() que provoca la ejecución del método especial interruptCallback() cuando se produce alguna de las señales prefijadas. Se puede aprovechar la ejecución de ese método para terminar el bucle de eventos de gobject. De tal modo que el servidor quedaría algo como:

class Server(Ice.Application):
    def run(self, argv):
        adapter = self.communicator().\
                  createObjectAdapterWithEndpoints("Server", "default -p 9999")
 
        adapter.add(HelloI(), Ice.stringToIdentity("Hello"))
        adapter.activate()
 
        self.callbackOnInterrupt()
 
        gobject.threads_init()
        gobject.timeout_add(2000, self.event)
        self.loop = gobject.MainLoop()
        self.loop.run()
 
        self.communicator().shutdown()
        return 0
 
    def interruptCallback(self, args):
        gobject.idle_add(self.loop.quit)
 
    def event(self):
        print 'Event!'
        return True

En la próxima entrega, lo mismo, pero en C++…

Comentarios

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de oscarah

En c++...

no estaría mal tener esto mismo en Ruby, PHP, Python, Java, C#...
¿no? Laughing out loud
________________________________________________
La "S" de "CRySoL" es de "Software" no de "Salsa-rosa".
La "L" de "CRySoL" es de "Libre" no de "Linux".

"aviso: la dereferencia de punteros de tipo castigado romperá las reglas de alias estricto" --GCC 4.3.1

Imagen de david.villa

feel free...

La “C” de CRySoL es de “Cómo no lo haces tú?” no de “Ciudad” Sticking out tongue

No soy portavoz de ningún colectivo, grupo o facción. Mi opinión es personal e intransferible.

Imagen de oscarah

jejejeje

Oye, ¡que yo no digo quién va a ser el autor! Eye-wink El test de ejemplo en C++ lo tengo listo, si quieres lo posteo. Pero los demás, tendremos que currarnoslos, sobre todo los de lenguajes raros como... Java...
________________________________________________
La "S" de "CRySoL" es de "Software" no de "Salsa-rosa".
La "L" de "CRySoL" es de "Libre" no de "Linux".

"aviso: la dereferencia de punteros de tipo castigado romperá las reglas de alias estricto" --GCC 4.3.1

Imagen de brue

primero...

que alguien explique lo que es Java.

--
PPC: int main(){long foo=1649571173;puts(&foo);}
x86: int main(){long foo=1702187618;puts(&foo);}

brue

Imagen de david.villa

Creo

que es un lenguaje para programar lavadoras o algo de eso Sticking out tongue

No soy portavoz de ningún colectivo, grupo o facción. Mi opinión es personal e intransferible.