Modules and Deprecation

This page describes the meaning of an “API Module”, as well as their deprecation policy.

API Modules

Currently, the Grader is separated into multiple modules to promote better isolation between various components of the system. These modules can generally be categorized into 3 types:

API Modules

API modules make up the base of the Grader, providing various interfaces, abstract base classes, as well as concrete implementation-agnostic classes for other modules to use.

API Modules are typically named as :<component>:<component>-api; <component> referring to the component which the module is designed to provide APIs for. The exception is :common, which is also an API module, since it also mainly provides implementation-agnostic classes for dependent modules to use.

API-Implementation Modules

API-Implementation Modules are implementation-specific modules which are used to implement API modules. Since different frameworks or libraries have different ways of doing things, API-Implementation modules are to provide concrete implementations for specific components using specific frameworks.

API-Implementation Modules are typically named as :<component>:<framework>-<component>. Other naming schemes can be used, as long as the module is located under the same subdirectory as the API Module.

External-Facing Modules

External-Facing Modules are modules which bridges the gap between the Grader’s capabilities and the users of the Grader, including the Submission System and a Command-Line Interface.

Deprecation Policy

Note

This deprecation policy only applies to components internal to the Grader. Other aspects, such as Redis and other future IPC APIs, are not covered here; In fact they don’t have a deprecation policy yet.

General Guidelines

In general, you should strive to put all obsolete methods and classes through a deprecation cycle before removing them from the codebase.

The general workflow should be as follows:

  1. Refactor the class(es) and/or method(s), and rewrite all internally-dependent APIs to use the new class(es) and/or method(s)

  2. If possible, rewrite old method(s) as aliases to new methods, and rewrite old class(es) as type-aliases to new class(es)

  3. Write extension methods to convert obsolete class(es) to new class(es)

  4. Deprecate the usage of old class(es) and/or method(s)

  5. Refactor all existing usages of the obsolete class(es) and/or method(s)

  6. Write unit tests to ensure that the functionality of the new class(es) and/or method(s) matches those of the obsolete versions

    • Do not use obsolete class(es) and method(s) to implement your unit tests

After an API has been marked as deprecated, the general rule is that the API can be removed one month after the Merge Request containing the deprecation has been merged. Annotations in the future may be provided to signify which Merge Request the deprecation is a part of, and how long the deprecation should last.

API Modules

API Modules must follow the guidelines listed above, as API modules are highly depended upon by other modules.

However, under circumstances where the above guidelines cannot be followed, you must mark the commit(s) which violate the guidelines (e.g. those which directly remove external classes without deprecation) by prepending the commit message with [BREAKING], as well as to describe why the breaking change is required. The merge request containing the commit must also be marked as [BREAKING], and reviewers will pay extra attention to see whether the breaking change is justified or not.