Change-Id: If95cb839ad81ca2a842ff7f6926847ac3928d8f2 Former-commit-id: 77e1a4d8f5237e5fae930c1e00589c752f8b3738
191 lines
6.5 KiB
Python
191 lines
6.5 KiB
Python
##
|
|
# This software was developed and / or modified by Raytheon Company,
|
|
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
#
|
|
# U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
# This software product contains export-restricted data whose
|
|
# export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
# to non-U.S. persons whether in the United States or abroad requires
|
|
# an export license or other authorization.
|
|
#
|
|
# Contractor Name: Raytheon Company
|
|
# Contractor Address: 6825 Pine Street, Suite 340
|
|
# Mail Stop B8
|
|
# Omaha, NE 68106
|
|
# 402.291.0100
|
|
#
|
|
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
# further licensing information.
|
|
##
|
|
#
|
|
# Name:
|
|
# AvnServer.py
|
|
# GFS1-NHD:A7965.0000-SCRIPT;1.6
|
|
#
|
|
# Status:
|
|
# DELIVERED
|
|
#
|
|
# AvnServer.py
|
|
# wrappers for name and event servers
|
|
# George Trojan, SAIC/MDL, August 2004
|
|
# last update: 06/04/05
|
|
|
|
import os, threading
|
|
import Pyro.core, Pyro.naming, Pyro.util, Pyro.constants
|
|
from Pyro.errors import *
|
|
import AvnPyro
|
|
|
|
class NameServer(threading.Thread):
|
|
def __init__(self, **kw):
|
|
threading.Thread.__init__(self)
|
|
self.setDaemon(1)
|
|
self.kw = kw
|
|
self.starter = Pyro.naming.NameServerStarter()
|
|
|
|
def run(self):
|
|
print "Launching Pyro Name Server"
|
|
kw = {'hostname': self.kw.get('-n', '')}
|
|
kw.update({'persistent': 1, 'dbdir': 'nsdb', 'verbose': 1,\
|
|
'Guards': (AvnPyro.NSGuard(), AvnPyro.BCGuard())})
|
|
self.starter.start(**kw)
|
|
|
|
def waitUntilStarted(self, timeout=None):
|
|
return self.starter.waitUntilStarted(timeout)
|
|
|
|
##############################################################################
|
|
import Pyro.EventService.Server
|
|
|
|
Log=Pyro.util.Log
|
|
|
|
class EventServer(threading.Thread):
|
|
def __init__(self, **kw):
|
|
threading.Thread.__init__(self)
|
|
self.setDaemon(1)
|
|
self.kw = kw
|
|
self.starter = EventServiceStarter()
|
|
|
|
def run(self):
|
|
Log.msg('Launching Pyro Event Server')
|
|
self.starter.start(hostname=self.kw.get('-n', ''))
|
|
|
|
def waitUntilStarted(self):
|
|
return self.starter.waitUntilStarted()
|
|
|
|
###############################################################################
|
|
# EventServiceStarter is copied from Pyro.EventService.Server, with minor
|
|
# modifications, to avoid the need for interactive call
|
|
|
|
class EventServiceStarter:
|
|
def __init__(self, identification=None):
|
|
self.running=1
|
|
self.identification=identification
|
|
self.started = Pyro.util.getEventObject()
|
|
|
|
def start(self, *args, **kwargs):
|
|
# see _start for allowed arguments
|
|
self._start(startloop=1, *args, **kwargs)
|
|
|
|
def initialize(self, *args, **kwargs):
|
|
# see _start for allowed arguments
|
|
self._start(startloop=0, *args, **kwargs)
|
|
|
|
def getServerSockets(self):
|
|
return self.daemon.getServerSockets()
|
|
|
|
def waitUntilStarted(self, timeout=None):
|
|
self.started.wait(timeout)
|
|
return self.started.isSet()
|
|
|
|
def _start(self, hostname='', port=None, startloop=1, useNameServer=1):
|
|
daemon = Pyro.core.Daemon(host=hostname, port=port)
|
|
if self.identification:
|
|
# Requiring connection authentication
|
|
daemon.setAllowedIdentifications([self.identification])
|
|
|
|
if useNameServer:
|
|
locator = Pyro.naming.NameServerLocator( \
|
|
identification=self.identification)
|
|
try:
|
|
port = int(os.environ['PYRO_NS_PORT'])
|
|
except KeyError:
|
|
port = None
|
|
ns = locator.getNS(port=port)
|
|
|
|
# check if ES already running
|
|
try:
|
|
ns.resolve(Pyro.constants.EVENTSERVER_NAME)
|
|
Log.warn('Event Server appears to be already running.')
|
|
# ns.unregister(Pyro.constants.EVENTSERVER_NAME)
|
|
except NamingError:
|
|
pass
|
|
|
|
daemon.useNameServer(ns)
|
|
|
|
es = Pyro.EventService.Server.EventService()
|
|
|
|
esURI=daemon.connectPersistent(es,
|
|
Pyro.constants.EVENTSERVER_NAME)
|
|
Log.msg('URI=%s' % esURI)
|
|
|
|
message = daemon.validateHostnameAndIP()
|
|
if message:
|
|
Log.warn('WARNING: ' + message)
|
|
|
|
Log.msg('Event Server started.')
|
|
|
|
self.started.set() # signal that we've started.
|
|
|
|
if startloop:
|
|
Log.msg('ES daemon','This is the Pyro Event Server.')
|
|
try:
|
|
daemon.setTimeout(20) # XXX fixed timeout
|
|
daemon.requestLoop(lambda s=self: s.running)
|
|
except KeyboardInterrupt:
|
|
Log.warn('ES daemon', 'shutdown on user break signal')
|
|
self.shutdown(es)
|
|
except:
|
|
try:
|
|
import traceback
|
|
(exc_type, exc_value, exc_trb) = sys.exc_info()
|
|
out = ''.join(traceback.format_exception(exc_type,
|
|
exc_value, exc_trb)[-5:])
|
|
Log.error('ES daemon', 'Unexpected exception, type',
|
|
exc_type,
|
|
'\n--- partial traceback of this exception follows:\n',
|
|
out,'\n--- end of traceback')
|
|
finally:
|
|
del exc_type, exc_value, exc_trb
|
|
Log.msg('ES daemon','Shut down gracefully.')
|
|
else:
|
|
# no loop, store the required objects for
|
|
# getServerSockets()
|
|
self.daemon=daemon
|
|
self.es=es
|
|
daemon.setTimeout(20) # XXX fixed timeout
|
|
|
|
def mustContinueRunning(self):
|
|
return self.running
|
|
|
|
def handleRequests(self, timeout=None):
|
|
# this method must be called from a custom event loop
|
|
self.daemon.handleRequests(timeout=timeout)
|
|
|
|
def shutdown(self, es):
|
|
if es:
|
|
# internal shutdown call with specified ES object
|
|
daemon=es.getDaemon()
|
|
else:
|
|
# custom shutdown call w/o specified ES object,
|
|
# use stored instance
|
|
daemon=self.daemon
|
|
es=self.es
|
|
del self.es, self.daemon
|
|
try:
|
|
daemon.disconnect(es) # clean up nicely
|
|
except NamingError,x:
|
|
Log.warn('ES daemon', 'disconnect error during shutdown:',x)
|
|
except ConnectionClosedError,x:
|
|
Log.warn('ES daemon',
|
|
'lost connection with Name Server, cannot unregister')
|
|
self.running=0
|
|
daemon.shutdown()
|