Added gunicorn as server application manager
This patch adds gunicorn as dependency for starting and managing server workers. Gunicorn allow users to chose whether to use workers based on a sync process, eventlet or gevent. It also manages multiple workers, ssl, process uid, process gid. Implements blueprint transport-base Change-Id: Ic328dbb937f8df69691911c6e6ff6b318bb1db34
This commit is contained in:
parent
859e571451
commit
948476edf9
@ -5,7 +5,17 @@ transport = marconi.transport.wsgi
|
|||||||
storage = marconi.storage.mongodb
|
storage = marconi.storage.mongodb
|
||||||
|
|
||||||
[drivers:transport:wsgi]
|
[drivers:transport:wsgi]
|
||||||
port = 8888
|
bind = 0.0.0.0:8888
|
||||||
|
; workers = 4
|
||||||
|
workers = 1
|
||||||
|
; worker_class = sync, gevent, eventlet
|
||||||
|
worker_class = sync
|
||||||
|
; user = 1000
|
||||||
|
; group = 1000
|
||||||
|
; proc_name = marconi
|
||||||
|
; certfile = cert.crt
|
||||||
|
; keyfile = cert.key
|
||||||
|
|
||||||
|
|
||||||
;[drivers:transport:zmq]
|
;[drivers:transport:zmq]
|
||||||
;port = 9999
|
;port = 9999
|
||||||
|
@ -3,4 +3,5 @@ transport = marconi.transport.wsgi
|
|||||||
storage = marconi.storage.sqlite
|
storage = marconi.storage.sqlite
|
||||||
|
|
||||||
[drivers:transport:wsgi]
|
[drivers:transport:wsgi]
|
||||||
port = 8888
|
bind = 0.0.0.0:8888
|
||||||
|
workers = 20
|
||||||
|
40
marconi/tests/transport/wsgi/test_app.py
Normal file
40
marconi/tests/transport/wsgi/test_app.py
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
# Copyright (c) 2013 Red Hat, Inc.
|
||||||
|
#
|
||||||
|
# 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 multiprocessing
|
||||||
|
import signal
|
||||||
|
|
||||||
|
import marconi
|
||||||
|
from marconi.tests import util
|
||||||
|
from marconi.transport.wsgi import app
|
||||||
|
|
||||||
|
|
||||||
|
class TestApplication(util.TestBase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestApplication, self).setUp()
|
||||||
|
|
||||||
|
conf_file = self.conf_path('wsgi_sqlite.conf')
|
||||||
|
boot = marconi.Bootstrap(conf_file)
|
||||||
|
|
||||||
|
self.app = app.Application(boot.transport.app)
|
||||||
|
|
||||||
|
def test_run(self):
|
||||||
|
server = multiprocessing.Process(target=self.app.run)
|
||||||
|
server.start()
|
||||||
|
self.assertTrue(server.is_alive())
|
||||||
|
server.terminate()
|
||||||
|
server.join()
|
||||||
|
self.assertEquals(server.exitcode, -signal.SIGTERM)
|
57
marconi/transport/wsgi/app.py
Normal file
57
marconi/transport/wsgi/app.py
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
# Copyright (c) 2013 Red Hat, Inc.
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
"""
|
||||||
|
Gunicorn Application implementation for Marconi
|
||||||
|
"""
|
||||||
|
|
||||||
|
import gunicorn.app.base as gunicorn
|
||||||
|
import gunicorn.config as gconfig
|
||||||
|
|
||||||
|
from marconi.common import config
|
||||||
|
|
||||||
|
|
||||||
|
OPTIONS = {
|
||||||
|
# Process
|
||||||
|
"user": None,
|
||||||
|
"group": None,
|
||||||
|
"proc_name": "marconi",
|
||||||
|
|
||||||
|
# SSL
|
||||||
|
"certfile": None,
|
||||||
|
"keyfile": None,
|
||||||
|
|
||||||
|
# Network
|
||||||
|
"workers": 1,
|
||||||
|
"bind": "0.0.0.0:8888",
|
||||||
|
"worker_class": "sync"
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg = config.namespace('drivers:transport:wsgi').from_options(**OPTIONS)
|
||||||
|
|
||||||
|
|
||||||
|
class Application(gunicorn.Application):
|
||||||
|
|
||||||
|
def __init__(self, wsgi_app, *args, **kwargs):
|
||||||
|
super(Application, self).__init__(*args, **kwargs)
|
||||||
|
self.app = wsgi_app
|
||||||
|
|
||||||
|
def load(self):
|
||||||
|
return self.app
|
||||||
|
|
||||||
|
def load_config(self):
|
||||||
|
self.cfg = gconfig.Config(self.usage, prog=self.prog)
|
||||||
|
|
||||||
|
for key in OPTIONS:
|
||||||
|
self.cfg.set(key, getattr(cfg, key))
|
@ -15,11 +15,8 @@
|
|||||||
|
|
||||||
import falcon
|
import falcon
|
||||||
|
|
||||||
from marconi.common import config
|
|
||||||
from marconi import transport
|
from marconi import transport
|
||||||
|
from marconi.transport.wsgi import app
|
||||||
|
|
||||||
cfg = config.namespace('drivers:transport:wsgi').from_options(port=8888)
|
|
||||||
|
|
||||||
|
|
||||||
class Driver(transport.DriverBase):
|
class Driver(transport.DriverBase):
|
||||||
@ -56,4 +53,4 @@ class Driver(transport.DriverBase):
|
|||||||
'/claims/{claim_id}', claim_item)
|
'/claims/{claim_id}', claim_item)
|
||||||
|
|
||||||
def listen(self):
|
def listen(self):
|
||||||
raise NotImplementedError
|
return app.Application(self.app).run()
|
||||||
|
@ -6,4 +6,5 @@ PasteDeploy
|
|||||||
pymongo
|
pymongo
|
||||||
python-keystoneclient
|
python-keystoneclient
|
||||||
WebOb
|
WebOb
|
||||||
|
gunicorn
|
||||||
iso8601>=0.1.4
|
iso8601>=0.1.4
|
||||||
|
Loading…
x
Reference in New Issue
Block a user