<- Back to Index

Developer Documentation

The SQL LRS is a Clojure Web Application built on the Pedestal Framework.

Build

The SQL LRS can be built or run with the following Makefile targets. They can be executed with make [target].

Build and Test Targets

TargetDescription
ciCalled when running continuous integration; runs all test cases in all SQL flavors.
test-sqliteRun all tests with SQLite database.
test-postgresRun all tests with Postgres database version 11. Set the LRSQL_TEST_DB_VERSION env var to a valid Postgres docker tag to use another version.
test-postgres-11Run all tests with Postgres database version 11.
test-postgres-12Run all tests with Postgres database version 12.
test-postgres-13Run all tests with Postgres database version 13.
test-postgres-14Run all tests with Postgres database version 14.
test-postgres-15Run all tests with Postgres database version 15.
bundleBuild a complete distribution of the SQL LRS including the user interface and native runtimes for multiple operating systems.
benchRun a load test and benchmark performance, returning performance metrics on predefined test data. Requires a running SQL LRS instance to test against. This test sends requests synchronously on one thread.
bench-asyncSame as bench but it runs with concurrent requests on multiple threads.
check-vulnRun the nvd-clojure tool, which checks for vulnerabilities against the National Vulnerability Database.

Run Targets

TargetDescription
ephemeralStart an in-memory SQL LRS based on SQLite DB.
ephemeral-prodSimilar to ephemeral, except that the :prod profile is used, enabling the use of environment variables without full compilation.
sqliteStart a SQLite-based SQL LRS.
postgresStart a Postgres SQL LRS. Requires a running Postgres instance.
run-jar-sqliteSimilar to sqlite but it runs the finished Jar instead of directly from Clojure. Runs with a predefined default set of env variables.
run-jar-sqlite-ephemeralSimilar to ephemeral but it runs the finished Jar instead of directly from Clojure. Runs with a predefined default set of env variables.
run-jar-postgresSimilar to postgres but it runs the finished Jar instead of directly from Clojure. Runs with a predefined default set of env variables.

Cleanup Targets

TargetDescription
cleanRemoves all build artifacts.
clean-non-dlSame as clean except that it does not delete downloaded folders.
clean-devRemoves development files.
clean-exeRemoves the finished Windows executables, allowing recreation.

Benchmarking

You can customize and run benchmarks for SQL LRS (or any conformant LRS, though the benchmarking framework was designed for SQL LRS). The benchmarking framework will insert auto-generated Statements into a running SQL LRS instance, then querying them and recording query time statistics.

1. Set up insertion inputs

This step can be skipped if your DB already has Statements stored and you are only running queries.

The insertion input file is a JSON file that follows the DATASIM input format. The benchmarking framework uses DATASIM to generate a Statement sequence from that input file. See the DATASIM documentation for more information about the proper input format.

2. Set up query inputs

The query input file is a JSON file containing an array of Statement query parameter objects. The following is an example query input:

[{}, { "verb": "https://w3id.org/xapi/video/verbs/seeked" }]

See the Statement resource documentation for a full list of query parameters.

3. Start an LRS instance

Start an instance of the SQL LRS (or any conformant LRS). The above Makefile targets provide a convenient way of doing so.

4. Run the benchmarks

In another terminal, run the benchmarking framework by calling:

clojure -M:bench -m lrsql.bench [arguments]

The following is the full list of arguments (which can also be accessed by passing the --help argument):

ArgumentValueDefaultDescription
-e, --lrs-endpointURI
http://0.0.0.0:8080/xapi/statements(URI)
The HTTP(S) endpoint of the (SQL) LRS webserver for Statement POSTs and GETs.
-i, --insert-inputFilepathNoneThe location of a JSON file containing a DATASIM input spec. If given, this input is used to insert statements into the DB.
-s, --input-sizeInteger1000The total number of statements to insert. Ignored if -i is not given.
-b, --batch-sizeInteger10The batch size to use for inserting statements. Ignored if -i is not given.
-a, --async?BooleanfalseWhether to insert asynchronously or not.
-c, --concurrencyInteger10The number of parallel threads to run during statement insertion and querying. Ignored if -a is false.
-r, --statement-refsKeywordnoneHow Statement References should be generated and inserted. Valid options are none (no Statement References), half (half of the Statements have StatementRef objects), and all (all Statements have StatementRef objects).
-q, --query-inputFilepathNoneThe location of a JSON file containing an array of statement query params. If not given, the benchmark does a single query with no params.
-n, --query-numberInteger30The number of times each query is performed.
-u, --userStringNoneHTTP Basic Auth user.
-p, --passStringNoneHTTP Basic Auth password.
-h, --helpNo argsNoneHelp menu.

5. Wait for results

After the bench has run, you should see results that look something like this:

********** Query benchmark results for n = 30 (in ms) **********

|                                              :query | :mean | :sd | :max | :min | :total |
|-----------------------------------------------------+-------+-----+------+------+--------|
|                                                  {} |    24 |  14 |   96 |   19 |    722 |
| {"verb" "https://w3id.org/xapi/video/verbs/seeked"} |    20 |   3 |   33 |   18 |    604 |

<- Back to Index