Skip to content

Commit d2618bc

Browse files
committed
move command_executor_service creation into l1, update call-sides
1 parent f062a07 commit d2618bc

6 files changed

Lines changed: 49 additions & 53 deletions

File tree

backend/src/commands/command_controller.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ pub async fn set_enabled(
9898
) -> AxResult<impl IntoResponse> {
9999
//TODO move into query parameter
100100
let enabled = bool::from_str(body.as_ref()).map_err(|_| StatusCode::BAD_REQUEST)?;
101-
command_repo::set_enabled(state, trigger_id.as_ref(), enabled)
101+
command_repo::set_enabled(state.l1.as_ref(), trigger_id.as_ref(), enabled)
102102
.await
103103
.map_err(|_| {
104104
// log
@@ -125,10 +125,10 @@ pub async fn set_visible(
125125
}
126126

127127
pub async fn save(
128-
State(state): State<AxumState>,
128+
l1: L1Arc,
129129
Json(to_save): Json<Command>,
130130
) -> impl IntoResponse {
131-
match command_repo::save(state, &to_save).await {
131+
match command_repo::save(l1.as_ref(), &to_save).await {
132132
Ok(()) => StatusCode::OK,
133133
Err(SaveCommandError::DbError(_db_error)) => {
134134
// log
@@ -143,10 +143,10 @@ pub async fn save(
143143
}
144144

145145
pub async fn delete_by_id(
146-
State(state): State<AxumState>,
146+
l1: L1Arc,
147147
Path(trigger_id): Path<String>,
148148
) -> AxResult<impl IntoResponse> {
149-
command_repo::delete_by_id(state, trigger_id.as_ref()).await.map_err(|_| {
149+
command_repo::delete_by_id(l1.as_ref(), trigger_id.as_ref()).await.map_err(|_| {
150150
// log
151151
StatusCode::INTERNAL_SERVER_ERROR
152152
})?;

backend/src/commands/command_executor_service.rs

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -132,41 +132,16 @@ static TEXT_COMMAND_CALLBACK: TriggerCallback = |app_state, trigger_id, _chat_me
132132
// - indicate to users of our service that we are being created, and make them wait for us to finish.
133133
// - move creation of out service into l1 state. The creation of this just requires the DB, the execution is difficult
134134
// we also can't just create an emtpy version of ourselves, and fill the rest in later, because then our users would try to modify non existing commands
135-
#[derive(Default)]
136135
pub struct CommandExecutorService {
137136
triggers: RwLock<Vec<CommandTrigger>>,
138137
cooldown_service: CooldownService,
139138
}
140139

141-
impl CommandExecutorService {
142-
pub async fn process_chat_message(app_state: Arc<FullState>, message: ChatMessage) {
143-
for trigger in app_state.l2.command_executor_service.triggers.read().await.iter() {
144-
app_state.l2.command_executor_service.execute_trigger_if_matching(app_state.clone(), trigger, message.clone()).await
145-
}
146-
}
147-
148-
async fn execute_trigger_if_matching(&self, app_state: Arc<FullState>, trigger: &CommandTrigger, chat_message: ChatMessage) {
149-
if chat_message.user.permission < trigger.permission {
150-
// logger.debug("User {} with {}, missing {} permission for command {}", message.user().name(), message.user().permission(), trigger.permission(), trigger.id());
151-
return;
152-
}
153-
154-
if !trigger.patterns.iter().any(|r| r.is_match(&chat_message.message)) {
155-
return;
156-
}
157-
158-
let cooldown_res = self.cooldown_service.check_update_cooldown(&chat_message, trigger.id.as_ref(), &trigger.user_cooldown, &trigger.global_cooldown);
159-
if cooldown_res.is_some() {
160-
// logger.debug("Call to command {} from {} rejected because of global cooldowns", trigger.id(), message.user().name());
161-
// logger.debug("Call to command {} from {} rejected because of user cooldowns", trigger.id(), message.user().name());
162-
return;
163-
}
164-
165-
(trigger.callback)(app_state, trigger.id.clone(), chat_message).await;
140+
impl CommandExecutorService {
141+
pub(crate) async fn new(_db: &ProdDB) -> CommandExecutorService {
142+
todo!("get commands from db, and also return Result here")
166143
}
167-
}
168144

169-
impl CommandExecutorService {
170145
pub(crate) async fn remove_command(&self, command_id: &TriggerId) {
171146
self.triggers.write().await.retain(|c| c.id.as_ref() != command_id);
172147
}
@@ -210,3 +185,31 @@ impl CommandExecutorService {
210185
}
211186
}
212187

188+
impl CommandExecutorService {
189+
pub async fn process_chat_message(app_state: Arc<FullState>, message: ChatMessage) {
190+
for trigger in app_state.l1.command_executor_service.triggers.read().await.iter() {
191+
app_state.l1.command_executor_service.execute_trigger_if_matching(app_state.clone(), trigger, message.clone()).await
192+
}
193+
}
194+
195+
async fn execute_trigger_if_matching(&self, app_state: Arc<FullState>, trigger: &CommandTrigger, chat_message: ChatMessage) {
196+
if chat_message.user.permission < trigger.permission {
197+
// logger.debug("User {} with {}, missing {} permission for command {}", message.user().name(), message.user().permission(), trigger.permission(), trigger.id());
198+
return;
199+
}
200+
201+
if !trigger.patterns.iter().any(|r| r.is_match(&chat_message.message)) {
202+
return;
203+
}
204+
205+
let cooldown_res = self.cooldown_service.check_update_cooldown(&chat_message, trigger.id.as_ref(), &trigger.user_cooldown, &trigger.global_cooldown);
206+
if cooldown_res.is_some() {
207+
// logger.debug("Call to command {} from {} rejected because of global cooldowns", trigger.id(), message.user().name());
208+
// logger.debug("Call to command {} from {} rejected because of user cooldowns", trigger.id(), message.user().name());
209+
return;
210+
}
211+
212+
(trigger.callback)(app_state, trigger.id.clone(), chat_message).await;
213+
}
214+
}
215+

backend/src/commands/command_repo.rs

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
use crate::axum::AxumState;
21
use crate::commands::command_controller::{Command, CooldownType, MessagePattern};
32
use crate::commands::command_executor_service::{CommandWithRegex, TriggerId, TwitchUserPermission};
43
use crate::commands::template_service::StringTemplate;
54
use crate::db::ProdDB;
5+
use crate::state::L1State;
66
use anyhow::Context;
77
use num_traits::FromPrimitive;
88
use sqlx::mysql::MySqlQueryResult;
@@ -221,8 +221,8 @@ async fn get_patterns(prod_db: &ProdDB, d: Vec<CommandTable>) -> anyhow::Result<
221221
Ok(commands)
222222
}
223223

224-
pub(crate) async fn set_enabled(state: AxumState, trigger_id: &TriggerId, enabled: bool) -> anyhow::Result<Option<()>> {
225-
let mut transaction = state.l1.prod_db.begin().await?;
224+
pub(crate) async fn set_enabled(l1: &L1State, trigger_id: &TriggerId, enabled: bool) -> anyhow::Result<Option<()>> {
225+
let mut transaction = l1.prod_db.begin().await?;
226226
let affected = query!("UPDATE `sys-chat_trigger-patterns` SET is_enabled = ? WHERE parent_trigger_id = ?", enabled, trigger_id)
227227
.execute(transaction.deref_mut())
228228
.await
@@ -231,9 +231,7 @@ pub(crate) async fn set_enabled(state: AxumState, trigger_id: &TriggerId, enable
231231
if affected == 0 {
232232
return Ok(None)
233233
}
234-
if let Some(l2) = state.l2.get() {
235-
l2.command_executor_service.refresh_patterns(&state.l1.prod_db, trigger_id).await;
236-
}
234+
l1.command_executor_service.refresh_patterns(&l1.prod_db, trigger_id).await;
237235
transaction.commit().await?;
238236
Ok(Some(()))
239237
}
@@ -255,18 +253,15 @@ pub(crate) enum SaveCommandError {
255253
RegexError(regex::Error),
256254
}
257255

258-
pub(crate) async fn save(state: AxumState, command: &Command) -> Result<(), SaveCommandError> {
259-
// make this in the beginning, to make sure this is all valid regex
256+
pub(crate) async fn save(l1: &L1State, command: &Command) -> Result<(), SaveCommandError> {
260257
let with_regex: CommandWithRegex = command.try_into().map_err(|re| SaveCommandError::RegexError(re))?;
261258

262-
let mut transaction = state.l1.prod_db.begin().await.context("failed to start save command transaction")
259+
let mut transaction = l1.prod_db.begin().await.context("failed to start save command transaction")
263260
.map_err(|e| SaveCommandError::DbError(e))?;
264261

265262
save_command(&command, &mut transaction).await.map_err(|e| SaveCommandError::DbError(e))?;
266263

267-
if let Some(l2) = state.l2.get() {
268-
l2.command_executor_service.upsert_command(with_regex).await
269-
}
264+
l1.command_executor_service.upsert_command(with_regex).await;
270265
transaction.commit().await.context("failed to commit save command transaction")
271266
.map_err(|e| SaveCommandError::DbError(e))?;
272267
Ok(())
@@ -310,8 +305,8 @@ async fn save_template<'a, E: MySqlExecutor<'a>>(prod_db: E, template: &StringTe
310305
.context("failed to save command template")
311306
}
312307

313-
pub(crate) async fn delete_by_id(state: AxumState, trigger_id: &TriggerId) -> anyhow::Result<()> {
314-
let pool = state.l1.prod_db.deref();
308+
pub(crate) async fn delete_by_id(l1: &L1State, trigger_id: &TriggerId) -> anyhow::Result<()> {
309+
let pool = l1.prod_db.deref();
315310
query!("DELETE FROM `sys-string_templates` WHERE id = (SELECT template_id FROM `sys-chat_trigger-trigger` WHERE id = ?)", trigger_id)
316311
.execute(pool)
317312
.await
@@ -321,9 +316,7 @@ pub(crate) async fn delete_by_id(state: AxumState, trigger_id: &TriggerId) -> an
321316
.await
322317
.context("failed to delete command trigger")?;
323318

324-
if let Some(l2) = state.l2.get() {
325-
l2.command_executor_service.remove_command(&trigger_id).await;
326-
}
319+
l1.command_executor_service.remove_command(&trigger_id).await;
327320
Ok(())
328321
}
329322

backend/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ pub async fn start() {
3838
server_base_url: Url::from_str("http://localhost:4771").unwrap(),
3939
panel_auth_twitch_client_id: "zmxjjn3xmncg8ewew6tjk08tub26bb".to_string()
4040
}),
41+
command_executor_service: CommandExecutorService::new(&prod_db).await,
4142
oauth_service: Default::default(),
4243
session_service: Default::default(),
4344
prod_db,
@@ -62,7 +63,6 @@ pub async fn start() {
6263
let service = TwitchService::new(l1.clone(), twitch_config).await.unwrap();
6364
let l2 = Arc::new(L2State {
6465
twitch_service: service,
65-
command_executor_service: Default::default(),
6666
});
6767

6868
// 3rd. (Full) Stage

backend/src/state.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,11 @@ pub struct L1State {
4545
pub session_service: SessionService,
4646
pub oauth_service: OAuthService,
4747
pub webserver_config: RwLock<WebserverConfig>,
48+
pub command_executor_service: CommandExecutorService
4849
}
4950

5051
pub struct L2State {
5152
pub twitch_service: TwitchService,
52-
pub command_executor_service: CommandExecutorService
5353
}
5454

5555
pub struct L1Arc(Arc<L1State>);

backend/src/twitch/twitch_service.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ pub(crate) struct TwitchConfig {
2929
pub client_secret: String,
3030
}
3131

32-
struct TwitchCredentialStatus {
32+
pub(super) struct TwitchCredentialStatus {
3333
valid_checked_at: Instant,
3434
was_valid_at_check: bool,
3535
credential: OauthCredential,

0 commit comments

Comments
 (0)