Merge remote-tracking branch 'origin' into pagination
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
use axum::Router;
|
||||
use cache::ClientLike;
|
||||
use config::config;
|
||||
use fred::prelude::*;
|
||||
use sqlx::postgres::PgPoolOptions;
|
||||
use std::fs::File;
|
||||
use std::sync::Arc;
|
||||
@@ -8,7 +8,7 @@ use std::time::Duration;
|
||||
use tokio::net::TcpListener;
|
||||
use tokio::signal;
|
||||
use tokio::sync::Mutex;
|
||||
use tower_governor::{governor::GovernorConfigBuilder, GovernorLayer};
|
||||
// use tower_governor::{governor::GovernorConfigBuilder, GovernorLayer};
|
||||
use tower_http::{
|
||||
cors::{Any, CorsLayer},
|
||||
trace::{self, TraceLayer},
|
||||
@@ -101,13 +101,13 @@ async fn main() {
|
||||
.expect("Failed to connect to database");
|
||||
|
||||
let pool_size = 8;
|
||||
let config = Config::from_url(&redis_url).unwrap(); // TODO: fix the unwrap <<<
|
||||
let config = cache::Config::from_url(&redis_url).unwrap(); // TODO: fix the unwrap <<<
|
||||
|
||||
let redis_pool = Builder::from_config(config)
|
||||
let redis_pool = cache::Builder::from_config(config)
|
||||
.with_performance_config(|config| {
|
||||
config.default_command_timeout = Duration::from_secs(60);
|
||||
})
|
||||
.set_policy(ReconnectPolicy::new_exponential(0, 100, 30_000, 2))
|
||||
.set_policy(cache::ReconnectPolicy::new_exponential(0, 100, 30_000, 2))
|
||||
.build_pool(pool_size)
|
||||
.expect("Failed to create cache pool");
|
||||
|
||||
|
@@ -5,7 +5,7 @@ use axum::{
|
||||
routing::get,
|
||||
Json,
|
||||
};
|
||||
use fred::types::Expiration;
|
||||
use cache::Expiration;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
|
@@ -13,8 +13,8 @@ use axum::{
|
||||
routing::{get, post},
|
||||
Json,
|
||||
};
|
||||
use cache::{Expiration, SetOptions};
|
||||
use chrono::Utc;
|
||||
use fred::types::{Expiration, SetOptions};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Deserialize, Serialize, Debug)]
|
||||
|
@@ -15,8 +15,8 @@ use axum::{
|
||||
routing::get,
|
||||
Json, Router,
|
||||
};
|
||||
use cache::Expiration;
|
||||
use chrono::Utc;
|
||||
use fred::types::Expiration;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
use crate::{datasources::projects::ProjectsDatasource, state::AppState, utils::datetime::*};
|
||||
use axum::{extract::State, http::StatusCode, response::IntoResponse, routing::get, Json, Router};
|
||||
use fred::types::Expiration;
|
||||
use cache::Expiration;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(sqlx::FromRow, Deserialize, Serialize, Debug, Clone)]
|
||||
|
@@ -1,83 +1,17 @@
|
||||
use fred::interfaces::KeysInterface;
|
||||
use fred::{clients::Pool, prelude::*};
|
||||
use sqlx::PgPool;
|
||||
|
||||
pub type AppState = std::sync::Arc<tokio::sync::Mutex<AppInternalState>>;
|
||||
|
||||
pub struct AppInternalState {
|
||||
pub database: sqlx::postgres::PgPool,
|
||||
pub cache: Cache,
|
||||
}
|
||||
|
||||
pub struct Cache {
|
||||
pub inmem: Pool,
|
||||
pub cache: cache::Cache,
|
||||
}
|
||||
|
||||
impl AppInternalState {
|
||||
pub fn new(database: PgPool, cache: Pool) -> Self {
|
||||
pub fn new(database: PgPool, cache: cache::Pool) -> Self {
|
||||
AppInternalState {
|
||||
database,
|
||||
cache: Cache { inmem: cache },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Cache {
|
||||
pub async fn get<T>(&mut self, key: String) -> Result<Option<T>, Box<dyn std::error::Error>>
|
||||
where
|
||||
T: for<'de> serde::Deserialize<'de>,
|
||||
{
|
||||
self.is_connected()?;
|
||||
let value: Option<String> = self.inmem.get(&key).await?;
|
||||
|
||||
match value {
|
||||
Some(json_str) => match serde_json::from_str::<T>(&json_str) {
|
||||
Ok(deserialized) => Ok(Some(deserialized)),
|
||||
Err(_) => Ok(None),
|
||||
},
|
||||
None => Ok(None),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn set<T>(
|
||||
&mut self,
|
||||
key: String,
|
||||
contents: &T,
|
||||
expiration: Option<Expiration>,
|
||||
set_opts: Option<SetOptions>,
|
||||
get: bool,
|
||||
) -> Result<(), Box<dyn std::error::Error>>
|
||||
where
|
||||
T: for<'de> serde::Deserialize<'de> + serde::Serialize,
|
||||
{
|
||||
self.is_connected()?;
|
||||
let json_string = match serde_json::to_string::<T>(contents) {
|
||||
Ok(s) => s,
|
||||
Err(_) => {
|
||||
return Err(Box::new(std::io::Error::new(
|
||||
std::io::ErrorKind::Other,
|
||||
"Unable to deserialize contents passed to cache".to_string(),
|
||||
)))
|
||||
}
|
||||
};
|
||||
|
||||
Ok(self
|
||||
.inmem
|
||||
.set(key, json_string, expiration, set_opts, get)
|
||||
.await?)
|
||||
}
|
||||
|
||||
pub async fn del(&mut self, key: String) -> Result<(), Box<dyn std::error::Error>> {
|
||||
Ok(self.inmem.del(key).await?)
|
||||
}
|
||||
|
||||
fn is_connected(&mut self) -> Result<(), Box<dyn std::error::Error>> {
|
||||
match self.inmem.is_connected() {
|
||||
true => Ok(()),
|
||||
false => Err(Box::new(std::io::Error::new(
|
||||
std::io::ErrorKind::Other,
|
||||
"Not connected to cache".to_string(),
|
||||
))),
|
||||
cache: cache::Cache { inmem: cache },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -73,17 +73,18 @@ pub fn generate_rss(
|
||||
format!(
|
||||
r#"<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>{safe_title}</title>
|
||||
<description>{safe_description}</description>
|
||||
<link>{link}</link>
|
||||
<language>en-us</language>
|
||||
<ttl>60</ttl>
|
||||
<generator>Kyouma 1.0.0-SE</generator>
|
||||
<atom:link href="https://wyattjmiller.com/posts.xml" rel="self" type="application/rss+xml" />
|
||||
{}
|
||||
</channel>
|
||||
</rss>"#,
|
||||
<channel>
|
||||
<title>{safe_title}</title>
|
||||
<description>{safe_description}</description>
|
||||
<link>{link}</link>
|
||||
<language>en-us</language>
|
||||
<ttl>60</ttl>
|
||||
<generator>Kyouma 1.0.0-SE</generator>
|
||||
<atom:link href="https://wyattjmiller.com/posts.xml" rel="self" type="application/rss+xml" />
|
||||
{}
|
||||
</channel>
|
||||
</rss>
|
||||
"#,
|
||||
rss_entries
|
||||
)
|
||||
}
|
||||
|
@@ -23,7 +23,6 @@ impl SitemapEntry {
|
||||
pub fn generate_sitemap(entries: &HashMap<String, SitemapEntry>) -> String {
|
||||
let urls = entries
|
||||
.values()
|
||||
.into_iter()
|
||||
.map(|entry| entry.to_item())
|
||||
.collect::<String>();
|
||||
format!(
|
||||
@@ -39,21 +38,21 @@ pub fn generate_sitemap(entries: &HashMap<String, SitemapEntry>) -> String {
|
||||
|
||||
pub fn get_static_pages(entries: &mut HashMap<String, SitemapEntry>, web_url: &String) {
|
||||
entries.insert(
|
||||
(entries.len() + 1).to_string(),
|
||||
"10000".to_string(),
|
||||
SitemapEntry {
|
||||
location: web_url.clone(),
|
||||
lastmod: chrono::Utc::now(),
|
||||
},
|
||||
);
|
||||
entries.insert(
|
||||
(entries.len() + 1).to_string(),
|
||||
"10001".to_string(),
|
||||
SitemapEntry {
|
||||
location: format!("{}/posts", web_url),
|
||||
lastmod: chrono::Utc::now(),
|
||||
},
|
||||
);
|
||||
entries.insert(
|
||||
(entries.len() + 1).to_string(),
|
||||
"10002".to_string(),
|
||||
SitemapEntry {
|
||||
location: format!("{}/projects", web_url),
|
||||
lastmod: chrono::Utc::now(),
|
||||
|
Reference in New Issue
Block a user