Skip to content

Commit

Permalink
Merge main and fix tests
Browse files Browse the repository at this point in the history
  • Loading branch information
paulgb committed Jan 19, 2024
2 parents b349f9b + 90eefde commit 051af42
Show file tree
Hide file tree
Showing 34 changed files with 249 additions and 331 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dev/controller.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#!/bin/sh

cargo run -- controller --db postgres://postgres@localhost "$@"
cargo run -- controller --db postgres://postgres@localhost "$@" --default-cluster localhost:9090
2 changes: 1 addition & 1 deletion docker/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ services:
dockerfile: docker/Dockerfile
context: ../
command:
"controller --db postgres://postgres@postgres --host 0.0.0.0"
"controller --db postgres://postgres@postgres --host 0.0.0.0 --default-cluster=localhost:9090"
networks:
- plane-dev
ports:
Expand Down
2 changes: 1 addition & 1 deletion docker/quickstart/supervisord.conf
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ environment=POSTGRES_HOST_AUTH_METHOD=trust
user=postgres

[program:plane-controller]
command=/bin/plane controller --db postgres://postgres@127.0.0.1 --host 0.0.0.0 --controller-url http://localhost:8080
command=/bin/plane controller --db postgres://postgres@127.0.0.1 --host 0.0.0.0 --controller-url http://localhost:8080 --default-cluster localhost:9090
autostart=true
autorestart=true
stderr_logfile=/var/log/plane-controller-stderr.log
Expand Down
108 changes: 0 additions & 108 deletions docs/pages/quickstart-guide.mdx
Original file line number Diff line number Diff line change
@@ -1,108 +0,0 @@
import { Callout } from 'nextra/components'

# Quickstart Guide

The easiest way to try out Plane is to use Docker Compose. These instructions are for a Linux or Mac environment
with Docker installed.

## Quickstart Steps

### 1. Clone Plane’s [git repo](https://github.com/drifting-in-space/plane)

```bash
git clone https://github.com/drifting-in-space/plane.git
cd plane
```

### 2. Start Plane

```bash
docker compose -f docker/docker-compose.yml up
```

This will run:
- An instance of Postgres
- A Plane controller
- A Plane “drone”
- A Plane proxy

See the [architecture overview](concepts/architecture.mdx) for background on each Plane component.

### 3. Connect to a backend

```bash
docker/cli.sh \
connect \
--cluster 'localhost:9090' \
--key 'my-first-backend' \
--image 'ghcr.io/drifting-in-space/demo-image-drop-four' \
--wait
```

You can think of Plane as a big key-value store that associates “keys” (arbitrary strings) with running processes
([session backends](concepts/session-backends.mdx)).

When you issue a “connect” request, Plane will return a URL that routes to the process associated with the key you provide.
If no process is running, Plane will start one (provided that you supply an image name in the connect request).

Here’s a breakdown of the command above:

- `docker/cli.sh` is a shell script that runs the Plane CLI in a Docker container, pre-configuring it to point to
a Plane instance started in the Docker Compose file.
- `connect` is the Plane CLI subcommand for issuing a “connect request”, which will return a URL that routes to
a backend process.
- `--cluster 'localhost:9090'` tells the CLI to start the backend on the `localhost:9090` cluster. Since the cluster name
includes a port (`:9090`), Plane will treat it as a “development” cluster and not enable HTTPS on it. See [clusters](concepts/clusters.mdx)
for more details.
- `--key 'my-first-backend'` tells the CLI to associate the backend with the key `my-first-backend`. The first time we run
this command, no backend with the key `my-first-backend` will exist, so Plane will start a new backend process. If we
subsequently run this command again while that backend process is still running, Plane will return a URL that routes
to that backend process.
- `--image '...'` tells the CLI that if it needs to start a new backend process,
it should use the given Docker image. In this case, the image serves a simple turn-based multiplayer game.
- `--wait` tells the CLI to display the backend’s status as it starts up, and to wait until the backend is `Ready` before
returning.

<Callout type="info">
At least one of `--key` or `--image` must be provided, but it is not neccesary to include both.

If you **only** want to connect to an existing backend, you can provide `--key` only. If a
backend with the given key is not running, Plane will return an error.

If you **don’t** want to connect to an existing backend process, you can provide `--image` only.
Plane will use a unique key to start a new backend, and return a URL that routes to it.
</Callout>

When you run the command above, you should see output like this:

```
Created backend: ba-xt8nmtlgti18qx
URL: http://localhost:9090/tYVHfS4PKgufdhwGCnn6LLfAaCo_iAHitbw4Bg8ETjA/
Status URL: http://0.0.0.0:8080/pub/c/localhost:9090/b/ba-xt8nmtlgti18qx/status
```

The first line tells you that Plane has created a backend with the key `ba-xt8nmtlgti18qx`. The second line tells you
a URL that routes to that backend. The third line tells you a URL that you can use to check the status of the backend
as JSON.

Below that output, it will show a running list of states and the time they were entered. The first
time you run a particular image, it may spend some time in the `Loading` state, because it will download the container
image if it does not have it cached.

Once the image is in the `Ready` state, you can open the URL provided in your browser to open the game.

## Docker Compose Configuration

The Docker Compose file defines four services:

| Container | Image | Port |
|------------------|----------------------|------|
| plane-postgres | `postgres:16` | 5432 |
| plane-controller | `plane/plane:latest` | 8080 |
| plane-drone | `plane/plane:latest` | |
| plane-proxy | `plane/plane:latest` | 9090 |

Note that the name of the cluster (`localhost:9090`) refers to the port of the proxy, not the controller.
This is because the name of the cluster refers to the address that end-user clients will use to access the
backends, and clients access backends through the cluster. See [the documentation on clusters](concepts/clusters.mdx)
for more information.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion plane/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "plane"
version = "0.4.0"
version = "0.4.1"
edition = "2021"
default-run = "plane"
description = "Session backend orchestrator for ambitious browser-based apps."
Expand Down
21 changes: 8 additions & 13 deletions plane/plane-tests/tests/backend_actions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,18 @@ use plane::{
database::backend::BackendActionMessage,
names::{DroneName, Name},
protocol::{BackendAction, Heartbeat, MessageFromDrone, MessageToDrone},
types::{ConnectRequest, ConnectResponse, ExecutorConfig, SpawnConfig},
types::{ClusterName, ConnectRequest, ConnectResponse, ExecutorConfig, SpawnConfig},
};
use plane_test_macro::plane_test;
use std::time::Duration;

mod common;

/// Return a dummy connect request, which does not use a key.
fn connect_request() -> ConnectRequest {
fn connect_request(cluster: &ClusterName) -> ConnectRequest {
ConnectRequest {
spawn_config: Some(SpawnConfig {
cluster: Some(cluster.clone()),
executable: ExecutorConfig::from_image_with_defaults("alpine"),
lifetime_limit_seconds: None,
max_idle_seconds: None,
Expand All @@ -31,12 +32,9 @@ async fn no_drone_available(env: TestEnvironment) {
let controller = env.controller().await;

let client = controller.client();
let connect_request = connect_request();
let connect_request = connect_request(&env.cluster);

let result = client
.connect(&env.cluster, &connect_request)
.await
.unwrap_err();
let result = client.connect(&connect_request).await.unwrap_err();

assert!(matches!(
result,
Expand Down Expand Up @@ -71,11 +69,8 @@ async fn backend_action_resent_if_not_acked(env: TestEnvironment) {

tracing::info!("Issuing the connect request.");
let client = controller.client();
let connect_request = connect_request();
let result = client
.connect(&env.cluster, &connect_request)
.await
.unwrap();
let connect_request = connect_request(&env.cluster);
let result = client.connect(&connect_request).await.unwrap();

let ConnectResponse {
spawned: true,
Expand Down Expand Up @@ -149,7 +144,7 @@ async fn backend_action_resent_if_not_acked(env: TestEnvironment) {

controller
.client()
.soft_terminate(&env.cluster, &backend_id)
.soft_terminate(&backend_id)
.await
.unwrap();

Expand Down
18 changes: 8 additions & 10 deletions plane/plane-tests/tests/backend_lifecycle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,10 @@ async fn backend_lifecycle(env: TestEnvironment) {
tracing::info!("Requesting backend.");
let connect_request = ConnectRequest {
spawn_config: Some(SpawnConfig {
cluster: Some(env.cluster.clone()),
executable: ExecutorConfig {
image: "ghcr.io/drifting-in-space/demo-image-drop-four".to_string(),
pull_policy: PullPolicy::IfNotPresent,
pull_policy: Some(PullPolicy::IfNotPresent),
env: HashMap::default(),
resource_limits: ResourceLimits::default(),
credentials: None,
Expand All @@ -39,10 +40,7 @@ async fn backend_lifecycle(env: TestEnvironment) {
user: None,
auth: Map::default(),
};
let response = client
.connect(&env.cluster, &connect_request)
.await
.unwrap();
let response = client.connect(&connect_request).await.unwrap();
tracing::info!("Got response.");

assert!(response.spawned);
Expand All @@ -51,7 +49,7 @@ async fn backend_lifecycle(env: TestEnvironment) {

tracing::info!("Streaming status.");
let mut backend_status_stream = client
.backend_status_stream(&env.cluster, &backend_id)
.backend_status_stream(&backend_id)
.with_timeout(10)
.await
.unwrap()
Expand Down Expand Up @@ -119,7 +117,7 @@ async fn backend_lifecycle(env: TestEnvironment) {

// Test non-streaming status endpoint.
let status = client
.backend_status(&env.cluster, &response.backend_id)
.backend_status(&response.backend_id)
.with_timeout(10)
.await
.unwrap()
Expand Down Expand Up @@ -156,7 +154,7 @@ async fn backend_lifecycle(env: TestEnvironment) {
let initial_keepalive = {
let backend = db
.backend()
.backend(&env.cluster, &response.backend_id)
.backend(&response.backend_id)
.with_timeout(10)
.await
.unwrap()
Expand All @@ -178,7 +176,7 @@ async fn backend_lifecycle(env: TestEnvironment) {
{
let backend = db
.backend()
.backend(&env.cluster, &response.backend_id)
.backend(&response.backend_id)
.with_timeout(10)
.await
.unwrap()
Expand All @@ -190,7 +188,7 @@ async fn backend_lifecycle(env: TestEnvironment) {

tracing::info!("Terminating backend.");
client
.soft_terminate(&env.cluster, &response.backend_id)
.soft_terminate(&response.backend_id)
.with_timeout(10)
.await
.unwrap()
Expand Down
15 changes: 5 additions & 10 deletions plane/plane-tests/tests/backend_status_in_response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@ async fn backend_status_in_response(env: TestEnvironment) {
tracing::info!("Requesting backend.");
let connect_request = ConnectRequest {
spawn_config: Some(SpawnConfig {
cluster: Some(env.cluster.clone()),
executable: ExecutorConfig {
image: "ghcr.io/drifting-in-space/demo-image-drop-four".to_string(),
pull_policy: PullPolicy::IfNotPresent,
pull_policy: Some(PullPolicy::IfNotPresent),
env: HashMap::default(),
resource_limits: ResourceLimits::default(),
credentials: None,
Expand All @@ -41,10 +42,7 @@ async fn backend_status_in_response(env: TestEnvironment) {
auth: Map::default(),
};

let response = client
.connect(&env.cluster, &connect_request)
.await
.unwrap();
let response = client.connect(&connect_request).await.unwrap();
tracing::info!("Got response.");

assert!(response.spawned);
Expand All @@ -53,7 +51,7 @@ async fn backend_status_in_response(env: TestEnvironment) {
let backend_id = response.backend_id.clone();

let mut backend_status_stream = client
.backend_status_stream(&env.cluster, &backend_id)
.backend_status_stream(&backend_id)
.with_timeout(10)
.await
.unwrap()
Expand All @@ -71,10 +69,7 @@ async fn backend_status_in_response(env: TestEnvironment) {
tracing::info!(status=?message, "Got status");
}

let response2 = client
.connect(&env.cluster, &connect_request)
.await
.unwrap();
let response2 = client.connect(&connect_request).await.unwrap();

assert!(!response2.spawned);
assert_eq!(response2.backend_id, backend_id);
Expand Down
2 changes: 1 addition & 1 deletion plane/plane-tests/tests/common/resources/database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ impl DevDatabase {
let port = container.get_port(5432).await?;
let connection_string = Self::get_connection_string(port);

println!("Connection_string: {}", connection_string);
tracing::info!("Connection string: {}", connection_string);

let db = attempt_to_connect(&connection_string).await?;

Expand Down
1 change: 1 addition & 0 deletions plane/plane-tests/tests/common/test_env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ impl TestEnvironment {
listener,
ControllerName::new_random(),
url,
None,
)
.await
.expect("Unable to construct controller.");
Expand Down
Loading

0 comments on commit 051af42

Please sign in to comment.