Expand description
flo_scene_pipe provides ways to connect scenes created in flo_scene across process boundaries.
This can create socket programs using different protocols. These will automatically accept connections
and pass them on as messages. For example, start_unencrypted_tcp_socket() will create a TCP/IP socket
subprogram that will decode and encode messages for the scene. Socket subprograms send
SocketMessage::Connection() messages to the scene to indicate when a new connection is established.
Receivers of this message can use it to read and write messages to the corresponding connection.
Internal (in-process), TCP and unix domain sockets are supported.
This also adds an interactive command interpreter that can be used to interact directly with a scene. This provides a lot of use cases - for example:
- Debug or query a running system
- Run automatic tests on a system that’s in production at a lower level than just clicking around the UI or prodding public API instances (for example as part of a commisioning process)
- Configure or reconfigure a system without needing to restart it
- Load modules or upgrade them in place, particularly when combined with
flo_scene_wasm
The command interface runs as a subprogram that interacts with a socket. Commands are themselves served by subprograms. For example, you can set up a unix-domain socket like this:
use flo_scene::*;
use flo_scene_pipe::*;
use flo_scene_pipe::commands::*;
// Create a scene with some commands
let scene = Scene::default()
.with_standard_json_commands();
// Create a program that will receive connections from the socket and run commands
let command_program = SubProgramId::new();
scene.add_subprogram(command_program, |input, context| command_connection_program(input, context, ()), 0);
// Set up a UNIX socket that will parse commands in the standard syntax using `read_command_data`
// and write the results to the output using `write_command_data`
let socket_program = SubProgramId::new();
start_unix_socket_program(&scene, socket_program, "./example_unix_socket", read_command_data, write_command_data).unwrap();
// Connect the programs together so socket connects are processed by the command program
scene.connect_programs(socket_program, command_program, StreamId::with_message_type::<CommandProgramSocketMessage>()).unwrap();Connect to this socket with socat - UNIX-CONNECT:./example_unix_socket - it will present an interactive prompt where you
can type help to get more instructions.
This pattern can be used to make other kinds of server: replace read_command_data and write_command_data with your
own functions to set the format of the data sent over the socket and replace command_connection_program to define how
those messages are processed. The different socket types can be chosen by changing start_unix_socket_program to
something else.
New commands can be created using CommandLauncher which can be used to configure a subprogram to process them.
For example:
use flo_scene::commands::*;
let command_program = SubProgramId::called("my_crate::my_commands");
let json_launcher = CommandLauncher::json()
.with_json_command("::test", |param: String, _context| async move {
CommandResponse::Json(serde_json::Value::String(param))
});
scene.add_subprogram(command_program, json_launcher.to_subprogram(), 1);Re-exports§
pub use commands::JsonCommandLauncherExt;pub use standard_json_commands::StandardCommandsLauncherExt;pub use standard_json_commands::StandardCommandsSceneExt;
Modules§
- commands
- parser
- standard_
json_ commands - A set of command subprograms that implement a basic set of commands for interacting with a scene
Structs§
- Socket
Connection - Represents an incoming socket connection. When a socket is connected, we retrieve an input stream, and need to respond with an output stream.
Enums§
- Internal
Socket Message - Requests that can be made to the internal socket program
- Socket
Message - Event message sent from a program that represents a socket. Socket programs represent points where two-way connections can be made to this program.
Functions§
- socket_
listener_ subprogram - Runs a socket listener suprogram. This accepts ‘Subscribe’ messages from subprograms that wish to receive connections (subscription messages are sent in a round-robin fashion), and calls the ‘accept_message’ function to receive incoming connections
- start_
internal_ socket_ program - Creates an internal socket program
- start_
unencrypted_ tcp_ socket - Starts a sub-program that accepts unencrypted connections on a TCP socket.
- start_
unix_ socket_ program - Starts a sub-program in a sceme that accepts connections on a unix domain socket that binds at a specified path