This Month in Reactive Graph! September 2024
Hello and welcome to another issue of This Month in Reactive Graph! Reactive Graph is a runtime empowering everyone to build reliable and efficient software. This is a monthly summary of its progress and community. Want something mentioned? Send us a pull request. Want to get involved? We love contributions.
This Month in Reactive Graph is openly developed on GitHub and archives can be viewed at this-month-in.reactive-graph.io. If you find any errors in this month's issue, please submit a PR.
Table of Contents
- Build
- Continuous Integration
- Command Line Interface
- Refactoring
- Design System Enhancements
- Project Maintenance
Build
Stable Rust
The biggest news this month is that we got managed to compile Reactive Graph with Stable Rust.
What has changed?
- Implemented
DashMap
as container for subscribers ofStream
and removed usage of the unstable featureunsized_tuple_coercion
- Inlined implementation of feature
path_file_prefix
which will be stabilized soon, so that this is not a blocker - Removed usage of the unstable feature
test
and migrated to criterion (see Benchmarking with Criterion) - Removed usage of the unstable feature
register_tool
and make tarpaulin work again without this feature - Detect if the compiler is nightly and only if so, make use of the unstable features
unboxed_closures
andfn_traits
Support for musl builds
We introduced support MUSL builds.
What is musl?
musl is an implementation of the C standard library built on top of the Linux system call API, including interfaces defined in the base language standard, POSIX, and widely agreed-upon extensions. musl is lightweight, fast, simple, free, and strives to be correct in the sense of standards-conformance and safety.
Setup and Compile using musl
In order to successfully compile, you also have to install the package musl-tools
. For example for Debian / Ubuntu, you can install it like so:
$ apt install musl-tools
Next you have to add the musl target using rustup
:
$ rustup target add x86_64-unknown-linux-musl
Finally you can compile reactive-graph for the target x86_64-unknown-linux-musl
:
$ cargo build --target x86_64-unknown-linux-musl
rustls
We've finished work on replacing OpenSSL with rustls. OpenSSL is no more needed to build Reactive Graph.
Benchmarking with Criterion
Now the benchmark tests are run with criterion (which doesn't need Nightly Rust). Furthermore, the benchmarks has been
moved into its own benches/
folders.
Features of Criterion
- Statistics: Statistical analysis detects if, and by how much, performance has changed since the last benchmark run
- Charts: Uses gnuplot to generate detailed graphs of benchmark results
- Stable-compatible: Benchmark your code without installing nightly Rust
A future task would be to write more benchmark tests and to execute benchmarking in the CI.
Continuous Integration
Upgrade Workflows and Improve CI performance
We've upgraded the workflow actions to recent versions. Furthermore, we made some changes to speed up the CI. We've merge workflow files and made build jobs and test jobs dependent on the formatting check job and linting jobs. With this change, no build time is wasted if linting and formatting doesn't meet the requirements. Furthermore, we're run linting and test suite on Linux GNU and Linux musl for Rust stable and Rust nightly. But we don't run the complete test suite on Windows and macOS anymore. This is because running the test suite on Windows is 2x slower and on macOS is 6x slower compared to running on Linux. At a later point we may reintroduce a smaller subset of the test suite to run on Windows and macOS.
New Checks
- Minimal Supported Rust Version (MSRV)
- Dependabot now checks for outdated dependencies
- Checks that the CHANGELOG was edited
Command Line Interface
Managing the Instance System
We finished the implementation of managing the instance system via CLI (entity instances and relation instances). Furthermore, the CLI lists the applied components of the reactive instances.
Documented Command Line Interface
The book now contains a section about the Command Line Interface. We've added a section about the interactive mode and a section about the command reference. For the command reference we make use of a new option to automatically generate the help in Markdown format:
$ reactive-graph --markdown-help
TODO: Insert output here
Output Format Count
We've added a new output format that simply prints the count instead of a table with the results.
The purpose of the new feature is similar to count(*)
in SQL and is also useful for shell automation.
$ reactive-graph client components list --output-format count
$ reactive-graph client entity-types list --output-format count
$ reactive-graph client relation-types list --output-format count
$ reactive-graph client entity-instances list --output-format count
$ reactive-graph client relation-instances list --output-format count
Examples
Print the count of components
$ reactive-graph client components list --output-format count
34 result(s)
Example: Print the count of entity-instances
$ reactive-graph client entity-instances list --output-format count
1554 result(s)
Example: Print the count of entity-instances that having the component core__action
$ reactive-graph client entity-instances list --components core__action --output-format count
2 result(s)
Output Format HTML
We have added a new option to output the result as HTML table. This applies to all type system and instance system operations.
List types and instances as HTML table
$ reactive-graph client components list --output-format html-table
$ reactive-graph client entity-types list --output-format html-table
$ reactive-graph client relation-types list --output-format html-table
$ reactive-graph client entity-instances list --output-format html-table
$ reactive-graph client relation-instances list --output-format html-table
List all components as HTML table
$ reactive-graph client components list --output-format html-table
namespace
name
description
properties
extensions
state
state_object
State of type object
name
data_type
socket_type
mutability
state
Object
None
Immutable
set_state
Object
Input
Mutable
value
value_debugger_trace
arithmetic
arithmetic_operation
Arithmetic operation with one input and one result
name
data_type
socket_type
mutability
result
Number
Output
Immutable
lhs
Number
Input
Mutable
Namespace
TypeName
Description
Extension
core
component_category
"math"
base
named
The entity or relation has a name.
name
data_type
socket_type
mutability
name
String
None
Mutable
Namespace
TypeName
Description
Extension
core
component_category
"base"
value
value_object
Value of type object
name
data_type
socket_type
mutability
value
Object
Output
Mutable
result
result_boolean
The entity returns a boolean
name
data_type
socket_type
mutability
result
Bool
Output
Immutable
Namespace
TypeName
Description
Extension
core
component_category
"result"
Output a single type or a single instance as HTML table
$ reactive-graph client components get <namespace> <type_name> --output-format html-table
$ reactive-graph client entity-types get <namespace> <type_name> --output-format html-table
$ reactive-graph client relation-types get <namespace> <type_name> --output-format html-table
$ reactive-graph client entity-instances get <namespace> <type_name> --output-format html-table
$ reactive-graph client relation-instances get <namespace> <type_name> --output-format html-table
Output a single component as HTML table
$ reactive-graph client components get value value_number --output-format html-table
namespace | name | description | properties | extensions | ||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
value | value_number | Value of type number |
|
Output Format Markdown
Similar to the Output Format HTML, the Output Format Markdown prints the result as Markdown Table.
List types and instances as Markdown table
$ reactive-graph client components list --output-format markdown-table
$ reactive-graph client entity-types list --output-format markdown-table
$ reactive-graph client relation-types list --output-format markdown-table
$ reactive-graph client entity-instances list --output-format markdown-table
$ reactive-graph client relation-instances list --output-format markdown-table
List all components as Markdown table
$ reactive-graph client components list --output-format markdown-table
namespace | name | description | properties | extensions | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
state | state_object | State of type object |
| |||||||||||||||||||||
value | value_debugger_trace | |||||||||||||||||||||||
arithmetic | arithmetic_operation | Arithmetic operation with one input and one result |
|
| ||||||||||||||||||||
base | named | The entity or relation has a name. |
|
| ||||||||||||||||||||
value | value_object | Value of type object |
| |||||||||||||||||||||
result | result_boolean | The entity returns a boolean |
|
|
Output a single type or a single instance as Markdown table
$ reactive-graph client components get <namespace> <type_name> --output-format markdown-table
$ reactive-graph client entity-types get <namespace> <type_name> --output-format markdown-table
$ reactive-graph client relation-types get <namespace> <type_name> --output-format markdown-table
$ reactive-graph client entity-instances get <namespace> <type_name> --output-format markdown-table
$ reactive-graph client relation-instances get <namespace> <type_name> --output-format markdown-table
Output a single component as Markdown table
$ reactive-graph client components get value value_number --output-format markdown-table
namespace | name | description | properties | extensions | ||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
value | value_number | Value of type number |
|
Shell Completions
In order to further improve the user experience with the command line interface we've implemented the feature to generate shell completions.
List of Supported Shells
- bash
- elvish
- fish
- powershell
- zsh
On linux it's possible to install the shell completions for the given shell by executing:
$ reactive-graph --install-shell-completions bash|fish|zsh
Then you have to restart the shell, for example:
$ zsh
Profit!
$ reactive-graph --
TAB
--daemon-group -- If set will drop privileges to the specified group. Note: Both must be given: user and group
--daemon -- If true, the process will run as daemon
--daemon-name -- Sets the name of the daemon
--daemon-pid -- The location of the daemon PID file. By default, no PID file will be created
--daemon-stderr -- Stderr will be written into this file
--daemon-stdout -- Stdout will be written into this file
--daemon-user -- If set will drop privileges to the specified user. Note: Both must be given: user and group
--daemon-working-directory -- The working directory of the daemon
--default-context-path -- The default context path which redirects the root context to a web resource provider
--disable-all-plugins -- If true, all plugins will be disabled
--disabled-plugins -- The list of plugins to disable
--disable-hot-deploy -- If true, hot deployment will be disabled
--enabled-plugins -- The list of plugins to enable
--graphql-config -- The GraphQL config location
--help -- Print help
--hostname -- The hostname to bind the GraphQL HTTP server
--hot-deploy-location -- The folder which is watched for hot deployment
--install-location -- The folder which plugins are installed permanently
--install-man-pages -- If true, installs man pages
--install-shell-completions -- If true, installs shell completions
--instance-config -- The instance config location
--instance-description -- The description of the instance
--instance-name -- The name of the instance
--logging-config -- The logging config location
--markdown-help -- If true, generates command line documentation
--plugins-config -- The plugins config location
--port -- The port to bind the GraphQL HTTP server
--print-man-pages -- If true, generates man pages
--print-shell-completions -- If true, prints shell completions
--quiet -- If true, logging is disabled completely
--secure -- If true, HTTPS is enabled
--shutdown-timeout -- Timeout for graceful workers shutdown in seconds. After receiving a stop signal, workers have this much time to finish serving requests. Workers still alive after the timeout are force dropped. By default, shutdown timeout sets to 30 seconds
--ssl-certificate-path -- The location of the certificate
--ssl-private-key-path -- The location of the private key
--stop-immediately -- If true, the runtime does not wait before exiting
--version -- Print version
--workers -- The number of workers to start. The default worker count is the number of physical CPU cores available
Man Pages (Linux only)
Similarly to shell completions, the command line interface can generate, print and install man pages.
What is a man page?
A man page (short for manual page) is a form of software documentation usually found on a Unix or Unix-like operating system. Topics covered include computer programs (including library and system calls), formal standards and conventions, and even abstract concepts. A user may invoke a man page by issuing the man command.
First, you can install man pages:
$ reactive-graph --install-man-pages
Then you can use the man
command:
$ man reactive-graph
reactive-graph(1) General Commands Manual reactive-graph(1)
NAME
reactive-graph - Reactive Graph is a reactive runtime based on a graph database, empowering everyone to build reliable and efficient software.
SYNOPSIS
reactive-graph [--logging-config] [--instance-config] [--graphql-config] [--plugins-config] [-n|--instance-name] [-d|--instance-description] [--hostname] [--port] [--secure] [--ssl-certificate-path] [--ssl-private-key-path] [--shutdown-timeout] [-w|--workers] [-c|--default-context-path] [-x|--disable-all-plugins] [-p|--dis‐
abled-plugins] [-P|--enabled-plugins] [--disable-hot-deploy] [--hot-deploy-location] [--install-location] [--stop-immediately] [-q|--quiet] [--print-man-pages] [--install-man-pages] [--print-shell-completions] [--install-shell-completions] [-D|--daemon] [--daemon-name] [--daemon-pid] [--daemon-working-directory] [--dae‐
mon-stdout] [--daemon-stderr] [--daemon-user] [--daemon-group] [-h|--help] [-V|--version] [subcommands]
DESCRIPTION
Reactive Graph is a reactive runtime based on a graph database, empowering everyone to build reliable and efficient software.
OPTIONS
--logging-config=LOGGING_CONFIG
The logging config location
May also be specified with the REACTIVE_GRAPH_LOGGING_CONFIG environment variable.
--instance-config=INSTANCE_CONFIG
The instance config location
May also be specified with the REACTIVE_GRAPH_INSTANCE_CONFIG environment variable.
...
Dedicated client binary
We follow the approach to have one binary for all use cases (server & client).
Additionally, we now provide a second binary that only contains the client.
$ ls -lah target/debug/reactive-graph*
-rwxrwxr-x 2 rust rust 81M reactive-graph
-rwxrwxr-x 2 rust rust 29M reactive-graph-client
$ reactive-graph-client relation-instances list --output-format count
9366 result(s)
Daemonize
On Linux, it's now possible to start the process and run it in the background. Because the daemon has no stdout and stderr, a file can be given as output. Also, the process can drop privileges to a given user+group. Optionally, a PID and name can be specified.
$ reactive-graph --help
-D, --daemon
If true, the process will run as daemon [env: REACTIVE_GRAPH_DAEMON=]
--daemon-name <DAEMON_NAME>
Sets the name of the daemon [env: REACTIVE_GRAPH_DAEMON_NAME=]
--daemon-pid <DAEMON_PID>
The location of the daemon PID file. By default, no PID file will be created [env: REACTIVE_GRAPH_DAEMON_PID=]
--daemon-working-directory <DAEMON_WORKING_DIRECTORY>
The working directory of the daemon [env: REACTIVE_GRAPH_DAEMON_WORKING_DIRECTORY=]
--daemon-stdout <DAEMON_STDOUT>
Stdout will be written into this file [env: REACTIVE_GRAPH_DAEMON_STDOUT=]
--daemon-stderr <DAEMON_STDERR>
Stderr will be written into this file [env: REACTIVE_GRAPH_DAEMON_STDERR=]
--daemon-user <DAEMON_USER>
If set will drop privileges to the specified user. Note: Both must be given: user and group [env: REACTIVE_GRAPH_DAEMON_USER=]
--daemon-group <DAEMON_GROUP>
If set will drop privileges to the specified group. Note: Both must be given: user and group [env: REACTIVE_GRAPH_DAEMON_GROUP=]
In order to start Reactive Graph as a daemon, you have to pass the parameter -D
or set the environment variable REACTIVE_GRAPH_DAEMON=true
:
$ reactive-graph --daemon
Refactoring
Extracted table model
The table model has been refactored into its own crate. This allows to print tables in other command line applications.
The examples are now using the table model. The printed tables look better than before. Thanks to the table model, it is no more necessary to render tables manually.
GraphQL Schema
There are some changes to the GraphQL schema:
List of Changes
- edgeKey has been renamed to relationInstanceId for consistency
- EdgeKeyDefinition has been renamed to RelationInstanceIdDefinition for consistency
- Extended mutation
instances -> relations -> update()
with the new parameters addProperties and removeProperties in order to add or remove one or multiple properties
Design System Enhancements
Circle Logos
We added a new set of logos with a circle around the inner graph symbol:
Black/White | Malachite | Selective Yellow | Celestial Blue | Mexican Pink | Chartreuse |
Horizontal Rules
Nothing special, but useful: horizontal rules
Project Maintenance
Social Media
We created a YouTube channel, a facebook profile and a mastodon account. We will start social media activities in near future.
Contribution Guidelines & Security Policy
We've extended the Contribution Guidelines and added a Security Policy.