Skip to content

Module specification

Sevoris Doe edited this page Jun 23, 2023 · 3 revisions

A "module" is native executable or on-the-machine interpretable code which can be invoked using the Command::new() function, and which has compliance with the stdin/stdout-based RPC communications to the Norgopolis-server.

Modules have a name, which is used to invoke communications with them. The module name must match the name of the executable (excluding the potential for a semantic version number at the end). The module name is a relative path from the modules load directory at ~/.local/share/norgopolis/modules.

Modules must return on startup a data structure which specifies their properties, available methods, and dependencies on other modules by name and semantic version number. Semantic version numbers may be given as ranges. This is used by the server loader to check that all other services needed by the module are available. If the loader fails to be able to provide all requested modules, it will command the new module to exit and return a "failed dependency" error to the event that caused the load to be attempted.

Exposing functions for calls

Function call requests occur in RPC protocol buffer binaries. Function calls may be a single message before the stream closes, or a stream of multiple messages. Likewise you may choose to return one or multiple messages on a streamed connection. As recipient of a function call invocation, the module has primacy over whether the call may be accepted or not. The RPC buffer will contain a function name to be invoked, and a messagepack binary. The later contains any data required to complete the function call. You must unpack and verify the messagepack. If it fails to comply, send an appropiate error message and close the connection.

Returns may be one or multiple messages in a streaming connection, containing return data as messagepack binary.

You must document your function methods and messagepack structure for parameters and return data. You may want to provide Rust crates wrapping the needed serialization and de-serialization as methods for consumers to make use of, providing and returning structs that can be used by the gRPC connections. This can also allow the use of things like messagepack custom types.

Clone this wiki locally