Last active: 10 months ago
axum reverse proxy with cache to redis
use super::error::{RouteError, RouteResult};
use crate::AppState;
use anyhow::{anyhow, Result};
use axum::{
body::Body,
extract::{Request, State},
http::{response::Parts, HeaderName, HeaderValue, Uri},
response::{IntoResponse, Response},
};
use http_body_util::BodyExt;
use hyper::{body::Bytes, HeaderMap};
use redis::{Client, Commands};
use serde::{Deserialize, Serialize};
use std::str::FromStr;
use std::{collections::HashMap, sync::Arc};
use tokio::sync::RwLock;
use tracing::error;
static BACKEND_URI: &str = "http://192.168.1.13:8086";
Last active: 10 months ago
serialize and deserialize with serde_json
use anyhow::Result;
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug)]
struct Test {
name: String,
age: i32,
test: Option<String>,
}
impl Default for Test {
fn default() -> Self {
Self {
name: "xfy".into(),
age: 14,
test: None,
}
}
}
Last active: 10 months ago
deserialize with custom function
fn de_str<'de, D>(deserializer: D) -> Result<i64, D::Error>
where
D: serde::de::Deserializer<'de>,
{
Ok(match Value::deserialize(deserializer)? {
Value::String(s) => s.parse().map_err(de::Error::custom)?,
Value::Number(num) => num.as_i64().ok_or(de::Error::custom("Invalide number"))?,
_ => return Err(de::Error::custom("wrong type")),
})
}
#[derive(Serialize, Deserialize, Debug)]
pub struct BoothExamplesList {
pub total: i64,
#[serde(deserialize_with = "de_str")]
pub per_page: i64,
pub current_page: i64,
pub last_page: i64,
pub data: Vec<BoothExamplesDatum>,
}
Last active: 10 months ago
implement model in rust
use crate::{
access_db,
api::{parse_booth_url, types::BoothExamples},
};
use anyhow::Result;
use sqlx::{Postgres, QueryBuilder};
pub struct BoothUrls(Vec<String>);
impl BoothUrls {
/// Record sucess post's url
pub async fn record_post(&self) -> Result<()> {
let pool = access_db().await;
let mut query_builder: QueryBuilder<Postgres> =
QueryBuilder::new("INSERT INTO post_record (url) ");
query_builder.push_values(&self.0, |mut b, url| {
b.push_bind(url);
});
Last active: 10 months ago
sqlx query builder insert many
pub async fn record_post(urls: Vec<String>) -> Result<()> {
let pool = access_db().await;
let mut query_builder: QueryBuilder<Postgres> =
QueryBuilder::new("INSERT INTO post_record (url) ");
query_builder.push_values(urls, |mut b, url| {
b.push_bind(url);
});
let query = query_builder.build();
query.execute(pool).await?;
Ok(())
}
Last active: 10 months ago
Tokio once_cell global postgres sqlx rust
static DB: OnceCell<Pool<Postgres>> = OnceCell::const_new();
async fn access_db() -> &'static Pool<Postgres> {
let initer = || async {
let db_url = env::var("SPIO_DB").expect("db host url must be set");
let pool = PgPoolOptions::new()
.max_connections(20)
.acquire_timeout(Duration::from_secs(3))
.connect(&db_url)
.await;
match pool {
Ok(pool) => pool,
Err(err) => {
panic!("connect to postgres failed {}", err)
}
}
};
DB.get_or_init(initer).await
}
Last active: 10 months ago
Zego message slice
import { AppThunk, RootState } from '@/store';
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
import { notification } from 'antd';
import { ZegoUser } from 'zego-express-engine-webrtc/sdk/src/common/zego.entity';
import type { ZegoRoomStateChangedReason } from 'zego-express-engine-webrtm/sdk/code/zh/ZegoExpressEntity';
import { ZegoBroadcastMessageInfo } from 'zego-express-engine-webrtm/sdk/code/zh/ZegoExpressEntity';
/**
* 是否是房间类消息
*/
export function isRoomMsg(
msg: RoomMessage | CharacterMessage
): msg is RoomMessage {
return msg.type === 'room';
}
/**
* 是否是角色消息
*/
export function isCharMsg(
msg: RoomMessage | CharacterMessage
Last active: 10 months ago
Go gin CORS middleware
package middlewares
import (
"github.com/gin-gonic/gin"
)
func CORSMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
c.Writer.Header().
Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With")
c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT")
if c.Request.Method == "OPTIONS" {
c.AbortWithStatus(204)
return
}
c.Next()
Last active: 10 months ago
Golang makefile example
NAME=exre
VERSION=0.0.1
.PHONY: build
## build: Compile the packages.
build:
@go build -buildvcs=false -o $(NAME)
.PHONY: run
## run: Build and Run in development mode.
run:
@nodemon --exec go run main.go --signal SIGTERM
.PHONY: run-prod
## run-prod: Build and Run in production mode.
run-prod:
@GIN_MODE=release \
nodemon --exec go run main.go --signal SIGTERM
.PHONY: clean
Last active: 10 months ago
Create video stream from ArraryBuffer
useEffect(() => {
(async () => {
const result = await decrypt_from_url(VIDEO_PATH);
if (!ref.current) return;
const video = ref.current;
const source = new MediaSource();
video.src = URL.createObjectURL(source);
source.addEventListener("sourceopen", (e) => {
const target = e.target as MediaSource;
const sourceBuffer = target.addSourceBuffer(mimeCodec);
sourceBuffer.addEventListener("updateend", () => {
target.endOfStream();
});
sourceBuffer.appendBuffer(result);
});
})();
}, []);