¡@

Home 

OpenStack Study: eventlet_server.py

OpenStack Index

**** CubicPower OpenStack Study ****

# Copyright 2012 OpenStack Foundation

# Copyright 2010 United States Government as represented by the

# Administrator of the National Aeronautics and Space Administration.

# Copyright 2010 OpenStack Foundation

# All Rights Reserved.

#

# Licensed under the Apache License, Version 2.0 (the "License"); you may

# not use this file except in compliance with the License. You may obtain

# a copy of the License at

#

# http://www.apache.org/licenses/LICENSE-2.0

#

# Unless required by applicable law or agreed to in writing, software

# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT

# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the

# License for the specific language governing permissions and limitations

# under the License.

import socket

import ssl

import sys

import eventlet

import eventlet.wsgi

import greenlet

from keystone.openstack.common.gettextutils import _

from keystone.openstack.common import log

LOG = log.getLogger(__name__)

**** CubicPower OpenStack Study ****

class Server(object):

"""Server class to manage multiple WSGI sockets and applications."""

**** CubicPower OpenStack Study ****

    def __init__(self, application, host=None, port=None, threads=1000,

                 keepalive=False, keepidle=None):

        self.application = application

        self.host = host or '0.0.0.0'

        self.port = port or 0

        self.pool = eventlet.GreenPool(threads)

        self.socket_info = {}

        self.greenthread = None

        self.do_ssl = False

        self.cert_required = False

        self.keepalive = keepalive

        self.keepidle = keepidle

**** CubicPower OpenStack Study ****

    def start(self, key=None, backlog=128):

        """Run a WSGI server with the given application."""

        LOG.info(_('Starting %(arg0)s on %(host)s:%(port)s'),

                 {'arg0': sys.argv[0],

                  'host': self.host,

                  'port': self.port})

        # TODO(dims): eventlet's green dns/socket module does not actually

        # support IPv6 in getaddrinfo(). We need to get around this in the

        # future or monitor upstream for a fix

        info = socket.getaddrinfo(self.host,

                                  self.port,

                                  socket.AF_UNSPEC,

                                  socket.SOCK_STREAM)[0]

        _socket = eventlet.listen(info[-1],

                                  family=info[0],

                                  backlog=backlog)

        if key:

            self.socket_info[key] = _socket.getsockname()

        # SSL is enabled

        if self.do_ssl:

            if self.cert_required:

                cert_reqs = ssl.CERT_REQUIRED

            else:

                cert_reqs = ssl.CERT_NONE

            sslsocket = eventlet.wrap_ssl(_socket, certfile=self.certfile,

                                          keyfile=self.keyfile,

                                          server_side=True,

                                          cert_reqs=cert_reqs,

                                          ca_certs=self.ca_certs)

            _socket = sslsocket

        # Optionally enable keepalive on the wsgi socket.

        if self.keepalive:

            _socket.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)

            # This option isn't available in the OS X version of eventlet

            if hasattr(socket, 'TCP_KEEPIDLE') and self.keepidle is not None:

                _socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE,

                                   self.keepidle)

        self.greenthread = self.pool.spawn(self._run,

                                           self.application,

                                           _socket)

**** CubicPower OpenStack Study ****

    def set_ssl(self, certfile, keyfile=None, ca_certs=None,

                cert_required=True):

        self.certfile = certfile

        self.keyfile = keyfile

        self.ca_certs = ca_certs

        self.cert_required = cert_required

        self.do_ssl = True

**** CubicPower OpenStack Study ****

    def kill(self):

        if self.greenthread is not None:

            self.greenthread.kill()

**** CubicPower OpenStack Study ****

    def wait(self):

        """Wait until all servers have completed running."""

        try:

            self.pool.waitall()

        except KeyboardInterrupt:

            pass

        except greenlet.GreenletExit:

            pass

**** CubicPower OpenStack Study ****

    def _run(self, application, socket):

        """Start a WSGI server in a new green thread."""

        logger = log.getLogger('eventlet.wsgi.server')

        try:

            eventlet.wsgi.server(socket, application, custom_pool=self.pool,

                                 log=log.WritableLogger(logger), debug=False)

        except Exception:

            LOG.exception(_('Server error'))

            raise