@@ -21,6 +21,7 @@ use databroker::broker::RegistrationError;
21
21
#[ cfg( feature = "tls" ) ]
22
22
use databroker:: grpc:: server:: ServerTLS ;
23
23
24
+ use std:: thread:: available_parallelism;
24
25
use tokio:: select;
25
26
use tokio:: signal:: unix:: { signal, SignalKind } ;
26
27
#[ cfg( feature = "tls" ) ]
@@ -170,8 +171,7 @@ async fn read_metadata_file<'a, 'b>(
170
171
Ok ( ( ) )
171
172
}
172
173
173
- #[ tokio:: main]
174
- async fn main ( ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
174
+ fn main ( ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
175
175
let version = option_env ! ( "CARGO_PKG_VERSION" ) . unwrap_or_default ( ) ;
176
176
177
177
let about = format ! (
@@ -249,10 +249,20 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
249
249
)
250
250
. arg (
251
251
Arg :: new ( "enable-databroker-v1" )
252
- . display_order ( 30 )
252
+ . display_order ( 33 )
253
253
. long ( "enable-databroker-v1" )
254
254
. help ( "Enable sdv.databroker.v1 (GRPC) service" )
255
255
. action ( ArgAction :: SetTrue ) ,
256
+ )
257
+ . arg (
258
+ Arg :: new ( "worker-threads" )
259
+ . display_order ( 34 )
260
+ . long ( "worker-threads" )
261
+ . help ( "How many worker threads will be spawned by the tokio runtime. Default is as many cores are detected on the system" )
262
+ . value_name ( "WORKER_THREADS" )
263
+ . required ( false )
264
+ . env ( "KUKSA_WORKER_THREADS" )
265
+ . value_parser ( clap:: value_parser!( usize ) )
256
266
) ;
257
267
258
268
#[ cfg( feature = "tls" ) ]
@@ -321,152 +331,166 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
321
331
322
332
let args = parser. get_matches ( ) ;
323
333
324
- // install global collector configured based on RUST_LOG env var.
325
- databroker:: init_logging ( ) ;
326
-
327
- info ! ( "Starting Kuksa Databroker {}" , version) ;
328
-
329
- let ip_addr = args. get_one :: < String > ( "address" ) . unwrap ( ) . parse ( ) ?;
330
- let port = args
331
- . get_one :: < u16 > ( "port" )
332
- . expect ( "port should be a number" ) ;
333
- let addr = std:: net:: SocketAddr :: new ( ip_addr, * port) ;
334
-
335
- let broker = broker:: DataBroker :: new ( version) ;
336
- let database = broker. authorized_access ( & permissions:: ALLOW_ALL ) ;
337
-
338
- add_kuksa_attribute (
339
- & database,
340
- "Kuksa.Databroker.GitVersion" . to_owned ( ) ,
341
- option_env ! ( "VERGEN_GIT_SEMVER_LIGHTWEIGHT" )
342
- . unwrap_or ( "N/A" )
343
- . to_owned ( ) ,
344
- "Databroker version as reported by GIT" . to_owned ( ) ,
345
- )
346
- . await ;
347
-
348
- add_kuksa_attribute (
349
- & database,
350
- "Kuksa.Databroker.CargoVersion" . to_owned ( ) ,
351
- option_env ! ( "CARGO_PKG_VERSION" ) . unwrap_or ( "N/A" ) . to_owned ( ) ,
352
- "Databroker version as reported by GIT" . to_owned ( ) ,
353
- )
354
- . await ;
355
-
356
- add_kuksa_attribute (
357
- & database,
358
- "Kuksa.Databroker.CommitSha" . to_owned ( ) ,
359
- option_env ! ( "VERGEN_GIT_SHA" ) . unwrap_or ( "N/A" ) . to_owned ( ) ,
360
- "Commit SHA of current version" . to_owned ( ) ,
361
- )
362
- . await ;
363
-
364
- if let Some ( metadata_filenames) = args. get_many :: < String > ( "vss-file" ) {
365
- for filename in metadata_filenames {
366
- read_metadata_file ( & database, filename) . await ?;
367
- }
368
- }
334
+ let cores = available_parallelism ( ) . unwrap ( ) . get ( ) ;
335
+ let worker_threads: & usize = args. get_one :: < usize > ( "worker-threads" ) . unwrap_or ( & cores) ;
369
336
370
- #[ cfg( feature = "tls" ) ]
371
- let tls_config = if args. get_flag ( "insecure" ) {
372
- ServerTLS :: Disabled
373
- } else {
374
- let cert_file = args. get_one :: < String > ( "tls-cert" ) ;
375
- let key_file = args. get_one :: < String > ( "tls-private-key" ) ;
376
- match ( cert_file, key_file) {
377
- ( Some ( cert_file) , Some ( key_file) ) => {
378
- let cert = std:: fs:: read ( cert_file) ?;
379
- let key = std:: fs:: read ( key_file) ?;
380
- let identity = tonic:: transport:: Identity :: from_pem ( cert, key) ;
381
- ServerTLS :: Enabled {
382
- tls_config : tonic:: transport:: ServerTlsConfig :: new ( ) . identity ( identity) ,
383
- }
384
- }
385
- ( Some ( _) , None ) => {
386
- return Err (
387
- "TLS private key (--tls-private-key) must be set if --tls-cert is." . into ( ) ,
388
- ) ;
389
- }
390
- ( None , Some ( _) ) => {
391
- return Err (
392
- "TLS certificate (--tls-cert) must be set if --tls-private-key is." . into ( ) ,
393
- ) ;
394
- }
395
- ( None , None ) => {
396
- warn ! (
397
- "TLS is not enabled. Default behavior of accepting insecure connections \
398
- when TLS is not configured may change in the future! \
399
- Please use --insecure to explicitly enable this behavior."
400
- ) ;
401
- ServerTLS :: Disabled
402
- }
403
- }
404
- } ;
337
+ let runtime = tokio:: runtime:: Builder :: new_multi_thread ( )
338
+ . worker_threads ( * worker_threads)
339
+ . enable_all ( )
340
+ . build ( )
341
+ . unwrap ( ) ;
405
342
406
- let enable_authorization = !args. get_flag ( "disable-authorization" ) ;
407
- let jwt_public_key = match args. get_one :: < String > ( "jwt-public-key" ) {
408
- Some ( pub_key_filename) => match std:: fs:: read_to_string ( pub_key_filename) {
409
- Ok ( pub_key) => {
410
- info ! ( "Using '{pub_key_filename}' to authenticate access tokens" ) ;
411
- Ok ( Some ( pub_key) )
412
- }
413
- Err ( err) => {
414
- error ! ( "Failed to open file {:?}: {}" , pub_key_filename, err) ;
415
- Err ( err)
343
+ runtime. block_on ( async {
344
+ // install global collector configured based on RUST_LOG env var.
345
+ databroker:: init_logging ( ) ;
346
+
347
+ info ! ( "Starting Kuksa Databroker {}" , version) ;
348
+ info ! (
349
+ "Using {} threads with {} cores available on the system" ,
350
+ worker_threads, cores
351
+ ) ;
352
+
353
+ let ip_addr = args. get_one :: < String > ( "address" ) . unwrap ( ) . parse ( ) ?;
354
+ let port = args
355
+ . get_one :: < u16 > ( "port" )
356
+ . expect ( "port should be a number" ) ;
357
+ let addr = std:: net:: SocketAddr :: new ( ip_addr, * port) ;
358
+
359
+ let broker = broker:: DataBroker :: new ( version) ;
360
+ let database = broker. authorized_access ( & permissions:: ALLOW_ALL ) ;
361
+
362
+ add_kuksa_attribute (
363
+ & database,
364
+ "Kuksa.Databroker.GitVersion" . to_owned ( ) ,
365
+ option_env ! ( "VERGEN_GIT_SEMVER_LIGHTWEIGHT" )
366
+ . unwrap_or ( "N/A" )
367
+ . to_owned ( ) ,
368
+ "Databroker version as reported by GIT" . to_owned ( ) ,
369
+ )
370
+ . await ;
371
+
372
+ add_kuksa_attribute (
373
+ & database,
374
+ "Kuksa.Databroker.CargoVersion" . to_owned ( ) ,
375
+ option_env ! ( "CARGO_PKG_VERSION" ) . unwrap_or ( "N/A" ) . to_owned ( ) ,
376
+ "Databroker version as reported by GIT" . to_owned ( ) ,
377
+ )
378
+ . await ;
379
+
380
+ add_kuksa_attribute (
381
+ & database,
382
+ "Kuksa.Databroker.CommitSha" . to_owned ( ) ,
383
+ option_env ! ( "VERGEN_GIT_SHA" ) . unwrap_or ( "N/A" ) . to_owned ( ) ,
384
+ "Commit SHA of current version" . to_owned ( ) ,
385
+ )
386
+ . await ;
387
+
388
+ if let Some ( metadata_filenames) = args. get_many :: < String > ( "vss-file" ) {
389
+ for filename in metadata_filenames {
390
+ read_metadata_file ( & database, filename) . await ?;
416
391
}
417
- } ,
418
- None => Ok ( None ) ,
419
- } ?;
420
-
421
- let authorization = match ( enable_authorization, jwt_public_key) {
422
- ( true , Some ( pub_key) ) => Authorization :: new ( pub_key) ?,
423
- ( true , None ) => {
424
- warn ! ( "Authorization is not enabled." ) ;
425
- Authorization :: Disabled
426
392
}
427
- ( false , _) => Authorization :: Disabled ,
428
- } ;
429
393
430
- #[ cfg( feature = "viss" ) ]
431
- {
432
- let viss_bind_addr = if args. contains_id ( "viss-address" ) {
433
- args. get_one :: < String > ( "viss-address" ) . unwrap ( ) . parse ( ) ?
394
+ #[ cfg( feature = "tls" ) ]
395
+ let tls_config = if args. get_flag ( "insecure" ) {
396
+ ServerTLS :: Disabled
434
397
} else {
435
- args. get_one :: < String > ( "address" ) . unwrap ( ) . parse ( ) ?
398
+ let cert_file = args. get_one :: < String > ( "tls-cert" ) ;
399
+ let key_file = args. get_one :: < String > ( "tls-private-key" ) ;
400
+ match ( cert_file, key_file) {
401
+ ( Some ( cert_file) , Some ( key_file) ) => {
402
+ let cert = std:: fs:: read ( cert_file) ?;
403
+ let key = std:: fs:: read ( key_file) ?;
404
+ let identity = tonic:: transport:: Identity :: from_pem ( cert, key) ;
405
+ ServerTLS :: Enabled {
406
+ tls_config : tonic:: transport:: ServerTlsConfig :: new ( ) . identity ( identity) ,
407
+ }
408
+ }
409
+ ( Some ( _) , None ) => {
410
+ return Err (
411
+ "TLS private key (--tls-private-key) must be set if --tls-cert is." . into ( ) ,
412
+ ) ;
413
+ }
414
+ ( None , Some ( _) ) => {
415
+ return Err (
416
+ "TLS certificate (--tls-cert) must be set if --tls-private-key is." . into ( ) ,
417
+ ) ;
418
+ }
419
+ ( None , None ) => {
420
+ warn ! (
421
+ "TLS is not enabled. Default behavior of accepting insecure connections \
422
+ when TLS is not configured may change in the future! \
423
+ Please use --insecure to explicitly enable this behavior."
424
+ ) ;
425
+ ServerTLS :: Disabled
426
+ }
427
+ }
436
428
} ;
437
429
438
- let viss_port = args
439
- . get_one :: < u16 > ( "viss-port" )
440
- . expect ( "port should be a number" ) ;
441
- let viss_addr = std:: net:: SocketAddr :: new ( viss_bind_addr, * viss_port) ;
442
-
443
- if args. get_flag ( "enable-viss" ) {
444
- let broker = broker. clone ( ) ;
445
- let authorization = authorization. clone ( ) ;
446
- tokio:: spawn ( async move {
447
- if let Err ( err) = viss:: server:: serve ( viss_addr, broker, authorization) . await {
448
- error ! ( "{err}" ) ;
430
+ let enable_authorization = !args. get_flag ( "disable-authorization" ) ;
431
+ let jwt_public_key = match args. get_one :: < String > ( "jwt-public-key" ) {
432
+ Some ( pub_key_filename) => match std:: fs:: read_to_string ( pub_key_filename) {
433
+ Ok ( pub_key) => {
434
+ info ! ( "Using '{pub_key_filename}' to authenticate access tokens" ) ;
435
+ Ok ( Some ( pub_key) )
449
436
}
450
- } ) ;
451
- }
452
- }
437
+ Err ( err) => {
438
+ error ! ( "Failed to open file {:?}: {}" , pub_key_filename, err) ;
439
+ Err ( err)
440
+ }
441
+ } ,
442
+ None => Ok ( None ) ,
443
+ } ?;
444
+
445
+ let authorization = match ( enable_authorization, jwt_public_key) {
446
+ ( true , Some ( pub_key) ) => Authorization :: new ( pub_key) ?,
447
+ ( true , None ) => {
448
+ warn ! ( "Authorization is not enabled." ) ;
449
+ Authorization :: Disabled
450
+ }
451
+ ( false , _) => Authorization :: Disabled ,
452
+ } ;
453
453
454
- let mut apis = vec ! [ grpc:: server:: Api :: KuksaValV1 ] ;
454
+ #[ cfg( feature = "viss" ) ]
455
+ {
456
+ let viss_bind_addr = if args. contains_id ( "viss-address" ) {
457
+ args. get_one :: < String > ( "viss-address" ) . unwrap ( ) . parse ( ) ?
458
+ } else {
459
+ args. get_one :: < String > ( "address" ) . unwrap ( ) . parse ( ) ?
460
+ } ;
461
+
462
+ let viss_port = args
463
+ . get_one :: < u16 > ( "viss-port" )
464
+ . expect ( "port should be a number" ) ;
465
+ let viss_addr = std:: net:: SocketAddr :: new ( viss_bind_addr, * viss_port) ;
466
+
467
+ if args. get_flag ( "enable-viss" ) {
468
+ let broker = broker. clone ( ) ;
469
+ let authorization = authorization. clone ( ) ;
470
+ tokio:: spawn ( async move {
471
+ if let Err ( err) = viss:: server:: serve ( viss_addr, broker, authorization) . await {
472
+ error ! ( "{err}" ) ;
473
+ }
474
+ } ) ;
475
+ }
476
+ }
455
477
456
- if args. get_flag ( "enable-databroker-v1" ) {
457
- apis. push ( grpc:: server:: Api :: SdvDatabrokerV1 ) ;
458
- }
478
+ let mut apis = vec ! [ grpc:: server:: Api :: KuksaValV1 ] ;
459
479
460
- grpc:: server:: serve (
461
- addr,
462
- broker,
463
- #[ cfg( feature = "tls" ) ]
464
- tls_config,
465
- & apis,
466
- authorization,
467
- shutdown_handler ( ) ,
468
- )
469
- . await ?;
480
+ if args. get_flag ( "enable-databroker-v1" ) {
481
+ apis. push ( grpc:: server:: Api :: SdvDatabrokerV1 ) ;
482
+ }
483
+ grpc:: server:: serve (
484
+ addr,
485
+ broker,
486
+ #[ cfg( feature = "tls" ) ]
487
+ tls_config,
488
+ & apis,
489
+ authorization,
490
+ shutdown_handler ( ) ,
491
+ )
492
+ . await
493
+ } ) ?;
470
494
471
495
Ok ( ( ) )
472
496
}
0 commit comments