Browse files

Start to remove dispatcher code.

  • Loading branch information...
1 parent 7a0c03b commit 8d6eef08f846712d7fd4e514080b833dec1b9843 @rduplain committed Mar 16, 2012
Showing with 25 additions and 60 deletions.
  1. +25 −60 wsgi_party.py
View
85 wsgi_party.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
"""
- Partyline dispatcher for WSGI with good intentions.
+ Partyline middleware for WSGI with good intentions.
:copyright: (c) 2012 by Ron DuPlain.
:license: BSD, see LICENSE for more details.
@@ -23,80 +23,45 @@ class PartylineOperator(object):
The WSGI application uses this object to communicate with the party.
"""
- def __init__(self, dispatcher):
- self.dispatcher = dispatcher
+ def __init__(self, partyline):
+ self.partyline = partyline
def connect(self, service, handler):
- return self.dispatcher.connect(service, handler)
+ return self.partyline.connect(service, handler)
def send_all(self, service, payload):
- return self.dispatcher.send_all(service, payload)
+ return self.partyline.send_all(service, payload)
class WSGIParty(object):
- """Dispatcher for cross-application communication.
+ """Partyline middleware WSGI object."""
- Originally based on :class:`~werkzeug.wsgi.DispatcherMiddleware`.
- """
-
- #: URL path to the registration URL of participating applications.
- invite_path = '/__invite__/'
-
- #: Key in environ with reference to this dispatcher.
+ #: Key in environ with reference to the partyline operator.
partyline_key = 'partyline'
#: Class to use as the partyline operator, for connecting listeners.
operator_class = PartylineOperator
- def __init__(self, app, mounts=None, base_url=None):
- #: Application mounted at root.
- self.app = app
-
- #: Applications mounted at sub URLs, with sub-URL as the key.
- self.mounts = mounts or {}
-
- #: Base URL for use in environ. Defaults to None.
- self.base_url = base_url
-
- # A dict of service -> handler mappings.
- self.partyline = {}
-
- self.send_invitations()
+ def __init__(self, application, invites=()):
+ #: Wrapped WSGI application.
+ self.application = application
+ self.send_invitations(invites)
def __call__(self, environ, start_response):
- """Dispatch WSGI call to a mounted application, default to root app."""
- # TODO: Consider supporting multiple applications mounted at root URL.
- # Then, consider providing priority of mounted applications.
- # One application could explicitly override some routes of other.
- script = environ.get('PATH_INFO', '')
- path_info = ''
- while '/' in script:
- if script in self.mounts:
- app = self.mounts[script]
- break
- items = script.split('/')
- script = '/'.join(items[:-1])
- path_info = '/%s%s' % (items[-1], path_info)
- else:
- app = self.mounts.get(script, self.app)
- original_script_name = environ.get('SCRIPT_NAME', '')
- environ['SCRIPT_NAME'] = original_script_name + script
- environ['PATH_INFO'] = path_info
- return app(environ, start_response)
-
- def send_invitations(self):
- """Call each application via our partyline connection protocol."""
- operator = self.operator_class(self)
- for script, application in [('', self.app)] + self.mounts.items():
- base_url = (self.base_url or '/'.rstrip('/')) + script
- environ = create_environ(path=self.invite_path, base_url=base_url)
- environ[self.partyline_key] = operator
- run_wsgi_app(application, environ)
-
- @property
- def applications(self):
- """A list of all mounted applications, matching our protocol or not."""
- return [self.app] + self.mounts.values()
+ """Call wrapped application."""
+ self.applications(environ, start_response)
+
+ def send_invitations(self, invites):
+ """Call each invite route to establish a partyline."""
+ self.operator = self.operator_class(self)
+ for invite in invites:
+ self.send_invitation(invite)
+
+ def send_invitation(self, invite):
+ """Call individual route to add an application to the partyline."""
+ environ = create_environ(path=invite)
+ environ[self.partyline_key] = operator
+ run_wsgi_app(application, environ)
def connect(self, service, handler):
"""Register a handler for a given service."""

0 comments on commit 8d6eef0

Please sign in to comment.