agones.dev/agones@v1.53.0/examples/rust-simple/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::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!("{}", msg);
    28              1
    29          }
    30      });
    31  }
    32  
    33  async fn run() -> Result<(), String> {
    34      println!("Creating SDK instance");
    35      let mut sdk = agones::Sdk::new(None /* default port */, None /* keep_alive */)
    36          .await
    37          .map_err(|e| format!("unable to create sdk client: {}", e))?;
    38  
    39      // Spawn a task that will send health checks every 2 seconds. If this current
    40      // thread/task panics or dropped, the health check will also be stopped
    41      let _health = {
    42          let health_tx = sdk.health_check();
    43          let (tx, mut rx) = tokio::sync::oneshot::channel::<()>();
    44  
    45          tokio::task::spawn(async move {
    46              let mut interval = tokio::time::interval(Duration::from_secs(2));
    47  
    48              loop {
    49                  tokio::select! {
    50                      _ = interval.tick() => {
    51                          if health_tx
    52                              .send(())
    53                              .await.is_err() {
    54                              eprintln!("Health check receiver was dropped");
    55                              break;
    56                          }
    57                      }
    58                      _ = &mut rx => {
    59                          println!("Health check task canceled");
    60                          break;
    61                      }
    62                  }
    63              }
    64          });
    65  
    66          tx
    67      };
    68  
    69      let _watch = {
    70          let mut watch_client = sdk.clone();
    71          let (tx, mut rx) = tokio::sync::oneshot::channel::<()>();
    72  
    73          tokio::task::spawn(async move {
    74              println!("Starting to watch GameServer updates...");
    75              match watch_client.watch_gameserver().await {
    76                  Err(e) => println!("Failed to watch for GameServer updates: {}", e),
    77                  Ok(mut stream) => loop {
    78                      tokio::select! {
    79                          gs = stream.message() => {
    80                              match gs {
    81                                  Ok(Some(gs)) => {
    82                                      println!("GameServer Update, name: {}", gs.object_meta.unwrap().name);
    83                                      println!("GameServer Update, state: {}", gs.status.unwrap().state);
    84                                  }
    85                                  Ok(None) => {
    86                                      println!("Server closed the GameServer watch stream");
    87                                      break;
    88                                  }
    89                                  Err(e) => {
    90                                      eprintln!("GameServer Update stream encountered an error: {}", e);
    91                                  }
    92                              }
    93  
    94                          }
    95                          _ = &mut rx => {
    96                              println!("Shutting down GameServer watch loop");
    97                              break;
    98                          }
    99                      }
   100                  },
   101              }
   102          });
   103  
   104          tx
   105      };
   106  
   107      println!("Setting a label");
   108      sdk.set_label("test-label", "test-value")
   109          .await
   110          .map_err(|e| format!("Could not run SetLabel(): {}. Exiting!", e))?;
   111  
   112      println!("Setting an annotation");
   113      sdk.set_annotation("test-annotation", "test value")
   114          .await
   115          .map_err(|e| format!("Could not run SetAnnotation(): {}. Exiting!", e))?;
   116  
   117      println!("Marking server as ready...");
   118      sdk.ready()
   119          .await
   120          .map_err(|e| format!("Could not run Ready(): {}. Exiting!", e))?;
   121  
   122      println!("...marked Ready");
   123  
   124      println!("Setting as Reserved for 5 seconds");
   125      sdk.reserve(Duration::from_secs(5))
   126          .await
   127          .map_err(|e| format!("Could not run Reserve(): {}. Exiting!", e))?;
   128      println!("...Reserved");
   129  
   130      tokio::time::sleep(Duration::from_secs(6)).await;
   131  
   132      println!("Getting GameServer details...");
   133      let gameserver = sdk
   134          .get_gameserver()
   135          .await
   136          .map_err(|e| format!("Could not run GameServer(): {}. Exiting!", e))?;
   137  
   138      println!("GameServer name: {}", gameserver.object_meta.unwrap().name);
   139  
   140      for i in 0..10 {
   141          let time = i * 10;
   142          println!("Running for {} seconds", time);
   143  
   144          tokio::time::sleep(Duration::from_secs(10)).await;
   145  
   146          if i == 5 {
   147              println!("Shutting down after 60 seconds...");
   148              sdk.shutdown()
   149                  .await
   150                  .map_err(|e| format!("Could not run Shutdown: {}. Exiting!", e))?;
   151              println!("...marked for Shutdown");
   152          }
   153      }
   154  
   155      Ok(())
   156  }