1
1
use serde:: Deserialize ;
2
+ use tokio:: fs;
2
3
use tokio:: sync:: RwLock ;
3
- use tracing:: info;
4
+ use tracing:: { error , info} ;
4
5
5
- #[ derive( Debug , Deserialize , Clone ) ]
6
+ #[ derive( Debug , Deserialize , Clone , PartialEq , Default ) ]
6
7
pub struct RuntimeConfig {
7
8
/// A list of tasks to drop before inserting into sqlite.
8
9
pub drop_task_killswitch : Vec < String > ,
@@ -14,25 +15,46 @@ pub struct RuntimeConfigManager {
14
15
}
15
16
16
17
impl RuntimeConfigManager {
17
- pub fn new ( path : String ) -> Self {
18
- let runtime_config = Self :: read_yaml_file ( & path) ;
18
+ pub async fn new ( path : String ) -> Self {
19
+ let runtime_config = Self :: read_yaml_file ( & path) . await ;
19
20
Self {
20
21
config : RwLock :: new ( runtime_config) ,
21
22
path,
22
23
}
23
24
}
24
25
25
- fn read_yaml_file ( path : & str ) -> RuntimeConfig {
26
- let contents = std:: fs:: read_to_string ( path)
27
- . unwrap_or_else ( |_| panic ! ( "Failed to read config file from {}" , path) ) ;
28
- serde_yaml:: from_str ( & contents)
29
- . unwrap_or_else ( |_| panic ! ( "Failed to parse YAML from {}" , path) )
26
+ async fn read_yaml_file ( path : & str ) -> RuntimeConfig {
27
+ let contents = fs:: read_to_string ( path) . await ;
28
+ match contents {
29
+ Ok ( contents) => {
30
+ let runtime_config = serde_yaml:: from_str :: < RuntimeConfig > ( & contents) ;
31
+ match runtime_config {
32
+ Ok ( runtime_config) => runtime_config,
33
+ Err ( e) => {
34
+ error ! ( "Using default runtime configs. Failed to parse file: {}" , e) ;
35
+ RuntimeConfig :: default ( )
36
+ }
37
+ }
38
+ }
39
+ Err ( e) => {
40
+ error ! (
41
+ "Using default runtime configs. Failed to read yaml file: {}" ,
42
+ e
43
+ ) ;
44
+ RuntimeConfig :: default ( )
45
+ }
46
+ }
30
47
}
31
48
32
- pub async fn reload_config ( & self ) {
33
- let new_config = Self :: read_yaml_file ( & self . path ) ;
34
- * self . config . write ( ) . await = new_config;
35
- info ! ( "Reloaded runtime config from {}" , self . path) ;
49
+ pub async fn reload_config ( & self ) -> Result < bool , anyhow:: Error > {
50
+ let new_config = Self :: read_yaml_file ( & self . path ) . await ;
51
+ if new_config != * self . config . read ( ) . await {
52
+ * self . config . write ( ) . await = new_config;
53
+ info ! ( "Reloaded new runtime config from {}" , self . path) ;
54
+ Ok ( true )
55
+ } else {
56
+ Ok ( false )
57
+ }
36
58
}
37
59
38
60
pub async fn read ( & self ) -> RuntimeConfig {
@@ -54,7 +76,7 @@ drop_task_killswitch:
54
76
let test_path = "runtime_test_config.yaml" ;
55
77
std:: fs:: write ( test_path, test_yaml) . unwrap ( ) ;
56
78
57
- let runtime_config = RuntimeConfigManager :: new ( test_path. to_string ( ) ) ;
79
+ let runtime_config = RuntimeConfigManager :: new ( test_path. to_string ( ) ) . await ;
58
80
let config = runtime_config. read ( ) . await ;
59
81
assert_eq ! ( config. drop_task_killswitch. len( ) , 1 ) ;
60
82
assert_eq ! ( config. drop_task_killswitch[ 0 ] , "test:do_nothing" ) ;
@@ -68,7 +90,7 @@ drop_task_killswitch:
68
90
)
69
91
. unwrap ( ) ;
70
92
71
- runtime_config. reload_config ( ) . await ;
93
+ let _ = runtime_config. reload_config ( ) . await ;
72
94
let config = runtime_config. read ( ) . await ;
73
95
assert_eq ! ( config. drop_task_killswitch. len( ) , 2 ) ;
74
96
assert_eq ! ( config. drop_task_killswitch[ 0 ] , "test:do_nothing" ) ;
0 commit comments