@@ -15,9 +15,60 @@ use std::{collections::HashMap, collections::HashSet, sync::Arc};
1515use worker:: * ;
1616
1717static INIT : Once = Once :: new ( ) ;
18- static ALLOW_USERS_CACHE : OnceLock < Arc < HashSet < i64 > > > = OnceLock :: new ( ) ;
18+ static ENV_CONFIG : OnceLock < EnvConfig > = OnceLock :: new ( ) ;
1919static CUSTOM_LLMS : OnceLock < HashMap < String , OpenAI > > = OnceLock :: new ( ) ;
2020
21+ struct EnvConfig {
22+ allow_users : Arc < HashSet < i64 > > ,
23+ maintainer_id : i64 ,
24+ bot : client_reqwest:: Bot ,
25+ auth_secret : String ,
26+ auth_username : String ,
27+ auth_password : String ,
28+ auth_token_expiration : i64 ,
29+ }
30+
31+ impl EnvConfig {
32+ fn from_env ( env : & Env ) -> Self {
33+ let token = get_string_from_env ( env, "TELEGRAM_TOKEN" ) ;
34+ let bot = client_reqwest:: Bot :: new ( & token) ;
35+
36+ let maintainer_id = get_string_from_env ( env, "MAINTAINER_ID" )
37+ . parse :: < i64 > ( )
38+ . unwrap_or ( 0 ) ;
39+
40+ let mut set = HashSet :: from ( [ maintainer_id] ) ;
41+ set. extend (
42+ get_string_from_env ( env, "ALLOW_USERS" )
43+ . split ( ',' )
44+ . filter ( |s| !s. is_empty ( ) )
45+ . filter_map ( |s| s. parse :: < i64 > ( ) . ok ( ) ) ,
46+ ) ;
47+ let allow_users = Arc :: new ( set) ;
48+
49+ let auth_secret = {
50+ let s = get_string_from_env ( env, "AUTH_SECRET" ) ;
51+ if s. is_empty ( ) {
52+ "default_secret" . to_string ( )
53+ } else {
54+ s
55+ }
56+ } ;
57+
58+ EnvConfig {
59+ allow_users,
60+ maintainer_id,
61+ bot,
62+ auth_secret,
63+ auth_username : get_string_from_env ( env, "AUTH_USERNAME" ) ,
64+ auth_password : get_string_from_env ( env, "AUTH_PASSWORD" ) ,
65+ auth_token_expiration : get_string_from_env ( env, "AUTH_TOKEN_EXPIRATION" )
66+ . parse :: < i64 > ( )
67+ . unwrap_or ( 1 ) ,
68+ }
69+ }
70+ }
71+
2172fn get_string_from_env ( env : & Env , key : & str ) -> String {
2273 match env. var ( key) {
2374 Ok ( v) => match v. as_ref ( ) . as_string ( ) {
@@ -44,47 +95,19 @@ async fn get_opt(env: Env) -> Arc<RunOpt<WasmD1, WasmAI>> {
4495 } ;
4596 } ) ;
4697
47- let token = get_string_from_env ( & env, "TELEGRAM_TOKEN" ) ;
48-
49- let maintainer_id = get_string_from_env ( & env, "MAINTAINER_ID" )
50- . parse :: < i64 > ( )
51- . unwrap_or ( 0 ) ;
52-
53- let allow_users = ALLOW_USERS_CACHE
54- . get_or_init ( || {
55- let mut set = HashSet :: from ( [ maintainer_id] ) ;
56-
57- set. extend (
58- get_string_from_env ( & env, "ALLOW_USERS" )
59- . split ( ',' )
60- . filter ( |s| !s. is_empty ( ) )
61- . filter_map ( |s| s. parse :: < i64 > ( ) . ok ( ) ) ,
62- ) ;
63-
64- Arc :: new ( set)
65- } )
66- . clone ( ) ;
98+ let config = ENV_CONFIG . get_or_init ( || EnvConfig :: from_env ( & env) ) ;
6799
68100 Arc :: new ( RunOpt {
69- allow_users,
101+ allow_users : config . allow_users . clone ( ) ,
70102 d1 : WasmD1 :: new ( & env, "DB" ) . await ,
71103 workers_ai : WasmAI :: new ( & env, "AI" ) ,
72- matainer : maintainer_id,
73- bot : client_reqwest :: Bot :: new ( & token ) ,
104+ matainer : config . maintainer_id ,
105+ bot : config . bot . clone ( ) ,
74106 custom_llms : CUSTOM_LLMS . get_or_init ( OpenAI :: from_assets) . clone ( ) ,
75- auth_secret : {
76- let s = get_string_from_env ( & env, "AUTH_SECRET" ) ;
77- if s. is_empty ( ) {
78- "default_secret" . to_string ( )
79- } else {
80- s
81- }
82- } ,
83- auth_username : get_string_from_env ( & env, "AUTH_USERNAME" ) ,
84- auth_password : get_string_from_env ( & env, "AUTH_PASSWORD" ) ,
85- auth_token_expiration : get_string_from_env ( & env, "AUTH_TOKEN_EXPIRATION" )
86- . parse :: < i64 > ( )
87- . unwrap_or ( 1 ) ,
107+ auth_secret : config. auth_secret . clone ( ) ,
108+ auth_username : config. auth_username . clone ( ) ,
109+ auth_password : config. auth_password . clone ( ) ,
110+ auth_token_expiration : config. auth_token_expiration ,
88111 } )
89112}
90113
@@ -271,49 +294,104 @@ mod tests {
271294 use std:: time:: Instant ;
272295
273296 #[ test]
274- fn benchmark_env_parsing_vs_arc_clone ( ) {
275- // Generate a simulated ALLOW_USERS string with 1000 IDs
297+ fn benchmark_env_parsing_vs_cached_config ( ) {
298+ // Simulate env vars
276299 let ids: Vec < String > = ( 0 ..1000 ) . map ( |i| i. to_string ( ) ) . collect ( ) ;
277- let env_val = ids. join ( "," ) ;
300+ let allow_users_str = ids. join ( "," ) ;
301+ let maintainer_id_str = "12345" ;
302+ let token_str = "some_long_token_string" ;
303+ let auth_secret_str = "some_secret" ;
304+ let auth_username_str = "user" ;
305+ let auth_password_str = "pass" ;
306+ let auth_expiration_str = "3600" ;
278307
279308 let iterations = 1000 ;
280309
281- // Baseline: Parse every time
310+ // Baseline: Parse everything every time
282311 let start = Instant :: now ( ) ;
283312 for _ in 0 ..iterations {
284- let set: HashSet < i64 > = env_val
285- . split ( ',' )
286- . filter ( |s| !s. is_empty ( ) )
287- . filter_map ( |v| v. parse ( ) . ok ( ) )
288- . collect ( ) ;
289- // Simulate creation of RunOpt (just the set part)
290- let _ = set;
313+ // Simulate maintainer_id parsing
314+ let maintainer_id = maintainer_id_str. parse :: < i64 > ( ) . unwrap_or ( 0 ) ;
315+
316+ // Simulate ALLOW_USERS parsing
317+ let mut set = HashSet :: from ( [ maintainer_id] ) ;
318+ set. extend (
319+ allow_users_str
320+ . split ( ',' )
321+ . filter ( |s| !s. is_empty ( ) )
322+ . filter_map ( |v| v. parse :: < i64 > ( ) . ok ( ) ) ,
323+ ) ;
324+ let allow_users = Arc :: new ( set) ;
325+
326+ // Simulate other env vars retrieval (allocation)
327+ let token = token_str. to_string ( ) ;
328+ let auth_secret = auth_secret_str. to_string ( ) ;
329+ let auth_username = auth_username_str. to_string ( ) ;
330+ let auth_password = auth_password_str. to_string ( ) ;
331+ let auth_expiration = auth_expiration_str. parse :: < i64 > ( ) . unwrap_or ( 1 ) ;
332+
333+ // Prevent optimization
334+ let _ = (
335+ allow_users,
336+ maintainer_id,
337+ token,
338+ auth_secret,
339+ auth_username,
340+ auth_password,
341+ auth_expiration,
342+ ) ;
291343 }
292344 let duration_parse = start. elapsed ( ) ;
293345
294- // Optimization: Arc clone
295- let initial_set: HashSet < i64 > = env_val
296- . split ( ',' )
297- . filter ( |s| !s. is_empty ( ) )
298- . filter_map ( |v| v. parse ( ) . ok ( ) )
299- . collect ( ) ;
300- let cached_arc = Arc :: new ( initial_set) ;
346+ // Optimization: Clone cached struct
347+ #[ allow( dead_code) ]
348+ struct CachedConfig {
349+ allow_users : Arc < HashSet < i64 > > ,
350+ maintainer_id : i64 ,
351+ token : String ,
352+ auth_secret : String ,
353+ auth_username : String ,
354+ auth_password : String ,
355+ auth_expiration : i64 ,
356+ }
301357
302- let start = Instant :: now ( ) ;
358+ // Setup cache once
359+ let maintainer_id = maintainer_id_str. parse :: < i64 > ( ) . unwrap_or ( 0 ) ;
360+ let mut set = HashSet :: from ( [ maintainer_id] ) ;
361+ set. extend (
362+ allow_users_str
363+ . split ( ',' )
364+ . filter ( |s| !s. is_empty ( ) )
365+ . filter_map ( |v| v. parse :: < i64 > ( ) . ok ( ) ) ,
366+ ) ;
367+ let cached = Arc :: new ( CachedConfig {
368+ allow_users : Arc :: new ( set) ,
369+ maintainer_id,
370+ token : token_str. to_string ( ) ,
371+ auth_secret : auth_secret_str. to_string ( ) ,
372+ auth_username : auth_username_str. to_string ( ) ,
373+ auth_password : auth_password_str. to_string ( ) ,
374+ auth_expiration : auth_expiration_str. parse :: < i64 > ( ) . unwrap_or ( 1 ) ,
375+ } ) ;
376+
377+ let start_clone = Instant :: now ( ) ;
303378 for _ in 0 ..iterations {
304- let _ = cached_arc . clone ( ) ;
379+ let _ = cached . clone ( ) ;
305380 }
306- let duration_clone = start . elapsed ( ) ;
381+ let duration_clone = start_clone . elapsed ( ) ;
307382
308- println ! ( "Parsing {} times took: {:?}" , iterations, duration_parse) ;
309383 println ! (
310- "Cloning Arc {} times took: {:?}" ,
384+ "Parsing full config {} times took: {:?}" ,
385+ iterations, duration_parse
386+ ) ;
387+ println ! (
388+ "Cloning cached config {} times took: {:?}" ,
311389 iterations, duration_clone
312390 ) ;
313391
314392 assert ! (
315393 duration_clone < duration_parse,
316- "Optimization should be faster"
394+ "Optimization should be significantly faster"
317395 ) ;
318396 }
319397}
0 commit comments