1- use crate :: setlock:: SetLock ;
2-
31use super :: { types:: LifetimedPinnedBoxedFutureResult , Priority , Service , ServiceInfo , ServiceManager } ;
4- use log:: { error, info} ;
2+ use log:: { error, info, warn } ;
53use serenity:: {
64 all:: { GatewayIntents , Ready } ,
75 async_trait,
@@ -12,7 +10,10 @@ use serenity::{
1210 prelude:: TypeMap ,
1311 Client , Error ,
1412} ;
15- use std:: { sync:: Arc , time:: Duration } ;
13+ use std:: {
14+ sync:: { Arc , OnceLock } ,
15+ time:: Duration ,
16+ } ;
1617use tokio:: {
1718 select, spawn,
1819 sync:: { Mutex , Notify , RwLock } ,
@@ -24,29 +25,29 @@ use tokio::{
2425pub struct DiscordService {
2526 info : ServiceInfo ,
2627 discord_token : String ,
27- pub ready : Arc < Mutex < SetLock < Ready > > > ,
28+ pub ready : Arc < OnceLock < Ready > > ,
2829 client_handle : Option < JoinHandle < Result < ( ) , Error > > > ,
29- pub cache : SetLock < Arc < Cache > > ,
30- pub data : SetLock < Arc < RwLock < TypeMap > > > ,
31- pub http : SetLock < Arc < Http > > ,
32- pub shard_manager : SetLock < Arc < ShardManager > > ,
33- pub voice_manager : SetLock < Arc < dyn VoiceGatewayManager > > ,
34- pub ws_url : SetLock < Arc < Mutex < String > > > ,
30+ pub cache : OnceLock < Arc < Cache > > ,
31+ pub data : OnceLock < Arc < RwLock < TypeMap > > > ,
32+ pub http : OnceLock < Arc < Http > > ,
33+ pub shard_manager : OnceLock < Arc < ShardManager > > ,
34+ pub voice_manager : OnceLock < Arc < dyn VoiceGatewayManager > > ,
35+ pub ws_url : OnceLock < Arc < Mutex < String > > > ,
3536}
3637
3738impl DiscordService {
3839 pub fn new ( discord_token : & str ) -> Self {
3940 Self {
4041 info : ServiceInfo :: new ( "lum_builtin_discord" , "Discord" , Priority :: Essential ) ,
4142 discord_token : discord_token. to_string ( ) ,
42- ready : Arc :: new ( Mutex :: new ( SetLock :: new ( ) ) ) ,
43+ ready : Arc :: new ( OnceLock :: new ( ) ) ,
4344 client_handle : None ,
44- cache : SetLock :: new ( ) ,
45- data : SetLock :: new ( ) ,
46- http : SetLock :: new ( ) ,
47- shard_manager : SetLock :: new ( ) ,
48- voice_manager : SetLock :: new ( ) ,
49- ws_url : SetLock :: new ( ) ,
45+ cache : OnceLock :: new ( ) ,
46+ data : OnceLock :: new ( ) ,
47+ http : OnceLock :: new ( ) ,
48+ shard_manager : OnceLock :: new ( ) ,
49+ voice_manager : OnceLock :: new ( ) ,
50+ ws_url : OnceLock :: new ( ) ,
5051 }
5152 }
5253}
@@ -71,30 +72,38 @@ impl Service for DiscordService {
7172 ) )
7273 . await ?;
7374
74- if let Err ( error) = self . cache . set ( Arc :: clone ( & client. cache ) ) {
75- return Err ( format ! ( "Failed to set cache SetLock: {}" , error) . into ( ) ) ;
75+ if self . cache . set ( Arc :: clone ( & client. cache ) ) . is_err ( ) {
76+ error ! ( "Could not set cache OnceLock because it was already set. This should never happen." ) ;
77+ return Err ( "Could not set cache OnceLock because it was already set." . into ( ) ) ;
7678 }
7779
78- if let Err ( error) = self . data . set ( Arc :: clone ( & client. data ) ) {
79- return Err ( format ! ( "Failed to set data SetLock: {}" , error) . into ( ) ) ;
80+ if self . data . set ( Arc :: clone ( & client. data ) ) . is_err ( ) {
81+ error ! ( "Could not set data OnceLock because it was already set. This should never happen." ) ;
82+ return Err ( "Could not set data OnceLock because it was already set." . into ( ) ) ;
8083 }
8184
82- if let Err ( error) = self . http . set ( Arc :: clone ( & client. http ) ) {
83- return Err ( format ! ( "Failed to set http SetLock: {}" , error) . into ( ) ) ;
85+ if self . http . set ( Arc :: clone ( & client. http ) ) . is_err ( ) {
86+ error ! ( "Could not set http OnceLock because it was already set. This should never happen." ) ;
87+ return Err ( "Could not set http OnceLock because it was already set." . into ( ) ) ;
8488 }
8589
86- if let Err ( error) = self . shard_manager . set ( Arc :: clone ( & client. shard_manager ) ) {
87- return Err ( format ! ( "Failed to set shard_manager SetLock: {}" , error) . into ( ) ) ;
90+ if self . shard_manager . set ( Arc :: clone ( & client. shard_manager ) ) . is_err ( ) {
91+ error ! ( "Could not set shard_manager OnceLock because it was already set. This should never happen." ) ;
92+ return Err ( "Could not set shard_manager OnceLock because it was already set." . into ( ) ) ;
8893 }
8994
9095 if let Some ( voice_manager) = & client. voice_manager {
91- if let Err ( error) = self . voice_manager . set ( Arc :: clone ( voice_manager) ) {
92- return Err ( format ! ( "Failed to set voice_manager SetLock: {}" , error) . into ( ) ) ;
96+ if self . voice_manager . set ( Arc :: clone ( voice_manager) ) . is_err ( ) {
97+ error ! ( "Could not set voice_manager OnceLock because it was already set. This should never happen." ) ;
98+ return Err ( "Could not set voice_manager OnceLock because it was already set." . into ( ) ) ;
9399 }
100+ } else {
101+ warn ! ( "Voice manager is not available" ) ;
94102 }
95103
96- if let Err ( error) = self . ws_url . set ( Arc :: clone ( & client. ws_url ) ) {
97- return Err ( format ! ( "Failed to set ws_url SetLock: {}" , error) . into ( ) ) ;
104+ if self . ws_url . set ( Arc :: clone ( & client. ws_url ) ) . is_err ( ) {
105+ error ! ( "Could not set ws_url OnceLock because it was already set. This should never happen." ) ;
106+ return Err ( "Could not set ws_url OnceLock because it was already set." . into ( ) ) ;
98107 }
99108
100109 let client_handle = spawn ( async move { client. start ( ) . await } ) ;
@@ -138,12 +147,12 @@ impl Service for DiscordService {
138147}
139148
140149struct EventHandler {
141- client : Arc < Mutex < SetLock < Ready > > > ,
150+ client : Arc < OnceLock < Ready > > ,
142151 ready_notify : Arc < Notify > ,
143152}
144153
145154impl EventHandler {
146- pub fn new ( client : Arc < Mutex < SetLock < Ready > > > , ready_notify : Arc < Notify > ) -> Self {
155+ pub fn new ( client : Arc < OnceLock < Ready > > , ready_notify : Arc < Notify > ) -> Self {
147156 Self { client, ready_notify }
148157 }
149158}
@@ -152,9 +161,9 @@ impl EventHandler {
152161impl client:: EventHandler for EventHandler {
153162 async fn ready ( & self , _ctx : Context , data_about_bot : Ready ) {
154163 info ! ( "Connected to Discord as {}" , data_about_bot. user. tag( ) ) ;
155- if let Err ( error ) = self . client . lock ( ) . await . set ( data_about_bot ) {
156- error ! ( "Failed to set client SetLock: {}" , error ) ;
157- panic ! ( "Failed to set client SetLock: {}" , error ) ;
164+ if self . client . set ( data_about_bot ) . is_err ( ) {
165+ error ! ( "Could not set client OnceLock because it was already set. This should never happen." ) ;
166+ panic ! ( "Could not set client OnceLock because it was already set" ) ;
158167 }
159168 self . ready_notify . notify_one ( ) ;
160169 }
0 commit comments