11// SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
22// SPDX-License-Identifier: Apache-2.0
3- //
4- // Licensed under the Apache License, Version 2.0 (the "License");
5- // you may not use this file except in compliance with the License.
6- // You may obtain a copy of the License at
7- //
8- // http://www.apache.org/licenses/LICENSE-2.0
9- //
10- // Unless required by applicable law or agreed to in writing, software
11- // distributed under the License is distributed on an "AS IS" BASIS,
12- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13- // See the License for the specific language governing permissions and
14- // limitations under the License.
153
164use super :: Result ;
175use derive_builder:: Builder ;
@@ -20,6 +8,7 @@ use figment::{
208 Figment ,
219} ;
2210use serde:: { Deserialize , Serialize } ;
11+ use std:: fmt;
2312use validator:: Validate ;
2413
2514/// Default HTTP server host
@@ -66,35 +55,58 @@ impl Default for WorkerConfig {
6655pub struct RuntimeConfig {
6756 /// Number of async worker threads
6857 /// If set to 1, the runtime will run in single-threaded mode
58+ /// Set this at runtime with environment variable DYN_RUNTIME_NUM_WORKER_THREADS. Defaults to
59+ /// number of cores.
6960 #[ validate( range( min = 1 ) ) ]
70- #[ builder( default = "16" ) ]
7161 #[ builder_field_attr( serde( skip_serializing_if = "Option::is_none" ) ) ]
72- pub num_worker_threads : usize ,
62+ pub num_worker_threads : Option < usize > ,
7363
7464 /// Maximum number of blocking threads
7565 /// Blocking threads are used for blocking operations, this value must be greater than 0.
66+ /// Set this at runtime with environment variable DYN_RUNTIME_MAX_BLOCKING_THREADS. Defaults to
67+ /// 512.
7668 #[ validate( range( min = 1 ) ) ]
7769 #[ builder( default = "512" ) ]
7870 #[ builder_field_attr( serde( skip_serializing_if = "Option::is_none" ) ) ]
7971 pub max_blocking_threads : usize ,
8072
8173 /// HTTP server host for health and metrics endpoints
74+ /// Set this at runtime with environment variable DYN_RUNTIME_HTTP_SERVER_HOST
8275 #[ builder( default = "DEFAULT_HTTP_SERVER_HOST.to_string()" ) ]
8376 #[ builder_field_attr( serde( skip_serializing_if = "Option::is_none" ) ) ]
8477 pub http_server_host : String ,
8578
8679 /// HTTP server port for health and metrics endpoints
8780 /// If set to 0, the system will assign a random available port
81+ /// Set this at runtime with environment variable DYN_RUNTIME_HTTP_SERVER_PORT
8882 #[ builder( default = "DEFAULT_HTTP_SERVER_PORT" ) ]
8983 #[ builder_field_attr( serde( skip_serializing_if = "Option::is_none" ) ) ]
9084 pub http_server_port : u16 ,
9185
9286 /// Health and metrics HTTP server enabled
87+ /// Set this at runtime with environment variable DYN_RUNTIME_HTTP_ENABLED
9388 #[ builder( default = "false" ) ]
9489 #[ builder_field_attr( serde( skip_serializing_if = "Option::is_none" ) ) ]
9590 pub http_enabled : bool ,
9691}
9792
93+ impl fmt:: Display for RuntimeConfig {
94+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
95+ // If None, it defaults to "number of cores", so we indicate that.
96+ match self . num_worker_threads {
97+ Some ( val) => write ! ( f, "num_worker_threads={val}, " ) ?,
98+ None => write ! ( f, "num_worker_threads=default (num_cores), " ) ?,
99+ }
100+
101+ write ! ( f, "max_blocking_threads={}, " , self . max_blocking_threads) ?;
102+ write ! ( f, "http_server_host={}, " , self . http_server_host) ?;
103+ write ! ( f, "http_server_port={}, " , self . http_server_port) ?;
104+ write ! ( f, "http_enabled={}" , self . http_enabled) ?;
105+
106+ Ok ( ( ) )
107+ }
108+ }
109+
98110impl RuntimeConfig {
99111 pub fn builder ( ) -> RuntimeConfigBuilder {
100112 RuntimeConfigBuilder :: default ( )
@@ -138,7 +150,7 @@ impl RuntimeConfig {
138150
139151 pub fn single_threaded ( ) -> Self {
140152 RuntimeConfig {
141- num_worker_threads : 1 ,
153+ num_worker_threads : Some ( 1 ) ,
142154 max_blocking_threads : 1 ,
143155 http_server_host : DEFAULT_HTTP_SERVER_HOST . to_string ( ) ,
144156 http_server_port : DEFAULT_HTTP_SERVER_PORT ,
@@ -147,20 +159,24 @@ impl RuntimeConfig {
147159 }
148160
149161 /// Create a new default runtime configuration
150- pub ( crate ) fn create_runtime ( & self ) -> Result < tokio:: runtime:: Runtime > {
151- Ok ( tokio:: runtime:: Builder :: new_multi_thread ( )
152- . worker_threads ( self . num_worker_threads )
162+ pub ( crate ) fn create_runtime ( & self ) -> std:: io:: Result < tokio:: runtime:: Runtime > {
163+ tokio:: runtime:: Builder :: new_multi_thread ( )
164+ . worker_threads (
165+ self . num_worker_threads
166+ . unwrap_or_else ( || std:: thread:: available_parallelism ( ) . unwrap ( ) . get ( ) ) ,
167+ )
153168 . max_blocking_threads ( self . max_blocking_threads )
154169 . enable_all ( )
155- . build ( ) ? )
170+ . build ( )
156171 }
157172}
158173
159174impl Default for RuntimeConfig {
160175 fn default ( ) -> Self {
176+ let num_cores = std:: thread:: available_parallelism ( ) . unwrap ( ) . get ( ) ;
161177 Self {
162- num_worker_threads : 16 ,
163- max_blocking_threads : 16 ,
178+ num_worker_threads : Some ( num_cores ) ,
179+ max_blocking_threads : num_cores ,
164180 http_server_host : DEFAULT_HTTP_SERVER_HOST . to_string ( ) ,
165181 http_server_port : DEFAULT_HTTP_SERVER_PORT ,
166182 http_enabled : false ,
@@ -240,7 +256,7 @@ mod tests {
240256 ] ,
241257 || {
242258 let config = RuntimeConfig :: from_settings ( ) ?;
243- assert_eq ! ( config. num_worker_threads, 24 ) ;
259+ assert_eq ! ( config. num_worker_threads, Some ( 24 ) ) ;
244260 assert_eq ! ( config. max_blocking_threads, 32 ) ;
245261 Ok ( ( ) )
246262 } ,
0 commit comments