agones.dev/agones@v1.54.0/test/sdk/rust/src/main.rs (about) 1 // Copyright 2018 Google LLC All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 use std::{env, thread, time::Duration}; 16 17 #[tokio::main(flavor = "multi_thread", worker_threads = 4)] 18 async fn main() { 19 println!("Rust Game Server has started!"); 20 21 ::std::process::exit(match run().await { 22 Ok(_) => { 23 println!("Rust Game Server finished."); 24 0 25 } 26 Err(msg) => { 27 println!("rust: {}", msg); 28 1 29 } 30 }); 31 } 32 33 async fn run() -> Result<(), String> { 34 let env_run_async = env::var("RUN_ASYNC").unwrap_or_default(); 35 if env_run_async.contains("true") { 36 println!("rust: RUN_ASYNC is set to true, so run test for async functions"); 37 run_async().await 38 } else { 39 tokio::task::block_in_place(run_sync) 40 } 41 } 42 43 fn run_sync() -> Result<(), String> { 44 use tokio::runtime::Handle; 45 46 println!("rust: Creating SDK instance"); 47 let mut sdk = Handle::current().block_on(async move { 48 agones::Sdk::new(None /* default port */, None /* keep_alive */) 49 .await 50 .map_err(|e| format!("unable to create sdk client: {}", e)) 51 })?; 52 53 // Spawn a task that will send health checks every 2 seconds. If this current 54 // thread/task panics or dropped, the health check will also be stopped 55 let _health = { 56 let health_tx = sdk.health_check(); 57 let (tx, mut rx) = tokio::sync::oneshot::channel::<()>(); 58 59 Handle::current().spawn(async move { 60 let mut interval = tokio::time::interval(Duration::from_secs(2)); 61 62 loop { 63 tokio::select! { 64 _ = interval.tick() => { 65 if health_tx 66 .send(()) 67 .await.is_err() { 68 eprintln!("Health check receiver was dropped"); 69 break; 70 } 71 } 72 _ = &mut rx => { 73 println!("Health check task canceled"); 74 break; 75 } 76 } 77 } 78 }); 79 80 tx 81 }; 82 83 let _watch = { 84 let mut watch_client = sdk.clone(); 85 let (tx, mut rx) = tokio::sync::oneshot::channel::<()>(); 86 87 tokio::task::spawn(async move { 88 println!("rust: Starting to watch GameServer updates..."); 89 let mut once = true; 90 match watch_client.watch_gameserver().await { 91 Err(e) => eprintln!("rust: Failed to watch for GameServer updates: {}", e), 92 Ok(mut stream) => loop { 93 tokio::select! { 94 gs = stream.message() => { 95 match gs { 96 Ok(Some(gs)) => { 97 let om = gs.object_meta.unwrap(); 98 println!("rust: GameServer Update, name: {}", om.name); 99 println!("rust: GameServer Update, state: {}", gs.status.unwrap().state); 100 101 if once { 102 println!("rust: Setting an annotation"); 103 let uid = om.uid.clone(); 104 105 if let Err(e) = watch_client.set_annotation("test-annotation", uid).await { 106 eprintln!("rust: Failed to set annotation from watch task: {}", e); 107 } 108 109 once = false; 110 } 111 } 112 Ok(None) => { 113 println!("rust: Server closed the GameServer watch stream"); 114 break; 115 } 116 Err(e) => { 117 eprintln!("rust: GameServer Update stream encountered an error: {}", e); 118 } 119 } 120 121 } 122 _ = &mut rx => { 123 println!("rust: Shutting down GameServer watch loop"); 124 break; 125 } 126 } 127 }, 128 } 129 }); 130 131 tx 132 }; 133 134 // Waiting for a thread to spawn 135 thread::sleep(Duration::from_secs(2)); 136 137 println!("rust: Marking server as ready..."); 138 Handle::current().block_on(async { 139 sdk.ready() 140 .await 141 .map_err(|e| format!("Could not run Ready(): {}. Exiting!", e)) 142 })?; 143 144 println!("rust: ...marked Ready"); 145 146 println!("rust: Reserving for 5 seconds"); 147 Handle::current().block_on(async { 148 sdk.reserve(Duration::from_secs(5)) 149 .await 150 .map_err(|e| format!("Could not run Reserve(): {}. Exiting!", e)) 151 })?; 152 println!("rust: ...Reserved"); 153 154 println!("rust: Allocate game server ..."); 155 Handle::current().block_on(async { 156 sdk.allocate() 157 .await 158 .map_err(|e| format!("Could not run Allocate(): {}. Exiting!", e)) 159 })?; 160 161 println!("rust: ...marked Allocated"); 162 163 println!("rust: Getting GameServer details..."); 164 let gameserver = Handle::current().block_on(async { 165 sdk.get_gameserver() 166 .await 167 .map_err(|e| format!("Could not run GameServer(): {}. Exiting!", e)) 168 })?; 169 170 println!( 171 "rust: GameServer name: {}", 172 gameserver.object_meta.clone().unwrap().name 173 ); 174 175 println!("rust: Setting a label"); 176 let creation_ts = gameserver.object_meta.unwrap().creation_timestamp; 177 Handle::current().block_on(async { 178 sdk.set_label("test-label", &creation_ts.to_string()) 179 .await 180 .map_err(|e| format!("Could not run SetLabel(): {}. Exiting!", e)) 181 })?; 182 183 let feature_gates = env::var("FEATURE_GATES").unwrap_or_default(); 184 if feature_gates.contains("PlayerTracking=true") { 185 run_player_tracking_features(sdk.alpha().clone())?; 186 } 187 if feature_gates.contains("CountsAndLists=true") { 188 run_counts_and_lists_features(sdk.beta().clone())?; 189 } 190 191 for i in 0..1 { 192 let time = i * 5; 193 println!("rust: Running for {} seconds", time); 194 195 thread::sleep(Duration::from_secs(5)); 196 } 197 198 println!("rust: Shutting down..."); 199 Handle::current().block_on(async { 200 sdk.shutdown() 201 .await 202 .map_err(|e| format!("Could not run Shutdown: {}. Exiting!", e)) 203 })?; 204 println!("rust: ...marked for Shutdown"); 205 206 Ok(()) 207 } 208 209 fn run_player_tracking_features(mut alpha: agones::alpha::Alpha) -> Result<(), String> { 210 use tokio::runtime::Handle; 211 212 println!("rust: Setting player capacity..."); 213 Handle::current().block_on(async { 214 alpha 215 .set_player_capacity(10) 216 .await 217 .map_err(|e| format!("Could not run SetPlayerCapacity(): {:#?}. Exiting!", e)) 218 })?; 219 220 println!("rust: Getting player capacity..."); 221 let capacity = Handle::current().block_on(async { 222 alpha 223 .get_player_capacity() 224 .await 225 .map_err(|e| format!("Could not run GetPlayerCapacity(): {}. Exiting!", e)) 226 })?; 227 println!("rust: Player capacity: {}", capacity); 228 229 println!("rust: Increasing the player count..."); 230 let player_id = "1234".to_string(); 231 232 let added = Handle::current().block_on(async { 233 alpha 234 .player_connect(&player_id) 235 .await 236 .map_err(|e| format!("Could not run PlayerConnect(): {}. Exiting!", e)) 237 })?; 238 if added { 239 println!("rust: Added player"); 240 } else { 241 panic!("rust: Failed to add player. Exiting!"); 242 } 243 244 let connected = Handle::current().block_on(async { 245 alpha 246 .is_player_connected(&player_id) 247 .await 248 .map_err(|e| format!("Could not run IsPlayerConnected(): {}. Exiting!", e)) 249 })?; 250 if connected { 251 println!("rust: {} is connected", player_id); 252 } else { 253 panic!("rust: {} is not connected. Exiting!", player_id); 254 } 255 256 let player_ids = Handle::current().block_on(async { 257 alpha 258 .get_connected_players() 259 .await 260 .map_err(|e| format!("Could not run GetConnectedPlayers(): {}. Exiting!", e)) 261 })?; 262 println!("rust: Connected players: {:?}", player_ids); 263 264 let player_count = Handle::current().block_on(async { 265 alpha 266 .get_player_count() 267 .await 268 .map_err(|e| format!("Could not run GetConnectedPlayers(): {}. Exiting!", e)) 269 })?; 270 println!("rust: Current player count: {}", player_count); 271 272 println!("rust: Decreasing the player count..."); 273 let removed = Handle::current().block_on(async { 274 alpha 275 .player_disconnect(&player_id) 276 .await 277 .map_err(|e| format!("Could not run PlayerDisconnect(): {}. Exiting!", e)) 278 })?; 279 if removed { 280 println!("rust: Removed player"); 281 } else { 282 panic!("rust: Failed to remove player. Exiting!"); 283 } 284 285 let player_count = Handle::current().block_on(async { 286 alpha 287 .get_player_count() 288 .await 289 .map_err(|e| format!("Could not GetPlayerCount(): {}. Exiting!", e)) 290 })?; 291 println!("rust: Current player count: {}", player_count); 292 293 Ok(()) 294 } 295 296 fn run_counts_and_lists_features(mut beta: agones::beta::Beta) -> Result<(), String> { 297 use tokio::runtime::Handle; 298 299 // Counter tests 300 let counter = "rooms"; 301 println!("rust: Getting Counter count..."); 302 let count = Handle::current().block_on(async { 303 beta.get_counter_count(counter) 304 .await 305 .map_err(|e| format!("Could not run GetCounterCount(): {}. Exiting!", e)) 306 })?; 307 if count != 1 { 308 return Err(format!("Counter count should be 1, but is {}", count)); 309 } 310 311 println!("rust: Incrementing Counter..."); 312 Handle::current().block_on(async { 313 beta.increment_counter(counter, 9) 314 .await 315 .map_err(|e| format!("Could not run IncrementCounter(): {}. Exiting!", e)) 316 })?; 317 318 println!("rust: Decrementing Counter..."); 319 Handle::current().block_on(async { 320 beta.decrement_counter(counter, 10) 321 .await 322 .map_err(|e| format!("Could not run DecrementCounter(): {}. Exiting!", e)) 323 })?; 324 325 println!("rust: Setting Counter count..."); 326 Handle::current().block_on(async { 327 beta.set_counter_count(counter, 10) 328 .await 329 .map_err(|e| format!("Could not run SetCounterCount(): {}. Exiting!", e)) 330 })?; 331 332 println!("rust: Getting Counter capacity..."); 333 let capacity = Handle::current().block_on(async { 334 beta.get_counter_capacity(counter) 335 .await 336 .map_err(|e| format!("Could not run GetCounterCapacity(): {}. Exiting!", e)) 337 })?; 338 if capacity != 10 { 339 return Err(format!("Counter capacity should be 10, but is {}", capacity)); 340 } 341 342 println!("rust: Setting Counter capacity..."); 343 Handle::current().block_on(async { 344 beta.set_counter_capacity(counter, 1) 345 .await 346 .map_err(|e| format!("Could not run SetCounterCapacity(): {}. Exiting!", e)) 347 })?; 348 349 // List tests 350 let list = "players"; 351 let vals = vec!["test0".to_string(), "test1".to_string(), "test2".to_string()]; 352 353 println!("rust: Checking if List contains 'test1'..."); 354 let contains = Handle::current().block_on(async { 355 beta.list_contains(list, "test1") 356 .await 357 .map_err(|e| format!("Could not run ListContains(): {}. Exiting!", e)) 358 })?; 359 if !contains { 360 return Err("List should contain value \"test1\"".to_string()); 361 } 362 363 println!("rust: Getting List length..."); 364 let length = Handle::current().block_on(async { 365 beta.get_list_length(list) 366 .await 367 .map_err(|e| format!("Could not run GetListLength(): {}. Exiting!", e)) 368 })?; 369 if length != 3 { 370 return Err(format!("List length should be 3, but is {}", length)); 371 } 372 373 println!("rust: Getting List values..."); 374 let values = Handle::current().block_on(async { 375 beta.get_list_values(list) 376 .await 377 .map_err(|e| format!("Could not run GetListValues(): {}. Exiting!", e)) 378 })?; 379 if values != vals { 380 return Err(format!("List values should be {:?}, but is {:?}", vals, values)); 381 } 382 383 println!("rust: Appending value 'test3' to List..."); 384 Handle::current().block_on(async { 385 beta.append_list_value(list, "test3") 386 .await 387 .map_err(|e| format!("Could not run AppendListValue(): {}. Exiting!", e)) 388 })?; 389 390 println!("rust: Deleting value 'test2' from List..."); 391 Handle::current().block_on(async { 392 beta.delete_list_value(list, "test2") 393 .await 394 .map_err(|e| format!("Could not run DeleteListValue(): {}. Exiting!", e)) 395 })?; 396 397 println!("rust: Getting List capacity..."); 398 399 Ok(()) 400 } 401 402 403 async fn run_async() -> Result<(), String> { 404 let mut sdk = match tokio::time::timeout( 405 Duration::from_secs(30), 406 agones::Sdk::new(None /* default port */, None /* keep_alive */), 407 ) 408 .await 409 { 410 Ok(sdk) => sdk.map_err(|e| format!("unable to create sdk client: {}", e))?, 411 Err(_) => return Err("timed out attempting to connect to the sidecar".to_owned()), 412 }; 413 414 let _health = { 415 let health_tx = sdk.health_check(); 416 let (tx, mut rx) = tokio::sync::oneshot::channel::<()>(); 417 418 tokio::task::spawn(async move { 419 let mut interval = tokio::time::interval(Duration::from_secs(2)); 420 421 loop { 422 tokio::select! { 423 _ = interval.tick() => { 424 if health_tx 425 .send(()) 426 .await.is_err() { 427 eprintln!("Health check receiver was dropped"); 428 break; 429 } 430 } 431 _ = &mut rx => { 432 println!("Health check task canceled"); 433 break; 434 } 435 } 436 } 437 }); 438 439 tx 440 }; 441 442 let _watch = { 443 let mut watch_client = sdk.clone(); 444 let (tx, mut rx) = tokio::sync::oneshot::channel::<()>(); 445 446 tokio::task::spawn(async move { 447 println!("rust_async: Starting to watch GameServer updates..."); 448 let mut once = true; 449 match watch_client.watch_gameserver().await { 450 Err(e) => eprintln!("rust_async: Failed to watch for GameServer updates: {}", e), 451 Ok(mut stream) => loop { 452 tokio::select! { 453 gs = stream.message() => { 454 match gs { 455 Ok(Some(gs)) => { 456 let om = gs.object_meta.unwrap(); 457 println!("rust_async: GameServer Update, name: {}", om.name); 458 println!("rust_async: GameServer Update, state: {}", gs.status.unwrap().state); 459 460 if once { 461 println!("rust_async: Setting an annotation"); 462 let uid = om.uid.clone(); 463 464 if let Err(e) = watch_client.set_annotation("test-annotation", uid).await { 465 eprintln!("rust_async: Failed to set annotation from watch task: {}", e); 466 } 467 468 once = false; 469 } 470 } 471 Ok(None) => { 472 println!("rust_async: Server closed the GameServer watch stream"); 473 break; 474 } 475 Err(e) => { 476 eprintln!("rust_async: GameServer Update stream encountered an error: {}", e); 477 } 478 } 479 480 } 481 _ = &mut rx => { 482 println!("rust_async: Shutting down GameServer watch loop"); 483 break; 484 } 485 } 486 }, 487 } 488 }); 489 490 tx 491 }; 492 493 tokio::time::sleep(Duration::from_secs(2)).await; 494 495 println!("rust_async: Marking server as ready..."); 496 sdk.ready() 497 .await 498 .map_err(|e| format!("Could not run Ready(): {}. Exiting!", e))?; 499 println!("rust_async: ...marked Ready"); 500 501 println!("rust_async: Reserving for 5 seconds"); 502 sdk.reserve(Duration::new(5, 0)) 503 .await 504 .map_err(|e| format!("Could not run Reserve(): {}. Exiting!", e))?; 505 println!("rust_async: ...Reserved"); 506 507 println!("rust_async: Allocate game server ..."); 508 sdk.allocate() 509 .await 510 .map_err(|e| format!("Could not run Allocate(): {}. Exiting!", e))?; 511 512 println!("rust_async: ...marked Allocated"); 513 514 println!("rust_async: Getting GameServer details..."); 515 let gameserver = sdk 516 .get_gameserver() 517 .await 518 .map_err(|e| format!("Could not run GameServer(): {}. Exiting!", e))?; 519 520 println!( 521 "rust_async: GameServer name: {}", 522 gameserver.object_meta.clone().unwrap().name 523 ); 524 525 println!("rust_async: Setting a label"); 526 let creation_ts = gameserver.object_meta.clone().unwrap().creation_timestamp; 527 sdk.set_label("test-label", &creation_ts.to_string()) 528 .await 529 .map_err(|e| format!("Could not run SetLabel(): {}. Exiting!", e))?; 530 531 let feature_gates = env::var("FEATURE_GATES").unwrap_or_default(); 532 if feature_gates.contains("PlayerTracking=true") { 533 run_player_tracking_features_async(sdk.alpha().clone()).await?; 534 } 535 if feature_gates.contains("CountsAndLists=true") { 536 run_counts_and_lists_features_async(sdk.beta().clone()).await?; 537 } 538 539 for i in 0..1 { 540 let time = i * 5; 541 println!("rust_async: Running for {} seconds", time); 542 543 tokio::time::sleep(Duration::from_secs(5)).await; 544 } 545 546 println!("rust_async: Shutting down..."); 547 sdk.shutdown() 548 .await 549 .map_err(|e| format!("Could not run Shutdown: {}. Exiting!", e))?; 550 println!("rust_async: ...marked for Shutdown"); 551 552 Ok(()) 553 } 554 555 async fn run_player_tracking_features_async(mut alpha: agones::alpha::Alpha) -> Result<(), String> { 556 println!("rust_async: Setting player capacity..."); 557 alpha 558 .set_player_capacity(10) 559 .await 560 .map_err(|e| format!("Could not run SetPlayerCapacity(): {}. Exiting!", e))?; 561 562 println!("rust_async: Getting player capacity..."); 563 let capacity = alpha 564 .get_player_capacity() 565 .await 566 .map_err(|e| format!("Could not run GetPlayerCapacity(): {}. Exiting!", e))?; 567 println!("rust_async: Player capacity: {}", capacity); 568 569 println!("rust_async: Increasing the player count..."); 570 let player_id = "1234".to_string(); 571 let added = alpha 572 .player_connect(&player_id) 573 .await 574 .map_err(|e| format!("Could not run PlayerConnect(): {}. Exiting!", e))?; 575 if added { 576 println!("Added player"); 577 } else { 578 panic!("rust_async: Failed to add player. Exiting!"); 579 } 580 581 let connected = alpha 582 .is_player_connected(&player_id) 583 .await 584 .map_err(|e| format!("Could not run IsPlayerConnected(): {}. Exiting!", e))?; 585 if connected { 586 println!("rust_async: {} is connected", player_id); 587 } else { 588 panic!("rust_async: {} is not connected. Exiting!", player_id); 589 } 590 591 let player_ids = alpha 592 .get_connected_players() 593 .await 594 .map_err(|e| format!("Could not run GetConnectedPlayers(): {}. Exiting!", e))?; 595 println!("rust_async: Connected players: {:?}", player_ids); 596 597 let player_count = alpha 598 .get_player_count() 599 .await 600 .map_err(|e| format!("Could not run GetConnectedPlayers(): {}. Exiting!", e))?; 601 println!("rust_async: Current player count: {}", player_count); 602 603 println!("rust_async: Decreasing the player count..."); 604 let removed = alpha 605 .player_disconnect(&player_id) 606 .await 607 .map_err(|e| format!("Could not run PlayerDisconnect(): {}. Exiting!", e))?; 608 if removed { 609 println!("rust_async: Removed player"); 610 } else { 611 panic!("rust_async: Failed to remove player. Exiting!"); 612 } 613 614 let player_count = alpha 615 .get_player_count() 616 .await 617 .map_err(|e| format!("Could not GetPlayerCount(): {}. Exiting!", e))?; 618 println!("rust_async: Current player count: {}", player_count); 619 620 Ok(()) 621 } 622 623 async fn run_counts_and_lists_features_async(mut beta: agones::beta::Beta) -> Result<(), String> { 624 // Counter tests 625 let counter = "rooms"; 626 println!("rust_async: Getting Counter count..."); 627 let count = beta.get_counter_count(counter) 628 .await 629 .map_err(|e| format!("Could not run GetCounterCount(): {}. Exiting!", e))?; 630 if count != 1 { 631 return Err(format!("Counter count should be 1, but is {}", count)); 632 } 633 634 println!("rust_async: Incrementing Counter..."); 635 beta.increment_counter(counter, 9) 636 .await 637 .map_err(|e| format!("Could not run IncrementCounter(): {}. Exiting!", e))?; 638 639 println!("rust_async: Decrementing Counter..."); 640 beta.decrement_counter(counter, 10) 641 .await 642 .map_err(|e| format!("Could not run DecrementCounter(): {}. Exiting!", e))?; 643 644 println!("rust_async: Setting Counter count..."); 645 beta.set_counter_count(counter, 10) 646 .await 647 .map_err(|e| format!("Could not run SetCounterCount(): {}. Exiting!", e))?; 648 649 println!("rust_async: Getting Counter capacity..."); 650 let capacity = beta.get_counter_capacity(counter) 651 .await 652 .map_err(|e| format!("Could not run GetCounterCapacity(): {}. Exiting!", e))?; 653 if capacity != 10 { 654 return Err(format!("Counter capacity should be 10, but is {}", capacity)); 655 } 656 657 println!("rust_async: Setting Counter capacity..."); 658 beta.set_counter_capacity(counter, 1) 659 .await 660 .map_err(|e| format!("Could not run SetCounterCapacity(): {}. Exiting!", e))?; 661 662 // List tests 663 let list = "players"; 664 let vals = vec!["test0".to_string(), "test1".to_string(), "test2".to_string()]; 665 666 println!("rust_async: Checking if List contains 'test1'..."); 667 let contains = beta.list_contains(list, "test1") 668 .await 669 .map_err(|e| format!("Could not run ListContains(): {}. Exiting!", e))?; 670 if !contains { 671 return Err("List should contain value \"test1\"".to_string()); 672 } 673 674 println!("rust_async: Getting List length..."); 675 let length = beta.get_list_length(list) 676 .await 677 .map_err(|e| format!("Could not run GetListLength(): {}. Exiting!", e))?; 678 if length != 3 { 679 return Err(format!("List length should be 3, but is {}", length)); 680 } 681 682 println!("rust_async: Getting List values..."); 683 let values = beta.get_list_values(list) 684 .await 685 .map_err(|e| format!("Could not run GetListValues(): {}. Exiting!", e))?; 686 if values != vals { 687 return Err(format!("List values should be {:?}, but is {:?}", vals, values)); 688 } 689 690 println!("rust_async: Appending value 'test3' to List..."); 691 beta.append_list_value(list, "test3") 692 .await 693 .map_err(|e| format!("Could not run AppendListValue(): {}. Exiting!", e))?; 694 695 println!("rust_async: Deleting value 'test2' from List..."); 696 beta.delete_list_value(list, "test2") 697 .await 698 .map_err(|e| format!("Could not run DeleteListValue(): {}. Exiting!", e))?; 699 700 println!("rust_async: Getting List capacity..."); 701 let list_capacity = beta.get_list_capacity(list) 702 .await 703 .map_err(|e| format!("Could not run GetListCapacity(): {}. Exiting!", e))?; 704 if list_capacity != 100 { 705 return Err(format!("List capacity should be 100, but is {}", list_capacity)); 706 } 707 708 println!("rust_async: Setting List capacity to 2..."); 709 beta.set_list_capacity(list, 2) 710 .await 711 .map_err(|e| format!("Could not run SetListCapacity(): {}. Exiting!", e))?; 712 713 Ok(()) 714 }