wip: still working torwards the Redis oriented arch.
This commit is contained in:
parent
703a52ea8f
commit
1cc260b998
|
@ -8,7 +8,7 @@ WORKDIR lonk
|
||||||
COPY ./Cargo.lock ./Cargo.lock
|
COPY ./Cargo.lock ./Cargo.lock
|
||||||
COPY ./Cargo.toml ./Cargo.toml
|
COPY ./Cargo.toml ./Cargo.toml
|
||||||
|
|
||||||
RUN cargo build --release
|
RUN cargo build
|
||||||
RUN src/*.rs
|
RUN src/*.rs
|
||||||
|
|
||||||
# Compile the source
|
# Compile the source
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"db": {
|
"db": {
|
||||||
"address": "redis://127.0.0.1"
|
"address": "redis://db"
|
||||||
},
|
},
|
||||||
"slug_rules": {
|
"slug_rules": {
|
||||||
"length": 5,
|
"length": 5,
|
||||||
"chars": "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-"
|
"chars": "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-"
|
||||||
},
|
},
|
||||||
"serve_rules": {
|
"serve_rules": {
|
||||||
"Dir": "/etc/lonk/served"
|
"Dir": "/data/served"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset='utf-8'>
|
||||||
|
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
|
||||||
|
<title>Lonk</title>
|
||||||
|
<meta name='viewport' content='width=device-width, initial-scale=1'>
|
||||||
|
<link rel='stylesheet' type='text/css' media='screen' href='main.css'>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -3,8 +3,8 @@ services:
|
||||||
lonk:
|
lonk:
|
||||||
build: .
|
build: .
|
||||||
environment:
|
environment:
|
||||||
- PROFILE: release
|
|
||||||
- LONK_CONFIG: /data/config.json
|
- LONK_CONFIG: /data/config.json
|
||||||
|
- PROFILE: debug
|
||||||
volumes:
|
volumes:
|
||||||
- ./data:/data
|
- ./data:/data
|
||||||
redis:
|
redis:
|
||||||
|
|
51
src/main.rs
51
src/main.rs
|
@ -1,8 +1,8 @@
|
||||||
use argh::FromArgs;
|
use argh::FromArgs;
|
||||||
use figment::{providers::Format, Figment};
|
use figment::{providers::Format, Figment};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::{collections::BTreeSet, path::PathBuf, str::FromStr, sync::Arc};
|
use std::{collections::BTreeSet, path::PathBuf, str::FromStr, sync::Arc, io::BufRead};
|
||||||
use tokio::sync::mpsc::UnboundedSender;
|
use tokio::{sync};
|
||||||
use validators::prelude::*;
|
use validators::prelude::*;
|
||||||
use warp::{filters::BoxedFilter, hyper::StatusCode, Filter};
|
use warp::{filters::BoxedFilter, hyper::StatusCode, Filter};
|
||||||
|
|
||||||
|
@ -15,6 +15,16 @@ macro_rules! unwrap_or_unwrap_err {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! clone_to_move {
|
||||||
|
($($y:ident),+$x:ident) => {
|
||||||
|
clone_to_move!($x);
|
||||||
|
clone_to_move!($y)
|
||||||
|
};
|
||||||
|
($x:ident) => {
|
||||||
|
let $x = $x.clone();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Validator, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Validator, Clone)]
|
||||||
#[validator(domain(ipv4(Allow), local(Allow), at_least_two_labels(Allow), port(Allow)))]
|
#[validator(domain(ipv4(Allow), local(Allow), at_least_two_labels(Allow), port(Allow)))]
|
||||||
struct Url {
|
struct Url {
|
||||||
|
@ -25,12 +35,14 @@ struct Url {
|
||||||
#[derive(Deserialize, Serialize, Debug, Clone)]
|
#[derive(Deserialize, Serialize, Debug, Clone)]
|
||||||
struct DbConfig {
|
struct DbConfig {
|
||||||
pub address: String,
|
pub address: String,
|
||||||
|
pub worker_threads: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for DbConfig {
|
impl Default for DbConfig {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
address: "redis://127.0.0.1".to_string(),
|
address: "redis://127.0.0.1".to_string(),
|
||||||
|
worker_threads: 4,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -102,17 +114,40 @@ impl FromStr for Base64WithoutPaddingUrl {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct SlugDatabase {
|
struct SlugDatabase {
|
||||||
tx: UnboundedSender<SlugDbMessage>,
|
tx: sync::mpsc::UnboundedSender<SlugDbMessage>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Clone, Debug)]
|
||||||
enum SlugDbMessage {
|
enum SlugDbMessage {
|
||||||
Add(Slug, Url),
|
Add(Slug, Url),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SlugDatabase {
|
impl SlugDatabase {
|
||||||
fn from_client(client: redis::Client) -> Self {
|
fn from_client(client: redis::Client, worker_threads: usize) -> Self {
|
||||||
todo!()
|
let (tx, rx) = sync::mpsc::unbounded_channel::<SlugDbMessage>();
|
||||||
|
|
||||||
|
// I want a FILO queue with a spin lock for consumption.
|
||||||
|
// I'm not sure this is the best way to implement this.
|
||||||
|
// (Alternatively: is there a better architecture?)
|
||||||
|
let rx = Arc::new(sync::Mutex::new(rx));
|
||||||
|
|
||||||
|
for _ in 0..worker_threads {
|
||||||
|
let mut connection = client.get_connection().expect("Could not open connection to Redis server.");
|
||||||
|
clone_to_move!(rx);
|
||||||
|
tokio::spawn(async move {
|
||||||
|
while let Some(msg) = {(*rx.lock().await).recv().await} {
|
||||||
|
match msg {
|
||||||
|
SlugDbMessage::Add(slug, url) => {
|
||||||
|
todo!()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
SlugDatabase {
|
||||||
|
tx,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn insert_slug(&self, slug: Slug, url: Url) -> Result<(), ()> {
|
fn insert_slug(&self, slug: Slug, url: Url) -> Result<(), ()> {
|
||||||
|
@ -128,7 +163,7 @@ struct SlugFactory {
|
||||||
slug_chars: BTreeSet<char>,
|
slug_chars: BTreeSet<char>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Clone, Debug)]
|
||||||
struct Slug(String);
|
struct Slug(String);
|
||||||
|
|
||||||
enum InvalidSlug {
|
enum InvalidSlug {
|
||||||
|
@ -199,7 +234,7 @@ async fn serve() {
|
||||||
let db = {
|
let db = {
|
||||||
let client = redis::Client::open(config.db.address).expect("Error opening Redis database.");
|
let client = redis::Client::open(config.db.address).expect("Error opening Redis database.");
|
||||||
//let conn = Connection::open(config.db_location).expect("Could not open database.");
|
//let conn = Connection::open(config.db_location).expect("Could not open database.");
|
||||||
Arc::new(SlugDatabase::from_client(client))
|
Arc::new(SlugDatabase::from_client(client, config.db.worker_threads))
|
||||||
};
|
};
|
||||||
|
|
||||||
// GET /
|
// GET /
|
||||||
|
|
Loading…
Reference in New Issue