Monorail's source code organization evolved from the way that source code was organized for Google Code (code.google.com). That site featured a suite of tools with code for each tool in a separate directory. Roughly speaking, the majority of the code was organized to match the information architecture of the web site. Monorail keeps that general approach, but makes a distinction between core issue tracking functionality (in the
tracker directory) and additional features (in the
Also dating back to Google Code‘s 2005 design, the concept of a “servlet” is key to Monorail’s UI-centric source code organization. A servlet is a python class with methods to handle all functionality for a given UI web page. Servlets handle the initial page rendering, any form processing, and have related classes for any XHR calls needed for interactive elements on a page. Servlet's mix application business logic, e.g., permission checks, with purely UI logic, e.g., screen flow and echoing UI state in query string parameters.
From 2018 to 2020, the old servlet-oriented source code organization is slowly being hollowed out and replaced with a more API-centric implementation. Server-side python code is gradually being shifted from the
features directories to the
Although Monorail's GAE app has several GAE services, we do not organize the source code around GAE services because they each share a significant amount of code.
At a high level, the code is organized into a few logical layers with dependencies going downward:
The main program
monorailapp.py that ties all the servlets together.
All GAE configuration files, e.g.,
Request handler layer
This including servlets, inbound email, Endpoints, and rRPC.
These files handle a request from a user, including syntactic validation of request fields, and formatting of the response.
Business logic layer
This layer does the main work of handling a request, including semantic validation of whether the request is valid, permission checking, coordinating calls to the services layer, and kicking off any follow-up tasks such as sending notification.
Much of the content of
*_bizobj.py files also belong to this layer, even though it has not been moved here as of 2019.
This layer include our object-relational-mapping logic.
It also manages connections to backends that we use other than the database, for example full-text search.
*_constants.pyfiles, and protobuf definitions.
monorailapp.py: The main program that loads all web app request handlers.
registerpages.py: Code to register specific request handlers at specific URLs.
*.yaml: GAE configuration files
Request handler layer
tracker/*.py: Servlets for core issue tracking functionality.
features/*.py: Servlets for issue tracking features that are not core to the product.
project/*.py: Servlets for creating and configuring projects and memberships.
sitewide/*.py: Servlets for user profile pages, the site home page, and user groups.
templates/*/*.ezt: Template files for old web UI page generation.
api/*.py: pRPC API request handlers.
services/api_svc_v1.py: Endpoints request handlers.
features/inboundemail.py: Inbound email request handlers and bounces.
features/notify.py: Email notification task handlers.
Business logic layer
businesslogic/work_env.py: Internal API for monorail.
*/*_helpers.py* files: Business logic that was written for servlets but that is gradually being used only through work_env.
schema/*.sql: SQL database table definitions.
services/service_manager.py: Simple object to hold all service objects.
cachemanager.py: RAM and memcache caches and distributed invalidation.
services/issues_svc.py: DB persistence for issues, comments, and attachments
services/user_svc.py: Persistence for user accounts.
services/usergroup_svc.py: Persistence for user groups.
services/features_svc.py: Persistence for hotlists, saved queries, and filter rules.
services/chart_svc.py: Persistence for issue snapshots and charting queries.
services/secrets_svc.py: Datastore code for key used to generate XSRF tokens.
services/project_svc.py: Persistence for projects and members.
services/config_svc.py: Persistence for issue tracking configuration in a project, except templates.
services/client_config_svc.py: Persistence for API allowlist.
services/tracker_fulltext.py: Connection to GAE fulltext search index.
services/template_svc.py: Persistence for issue templates.
services/star_svc.py: Persistence for all types of stars.
services/spam_svc.py: Persistence for abuse flags and spam verdicts.
services/ml_helpers.py: Utilities for working with ML Engine backend.
search/*: frontend and backend code for sharded issue search and result set caching.
framework/sql.py: SQL DB table managers and safe SQL statement generation.
jsonfeed.py: Base classes for servlets.
framework/warmup.py: Trivial servlet needed for GAE warmup feature.
framework/permissions.py: Permissionset objects and permission checking functions.
monorailcontext.py: objects that represent information about the incoming request.
banned.py: Anti-abuse utilities.
testing/*.py: Utilities for python unit tests.
settings.py: Server instance configuration.
framework/urls.py: Constants for web UI URLs.
framework/exceptions.py: python exceptions used throughout the code.
framework/framework_constants.py: Implementation-oriented constants.
proto/*.proto: ProtoRPC definitions for internal representation of business objects.