示例#1
0
    def setUp(self):
        self.runLoop = RunLoop.currentRunLoop()
        self.runLoop.waitBeforeCalling(60, self.timeout)
        
        self.timedOut = False
        self.tempdir = tempfile.mkdtemp('.apps')
        self.appBundlePath = os.path.join(self.tempdir, 'testapp')
        os.mkdir(self.appBundlePath)
        
        self.appConfPath = os.path.join(self.appBundlePath, 'app.conf')
    
        self.configTemplate = '''
        <app>
        <!-- the worlds most boring app -->
        </app>
        ''' 

        open(self.appConfPath,'w').write(self.configTemplate)
  def setUp(self):
    self.delegate = Delegate()
    super(self.__class__,self).setUp()
    self.runLoop = RunLoop.currentRunLoop()

    # Wire URLProtocol
    URLHTTPProtocol.run_loop = RunLoop
    URLHTTPProtocol.assembled()
    URLProtocol.registerClass(URLHTTPProtocol)
    URLConnection.URLProtocol = URLProtocol
    URLCache.assembled()
    URLConnection.URLCache = URLCache
    URLConnection.runLoop = RunLoop
        
    # Wire RunLoop
    ls = LogService()
    ls.useStreamHandler(sys.stderr)
    RunLoop.log = ls.__binding__('RunLoop', RunLoop)
示例#3
0
  def setUp(self):
    super(self.__class__,self).setUp()
    self.runLoop = RunLoop.currentRunLoop()
    # Wire URLHTTPProtocol
    URLHTTPProtocol.LRProtocol = LineReceiverProtocol
    URLHTTPProtocol.portFactory = Port

    # Wire URLProtocol
    URLProtocol.registerClass(URLDataProtocol)
    URLProtocol.registerClass(URLHTTPProtocol)
    
    # Wire URLConnection
    URLConnection.URLProtocol = URLProtocol
    URLConnection.runLoop = RunLoop
    URLConnection.URLRequest = URLRequest
      
    # Wire RunLoop
    ls = LogService()
    ls.useStreamHandler(sys.stderr)
    RunLoop.log = ls.__binding__('RunLoop', RunLoop)
    XMLSchemaService.URLConnection = URLConnection
    
    self.XMLSchemaService = XMLSchemaService
    self.schema = None
示例#4
0
def main():
    
    """Used by ramblerapp, a script that is created automatically for
    us by setuptools, to load an appBundle into it's own process."""

    import os,sys

    # Todo: this should really double fork (on posix platforms, not
    # sure about windows which doesn't have fork), I if you start appMan from the command line
    # and send it a ^C any sub app it starts also get's that ^C which
    # isn't what we want.

    from optparse import OptionParser
    parser = OptionParser()

    parser.add_option("-d", dest="daemonize", action="store_true", default=False,
                      help="Run this process as a background daemon")
    parser.add_option("-v", dest="logLevel",  action="count", default=0,
                      help="Increase logging verbosity by one for each -v specified on the commandline")

    parser.add_option("-b", dest="breakAt", default=None,
                      help="Use python debugger to break @ file:line, needs -f")

    parser.add_option("-o", action="append", dest="options",
                      default=[], help='Set extension option -o "section:key=value"')


    (options, args) = parser.parse_args()

    # app's can be started using the ramblerapp shell command, in that
    # case the first argument must be the path to the application
    # bundle. If the name of the script isn't ramblerapp say it's
    # "foo" then we assume this is an application whose bundle is
    # under /usr/lib/Rambler/extensions.

    # Todo: come up with a better way to specify the rambler
    # extensions directory. Perhaps check home directories as well,
    # that might make development eaiser

    scriptname = os.path.basename(sys.argv[0])
    appBundlePath=None
    if scriptname != "ramblerapp":


        # Depending on what platform we're on the scriptname could
        # either either foo or foo.exe, to add insult too injury the
        # scrip probably isn't installed in the bundle directory (the
        # directory containg the app.conf) file. So using setuptools
        # we'll first determine which egg this script came from, then
        # we'll use that to find the directory containing the app.conf

        # We may have more than one module that uses the same
        # appBundle, like appmanager and ramblercon, so consolt the
        # pkg_resources for that information. This only works if the script
        # wass installed as an egg 'console_script'

        for ep in pkg_resources.iter_entry_points('console_scripts',scriptname):
             
            # Note, asking for the '' filename only works on unzipped
            # packages. If I want to make ramblerapps out of eggs
            # we'll need to redesign the "Bundle" concept. Heck we
            # might be able to ditch Bundles in favor of eggs
            # alltogether....

            # We may one or more scripts that 


            appBundlePath = pkg_resources.resource_filename(ep.dist.project_name,'')

            # Warning: There could be more than one script of the same
            # name in setuptools database. Typically this means that
            # two different projects installed the same console_script
            # with the same name. Now the bad part is, who knows which
            # script is actually installed.
            break

        # if appBundlePath wasn't set, then the script name didn't
        # refer to a script installed by an egg. As a last ditch
        # effort and probably the most common case the scriptname
        # referes to a vanilla python package
        
        appBundlePath = appBundlePath or  pkg_resources.resource_filename(os.path.basename(scriptname),'')

        
    elif len(args) < 1:
        print >> sys.stderr, "Please specify the application directory."
        return 1
    else:
        appBundlePath = args[0]
        args = args[1:]
                    
        

    # clear the options in sys.argv we didn't use and put the
    # positional ones back in. Right now we're donig this mostly for
    # ramblercon which is a commandline application. Might be nice to
    # have a way of getting positional arguments to a component that
    # doesn't involve munging the command line.

    #del sys.argv[1:]
    #sys.argv.extend(args)


    
    authoritativeOptions = None



    # close any open file handles, have to do this before we load the
    # app cause who knows what files we may open next

    if not options.daemonize:
        # keep stderr, stdin and stdout open
        startfd = 3
    else:
        startfd = 3

    # wonder if closing files is neccesary now that we don't fork..
    import os
    try:
        maxfd = os.sysconf("SC_OPEN_MAX")
    except (AttributeError, ValueError):
        maxfd = 256       # default maximum

    for fd in range(startfd, maxfd):
        try:
            os.close(fd)
        except OSError:   # ERROR (ignore)
            pass

    app = Application(appBundlePath,
                      authoritativeOptions=authoritativeOptions)
  
    logService = app.lookup("LogService")
    level = logService.defaultLevel - (options.logLevel * 10)
    logService.setLevel(level)


    if not options.daemonize:
        logService.useStreamHandler(sys.stderr)
    else:
        # since we didn't pass anything in this should already be done for us

        logService.useSyslogHandler()
        pass


    try:
        app.load()
        
    except:
        app.log.exception("Exception encountred while loading as a subprocess")
        return 1

    try:
        RunLoop.currentRunLoop().run()
    except:
        app.log.exception("Unhandled exception encuntered in runLoop")
        return 255
    
    # if we didn't die with an exception, exit with a 0, no errors
    return 0
示例#5
0
    def __init__(self, appDir,  authoritativeOptions = None, **defaultComps):
        self.appBundle = Bundle(appDir)
        self.configFile = self.appBundle.pathForResource('app.conf')
        self.status = Application.STOPPED

        self.digest = ""
        self.name = os.path.basename(os.path.abspath(appDir))

        if not authoritativeOptions:
            authoritativeOptions = {}
        authoritativeOptions['application.name'] =  self.name
        authoritativeOptions['application.path'] =  os.path.abspath(appDir)
        authoritativeOptions['system.hostname'] =  socket.gethostname()

        self.loadConfig()

        logService = defaultComps.get("LogService")

        if logService is None:
            # everybody needs logging, especally  during devel. If one
            # isn't passed to us, set one up to go directly to syslog

            logService = LogService()
            logService.addData('app', self.name)

            logService.setFormat('[%(app)s:%(name)s:%(levelname)s] %(message)s')
            logService.useSyslogHandler()
            defaultComps["LogService"] = logService

        # load the module that adapts our logging to somthething that twisted deferred's and failuers likes
        defaultComps["StdioOnnaStick"] =  StdioOnnaStick()

        defaultComps["ErrorFactory"] = ErrorFactory()

        

        # these two are sessions so we put their classe rather than
        # instances in componentRegistry
        defaultComps["RunLoop"] = RunLoop
        defaultComps["PortFactory"] = Port

        # our os signal handling, has to be as light weight as
        # possible. so any signal this app receives will be processed
        # by the sameRunLoop that started this app (hopefully you
        # don't have it bogged down running long synchronous tasks)

        self.mainRunLoop = RunLoop.currentRunLoop()

        self.componentRegistry = CompBinder()
        for compName, component in defaultComps.items():
            self.componentRegistry.addComponent(compName, component)

        serviceRegistry = ServiceRegistry()
        # blehq, serviceRegistry needs the application name in order to
        # load services that have been configured by convention 
        serviceRegistry.app_name = self.name
        serviceRegistry.app = self
        self.componentRegistry.addComponent("ServiceRegistry", serviceRegistry)
        # need to bind ServiceRegistry's before we can add the App as
        # a service.
        self.componentRegistry.bind()
        

        # Set up the config service with authorative options
        configService = ciConfigService()
        for option, value in authoritativeOptions.items():
          configService.set_default(option, value)

        try: # todo, remove this crap afte we pull the last bits of corba/omniorb from Rambler
            from epo import ciIApplication, ciIConfigService
            # Register the application service so that we can be remotely managed
            serviceRegistry.addService("Application", self, ciIApplication, [])
            serviceRegistry.addService("ConfigService", configService, ciIConfigService, [])
        except ImportError:
            # corba isn't installed
            serviceRegistry.addService("Application", self, None, [])
            # Note: ConfigService is placed into the componentRegistry
            # via the service registry. Not sure why I did this.
            serviceRegistry.addService("ConfigService", configService, None, [])



        self.componentRegistry.bind()
示例#6
0
            except:
                # we died during shutdown, althought this should be
                # reported as a crash,we don't want a crash handler to try
                # and restart us, after all we died when we were stopping
                
                self.log.exception('Did not shutdown cleanly!')

            # Now that the components are offline, we'll tell the
            # Server that we're done, and then stop the RunLoop as
            # soon as the controller aknowledeges us
            self.setStatus(Application.STOPPED)
        

        elif status in (Application.STOPPED, Application.CRASHED):
            self.log.info("Shutdown Complete")
            RunLoop.currentRunLoop().stop()

    def onStatusError(self, failure, status):
        # Couldn't notify our controller, it could be temporarily
        # down, let's continue about our merry way.
        self.log.debug("%s got error %s while notifying controller of status %s,"
                      " continuing." % (self.name, failure.getErrorMessage(), status))
        
        self.onStatusSent(None, status)
    
                

def main():
    
    """Used by ramblerapp, a script that is created automatically for
    us by setuptools, to load an appBundle into it's own process."""
示例#7
0
 def setUp(self):
     self.observed = False
     self.run_loop = RunLoop.currentRunLoop()
示例#8
0
 def timeout(self):
     # test took to long to complete, set a flag and stop the RunLoop
     self.timedOut = True
     RunLoop.currentRunLoop().stop()
示例#9
0
 def stopRunLoop(*args, **kw):
     if len(args) > 0 and hasattr(args[0], 'printTraceback'):
         args[0].printTraceback()
         
     # used to stop the runLoop from via a deffered object which usually calls back with one or more args
     RunLoop.currentRunLoop().stop()