KARL3 Architecture By Technology

While you can look at KARL3’s architecture by feature, technologists might also want to see the details organized by technology.

Programming Language

KARL3 uses Python. This may seem strange, as KARL2 uses Python, and Plone uses Python. But in KARL3, Python is more than the implementation language. It is the “platform”. We intend for Python web developers to feel right at home in KARL3. For too long, the worlds of Zope/Plone and Python have been separated.

Templating Language

KARL2 used XSLT as the templating language, running in a separate process. In that approach, the “backend” tier generated XML and sent it to the frontend tier, where XSLT generated the HTML user interface.

In KARL3, Zope Page Templates (ZPT) is the templating language. KARL3, though, uses Chameleon, a new and far faster (12x) implementation of ZPT.

Views

KARL2 used a very confusing mixture of technologies to generate the XML views sent from the backend to the frontend. In KARL3, views couldn’t be simpler: a decorator (or ZCML declaration) combined with a plain-ol’ Python function.

Content Type Schemas

KARL2 used a number of technologies to express the structure of content types. Archetypes was used for some, with accompanying Zope3 interfaces, and a custom bridging system called Fate.

In KARL3, “content types” are a very small and very limited facility. We don’t need pluggability and “CRUD” autogenerated forms. Thus, Zope3 interfaces provide the definition of content types.

There are no abstract “factories”.

Content Database

Both KARL2 and KARL3 use the Zope database (ZODB+ZEO). KARL3 uses a newer version, which also gives BLOB support, where binary files like PDFs are stored on the filesystem.

Indexing

For indexing and searching, KARL2 used Xapian and its (deprecated) Python binding for integration into Plone. Xapian has great performance and some compelling features, but created a number of sore spots for KARL:

  • Cumbersome pile of C++ code.
  • KARL2 was based on very old, no longer supported Python binding.
  • Original integration meant only one ZEO client, and later integration meant no real-time indexing.
  • The view subsystem routed all container listings through Xapian, making it a hotspot.

In KARL2 we are reverting to using the Zope cataloging machinery, by way of repoze.catalog. Performance will actually go up and complexity go way, way down.

Authentication

KARL2 used Zope’s “pluggable authentication system” to manage user data in Postgresql.

In KARL3 we use the repoze.who middleware for authentication. repoze.who is simply PAS moved out to middleware, allowing common authentication with other Python web applications that support repoze.who (e.g. TurboGears, Pylons.) Additionally, KARL3 uses SQLAlchemy as a mapping layer atop Postgresql.

It is possible that KARL3 separates the user information from the profile information, turning the latter into “content”.

Object Publisher

In the move from KARL1 to KARL2, KARL was actually changed into a WSGI application using the (mostly monolithic) repoze.plone distribution. This meant that KARL2 started using the refactored object publisher known as repoze.obob, a thin layer of WSGI integration that acted like the Zope2 object publisher.

KARL3, on the other hand, uses BFG, the microframework made out of Repoze technologies. This gives a very well documented and stable object publisher for graph traversal.

Application Server

Zope2 and, to a degree, Plone (via repoze.zope2 and repoze.plone) were the application server for KARL2. These large monolothic megaframeworks were published as a WSGI application. In KARL3, there isn’t much of an “application server”. Everything is much more modular, relying on pluggable WSGI middleware and repoze.bfg as an object publisher.

Content Management

Zope’s Content Management Framework (CMF), workflow (DCWorkflow) and the parts of Plone’s framework constituted the content management in KARL2.

In KARL3, there is no content management. KARL3 is an application that does what KARL wants done. This is good, because KARL isn’t in the content management domain.

Ajax

MochiKit was used as the cross-browser JavaScript library in KARL2. For Ajax UI we used client-side XSLT plus a lot of custom-written JavaScript. KARL2 leveraged no existing Ajax widget toolset for nice-looking web effects.

KARL3 uses KSS (from Zope) for Ajax, along with ExtJS as the widget framework. The latter gives access to a large pool of very high quality, usable widgets (LiveSearch, calendar popup, tagging autocomplete, sortable grids, etc.)

Forms

The form machinery in KARL2 was cumbersome and baroque. An Archetype schema was written (even when there wasn’t a content type), handled by code which autogenerated a Zope 3 interface and passed to zope.formlib to produce XML that was sent to the frontend and converted into HTML via XSLT.

KARL3 goes very far out of its way to be “normal” by integrating the most popular and mature form validation system used in Python, known as FormEncode. In this approach, a form is a form. We don’t define a content type and attempt to autogenerate a form from the schema.

Editor

Both KARL2 and KARL3 use TinyMCE 3, arguably the most popular web editor.

HTTP Server

As noted, KARL2 used a two-tier, frontend-backend architecture. This lead to an HTTP server approach where:

  • A request is answered by Apache
  • Forwarded via mod_proxy to a Python WSGI server using CherryPy as the HTTP server
  • Which then proxied to another Python WSGI server using Paste Proxy

In this, a single browser request lead to 2 additional HTTP requests. In KARL3 we intend to use mod_wsgi, thus eliminating the extra 2 requests (though possibly adding an IPC connection if we use daemon mode.)

mod_wsgi has a number of attractive process management possibilities. For example, since KARL3 startup time is under 2 seconds (as opposed to 30 seconds for KARL2,) we could let mod_wsgi transparently restart processes after 1,000 requests.

Process Monitor

mod_wsgi notwithstanding, both KARL2 and KARL3 both use Supervisor to start, stop, restart, and monitor all the processes KARL uses.

Build System

Both KARL2 and KARL3 use buildout and Python eggs to compose a sandbox. KARL3, though, will be markedly easier, as the number of dependencies has dropped dramatically.