Refactor to use Cache API over KV
This commit is contained in:
parent
19c4660eb8
commit
008e43acb1
1057
Cargo.lock
generated
1057
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -4,14 +4,10 @@ version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
reqwest = "0.11"
|
reqwest = "0.12"
|
||||||
rss = "2.0"
|
rss = "2.0"
|
||||||
regex = "1.5"
|
regex = "1.5"
|
||||||
worker = "0.0.18"
|
worker = "0.3.1"
|
||||||
chrono = "0.4.26"
|
|
||||||
|
|
||||||
[target.wasm32-unknown-unknown.dependencies]
|
|
||||||
getrandom = { version = "0.2", features = ["js"] }
|
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
crate-type = ["cdylib", "rlib"]
|
crate-type = ["cdylib", "rlib"]
|
||||||
|
|
|
@ -80,6 +80,7 @@
|
||||||
rustc
|
rustc
|
||||||
nodePackages_latest.wrangler
|
nodePackages_latest.wrangler
|
||||||
worker-build
|
worker-build
|
||||||
|
wasm-pack
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
74
src/lib.rs
74
src/lib.rs
|
@ -1,24 +1,28 @@
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use reqwest::Error as ReqwestError;
|
|
||||||
use rss::{Channel, Error as RssError};
|
use rss::{Channel, Error as RssError};
|
||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
use worker::{console_log, event, kv::KvStore, Env, Headers, Request, Response, Router};
|
use worker::{event, Cache, Env, Error as WorkerError, Request, Response, Router};
|
||||||
|
use reqwest::Error as ReqwestError;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
enum CustomError {
|
enum CustomError {
|
||||||
Reqwest(ReqwestError),
|
Reqwest(ReqwestError),
|
||||||
Rss(RssError),
|
Rss(RssError),
|
||||||
|
Worker(WorkerError),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ReqwestError> for CustomError {
|
impl From<ReqwestError> for CustomError {
|
||||||
fn from(error: ReqwestError) -> Self {
|
fn from(v: ReqwestError) -> Self {
|
||||||
CustomError::Reqwest(error)
|
Self::Reqwest(v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<RssError> for CustomError {
|
impl From<RssError> for CustomError {
|
||||||
fn from(error: RssError) -> Self {
|
fn from(v: RssError) -> Self {
|
||||||
CustomError::Rss(error)
|
Self::Rss(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl From<WorkerError> for CustomError {
|
||||||
|
fn from(v: WorkerError) -> Self {
|
||||||
|
Self::Worker(v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,54 +30,32 @@ impl From<RssError> for CustomError {
|
||||||
pub async fn main(req: Request, env: Env, _ctx: worker::Context) -> worker::Result<Response> {
|
pub async fn main(req: Request, env: Env, _ctx: worker::Context) -> worker::Result<Response> {
|
||||||
let router = Router::new();
|
let router = Router::new();
|
||||||
router
|
router
|
||||||
.get_async("/", |_, ctx| async move {
|
.get_async("/", |req, _ctx| async move {
|
||||||
let kv = match ctx.kv("HN") {
|
let cache = Cache::default();
|
||||||
Ok(k) => k,
|
let key = req.url()?.to_string();
|
||||||
Err(e) => panic!("{:?}", e),
|
if let Some(res) = cache.get(&key, false).await? {
|
||||||
};
|
return Ok(res)
|
||||||
|
}
|
||||||
|
|
||||||
let rss = match kv.get("feed").text().await {
|
let rss = match fetch_modified_rss().await {
|
||||||
Ok(r) => match r {
|
Ok(r) => r,
|
||||||
Some(s) => s,
|
Err(_) => {
|
||||||
None => {
|
"".to_owned()
|
||||||
let r = fetch_modified_rss().await.unwrap_or("".to_owned());
|
|
||||||
match set_cache(&kv, &r).await {
|
|
||||||
Some(_) => console_log!("set new rss cache"),
|
|
||||||
None => console_log!("unable to set rss cache"),
|
|
||||||
};
|
|
||||||
r
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
Err(e) => {
|
|
||||||
console_log!("{:?}", e);
|
|
||||||
fetch_modified_rss().await.unwrap_or("".to_owned())
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let res = Response::from_bytes(rss.into()).unwrap();
|
let mut res = Response::from_bytes(rss.into()).unwrap();
|
||||||
let mut headers = Headers::new();
|
let headers = res.headers_mut();
|
||||||
let _ = headers.set("content-type", "application/rss+xml");
|
let _ = headers.set("content-type", "application/rss+xml");
|
||||||
|
let _ = headers.set("Cache-Control", "public, max-age=1800");
|
||||||
|
cache.put(key, res.cloned()?).await?;
|
||||||
|
|
||||||
Ok(res.with_headers(headers))
|
Ok(res)
|
||||||
})
|
})
|
||||||
.run(req, env)
|
.run(req, env)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn set_cache(kv: &KvStore, res: &String) -> Option<bool> {
|
|
||||||
let feed = kv
|
|
||||||
.put("feed", res)
|
|
||||||
.unwrap()
|
|
||||||
.expiration_ttl(1800)
|
|
||||||
.execute()
|
|
||||||
.await;
|
|
||||||
if feed.is_err() {
|
|
||||||
console_log!("{:?}", feed.err());
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
Some(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn fetch_modified_rss() -> Result<String, CustomError> {
|
async fn fetch_modified_rss() -> Result<String, CustomError> {
|
||||||
let url = "https://news.ycombinator.com/rss";
|
let url = "https://news.ycombinator.com/rss";
|
||||||
|
|
||||||
|
@ -84,7 +66,6 @@ async fn fetch_modified_rss() -> Result<String, CustomError> {
|
||||||
let channel = match Channel::read_from(cursor) {
|
let channel = match Channel::read_from(cursor) {
|
||||||
Ok(channel) => channel,
|
Ok(channel) => channel,
|
||||||
Err(RssError::InvalidStartTag) => {
|
Err(RssError::InvalidStartTag) => {
|
||||||
eprintln!("Invalid start tag found in the feed. Please check the feed URL or try again later.");
|
|
||||||
return Ok(String::new());
|
return Ok(String::new());
|
||||||
}
|
}
|
||||||
Err(err) => return Err(err.into()),
|
Err(err) => return Err(err.into()),
|
||||||
|
@ -105,7 +86,6 @@ async fn fetch_modified_rss() -> Result<String, CustomError> {
|
||||||
|
|
||||||
let mut modified_rss = Channel::default();
|
let mut modified_rss = Channel::default();
|
||||||
modified_rss.set_items(updated_items);
|
modified_rss.set_items(updated_items);
|
||||||
|
|
||||||
Ok(modified_rss.to_string())
|
Ok(modified_rss.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,23 +1,16 @@
|
||||||
name = "hn-rss"
|
name = "hn-rss"
|
||||||
type = "javascript"
|
|
||||||
workers_dev = true
|
workers_dev = true
|
||||||
compatibility_date = "2022-01-20"
|
compatibility_date = "2022-01-20"
|
||||||
|
|
||||||
kv_namespaces = [
|
main = "build/worker/shim.mjs"
|
||||||
{ binding = "HN", id = "a30242f65ba34788ab1560f1a9c4eac7", preview_id = "9fd4871334174ceab34d2fd8c0e989cc" }
|
|
||||||
]
|
account_id = "7dc420732ea679a530aee304ea49a63c"
|
||||||
|
|
||||||
|
tail_consumers = [{service = "hn-rss-tail"}]
|
||||||
|
logpush = true
|
||||||
|
|
||||||
[vars]
|
[vars]
|
||||||
WORKERS_RS_VERSION = "0.0.18"
|
WORKERS_RS_VERSION = "0.3.1"
|
||||||
|
|
||||||
[build]
|
[build]
|
||||||
command = "cargo install -q worker-build && worker-build --release" # required
|
command = "cargo install -q worker-build && worker-build --release" # required
|
||||||
|
|
||||||
[build.upload]
|
|
||||||
dir = "build/worker"
|
|
||||||
format = "modules"
|
|
||||||
main = "./shim.mjs"
|
|
||||||
|
|
||||||
[[build.upload.rules]]
|
|
||||||
globs = ["**/*.wasm"]
|
|
||||||
type = "CompiledWasm"
|
|
||||||
|
|
Loading…
Reference in a new issue