Skip to content

Commit

Permalink
refactor: make deployed services have their own runtime
Browse files Browse the repository at this point in the history
  • Loading branch information
chesedo authored Mar 8, 2022
1 parent ef8e117 commit 6c6e88b
Show file tree
Hide file tree
Showing 9 changed files with 770 additions and 69 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,6 @@ jobs:
override: true
- name: Make config file
run: mkdir -p ~/.config/unveil/ && echo "api_key = \"ci-test\"" > ~/.config/unveil/config.toml
- name: Use local unveil-service
run: mkdir -p ~/.cargo && echo -e "[patch.crates-io]\nunveil-service = { path = \"${GITHUB_WORKSPACE}/service\" }" > ~/.cargo/config.toml
- run: cargo test
1 change: 1 addition & 0 deletions Cargo.lock

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

68 changes: 24 additions & 44 deletions api/src/deployment.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
use core::default::Default;
use futures::future::{abortable, AbortHandle};
use libloading::Library;
use rocket::data::ByteUnit;
use rocket::tokio;
use rocket::Data;
use std::collections::HashMap;
use std::fs::DirEntry;
use std::io::Write;
use std::net::{Ipv4Addr, SocketAddrV4, TcpListener};
use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4, TcpListener};
use std::path::{Path, PathBuf};
use std::sync::{Arc, Mutex};
use std::time::Duration;
use anyhow::{anyhow, Context as AnyhowContext};
use tokio::task::JoinHandle;
use tokio::sync::RwLock;

use crate::build::Build;
use crate::{BuildSystem, UnveilFactory};
use lib::{DeploymentApiError, DeploymentId, DeploymentMeta, DeploymentStateMeta, Host, Port};
Expand Down Expand Up @@ -120,7 +119,7 @@ impl Deployment {
}
}
}
DeploymentState::Loaded(loaded) => {
DeploymentState::Loaded(mut loaded) => {
let port = identify_free_port();

log::debug!(
Expand All @@ -134,38 +133,24 @@ impl Deployment {
let factory =
UnveilFactory::new(&mut db_state, meta.config.clone(), db_context.clone());

let deployed_future = match loaded.service.deploy(&factory) {
unveil_service::Deployment::Rocket(r) => {
if let database::State::Ready(ready) = &db_state {
self.meta.write().await.database_deployment = Some(ready.clone());
}
let config = rocket::Config {
port,
log_level: rocket::config::LogLevel::Normal,
..Default::default()
};

r.configure(config).launch()
}
};
if loaded.service.build(&factory).await.is_err() {
DeploymentState::Error
} else {
let serve_task = loaded
.service
.bind(SocketAddr::new(Ipv4Addr::LOCALHOST.into(), port));

let (task, abort_handle) = abortable(deployed_future);
// TODO: upon resolving this future, change the status of the deployment
let handle = tokio::spawn(serve_task);

tokio::spawn(task);
// Remove stale active deployments
if let Some(stale_id) = context.router.promote(meta.host, meta.id).await {
log::debug!("removing stale deployment `{}`", &stale_id);
context.deployments.write().await.remove(&stale_id);
}

// Remove stale active deployments
if let Some(stale_id) = context.router.promote(meta.host, meta.id).await {
log::debug!("removing stale deployment `{}`", &stale_id);
context.deployments.write().await.remove(&stale_id);
DeploymentState::deployed(loaded.so, port, handle, db_state)
}

DeploymentState::deployed(
loaded.so,
loaded.service,
port,
abort_handle,
db_state,
)
}
deployed_or_error => deployed_or_error, /* nothing to do here */
};
Expand Down Expand Up @@ -473,12 +458,8 @@ impl DeploymentSystem {
// library when the runtime gets around to it.

let mut lock = deployment.state.write().await;
if let DeploymentState::Deployed(DeployedState {
so, abort_handle, ..
}) = lock.take()
{
abort_handle.abort();

if let DeploymentState::Deployed(DeployedState { so, handle, .. }) = lock.take() {
handle.abort();
tokio::spawn(async move {
so.close().unwrap();
});
Expand Down Expand Up @@ -529,6 +510,8 @@ impl DeploymentSystem {

const ENTRYPOINT_SYMBOL_NAME: &[u8] = b"_create_service\0";

type ServeHandle = JoinHandle<Result<(), unveil_service::Error>>;

type CreateService = unsafe extern "C" fn() -> *mut dyn Service;

/// Dynamically load from a `.so` file a value of a type implementing the
Expand Down Expand Up @@ -593,16 +576,14 @@ impl DeploymentState {

fn deployed(
so: Library,
service: Box<dyn Service>,
port: Port,
abort_handle: AbortHandle,
handle: ServeHandle,
db_state: database::State,
) -> Self {
Self::Deployed(DeployedState {
service,
so,
port,
abort_handle,
handle,
db_state,
})
}
Expand Down Expand Up @@ -633,9 +614,8 @@ struct LoadedState {

#[allow(dead_code)]
struct DeployedState {
service: Box<dyn Service>,
so: Library,
port: Port,
abort_handle: AbortHandle,
handle: ServeHandle,
db_state: database::State,
}
Loading

0 comments on commit 6c6e88b

Please sign in to comment.