Skip to content

Commit

Permalink
Fix bug with db connection failing when getting tags
Browse files Browse the repository at this point in the history
  • Loading branch information
Sven65 committed Sep 30, 2023
1 parent 461c965 commit 6968252
Show file tree
Hide file tree
Showing 8 changed files with 245 additions and 114 deletions.
239 changes: 162 additions & 77 deletions Cargo.lock

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "tagbot"
version = "4.0.2"
version = "4.0.3"
edition = "2021"
license = "OPL-3.0"
publish = false
Expand All @@ -9,7 +9,7 @@ publish = false

[dependencies]
dotenv = "0.15"
reql = "0.11.1"
reql = "0.11.2"
tokio = { version = "1.20.1", features = ["macros", "rt-multi-thread"] }
tracing = "0.1.36"
tracing-subscriber = "0.2.0"
Expand All @@ -33,4 +33,4 @@ features = [ "builder", "cache", "client", "gateway", "http", "model", "utils",

[dev-dependencies]
test-case = "2.2.1"
serde_json = "1.0.1"
serde_json = "1.0.1"
14 changes: 8 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

################# COMPILE TAGBOT #################

FROM rust:1.63.0 as build

FROM rust:1.72.1-bullseye as build

# Capture deps
# COPY Cargo.toml Cargo.lock /app/
Expand All @@ -13,10 +12,12 @@ FROM rust:1.63.0 as build

RUN cargo new --lib /app/
COPY ./Cargo.toml /app/
COPY ./Cargo.lock /app/

# We do the same for macros
RUN cargo new /app/tagbot-macros
COPY tagbot-macros/Cargo.toml /app/tagbot-macros/
COPY tagbot-macros/Cargo.lock /app/tagbot-macros/

COPY ./src /app/src
COPY ./tagbot-macros /app/tagbot-macros
Expand Down Expand Up @@ -86,7 +87,8 @@ RUN luarocks install kikito/sandbox

# # TODO: Add luarocks and sandbox

FROM debian:buster-slim as final
# FROM debian:buster-slim as final
FROM debian:bullseye as final

WORKDIR /home

Expand Down Expand Up @@ -130,9 +132,9 @@ COPY --from=lua_modules /usr/local/share/lua/ /usr/local/share/lua/

## Copy libm bs lmao

COPY --from=build /lib/x86_64-linux-gnu/libm-2.31.so /lib/x86_64-linux-gnu/
RUN rm /lib/x86_64-linux-gnu/libm.so.6
RUN ln -s /lib/x86_64-linux-gnu/libm-2.31.so /lib/x86_64-linux-gnu/libm.so.6
# COPY --from=build /lib/x86_64-linux-gnu/libm.so.6 /lib/x86_64-linux-gnu/
# RUN rm /lib/x86_64-linux-gnu/libm.so.6
# RUN ln -s /lib/x86_64-linux-gnu/libm.so.6 /lib/x86_64-linux-gnu/libm.so.6

## Copy tagbot binary

Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
DOCKER_REGISTRY=
DOCKER_REGISTRY ?=
PACKAGE_VERSION := $(shell cargo metadata --no-deps --format-version 1 | jq '.packages[0].version' | tr -d '"')
IMAGE_NAME := $(shell cargo metadata --no-deps --format-version 1 | jq '.packages[0].name' | tr -d '"')

Expand Down
2 changes: 1 addition & 1 deletion src/commands/commands/tag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pub async fn tag(interaction: ApplicationCommandInteraction, ctx: Context) -> St
let gotten_tag = TagsTable::get_tag(name.clone()).await;

if gotten_tag.is_err() {
cat_loggr::log_fatal!("{}: {:?}", "Failed to get tag:", gotten_tag.err());
cat_loggr::log_fatal!("{}: {:?}", "Failed to get tag (1):", gotten_tag.err());
handle_error!(
send_app_interaction_message(ctx, interaction, "That tag doesn't exist", false).await,
"Failed to send non-existant tag message"
Expand Down
4 changes: 2 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
mod services;
mod commands;
mod util;
mod services;
pub mod tags;
mod util;
50 changes: 38 additions & 12 deletions src/services/rethinkdb/rethinkdb.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,38 @@
use cat_loggr::{log_fatal, log_info};
use dotenv::dotenv;
use futures::lock::Mutex;
use lazy_static::lazy_static;
use reql::{cmd::connect::Options, r, Session};
use std::env;
use std::{env, sync::Arc};
use tokio::runtime::Handle;

#[derive(Clone)]
pub struct RethinkDBOptions {
host: String,
port: u16,
db_name: String,
user: String,
password: String,
}

#[derive(Clone)]
pub struct RethinkDB {
pub connection_options: Option<RethinkDBOptions>,
pub session: Option<Session>,
}

impl RethinkDB {
async fn init_connection(&mut self) -> Result<&Session, reql::Error> {
pub fn get_options_as_connect(&self) -> Options {
let rdb_opts = self.connection_options.clone().unwrap();
Options::new()
.host(rdb_opts.host)
.port(rdb_opts.port)
.db(rdb_opts.db_name)
.user(rdb_opts.user)
.password(rdb_opts.password)
}

pub fn init_options(&mut self) {
dotenv().ok();

let host = env::var("RETHINK_HOST").expect("Expected rethinkdb host to be present in env.");
Expand All @@ -25,14 +46,11 @@ impl RethinkDB {
let password = env::var("RETHINK_PASSWORD")
.expect("Expected rethinkdb password to be present in env.");

let options = Options::new()
.host(host)
.port(port)
.db(db_name)
.user(user)
.password(password);
self.connection_options = Some(RethinkDBOptions { host, port, db_name, user, password });
}

let conn = r.connect(options).await?;
pub async fn init_connection(&mut self) -> Result<&Session, reql::Error> {
let conn = r.connect(self.get_options_as_connect()).await?;

self.session = Some(conn);

Expand All @@ -42,11 +60,19 @@ impl RethinkDB {
}

pub async fn get_connection(&self) -> Option<&Session> {
self.session.as_ref()
let connection = self.session.as_ref();

if connection.is_none() {
println!("Connection to DB lost.");
}

connection
}

pub fn new() -> Self {
let mut rdb: RethinkDB = RethinkDB { session: None };
let mut rdb: RethinkDB = RethinkDB { session: None, connection_options: None };

rdb.init_options();

let handle = Handle::current();

Expand All @@ -69,5 +95,5 @@ impl RethinkDB {
}

lazy_static! {
pub static ref RDB: RethinkDB = RethinkDB::new();
pub static ref RDB: Arc<Mutex<RethinkDB>> = Arc::new(Mutex::new(RethinkDB::new()));
}
42 changes: 30 additions & 12 deletions src/services/rethinkdb/tags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use futures::TryStreamExt;
use reql::{func, r, types::WriteStatus, Session};
use serde::{Deserialize, Serialize};

use super::rethinkdb::RDB;
use crate::services::rethinkdb::rethinkdb::RDB;

macro_rules! create_error {
($($args:tt)*) => {
Expand Down Expand Up @@ -72,7 +72,8 @@ impl TagsTable {
owner_id: String,
tag_type: Option<TagType>,
) -> Result<WriteStatus, reql::Error> {
let connection = RDB.get_connection().await;
let rdb = RDB.lock().await;
let connection = rdb.get_connection().await;

if connection.is_none() {
return create_error!("Failed to create tag: Failed to get DB Connection.".to_string());
Expand Down Expand Up @@ -100,7 +101,11 @@ impl TagsTable {
///
/// * `tag_name` - The name of the tag to get. Automatically converted to lowercase.
pub async fn get_tag(tag_name: String) -> Result<Tag, reql::Error> {
let connection = RDB.get_connection().await;
let mut rdb_lock = RDB.lock().await;

let rdb = rdb_lock.to_owned();

let connection = rdb.get_connection().await;

if connection.is_none() {
return create_error!("Failed to get tag: Failed to get DB Connection.");
Expand All @@ -113,11 +118,19 @@ impl TagsTable {
.get(tag_name.to_lowercase())
.run::<&Session, Tag>(connection);

if let Some(result) = query.try_next().await? {
return Ok(result);
match query.try_next().await {
Ok(Some(result)) => Ok(result),
Ok(None) => create_error!("Failed to get tag"),
Err(_) => {
rdb_lock.init_connection().await?;
Ok(Tag {
content: "Failed to get tag, please try again.".to_string(),
id: "failed-tag".to_string(),
owner: "1".to_string(),
tag_type: Some(TagType::Legacy),
})
} // Propagate the error
}

create_error!("Failed to get tag")
}

/// Deletes a tag from the tags table, if it exists.
Expand All @@ -126,7 +139,8 @@ impl TagsTable {
///
/// * `tag_name` - The name of the tag to delete. Automatically converted to lowercase.
pub async fn delete_tag(tag_name: String) -> Result<WriteStatus, reql::Error> {
let connection = RDB.get_connection().await;
let rdb = RDB.lock().await;
let connection = rdb.get_connection().await;

if connection.is_none() {
return create_error!("Failed to get tag: Failed to get DB Connection.");
Expand All @@ -151,7 +165,8 @@ impl TagsTable {

/// Gets all tags in the database
pub async fn get_all() -> Result<Vec<Tag>, reql::Error> {
let connection = RDB.get_connection().await;
let rdb = RDB.lock().await;
let connection = rdb.get_connection().await;

if connection.is_none() {
return create_error!("Failed to get all tags: Failed to get DB Connection.");
Expand All @@ -176,7 +191,8 @@ impl TagsTable {
///
/// * `owner_id` - The id of the user whose tags to get
pub async fn get_all_by_owner(owner_id: String) -> Result<Vec<Tag>, reql::Error> {
let connection = RDB.get_connection().await;
let rdb = RDB.lock().await;
let connection = rdb.get_connection().await;

if connection.is_none() {
return create_error!("Failed to get user tags: Failed to get DB Connection.");
Expand Down Expand Up @@ -208,7 +224,8 @@ impl TagsTable {
tag_name: String,
new_owner: String,
) -> Result<WriteStatus, reql::Error> {
let connection = RDB.get_connection().await;
let rdb = RDB.lock().await;
let connection = rdb.get_connection().await;

if connection.is_none() {
return create_error!("Failed to set tag owner: Failed to get DB Connection.");
Expand Down Expand Up @@ -241,7 +258,8 @@ impl TagsTable {
tag_name: String,
new_content: String,
) -> Result<WriteStatus, reql::Error> {
let connection = RDB.get_connection().await;
let rdb = RDB.lock().await;
let connection = rdb.get_connection().await;

if connection.is_none() {
return create_error!("Failed to set tag content: Failed to get DB Connection.");
Expand Down

0 comments on commit 6968252

Please sign in to comment.