From cc380792097fef31c93863dea1fb2f582ae25fc4 Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Tue, 25 May 2021 10:37:32 +0200 Subject: [PATCH 01/24] Begin replacing grpio with tonic --- sdks/rust/Cargo.toml | 24 +- sdks/rust/build.rs | 11 + sdks/rust/proto/allocation/allocation.proto | 92 +++++ .../googleapis/google/api/annotations.proto | 31 ++ .../proto/googleapis/google/api/http.proto | 318 ++++++++++++++++++ sdks/rust/proto/sdk/alpha/alpha.proto | 138 ++++++++ sdks/rust/proto/sdk/beta/beta.proto | 23 ++ sdks/rust/proto/sdk/sdk.proto | 162 +++++++++ 8 files changed, 793 insertions(+), 6 deletions(-) create mode 100644 sdks/rust/build.rs create mode 100644 sdks/rust/proto/allocation/allocation.proto create mode 100644 sdks/rust/proto/googleapis/google/api/annotations.proto create mode 100644 sdks/rust/proto/googleapis/google/api/http.proto create mode 100644 sdks/rust/proto/sdk/alpha/alpha.proto create mode 100644 sdks/rust/proto/sdk/beta/beta.proto create mode 100644 sdks/rust/proto/sdk/sdk.proto diff --git a/sdks/rust/Cargo.toml b/sdks/rust/Cargo.toml index c1f8de34f6..dff9cf15b3 100644 --- a/sdks/rust/Cargo.toml +++ b/sdks/rust/Cargo.toml @@ -18,12 +18,24 @@ version = "0.1.0" edition = "2018" [features] -openssl = ["grpcio/openssl"] -openssl-vendored = ["grpcio/openssl-vendored"] +tls = ["tonic/tls"] [dependencies] -grpcio = "0.6.0" -protobuf = "2.16.2" -futures = { version = "0.3", features = ["compat"] } -futures01 = "0.1" error-chain = "0.12.3" + +[dependencies.tonic] +version = "0.4" +default-features = false +features = [ + "codegen", + "transport", + "prost", +] + +[build-dependencies.tonic-build] +version = "0.4" +default-features = false +features = [ + "prost", + "transport", +] \ No newline at end of file diff --git a/sdks/rust/build.rs b/sdks/rust/build.rs new file mode 100644 index 0000000000..be4297bebb --- /dev/null +++ b/sdks/rust/build.rs @@ -0,0 +1,11 @@ +fn main() { + println!("cargo:rerun-if-changed=build.rs"); + println!("cargo:rerun-if-changed=protos"); + + tonic_build::configure() + .compile( + &["proto/sdk/alpha/alpha.proto", "proto/sdk/sdk.proto"], + &["proto/googleapis", "proto/sdk/alpha", "proto/sdk"], + ) + .expect("failed to compile protobuffers"); +} diff --git a/sdks/rust/proto/allocation/allocation.proto b/sdks/rust/proto/allocation/allocation.proto new file mode 100644 index 0000000000..79015130b2 --- /dev/null +++ b/sdks/rust/proto/allocation/allocation.proto @@ -0,0 +1,92 @@ +// Copyright 2020 Google LLC All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package allocation; + +import "google/api/annotations.proto"; + +service AllocationService { + rpc Allocate(AllocationRequest) returns (AllocationResponse) { + option (google.api.http) = { + post: "/gameserverallocation" + body: "*" + }; + } +} + +message AllocationRequest { + // The k8s namespace that is hosting the targeted fleet of gameservers to be allocated + string namespace = 1; + + // If specified, multi-cluster policies are applied. Otherwise, allocation will happen locally. + MultiClusterSetting multiClusterSetting = 2; + + // The required allocation. Defaults to all GameServers. + LabelSelector requiredGameServerSelector = 3; + + // The ordered list of preferred allocations out of the `required` set. + // If the first selector is not matched, the selection attempts the second selector, and so on. + repeated LabelSelector preferredGameServerSelectors = 4; + + // Scheduling strategy. Defaults to "Packed". + SchedulingStrategy scheduling = 5; + enum SchedulingStrategy { + Packed = 0; + Distributed = 1; + } + + // Deprecated: Please use metadata instead. This field is ignored if the + // metadata field is set + MetaPatch metaPatch = 6; + + // Metadata is optional custom metadata that is added to the game server at + // allocation. You can use this to tell the server necessary session data + MetaPatch metadata = 7; +} + +message AllocationResponse { + string gameServerName = 2; + repeated GameServerStatusPort ports = 3; + string address = 4; + string nodeName = 5; + + // The gameserver port info that is allocated. + message GameServerStatusPort { + string name = 1; + int32 port = 2; + } +} + +// Specifies settings for multi-cluster allocation. +message MultiClusterSetting { + // If set to true, multi-cluster allocation is enabled. + bool enabled = 1; + + // Selects multi-cluster allocation policies to apply. If not specified, all multi-cluster allocation policies are to be applied. + LabelSelector policySelector = 2; +} + +// MetaPatch is the metadata used to patch the GameServer metadata on allocation +message MetaPatch { + map labels = 1; + map annotations = 2; +} + +// LabelSelector used for finding a GameServer with matching labels. +message LabelSelector { + // Labels to match. + map matchLabels = 1; +} \ No newline at end of file diff --git a/sdks/rust/proto/googleapis/google/api/annotations.proto b/sdks/rust/proto/googleapis/google/api/annotations.proto new file mode 100644 index 0000000000..85c361b47f --- /dev/null +++ b/sdks/rust/proto/googleapis/google/api/annotations.proto @@ -0,0 +1,31 @@ +// Copyright (c) 2015, Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +import "google/api/http.proto"; +import "google/protobuf/descriptor.proto"; + +option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; +option java_multiple_files = true; +option java_outer_classname = "AnnotationsProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +extend google.protobuf.MethodOptions { + // See `HttpRule`. + HttpRule http = 72295728; +} diff --git a/sdks/rust/proto/googleapis/google/api/http.proto b/sdks/rust/proto/googleapis/google/api/http.proto new file mode 100644 index 0000000000..2bd3a19bfa --- /dev/null +++ b/sdks/rust/proto/googleapis/google/api/http.proto @@ -0,0 +1,318 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +option cc_enable_arenas = true; +option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; +option java_multiple_files = true; +option java_outer_classname = "HttpProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + + +// Defines the HTTP configuration for an API service. It contains a list of +// [HttpRule][google.api.HttpRule], each specifying the mapping of an RPC method +// to one or more HTTP REST API methods. +message Http { + // A list of HTTP configuration rules that apply to individual API methods. + // + // **NOTE:** All service configuration rules follow "last one wins" order. + repeated HttpRule rules = 1; + + // When set to true, URL path parmeters will be fully URI-decoded except in + // cases of single segment matches in reserved expansion, where "%2F" will be + // left encoded. + // + // The default behavior is to not decode RFC 6570 reserved characters in multi + // segment matches. + bool fully_decode_reserved_expansion = 2; +} + +// `HttpRule` defines the mapping of an RPC method to one or more HTTP +// REST API methods. The mapping specifies how different portions of the RPC +// request message are mapped to URL path, URL query parameters, and +// HTTP request body. The mapping is typically specified as an +// `google.api.http` annotation on the RPC method, +// see "google/api/annotations.proto" for details. +// +// The mapping consists of a field specifying the path template and +// method kind. The path template can refer to fields in the request +// message, as in the example below which describes a REST GET +// operation on a resource collection of messages: +// +// +// service Messaging { +// rpc GetMessage(GetMessageRequest) returns (Message) { +// option (google.api.http).get = "/v1/messages/{message_id}/{sub.subfield}"; +// } +// } +// message GetMessageRequest { +// message SubMessage { +// string subfield = 1; +// } +// string message_id = 1; // mapped to the URL +// SubMessage sub = 2; // `sub.subfield` is url-mapped +// } +// message Message { +// string text = 1; // content of the resource +// } +// +// The same http annotation can alternatively be expressed inside the +// `GRPC API Configuration` YAML file. +// +// http: +// rules: +// - selector: .Messaging.GetMessage +// get: /v1/messages/{message_id}/{sub.subfield} +// +// This definition enables an automatic, bidrectional mapping of HTTP +// JSON to RPC. Example: +// +// HTTP | RPC +// -----|----- +// `GET /v1/messages/123456/foo` | `GetMessage(message_id: "123456" sub: SubMessage(subfield: "foo"))` +// +// In general, not only fields but also field paths can be referenced +// from a path pattern. Fields mapped to the path pattern cannot be +// repeated and must have a primitive (non-message) type. +// +// Any fields in the request message which are not bound by the path +// pattern automatically become (optional) HTTP query +// parameters. Assume the following definition of the request message: +// +// +// service Messaging { +// rpc GetMessage(GetMessageRequest) returns (Message) { +// option (google.api.http).get = "/v1/messages/{message_id}"; +// } +// } +// message GetMessageRequest { +// message SubMessage { +// string subfield = 1; +// } +// string message_id = 1; // mapped to the URL +// int64 revision = 2; // becomes a parameter +// SubMessage sub = 3; // `sub.subfield` becomes a parameter +// } +// +// +// This enables a HTTP JSON to RPC mapping as below: +// +// HTTP | RPC +// -----|----- +// `GET /v1/messages/123456?revision=2&sub.subfield=foo` | `GetMessage(message_id: "123456" revision: 2 sub: SubMessage(subfield: "foo"))` +// +// Note that fields which are mapped to HTTP parameters must have a +// primitive type or a repeated primitive type. Message types are not +// allowed. In the case of a repeated type, the parameter can be +// repeated in the URL, as in `...?param=A¶m=B`. +// +// For HTTP method kinds which allow a request body, the `body` field +// specifies the mapping. Consider a REST update method on the +// message resource collection: +// +// +// service Messaging { +// rpc UpdateMessage(UpdateMessageRequest) returns (Message) { +// option (google.api.http) = { +// put: "/v1/messages/{message_id}" +// body: "message" +// }; +// } +// } +// message UpdateMessageRequest { +// string message_id = 1; // mapped to the URL +// Message message = 2; // mapped to the body +// } +// +// +// The following HTTP JSON to RPC mapping is enabled, where the +// representation of the JSON in the request body is determined by +// protos JSON encoding: +// +// HTTP | RPC +// -----|----- +// `PUT /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: "123456" message { text: "Hi!" })` +// +// The special name `*` can be used in the body mapping to define that +// every field not bound by the path template should be mapped to the +// request body. This enables the following alternative definition of +// the update method: +// +// service Messaging { +// rpc UpdateMessage(Message) returns (Message) { +// option (google.api.http) = { +// put: "/v1/messages/{message_id}" +// body: "*" +// }; +// } +// } +// message Message { +// string message_id = 1; +// string text = 2; +// } +// +// +// The following HTTP JSON to RPC mapping is enabled: +// +// HTTP | RPC +// -----|----- +// `PUT /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: "123456" text: "Hi!")` +// +// Note that when using `*` in the body mapping, it is not possible to +// have HTTP parameters, as all fields not bound by the path end in +// the body. This makes this option more rarely used in practice of +// defining REST APIs. The common usage of `*` is in custom methods +// which don't use the URL at all for transferring data. +// +// It is possible to define multiple HTTP methods for one RPC by using +// the `additional_bindings` option. Example: +// +// service Messaging { +// rpc GetMessage(GetMessageRequest) returns (Message) { +// option (google.api.http) = { +// get: "/v1/messages/{message_id}" +// additional_bindings { +// get: "/v1/users/{user_id}/messages/{message_id}" +// } +// }; +// } +// } +// message GetMessageRequest { +// string message_id = 1; +// string user_id = 2; +// } +// +// +// This enables the following two alternative HTTP JSON to RPC +// mappings: +// +// HTTP | RPC +// -----|----- +// `GET /v1/messages/123456` | `GetMessage(message_id: "123456")` +// `GET /v1/users/me/messages/123456` | `GetMessage(user_id: "me" message_id: "123456")` +// +// # Rules for HTTP mapping +// +// The rules for mapping HTTP path, query parameters, and body fields +// to the request message are as follows: +// +// 1. The `body` field specifies either `*` or a field path, or is +// omitted. If omitted, it indicates there is no HTTP request body. +// 2. Leaf fields (recursive expansion of nested messages in the +// request) can be classified into three types: +// (a) Matched in the URL template. +// (b) Covered by body (if body is `*`, everything except (a) fields; +// else everything under the body field) +// (c) All other fields. +// 3. URL query parameters found in the HTTP request are mapped to (c) fields. +// 4. Any body sent with an HTTP request can contain only (b) fields. +// +// The syntax of the path template is as follows: +// +// Template = "/" Segments [ Verb ] ; +// Segments = Segment { "/" Segment } ; +// Segment = "*" | "**" | LITERAL | Variable ; +// Variable = "{" FieldPath [ "=" Segments ] "}" ; +// FieldPath = IDENT { "." IDENT } ; +// Verb = ":" LITERAL ; +// +// The syntax `*` matches a single path segment. The syntax `**` matches zero +// or more path segments, which must be the last part of the path except the +// `Verb`. The syntax `LITERAL` matches literal text in the path. +// +// The syntax `Variable` matches part of the URL path as specified by its +// template. A variable template must not contain other variables. If a variable +// matches a single path segment, its template may be omitted, e.g. `{var}` +// is equivalent to `{var=*}`. +// +// If a variable contains exactly one path segment, such as `"{var}"` or +// `"{var=*}"`, when such a variable is expanded into a URL path, all characters +// except `[-_.~0-9a-zA-Z]` are percent-encoded. Such variables show up in the +// Discovery Document as `{var}`. +// +// If a variable contains one or more path segments, such as `"{var=foo/*}"` +// or `"{var=**}"`, when such a variable is expanded into a URL path, all +// characters except `[-_.~/0-9a-zA-Z]` are percent-encoded. Such variables +// show up in the Discovery Document as `{+var}`. +// +// NOTE: While the single segment variable matches the semantics of +// [RFC 6570](https://tools.ietf.org/html/rfc6570) Section 3.2.2 +// Simple String Expansion, the multi segment variable **does not** match +// RFC 6570 Reserved Expansion. The reason is that the Reserved Expansion +// does not expand special characters like `?` and `#`, which would lead +// to invalid URLs. +// +// NOTE: the field paths in variables and in the `body` must not refer to +// repeated fields or map fields. +message HttpRule { + // Selects methods to which this rule applies. + // + // Refer to [selector][google.api.DocumentationRule.selector] for syntax details. + string selector = 1; + + // Determines the URL pattern is matched by this rules. This pattern can be + // used with any of the {get|put|post|delete|patch} methods. A custom method + // can be defined using the 'custom' field. + oneof pattern { + // Used for listing and getting information about resources. + string get = 2; + + // Used for updating a resource. + string put = 3; + + // Used for creating a resource. + string post = 4; + + // Used for deleting a resource. + string delete = 5; + + // Used for updating a resource. + string patch = 6; + + // The custom pattern is used for specifying an HTTP method that is not + // included in the `pattern` field, such as HEAD, or "*" to leave the + // HTTP method unspecified for this rule. The wild-card rule is useful + // for services that provide content to Web (HTML) clients. + CustomHttpPattern custom = 8; + } + + // The name of the request field whose value is mapped to the HTTP body, or + // `*` for mapping all fields not captured by the path pattern to the HTTP + // body. NOTE: the referred field must not be a repeated field and must be + // present at the top-level of request message type. + string body = 7; + + // Optional. The name of the response field whose value is mapped to the HTTP + // body of response. Other response fields are ignored. When + // not set, the response message will be used as HTTP body of response. + string response_body = 12; + + // Additional HTTP bindings for the selector. Nested bindings must + // not contain an `additional_bindings` field themselves (that is, + // the nesting may only be one level deep). + repeated HttpRule additional_bindings = 11; +} + +// A custom pattern is used for defining custom HTTP verb. +message CustomHttpPattern { + // The name of this custom HTTP verb. + string kind = 1; + + // The path matched by this custom verb. + string path = 2; +} diff --git a/sdks/rust/proto/sdk/alpha/alpha.proto b/sdks/rust/proto/sdk/alpha/alpha.proto new file mode 100644 index 0000000000..b9f2bb6524 --- /dev/null +++ b/sdks/rust/proto/sdk/alpha/alpha.proto @@ -0,0 +1,138 @@ +// Copyright 2020 Google LLC All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package agones.dev.sdk.alpha; +option go_package = "alpha"; + +import "google/api/annotations.proto"; + +// SDK service to be used in the GameServer SDK to the Pod Sidecar. +service SDK { + // PlayerConnect increases the SDK’s stored player count by one, and appends this playerID to GameServer.Status.Players.IDs. + // + // GameServer.Status.Players.Count and GameServer.Status.Players.IDs are then set to update the player count and id list a second from now, + // unless there is already an update pending, in which case the update joins that batch operation. + // + // PlayerConnect returns true and adds the playerID to the list of playerIDs if this playerID was not already in the + // list of connected playerIDs. + // + // If the playerID exists within the list of connected playerIDs, PlayerConnect will return false, and the list of + // connected playerIDs will be left unchanged. + // + // An error will be returned if the playerID was not already in the list of connected playerIDs but the player capacity for + // the server has been reached. The playerID will not be added to the list of playerIDs. + // + // Warning: Do not use this method if you are manually managing GameServer.Status.Players.IDs and GameServer.Status.Players.Count + // through the Kubernetes API, as indeterminate results will occur. + rpc PlayerConnect (PlayerID) returns (Bool) { + option (google.api.http) = { + post: "/alpha/player/connect" + body: "*" + }; + } + + // Decreases the SDK’s stored player count by one, and removes the playerID from GameServer.Status.Players.IDs. + // + // GameServer.Status.Players.Count and GameServer.Status.Players.IDs are then set to update the player count and id list a second from now, + // unless there is already an update pending, in which case the update joins that batch operation. + // + // PlayerDisconnect will return true and remove the supplied playerID from the list of connected playerIDs if the + // playerID value exists within the list. + // + // If the playerID was not in the list of connected playerIDs, the call will return false, and the connected playerID list + // will be left unchanged. + // + // Warning: Do not use this method if you are manually managing GameServer.status.players.IDs and GameServer.status.players.Count + // through the Kubernetes API, as indeterminate results will occur. + rpc PlayerDisconnect (PlayerID) returns (Bool) { + option (google.api.http) = { + post: "/alpha/player/disconnect" + body: "*" + }; + } + + // Update the GameServer.Status.Players.Capacity value with a new capacity. + rpc SetPlayerCapacity (Count) returns (Empty) { + option (google.api.http) = { + put: "/alpha/player/capacity" + body: "*" + }; + } + + // Retrieves the current player capacity. This is always accurate from what has been set through this SDK, + // even if the value has yet to be updated on the GameServer status resource. + // + // If GameServer.Status.Players.Capacity is set manually through the Kubernetes API, use SDK.GameServer() or SDK.WatchGameServer() instead to view this value. + rpc GetPlayerCapacity (Empty) returns (Count) { + option (google.api.http) = { + get: "/alpha/player/capacity" + }; + } + + // Retrieves the current player count. This is always accurate from what has been set through this SDK, + // even if the value has yet to be updated on the GameServer status resource. + // + // If GameServer.Status.Players.Count is set manually through the Kubernetes API, use SDK.GameServer() or SDK.WatchGameServer() instead to view this value. + rpc GetPlayerCount (Empty) returns (Count) { + option (google.api.http) = { + get: "/alpha/player/count" + }; + } + + // Returns if the playerID is currently connected to the GameServer. This is always accurate from what has been set through this SDK, + // even if the value has yet to be updated on the GameServer status resource. + // + // If GameServer.Status.Players.IDs is set manually through the Kubernetes API, use SDK.GameServer() or SDK.WatchGameServer() instead to determine connected status. + rpc IsPlayerConnected (PlayerID) returns (Bool) { + option (google.api.http) = { + get: "/alpha/player/connected/{playerID}" + }; + } + + // Returns the list of the currently connected player ids. This is always accurate from what has been set through this SDK, + // even if the value has yet to be updated on the GameServer status resource. + // + // If GameServer.Status.Players.IDs is set manually through the Kubernetes API, use SDK.GameServer() or SDK.WatchGameServer() instead to view this value. + rpc GetConnectedPlayers(Empty) returns (PlayerIDList) { + option (google.api.http) = { + get: "/alpha/player/connected" + }; + } +} + +// I am Empty +message Empty { +} + +// Store a count variable. +message Count { + int64 count = 1; +} + +// Store a boolean result +message Bool { + bool bool = 1; +} + +// The unique identifier for a given player. +message PlayerID { + string playerID = 1; +} + +// List of Player IDs +message PlayerIDList { + repeated string list = 1; +} \ No newline at end of file diff --git a/sdks/rust/proto/sdk/beta/beta.proto b/sdks/rust/proto/sdk/beta/beta.proto new file mode 100644 index 0000000000..d55fbabdb6 --- /dev/null +++ b/sdks/rust/proto/sdk/beta/beta.proto @@ -0,0 +1,23 @@ +// Copyright 2020 Google LLC All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package agones.dev.sdk.beta; +option go_package = "beta"; + +import "google/api/annotations.proto"; + +// SDK service to be used in the GameServer SDK to the Pod Sidecar +service SDK {} \ No newline at end of file diff --git a/sdks/rust/proto/sdk/sdk.proto b/sdks/rust/proto/sdk/sdk.proto new file mode 100644 index 0000000000..0d7c65d299 --- /dev/null +++ b/sdks/rust/proto/sdk/sdk.proto @@ -0,0 +1,162 @@ +// Copyright 2017 Google LLC All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package agones.dev.sdk; +option go_package = "sdk"; + +import "google/api/annotations.proto"; + +// SDK service to be used in the GameServer SDK to the Pod Sidecar +service SDK { + // Call when the GameServer is ready + rpc Ready (Empty) returns (Empty) { + option (google.api.http) = { + post: "/ready" + body: "*" + }; + } + + // Call to self Allocation the GameServer + rpc Allocate(Empty) returns (Empty) { + option (google.api.http) = { + post: "/allocate" + body: "*" + }; + } + + // Call when the GameServer is shutting down + rpc Shutdown (Empty) returns (Empty) { + option (google.api.http) = { + post: "/shutdown" + body: "*" + }; + } + // Send a Empty every d Duration to declare that this GameSever is healthy + rpc Health (stream Empty) returns (Empty) { + option (google.api.http) = { + post: "/health" + body: "*" + }; + } + // Retrieve the current GameServer data + rpc GetGameServer (Empty) returns (GameServer) { + option (google.api.http) = { + get: "/gameserver" + }; + } + // Send GameServer details whenever the GameServer is updated + rpc WatchGameServer (Empty) returns (stream GameServer) { + option (google.api.http) = { + get: "/watch/gameserver" + }; + } + + // Apply a Label to the backing GameServer metadata + rpc SetLabel(KeyValue) returns (Empty) { + option (google.api.http) = { + put: "/metadata/label" + body: "*" + }; + } + + // Apply a Annotation to the backing GameServer metadata + rpc SetAnnotation(KeyValue) returns (Empty) { + option (google.api.http) = { + put: "/metadata/annotation" + body: "*" + }; + } + + // Marks the GameServer as the Reserved state for Duration + rpc Reserve(Duration) returns (Empty) { + option (google.api.http) = { + post: "/reserve" + body: "*" + }; + } +} + +// I am Empty +message Empty { +} + +// Key, Value entry +message KeyValue { + string key = 1; + string value = 2; +} + +// time duration, in seconds +message Duration { + int64 seconds = 1; +} + +// A GameServer Custom Resource Definition object +// We will only export those resources that make the most +// sense. Can always expand to more as needed. +message GameServer { + ObjectMeta object_meta = 1; + Spec spec = 2; + Status status = 3; + + // representation of the K8s ObjectMeta resource + message ObjectMeta { + string name = 1; + string namespace = 2; + string uid = 3; + string resource_version = 4; + int64 generation = 5; + // timestamp is in Epoch format, unit: seconds + int64 creation_timestamp = 6; + // optional deletion timestamp in Epoch format, unit: seconds + int64 deletion_timestamp = 7; + map annotations = 8; + map labels = 9; + } + + message Spec { + Health health = 1; + + message Health { + bool disabled = 1; + int32 period_seconds = 2; + int32 failure_threshold = 3; + int32 initial_delay_seconds = 4; + } + } + + message Status { + message Port { + string name = 1; + int32 port = 2; + } + // [Stage:Alpha] + // [FeatureFlag:PlayerTracking] + message PlayerStatus { + int64 count = 1; + int64 capacity = 2; + repeated string ids = 3; + } + + string state = 1; + string address = 2; + repeated Port ports = 3; + + // [Stage:Alpha] + // [FeatureFlag:PlayerTracking] + PlayerStatus players = 4; + } +} From 5085d9bc48cf27ac23b8ea69b040a1eef2e7e14e Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Wed, 26 May 2021 09:17:09 +0200 Subject: [PATCH 02/24] "Finish" porting to tonic --- sdks/rust/Cargo.toml | 13 +- sdks/rust/build.rs | 2 + sdks/rust/proto/sdk/alpha/alpha.proto | 2 +- sdks/rust/proto/sdk/sdk.proto | 21 +- sdks/rust/src/alpha.rs | 218 +- sdks/rust/src/errors.rs | 22 +- sdks/rust/src/grpc/alpha.rs | 951 --------- sdks/rust/src/grpc/alpha_grpc.rs | 254 --- sdks/rust/src/grpc/mod.rs | 18 - sdks/rust/src/grpc/sdk.rs | 2694 ------------------------- sdks/rust/src/grpc/sdk_grpc.rs | 294 --- sdks/rust/src/lib.rs | 4 - sdks/rust/src/sdk.rs | 435 ++-- sdks/rust/src/types.rs | 166 -- 14 files changed, 245 insertions(+), 4849 deletions(-) delete mode 100644 sdks/rust/src/grpc/alpha.rs delete mode 100644 sdks/rust/src/grpc/alpha_grpc.rs delete mode 100644 sdks/rust/src/grpc/mod.rs delete mode 100644 sdks/rust/src/grpc/sdk.rs delete mode 100644 sdks/rust/src/grpc/sdk_grpc.rs delete mode 100644 sdks/rust/src/types.rs diff --git a/sdks/rust/Cargo.toml b/sdks/rust/Cargo.toml index dff9cf15b3..19fbdb8ef2 100644 --- a/sdks/rust/Cargo.toml +++ b/sdks/rust/Cargo.toml @@ -17,11 +17,16 @@ name = "agones" version = "0.1.0" edition = "2018" -[features] -tls = ["tonic/tls"] - [dependencies] -error-chain = "0.12.3" +async-stream = "0.3" +http = "0.2" +prost = "0.7" +thiserror = "1.0" + +[dependencies.tokio] +version = "1.0" +default-features = false +features = ["sync", "time"] [dependencies.tonic] version = "0.4" diff --git a/sdks/rust/build.rs b/sdks/rust/build.rs index be4297bebb..402691cfc8 100644 --- a/sdks/rust/build.rs +++ b/sdks/rust/build.rs @@ -3,6 +3,8 @@ fn main() { println!("cargo:rerun-if-changed=protos"); tonic_build::configure() + // The SDK is just a client, no need to build the server types + .build_server(false) .compile( &["proto/sdk/alpha/alpha.proto", "proto/sdk/sdk.proto"], &["proto/googleapis", "proto/sdk/alpha", "proto/sdk"], diff --git a/sdks/rust/proto/sdk/alpha/alpha.proto b/sdks/rust/proto/sdk/alpha/alpha.proto index b9f2bb6524..7811e0903b 100644 --- a/sdks/rust/proto/sdk/alpha/alpha.proto +++ b/sdks/rust/proto/sdk/alpha/alpha.proto @@ -135,4 +135,4 @@ message PlayerID { // List of Player IDs message PlayerIDList { repeated string list = 1; -} \ No newline at end of file +} diff --git a/sdks/rust/proto/sdk/sdk.proto b/sdks/rust/proto/sdk/sdk.proto index 0d7c65d299..355729c9a0 100644 --- a/sdks/rust/proto/sdk/sdk.proto +++ b/sdks/rust/proto/sdk/sdk.proto @@ -44,19 +44,22 @@ service SDK { body: "*" }; } + // Send a Empty every d Duration to declare that this GameSever is healthy rpc Health (stream Empty) returns (Empty) { option (google.api.http) = { - post: "/health" - body: "*" - }; + post: "/health" + body: "*" + }; } + // Retrieve the current GameServer data rpc GetGameServer (Empty) returns (GameServer) { option (google.api.http) = { get: "/gameserver" }; } + // Send GameServer details whenever the GameServer is updated rpc WatchGameServer (Empty) returns (stream GameServer) { option (google.api.http) = { @@ -67,17 +70,17 @@ service SDK { // Apply a Label to the backing GameServer metadata rpc SetLabel(KeyValue) returns (Empty) { option (google.api.http) = { - put: "/metadata/label" - body: "*" - }; + put: "/metadata/label" + body: "*" + }; } // Apply a Annotation to the backing GameServer metadata rpc SetAnnotation(KeyValue) returns (Empty) { option (google.api.http) = { - put: "/metadata/annotation" - body: "*" - }; + put: "/metadata/annotation" + body: "*" + }; } // Marks the GameServer as the Reserved state for Duration diff --git a/sdks/rust/src/alpha.rs b/sdks/rust/src/alpha.rs index 10f4c39dfd..81098ec577 100644 --- a/sdks/rust/src/alpha.rs +++ b/sdks/rust/src/alpha.rs @@ -12,198 +12,116 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::sync::Arc; +use crate::errors::Result; +use tonic::transport::Channel; -use grpcio; +mod api { + tonic::include_proto!("agones.dev.sdk.alpha"); +} -use super::errors::*; -use super::grpc::alpha; -use super::grpc::alpha_grpc; +use api::sdk_client::SdkClient; /// Alpha is an instance of the Agones Alpha SDK +#[derive(Clone)] pub struct Alpha { - client: Arc, + client: SdkClient, } impl Alpha { /// new creates a new instance of the Alpha SDK - pub fn new(ch: grpcio::Channel) -> Alpha { - let cli = alpha_grpc::SdkClient::new(ch); - Alpha { - client: Arc::new(cli), + pub(crate) fn new(ch: Channel) -> Self { + Self { + client: SdkClient::new(ch), } } /// This returns the last player capacity that was set through the SDK. - /// If the player capacity is set from outside the SDK, use sdk.get_gameserver() instead. - pub fn get_player_capacity(&self) -> Result { - let req = alpha::Empty::new(); - let count = self.client.get_player_capacity(&req).map(|c| c.count)?; - Ok(count) - } - - /// This changes the player capacity to a new value. - pub fn set_player_capacity(&self, capacity: i64) -> Result<()> { - let mut c = alpha::Count::new(); - c.set_count(capacity); - let res = self.client.set_player_capacity(&c).map(|_| ())?; - Ok(res) - } - - /// This function increases the SDK’s stored player count by one, and appends this playerID to GameServer.status.players.ids. - /// Returns true and adds the playerID to the list of playerIDs if the playerIDs was not already in the list of connected playerIDs. - pub fn player_connect(&self, id: S) -> Result - where - S: Into, - { - let mut p = alpha::PlayerID::new(); - p.set_playerID(id.into()); - let res = self.client.player_connect(&p).map(|b| b.bool)?; - Ok(res) - } - - /// This function decreases the SDK’s stored player count by one, and removes the playerID from GameServer.status.players.ids. - /// Will return true and remove the supplied playerID from the list of connected playerIDs if the playerID value exists within the list. - pub fn player_disconnect(&self, id: S) -> Result - where - S: Into, - { - let mut p = alpha::PlayerID::new(); - p.set_playerID(id.into()); - let res = self.client.player_disconnect(&p).map(|b| b.bool)?; - Ok(res) - } - - /// Returns the current player count. - pub fn get_player_count(&self) -> Result { - let req = alpha::Empty::new(); - let count = self.client.get_player_count(&req).map(|c| c.count)?; - Ok(count) - } - - /// This returns if the playerID is currently connected to the GameServer. - /// This is always accurate, even if the value hasn’t been updated to the GameServer status yet. - pub fn is_player_connected(&self, id: S) -> Result - where - S: Into, - { - let mut p = alpha::PlayerID::new(); - p.set_playerID(id.into()); - let res = self.client.is_player_connected(&p).map(|b| b.bool)?; - Ok(res) - } - - /// This returns the list of the currently connected player ids. - /// This is always accurate, even if the value has not been updated to the Game Server status yet. - pub fn get_connected_players(&self) -> Result> { - let req = alpha::Empty::new(); - let res = self + /// If the player capacity is set from outside the SDK, use + /// [`Sdk::get_gameserver`] instead. + #[inline] + pub async fn get_player_capacity(&mut self) -> Result { + Ok(self .client - .get_connected_players(&req) - .map(|pl| pl.list.into())?; - Ok(res) - } - - /// This returns the last player capacity that was set through the SDK. - /// If the player capacity is set from outside the SDK, use sdk.get_gameserver() instead. - pub async fn get_player_capacity_async(&self) -> Result { - let req = alpha::Empty::new(); - let count = self - .client - .get_player_capacity_async(&req)? + .get_player_capacity(api::Empty {}) .await - .map(|c| c.count)?; - Ok(count) + .map(|c| c.into_inner().count)?) } /// This changes the player capacity to a new value. - pub async fn set_player_capacity_async(&self, capacity: i64) -> Result<()> { - let mut c = alpha::Count::new(); - c.set_count(capacity); - let res = self + #[inline] + pub async fn set_player_capacity(&mut self, count: i64) -> Result<()> { + Ok(self .client - .set_player_capacity_async(&c)? + .set_player_capacity(api::Count { count }) .await - .map(|_| ())?; - Ok(res) + .map(|_| ())?) } - /// This function increases the SDK’s stored player count by one, and appends this playerID to GameServer.status.players.ids. - /// Returns true and adds the playerID to the list of playerIDs if the playerIDs was not already in the list of connected playerIDs. - pub async fn player_connect_async(&self, id: S) -> Result - where - S: Into, - { - let mut p = alpha::PlayerID::new(); - p.set_playerID(id.into()); - let res = self + /// This function increases the SDK’s stored player count by one, and appends + /// this playerID to `GameServer.status.players.ids`. + /// + /// Returns true and adds the playerID to the list of playerIDs if the + /// playerIDs was not already in the list of connected playerIDs. + #[inline] + pub async fn player_connect(&mut self, id: impl Into) -> Result { + Ok(self .client - .player_connect_async(&p)? + .player_connect(api::PlayerId { + player_id: id.into(), + }) .await - .map(|b| b.bool)?; - Ok(res) + .map(|b| b.into_inner().bool)?) } - /// This function decreases the SDK’s stored player count by one, and removes the playerID from GameServer.status.players.ids. - /// Will return true and remove the supplied playerID from the list of connected playerIDs if the playerID value exists within the list. - pub async fn player_disconnect_async(&self, id: S) -> Result - where - S: Into, - { - let mut p = alpha::PlayerID::new(); - p.set_playerID(id.into()); - let res = self + /// This function decreases the SDK’s stored player count by one, and removes + /// the playerID from GameServer.status.players.ids. + /// + /// Will return true and remove the supplied playerID from the list of + /// connected playerIDs if the playerID value exists within the list. + #[inline] + pub async fn player_disconnect(&mut self, id: impl Into) -> Result { + Ok(self .client - .player_disconnect_async(&p)? + .player_disconnect(api::PlayerId { + player_id: id.into(), + }) .await - .map(|b| b.bool)?; - Ok(res) + .map(|b| b.into_inner().bool)?) } /// Returns the current player count. - pub async fn get_player_count_async(&self) -> Result { - let req = alpha::Empty::new(); - let count = self + #[inline] + pub async fn get_player_count(&mut self) -> Result { + Ok(self .client - .get_player_count_async(&req)? + .get_player_count(api::Empty {}) .await - .map(|c| c.count)?; - Ok(count) + .map(|c| c.into_inner().count)?) } /// This returns if the playerID is currently connected to the GameServer. - /// This is always accurate, even if the value hasn’t been updated to the GameServer status yet. - pub async fn is_player_connected_async(&self, id: S) -> Result - where - S: Into, - { - let mut p = alpha::PlayerID::new(); - p.set_playerID(id.into()); - let res = self + /// This is always accurate, even if the value hasn’t been updated to the + /// Game Server status yet. + #[inline] + pub async fn is_player_connected(&mut self, id: impl Into) -> Result { + Ok(self .client - .is_player_connected_async(&p)? + .is_player_connected(api::PlayerId { + player_id: id.into(), + }) .await - .map(|b| b.bool)?; - Ok(res) + .map(|b| b.into_inner().bool)?) } /// This returns the list of the currently connected player ids. - /// This is always accurate, even if the value has not been updated to the Game Server status yet. - pub async fn get_connected_players_async(&self) -> Result> { - let req = alpha::Empty::new(); - let res = self + /// This is always accurate, even if the value has not been updated to the + /// Game Server status yet. + #[inline] + pub async fn get_connected_players(&mut self) -> Result> { + Ok(self .client - .get_connected_players_async(&req)? + .get_connected_players(api::Empty {}) .await - .map(|pl| pl.list.into())?; - Ok(res) - } -} - -impl Clone for Alpha { - fn clone(&self) -> Self { - Self { - client: Arc::clone(&self.client), - } + .map(|pl| pl.into_inner().list)?) } } diff --git a/sdks/rust/src/errors.rs b/sdks/rust/src/errors.rs index f35cd6d2a2..e75bf52244 100644 --- a/sdks/rust/src/errors.rs +++ b/sdks/rust/src/errors.rs @@ -12,16 +12,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -// Wrap in a new error -error_chain! { - foreign_links { - Grpc(::grpcio::Error); - } +pub type Result = std::result::Result; - errors { - HealthPingConnectionFailure(t: String) { - description("health ping connection failure"), - display("health ping connection failure: '{}'", t), - } - } +#[derive(thiserror::Error, Debug)] +pub enum Error { + #[error("health ping connection failure: `{0}`")] + HealthPingConnectionFailure(String), + #[error("failed to parse connection uri")] + InvalidUri(#[from] http::uri::InvalidUri), + #[error("rpc failure")] + Rpc(#[from] tonic::Status), + #[error("transport failure")] + Transport(#[from] tonic::transport::Error), } diff --git a/sdks/rust/src/grpc/alpha.rs b/sdks/rust/src/grpc/alpha.rs deleted file mode 100644 index d1ac1197ee..0000000000 --- a/sdks/rust/src/grpc/alpha.rs +++ /dev/null @@ -1,951 +0,0 @@ -// Copyright 2020 Google LLC All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// This code was autogenerated. Do not edit directly. -// This file is generated by rust-protobuf 2.16.2. Do not edit -// @generated - -// https://github.com/rust-lang/rust-clippy/issues/702 -#![allow(unknown_lints)] -#![allow(clippy::all)] - -#![allow(unused_attributes)] -#![rustfmt::skip] - -#![allow(box_pointers)] -#![allow(dead_code)] -#![allow(missing_docs)] -#![allow(non_camel_case_types)] -#![allow(non_snake_case)] -#![allow(non_upper_case_globals)] -#![allow(trivial_casts)] -#![allow(unused_imports)] -#![allow(unused_results)] -//! Generated file from `alpha.proto` - -/// Generated files are compatible only with the same version -/// of protobuf runtime. -// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_16_2; - -#[derive(PartialEq,Clone,Default)] -pub struct Empty { - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a Empty { - fn default() -> &'a Empty { - ::default_instance() - } -} - -impl Empty { - pub fn new() -> Empty { - ::std::default::Default::default() - } -} - -impl ::protobuf::Message for Empty { - fn is_initialized(&self) -> bool { - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> Empty { - Empty::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let fields = ::std::vec::Vec::new(); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "Empty", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static Empty { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(Empty::new) - } -} - -impl ::protobuf::Clear for Empty { - fn clear(&mut self) { - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for Empty { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for Empty { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct Count { - // message fields - pub count: i64, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a Count { - fn default() -> &'a Count { - ::default_instance() - } -} - -impl Count { - pub fn new() -> Count { - ::std::default::Default::default() - } - - // int64 count = 1; - - - pub fn get_count(&self) -> i64 { - self.count - } - pub fn clear_count(&mut self) { - self.count = 0; - } - - // Param is passed by value, moved - pub fn set_count(&mut self, v: i64) { - self.count = v; - } -} - -impl ::protobuf::Message for Count { - fn is_initialized(&self) -> bool { - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_int64()?; - self.count = tmp; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if self.count != 0 { - my_size += ::protobuf::rt::value_size(1, self.count, ::protobuf::wire_format::WireTypeVarint); - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if self.count != 0 { - os.write_int64(1, self.count)?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> Count { - Count::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt64>( - "count", - |m: &Count| { &m.count }, - |m: &mut Count| { &mut m.count }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "Count", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static Count { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(Count::new) - } -} - -impl ::protobuf::Clear for Count { - fn clear(&mut self) { - self.count = 0; - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for Count { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for Count { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct Bool { - // message fields - pub bool: bool, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a Bool { - fn default() -> &'a Bool { - ::default_instance() - } -} - -impl Bool { - pub fn new() -> Bool { - ::std::default::Default::default() - } - - // bool bool = 1; - - - pub fn get_bool(&self) -> bool { - self.bool - } - pub fn clear_bool(&mut self) { - self.bool = false; - } - - // Param is passed by value, moved - pub fn set_bool(&mut self, v: bool) { - self.bool = v; - } -} - -impl ::protobuf::Message for Bool { - fn is_initialized(&self) -> bool { - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_bool()?; - self.bool = tmp; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if self.bool != false { - my_size += 2; - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if self.bool != false { - os.write_bool(1, self.bool)?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> Bool { - Bool::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( - "bool", - |m: &Bool| { &m.bool }, - |m: &mut Bool| { &mut m.bool }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "Bool", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static Bool { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(Bool::new) - } -} - -impl ::protobuf::Clear for Bool { - fn clear(&mut self) { - self.bool = false; - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for Bool { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for Bool { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct PlayerID { - // message fields - pub playerID: ::std::string::String, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a PlayerID { - fn default() -> &'a PlayerID { - ::default_instance() - } -} - -impl PlayerID { - pub fn new() -> PlayerID { - ::std::default::Default::default() - } - - // string playerID = 1; - - - pub fn get_playerID(&self) -> &str { - &self.playerID - } - pub fn clear_playerID(&mut self) { - self.playerID.clear(); - } - - // Param is passed by value, moved - pub fn set_playerID(&mut self, v: ::std::string::String) { - self.playerID = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_playerID(&mut self) -> &mut ::std::string::String { - &mut self.playerID - } - - // Take field - pub fn take_playerID(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.playerID, ::std::string::String::new()) - } -} - -impl ::protobuf::Message for PlayerID { - fn is_initialized(&self) -> bool { - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.playerID)?; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if !self.playerID.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.playerID); - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.playerID.is_empty() { - os.write_string(1, &self.playerID)?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> PlayerID { - PlayerID::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "playerID", - |m: &PlayerID| { &m.playerID }, - |m: &mut PlayerID| { &mut m.playerID }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "PlayerID", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static PlayerID { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(PlayerID::new) - } -} - -impl ::protobuf::Clear for PlayerID { - fn clear(&mut self) { - self.playerID.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for PlayerID { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for PlayerID { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct PlayerIDList { - // message fields - pub list: ::protobuf::RepeatedField<::std::string::String>, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a PlayerIDList { - fn default() -> &'a PlayerIDList { - ::default_instance() - } -} - -impl PlayerIDList { - pub fn new() -> PlayerIDList { - ::std::default::Default::default() - } - - // repeated string list = 1; - - - pub fn get_list(&self) -> &[::std::string::String] { - &self.list - } - pub fn clear_list(&mut self) { - self.list.clear(); - } - - // Param is passed by value, moved - pub fn set_list(&mut self, v: ::protobuf::RepeatedField<::std::string::String>) { - self.list = v; - } - - // Mutable pointer to the field. - pub fn mut_list(&mut self) -> &mut ::protobuf::RepeatedField<::std::string::String> { - &mut self.list - } - - // Take field - pub fn take_list(&mut self) -> ::protobuf::RepeatedField<::std::string::String> { - ::std::mem::replace(&mut self.list, ::protobuf::RepeatedField::new()) - } -} - -impl ::protobuf::Message for PlayerIDList { - fn is_initialized(&self) -> bool { - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_repeated_string_into(wire_type, is, &mut self.list)?; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - for value in &self.list { - my_size += ::protobuf::rt::string_size(1, &value); - }; - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - for v in &self.list { - os.write_string(1, &v)?; - }; - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> PlayerIDList { - PlayerIDList::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "list", - |m: &PlayerIDList| { &m.list }, - |m: &mut PlayerIDList| { &mut m.list }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "PlayerIDList", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static PlayerIDList { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(PlayerIDList::new) - } -} - -impl ::protobuf::Clear for PlayerIDList { - fn clear(&mut self) { - self.list.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for PlayerIDList { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for PlayerIDList { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x0balpha.proto\x12\x14agones.dev.sdk.alpha\x1a\x1cgoogle/api/annotati\ - ons.proto\"\x07\n\x05Empty\"\x1d\n\x05Count\x12\x14\n\x05count\x18\x01\ - \x20\x01(\x03R\x05count\"\x1a\n\x04Bool\x12\x12\n\x04bool\x18\x01\x20\ - \x01(\x08R\x04bool\"&\n\x08PlayerID\x12\x1a\n\x08playerID\x18\x01\x20\ - \x01(\tR\x08playerID\"\"\n\x0cPlayerIDList\x12\x12\n\x04list\x18\x01\x20\ - \x03(\tR\x04list2\xa9\x06\n\x03SDK\x12m\n\rPlayerConnect\x12\x1e.agones.\ - dev.sdk.alpha.PlayerID\x1a\x1a.agones.dev.sdk.alpha.Bool\"\x20\x82\xd3\ - \xe4\x93\x02\x1a\"\x15/alpha/player/connect:\x01*\x12s\n\x10PlayerDiscon\ - nect\x12\x1e.agones.dev.sdk.alpha.PlayerID\x1a\x1a.agones.dev.sdk.alpha.\ - Bool\"#\x82\xd3\xe4\x93\x02\x1d\"\x18/alpha/player/disconnect:\x01*\x12p\ - \n\x11SetPlayerCapacity\x12\x1b.agones.dev.sdk.alpha.Count\x1a\x1b.agone\ - s.dev.sdk.alpha.Empty\"!\x82\xd3\xe4\x93\x02\x1b\x1a\x16/alpha/player/ca\ - pacity:\x01*\x12m\n\x11GetPlayerCapacity\x12\x1b.agones.dev.sdk.alpha.Em\ - pty\x1a\x1b.agones.dev.sdk.alpha.Count\"\x1e\x82\xd3\xe4\x93\x02\x18\x12\ - \x16/alpha/player/capacity\x12g\n\x0eGetPlayerCount\x12\x1b.agones.dev.s\ - dk.alpha.Empty\x1a\x1b.agones.dev.sdk.alpha.Count\"\x1b\x82\xd3\xe4\x93\ - \x02\x15\x12\x13/alpha/player/count\x12{\n\x11IsPlayerConnected\x12\x1e.\ - agones.dev.sdk.alpha.PlayerID\x1a\x1a.agones.dev.sdk.alpha.Bool\"*\x82\ - \xd3\xe4\x93\x02$\x12\"/alpha/player/connected/{playerID}\x12w\n\x13GetC\ - onnectedPlayers\x12\x1b.agones.dev.sdk.alpha.Empty\x1a\".agones.dev.sdk.\ - alpha.PlayerIDList\"\x1f\x82\xd3\xe4\x93\x02\x19\x12\x17/alpha/player/co\ - nnectedB\x07Z\x05alphaJ\xd0)\n\x07\x12\x05\x0e\0\x89\x01\x01\n\xd1\x04\n\ - \x01\x0c\x12\x03\x0e\0\x122\xc6\x04\x20Copyright\x202020\x20Google\x20LL\ - C\x20All\x20Rights\x20Reserved.\n\n\x20Licensed\x20under\x20the\x20Apach\ - e\x20License,\x20Version\x202.0\x20(the\x20\"License\");\n\x20you\x20may\ - \x20not\x20use\x20this\x20file\x20except\x20in\x20compliance\x20with\x20\ - the\x20License.\n\x20You\x20may\x20obtain\x20a\x20copy\x20of\x20the\x20L\ - icense\x20at\n\n\x20\x20\x20\x20\x20http://www.apache.org/licenses/LICEN\ - SE-2.0\n\n\x20Unless\x20required\x20by\x20applicable\x20law\x20or\x20agr\ - eed\x20to\x20in\x20writing,\x20software\n\x20distributed\x20under\x20the\ - \x20License\x20is\x20distributed\x20on\x20an\x20\"AS\x20IS\"\x20BASIS,\n\ - \x20WITHOUT\x20WARRANTIES\x20OR\x20CONDITIONS\x20OF\x20ANY\x20KIND,\x20e\ - ither\x20express\x20or\x20implied.\n\x20See\x20the\x20License\x20for\x20\ - the\x20specific\x20language\x20governing\x20permissions\x20and\n\x20limi\ - tations\x20under\x20the\x20License.\n\n\x08\n\x01\x02\x12\x03\x10\0\x1d\ - \n\x08\n\x01\x08\x12\x03\x11\0\x1c\n\t\n\x02\x08\x0b\x12\x03\x11\0\x1c\n\ - \t\n\x02\x03\0\x12\x03\x13\0&\nN\n\x02\x06\0\x12\x04\x16\0q\x01\x1aB\x20\ - SDK\x20service\x20to\x20be\x20used\x20in\x20the\x20GameServer\x20SDK\x20\ - to\x20the\x20Pod\x20Sidecar.\n\n\n\n\x03\x06\0\x01\x12\x03\x16\x08\x0b\n\ - \xbe\x08\n\x04\x06\0\x02\0\x12\x04'\x04,\x05\x1a\xaf\x08\x20PlayerConnec\ - t\x20increases\x20the\x20SDK\xe2\x80\x99s\x20stored\x20player\x20count\ - \x20by\x20one,\x20and\x20appends\x20this\x20playerID\x20to\x20GameServer\ - .Status.Players.IDs.\n\n\x20GameServer.Status.Players.Count\x20and\x20Ga\ - meServer.Status.Players.IDs\x20are\x20then\x20set\x20to\x20update\x20the\ - \x20player\x20count\x20and\x20id\x20list\x20a\x20second\x20from\x20now,\ - \n\x20unless\x20there\x20is\x20already\x20an\x20update\x20pending,\x20in\ - \x20which\x20case\x20the\x20update\x20joins\x20that\x20batch\x20operatio\ - n.\n\n\x20PlayerConnect\x20returns\x20true\x20and\x20adds\x20the\x20play\ - erID\x20to\x20the\x20list\x20of\x20playerIDs\x20if\x20this\x20playerID\ - \x20was\x20not\x20already\x20in\x20the\n\x20list\x20of\x20connected\x20p\ - layerIDs.\n\n\x20If\x20the\x20playerID\x20exists\x20within\x20the\x20lis\ - t\x20of\x20connected\x20playerIDs,\x20PlayerConnect\x20will\x20return\ - \x20false,\x20and\x20the\x20list\x20of\n\x20connected\x20playerIDs\x20wi\ - ll\x20be\x20left\x20unchanged.\n\n\x20An\x20error\x20will\x20be\x20retur\ - ned\x20if\x20the\x20playerID\x20was\x20not\x20already\x20in\x20the\x20li\ - st\x20of\x20connected\x20playerIDs\x20but\x20the\x20player\x20capacity\ - \x20for\n\x20the\x20server\x20has\x20been\x20reached.\x20The\x20playerID\ - \x20will\x20not\x20be\x20added\x20to\x20the\x20list\x20of\x20playerIDs.\ - \n\n\x20Warning:\x20Do\x20not\x20use\x20this\x20method\x20if\x20you\x20a\ - re\x20manually\x20managing\x20GameServer.Status.Players.IDs\x20and\x20Ga\ - meServer.Status.Players.Count\n\x20through\x20the\x20Kubernetes\x20API,\ - \x20as\x20indeterminate\x20results\x20will\x20occur.\n\n\x0c\n\x05\x06\0\ - \x02\0\x01\x12\x03'\x08\x15\n\x0c\n\x05\x06\0\x02\0\x02\x12\x03'\x17\x1f\ - \n\x0c\n\x05\x06\0\x02\0\x03\x12\x03'*.\n\r\n\x05\x06\0\x02\0\x04\x12\ - \x04(\x08+\n\n\x11\n\t\x06\0\x02\0\x04\xb0\xca\xbc\"\x12\x04(\x08+\n\n\ - \xda\x06\n\x04\x06\0\x02\x01\x12\x04;\x04@\x05\x1a\xcb\x06\x20Decreases\ - \x20the\x20SDK\xe2\x80\x99s\x20stored\x20player\x20count\x20by\x20one,\ - \x20and\x20removes\x20the\x20playerID\x20from\x20GameServer.Status.Playe\ - rs.IDs.\n\n\x20GameServer.Status.Players.Count\x20and\x20GameServer.Stat\ - us.Players.IDs\x20are\x20then\x20set\x20to\x20update\x20the\x20player\ - \x20count\x20and\x20id\x20list\x20a\x20second\x20from\x20now,\n\x20unles\ - s\x20there\x20is\x20already\x20an\x20update\x20pending,\x20in\x20which\ - \x20case\x20the\x20update\x20joins\x20that\x20batch\x20operation.\n\n\ - \x20PlayerDisconnect\x20will\x20return\x20true\x20and\x20remove\x20the\ - \x20supplied\x20playerID\x20from\x20the\x20list\x20of\x20connected\x20pl\ - ayerIDs\x20if\x20the\n\x20playerID\x20value\x20exists\x20within\x20the\ - \x20list.\n\n\x20If\x20the\x20playerID\x20was\x20not\x20in\x20the\x20lis\ - t\x20of\x20connected\x20playerIDs,\x20the\x20call\x20will\x20return\x20f\ - alse,\x20and\x20the\x20connected\x20playerID\x20list\n\x20will\x20be\x20\ - left\x20unchanged.\n\n\x20Warning:\x20Do\x20not\x20use\x20this\x20method\ - \x20if\x20you\x20are\x20manually\x20managing\x20GameServer.status.player\ - s.IDs\x20and\x20GameServer.status.players.Count\n\x20through\x20the\x20K\ - ubernetes\x20API,\x20as\x20indeterminate\x20results\x20will\x20occur.\n\ - \n\x0c\n\x05\x06\0\x02\x01\x01\x12\x03;\x08\x18\n\x0c\n\x05\x06\0\x02\ - \x01\x02\x12\x03;\x1a\"\n\x0c\n\x05\x06\0\x02\x01\x03\x12\x03;-1\n\r\n\ - \x05\x06\0\x02\x01\x04\x12\x04<\x08?\n\n\x11\n\t\x06\0\x02\x01\x04\xb0\ - \xca\xbc\"\x12\x04<\x08?\n\nX\n\x04\x06\0\x02\x02\x12\x04C\x04H\x05\x1aJ\ - \x20Update\x20the\x20GameServer.Status.Players.Capacity\x20value\x20with\ - \x20a\x20new\x20capacity.\n\n\x0c\n\x05\x06\0\x02\x02\x01\x12\x03C\x08\ - \x19\n\x0c\n\x05\x06\0\x02\x02\x02\x12\x03C\x1b\x20\n\x0c\n\x05\x06\0\ - \x02\x02\x03\x12\x03C+0\n\r\n\x05\x06\0\x02\x02\x04\x12\x04D\x08G\n\n\ - \x11\n\t\x06\0\x02\x02\x04\xb0\xca\xbc\"\x12\x04D\x08G\n\n\xe2\x02\n\x04\ - \x06\0\x02\x03\x12\x04N\x04R\x05\x1a\xd3\x02\x20Retrieves\x20the\x20curr\ - ent\x20player\x20capacity.\x20This\x20is\x20always\x20accurate\x20from\ - \x20what\x20has\x20been\x20set\x20through\x20this\x20SDK,\n\x20even\x20i\ - f\x20the\x20value\x20has\x20yet\x20to\x20be\x20updated\x20on\x20the\x20G\ - ameServer\x20status\x20resource.\n\n\x20If\x20GameServer.Status.Players.\ - Capacity\x20is\x20set\x20manually\x20through\x20the\x20Kubernetes\x20API\ - ,\x20use\x20SDK.GameServer()\x20or\x20SDK.WatchGameServer()\x20instead\ - \x20to\x20view\x20this\x20value.\n\n\x0c\n\x05\x06\0\x02\x03\x01\x12\x03\ - N\x08\x19\n\x0c\n\x05\x06\0\x02\x03\x02\x12\x03N\x1b\x20\n\x0c\n\x05\x06\ - \0\x02\x03\x03\x12\x03N+0\n\r\n\x05\x06\0\x02\x03\x04\x12\x04O\x08Q\n\n\ - \x11\n\t\x06\0\x02\x03\x04\xb0\xca\xbc\"\x12\x04O\x08Q\n\n\xdc\x02\n\x04\ - \x06\0\x02\x04\x12\x04X\x04\\\x05\x1a\xcd\x02\x20Retrieves\x20the\x20cur\ - rent\x20player\x20count.\x20This\x20is\x20always\x20accurate\x20from\x20\ - what\x20has\x20been\x20set\x20through\x20this\x20SDK,\n\x20even\x20if\ - \x20the\x20value\x20has\x20yet\x20to\x20be\x20updated\x20on\x20the\x20Ga\ - meServer\x20status\x20resource.\n\n\x20If\x20GameServer.Status.Players.C\ - ount\x20is\x20set\x20manually\x20through\x20the\x20Kubernetes\x20API,\ - \x20use\x20SDK.GameServer()\x20or\x20SDK.WatchGameServer()\x20instead\ - \x20to\x20view\x20this\x20value.\n\n\x0c\n\x05\x06\0\x02\x04\x01\x12\x03\ - X\x08\x16\n\x0c\n\x05\x06\0\x02\x04\x02\x12\x03X\x18\x1d\n\x0c\n\x05\x06\ - \0\x02\x04\x03\x12\x03X(-\n\r\n\x05\x06\0\x02\x04\x04\x12\x04Y\x08[\n\n\ - \x11\n\t\x06\0\x02\x04\x04\xb0\xca\xbc\"\x12\x04Y\x08[\n\n\x83\x03\n\x04\ - \x06\0\x02\x05\x12\x04b\x04f\x05\x1a\xf4\x02\x20Returns\x20if\x20the\x20\ - playerID\x20is\x20currently\x20connected\x20to\x20the\x20GameServer.\x20\ - This\x20is\x20always\x20accurate\x20from\x20what\x20has\x20been\x20set\ - \x20through\x20this\x20SDK,\n\x20even\x20if\x20the\x20value\x20has\x20ye\ - t\x20to\x20be\x20updated\x20on\x20the\x20GameServer\x20status\x20resourc\ - e.\n\n\x20If\x20GameServer.Status.Players.IDs\x20is\x20set\x20manually\ - \x20through\x20the\x20Kubernetes\x20API,\x20use\x20SDK.GameServer()\x20o\ - r\x20SDK.WatchGameServer()\x20instead\x20to\x20determine\x20connected\ - \x20status.\n\n\x0c\n\x05\x06\0\x02\x05\x01\x12\x03b\x08\x19\n\x0c\n\x05\ - \x06\0\x02\x05\x02\x12\x03b\x1b#\n\x0c\n\x05\x06\0\x02\x05\x03\x12\x03b.\ - 2\n\r\n\x05\x06\0\x02\x05\x04\x12\x04c\x08e\n\n\x11\n\t\x06\0\x02\x05\ - \x04\xb0\xca\xbc\"\x12\x04c\x08e\n\n\xee\x02\n\x04\x06\0\x02\x06\x12\x04\ - l\x04p\x05\x1a\xdf\x02\x20Returns\x20the\x20list\x20of\x20the\x20current\ - ly\x20connected\x20player\x20ids.\x20This\x20is\x20always\x20accurate\ - \x20from\x20what\x20has\x20been\x20set\x20through\x20this\x20SDK,\n\x20e\ - ven\x20if\x20the\x20value\x20has\x20yet\x20to\x20be\x20updated\x20on\x20\ - the\x20GameServer\x20status\x20resource.\n\n\x20If\x20GameServer.Status.\ - Players.IDs\x20is\x20set\x20manually\x20through\x20the\x20Kubernetes\x20\ - API,\x20use\x20SDK.GameServer()\x20or\x20SDK.WatchGameServer()\x20instea\ - d\x20to\x20view\x20this\x20value.\n\n\x0c\n\x05\x06\0\x02\x06\x01\x12\ - \x03l\x08\x1b\n\x0c\n\x05\x06\0\x02\x06\x02\x12\x03l\x1c!\n\x0c\n\x05\ - \x06\0\x02\x06\x03\x12\x03l,8\n\r\n\x05\x06\0\x02\x06\x04\x12\x04m\x08o\ - \n\n\x11\n\t\x06\0\x02\x06\x04\xb0\xca\xbc\"\x12\x04m\x08o\n\n\x18\n\x02\ - \x04\0\x12\x04t\0u\x01\x1a\x0c\x20I\x20am\x20Empty\n\n\n\n\x03\x04\0\x01\ - \x12\x03t\x08\r\n%\n\x02\x04\x01\x12\x04x\0z\x01\x1a\x19\x20Store\x20a\ - \x20count\x20variable.\n\n\n\n\x03\x04\x01\x01\x12\x03x\x08\r\n\x0b\n\ - \x04\x04\x01\x02\0\x12\x03y\x04\x14\n\r\n\x05\x04\x01\x02\0\x04\x12\x04y\ - \x04x\x0f\n\x0c\n\x05\x04\x01\x02\0\x05\x12\x03y\x04\t\n\x0c\n\x05\x04\ - \x01\x02\0\x01\x12\x03y\n\x0f\n\x0c\n\x05\x04\x01\x02\0\x03\x12\x03y\x12\ - \x13\n$\n\x02\x04\x02\x12\x04}\0\x7f\x01\x1a\x18\x20Store\x20a\x20boolea\ - n\x20result\n\n\n\n\x03\x04\x02\x01\x12\x03}\x08\x0c\n\x0b\n\x04\x04\x02\ - \x02\0\x12\x03~\x04\x12\n\r\n\x05\x04\x02\x02\0\x04\x12\x04~\x04}\x0e\n\ - \x0c\n\x05\x04\x02\x02\0\x05\x12\x03~\x04\x08\n\x0c\n\x05\x04\x02\x02\0\ - \x01\x12\x03~\t\r\n\x0c\n\x05\x04\x02\x02\0\x03\x12\x03~\x10\x11\n9\n\ - \x02\x04\x03\x12\x06\x82\x01\0\x84\x01\x01\x1a+\x20The\x20unique\x20iden\ - tifier\x20for\x20a\x20given\x20player.\n\n\x0b\n\x03\x04\x03\x01\x12\x04\ - \x82\x01\x08\x10\n\x0c\n\x04\x04\x03\x02\0\x12\x04\x83\x01\x04\x18\n\x0f\ - \n\x05\x04\x03\x02\0\x04\x12\x06\x83\x01\x04\x82\x01\x12\n\r\n\x05\x04\ - \x03\x02\0\x05\x12\x04\x83\x01\x04\n\n\r\n\x05\x04\x03\x02\0\x01\x12\x04\ - \x83\x01\x0b\x13\n\r\n\x05\x04\x03\x02\0\x03\x12\x04\x83\x01\x16\x17\n\"\ - \n\x02\x04\x04\x12\x06\x87\x01\0\x89\x01\x01\x1a\x14\x20List\x20of\x20Pl\ - ayer\x20IDs\n\n\x0b\n\x03\x04\x04\x01\x12\x04\x87\x01\x08\x14\n\x0c\n\ - \x04\x04\x04\x02\0\x12\x04\x88\x01\x04\x1d\n\r\n\x05\x04\x04\x02\0\x04\ - \x12\x04\x88\x01\x04\x0c\n\r\n\x05\x04\x04\x02\0\x05\x12\x04\x88\x01\r\ - \x13\n\r\n\x05\x04\x04\x02\0\x01\x12\x04\x88\x01\x14\x18\n\r\n\x05\x04\ - \x04\x02\0\x03\x12\x04\x88\x01\x1b\x1cb\x06proto3\ -"; - -static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; - -fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto { - ::protobuf::parse_from_bytes(file_descriptor_proto_data).unwrap() -} - -pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto { - file_descriptor_proto_lazy.get(|| { - parse_descriptor_proto() - }) -} diff --git a/sdks/rust/src/grpc/alpha_grpc.rs b/sdks/rust/src/grpc/alpha_grpc.rs deleted file mode 100644 index ec73ce3261..0000000000 --- a/sdks/rust/src/grpc/alpha_grpc.rs +++ /dev/null @@ -1,254 +0,0 @@ -// Copyright 2020 Google LLC All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// This code was autogenerated. Do not edit directly. -// This file is generated. Do not edit -// @generated - -// https://github.com/Manishearth/rust-clippy/issues/702 -#![allow(unknown_lints)] -#![allow(clippy::all)] - -#![cfg_attr(rustfmt, rustfmt_skip)] - -#![allow(box_pointers)] -#![allow(dead_code)] -#![allow(missing_docs)] -#![allow(non_camel_case_types)] -#![allow(non_snake_case)] -#![allow(non_upper_case_globals)] -#![allow(trivial_casts)] -#![allow(unsafe_code)] -#![allow(unused_imports)] -#![allow(unused_results)] - -const METHOD_SDK_PLAYER_CONNECT: ::grpcio::Method = ::grpcio::Method { - ty: ::grpcio::MethodType::Unary, - name: "/agones.dev.sdk.alpha.SDK/PlayerConnect", - req_mar: ::grpcio::Marshaller { ser: ::grpcio::pb_ser, de: ::grpcio::pb_de }, - resp_mar: ::grpcio::Marshaller { ser: ::grpcio::pb_ser, de: ::grpcio::pb_de }, -}; - -const METHOD_SDK_PLAYER_DISCONNECT: ::grpcio::Method = ::grpcio::Method { - ty: ::grpcio::MethodType::Unary, - name: "/agones.dev.sdk.alpha.SDK/PlayerDisconnect", - req_mar: ::grpcio::Marshaller { ser: ::grpcio::pb_ser, de: ::grpcio::pb_de }, - resp_mar: ::grpcio::Marshaller { ser: ::grpcio::pb_ser, de: ::grpcio::pb_de }, -}; - -const METHOD_SDK_SET_PLAYER_CAPACITY: ::grpcio::Method = ::grpcio::Method { - ty: ::grpcio::MethodType::Unary, - name: "/agones.dev.sdk.alpha.SDK/SetPlayerCapacity", - req_mar: ::grpcio::Marshaller { ser: ::grpcio::pb_ser, de: ::grpcio::pb_de }, - resp_mar: ::grpcio::Marshaller { ser: ::grpcio::pb_ser, de: ::grpcio::pb_de }, -}; - -const METHOD_SDK_GET_PLAYER_CAPACITY: ::grpcio::Method = ::grpcio::Method { - ty: ::grpcio::MethodType::Unary, - name: "/agones.dev.sdk.alpha.SDK/GetPlayerCapacity", - req_mar: ::grpcio::Marshaller { ser: ::grpcio::pb_ser, de: ::grpcio::pb_de }, - resp_mar: ::grpcio::Marshaller { ser: ::grpcio::pb_ser, de: ::grpcio::pb_de }, -}; - -const METHOD_SDK_GET_PLAYER_COUNT: ::grpcio::Method = ::grpcio::Method { - ty: ::grpcio::MethodType::Unary, - name: "/agones.dev.sdk.alpha.SDK/GetPlayerCount", - req_mar: ::grpcio::Marshaller { ser: ::grpcio::pb_ser, de: ::grpcio::pb_de }, - resp_mar: ::grpcio::Marshaller { ser: ::grpcio::pb_ser, de: ::grpcio::pb_de }, -}; - -const METHOD_SDK_IS_PLAYER_CONNECTED: ::grpcio::Method = ::grpcio::Method { - ty: ::grpcio::MethodType::Unary, - name: "/agones.dev.sdk.alpha.SDK/IsPlayerConnected", - req_mar: ::grpcio::Marshaller { ser: ::grpcio::pb_ser, de: ::grpcio::pb_de }, - resp_mar: ::grpcio::Marshaller { ser: ::grpcio::pb_ser, de: ::grpcio::pb_de }, -}; - -const METHOD_SDK_GET_CONNECTED_PLAYERS: ::grpcio::Method = ::grpcio::Method { - ty: ::grpcio::MethodType::Unary, - name: "/agones.dev.sdk.alpha.SDK/GetConnectedPlayers", - req_mar: ::grpcio::Marshaller { ser: ::grpcio::pb_ser, de: ::grpcio::pb_de }, - resp_mar: ::grpcio::Marshaller { ser: ::grpcio::pb_ser, de: ::grpcio::pb_de }, -}; - -#[derive(Clone)] -pub struct SdkClient { - client: ::grpcio::Client, -} - -impl SdkClient { - pub fn new(channel: ::grpcio::Channel) -> Self { - SdkClient { - client: ::grpcio::Client::new(channel), - } - } - - pub fn player_connect_opt(&self, req: &super::alpha::PlayerID, opt: ::grpcio::CallOption) -> ::grpcio::Result { - self.client.unary_call(&METHOD_SDK_PLAYER_CONNECT, req, opt) - } - - pub fn player_connect(&self, req: &super::alpha::PlayerID) -> ::grpcio::Result { - self.player_connect_opt(req, ::grpcio::CallOption::default()) - } - - pub fn player_connect_async_opt(&self, req: &super::alpha::PlayerID, opt: ::grpcio::CallOption) -> ::grpcio::Result<::grpcio::ClientUnaryReceiver> { - self.client.unary_call_async(&METHOD_SDK_PLAYER_CONNECT, req, opt) - } - - pub fn player_connect_async(&self, req: &super::alpha::PlayerID) -> ::grpcio::Result<::grpcio::ClientUnaryReceiver> { - self.player_connect_async_opt(req, ::grpcio::CallOption::default()) - } - - pub fn player_disconnect_opt(&self, req: &super::alpha::PlayerID, opt: ::grpcio::CallOption) -> ::grpcio::Result { - self.client.unary_call(&METHOD_SDK_PLAYER_DISCONNECT, req, opt) - } - - pub fn player_disconnect(&self, req: &super::alpha::PlayerID) -> ::grpcio::Result { - self.player_disconnect_opt(req, ::grpcio::CallOption::default()) - } - - pub fn player_disconnect_async_opt(&self, req: &super::alpha::PlayerID, opt: ::grpcio::CallOption) -> ::grpcio::Result<::grpcio::ClientUnaryReceiver> { - self.client.unary_call_async(&METHOD_SDK_PLAYER_DISCONNECT, req, opt) - } - - pub fn player_disconnect_async(&self, req: &super::alpha::PlayerID) -> ::grpcio::Result<::grpcio::ClientUnaryReceiver> { - self.player_disconnect_async_opt(req, ::grpcio::CallOption::default()) - } - - pub fn set_player_capacity_opt(&self, req: &super::alpha::Count, opt: ::grpcio::CallOption) -> ::grpcio::Result { - self.client.unary_call(&METHOD_SDK_SET_PLAYER_CAPACITY, req, opt) - } - - pub fn set_player_capacity(&self, req: &super::alpha::Count) -> ::grpcio::Result { - self.set_player_capacity_opt(req, ::grpcio::CallOption::default()) - } - - pub fn set_player_capacity_async_opt(&self, req: &super::alpha::Count, opt: ::grpcio::CallOption) -> ::grpcio::Result<::grpcio::ClientUnaryReceiver> { - self.client.unary_call_async(&METHOD_SDK_SET_PLAYER_CAPACITY, req, opt) - } - - pub fn set_player_capacity_async(&self, req: &super::alpha::Count) -> ::grpcio::Result<::grpcio::ClientUnaryReceiver> { - self.set_player_capacity_async_opt(req, ::grpcio::CallOption::default()) - } - - pub fn get_player_capacity_opt(&self, req: &super::alpha::Empty, opt: ::grpcio::CallOption) -> ::grpcio::Result { - self.client.unary_call(&METHOD_SDK_GET_PLAYER_CAPACITY, req, opt) - } - - pub fn get_player_capacity(&self, req: &super::alpha::Empty) -> ::grpcio::Result { - self.get_player_capacity_opt(req, ::grpcio::CallOption::default()) - } - - pub fn get_player_capacity_async_opt(&self, req: &super::alpha::Empty, opt: ::grpcio::CallOption) -> ::grpcio::Result<::grpcio::ClientUnaryReceiver> { - self.client.unary_call_async(&METHOD_SDK_GET_PLAYER_CAPACITY, req, opt) - } - - pub fn get_player_capacity_async(&self, req: &super::alpha::Empty) -> ::grpcio::Result<::grpcio::ClientUnaryReceiver> { - self.get_player_capacity_async_opt(req, ::grpcio::CallOption::default()) - } - - pub fn get_player_count_opt(&self, req: &super::alpha::Empty, opt: ::grpcio::CallOption) -> ::grpcio::Result { - self.client.unary_call(&METHOD_SDK_GET_PLAYER_COUNT, req, opt) - } - - pub fn get_player_count(&self, req: &super::alpha::Empty) -> ::grpcio::Result { - self.get_player_count_opt(req, ::grpcio::CallOption::default()) - } - - pub fn get_player_count_async_opt(&self, req: &super::alpha::Empty, opt: ::grpcio::CallOption) -> ::grpcio::Result<::grpcio::ClientUnaryReceiver> { - self.client.unary_call_async(&METHOD_SDK_GET_PLAYER_COUNT, req, opt) - } - - pub fn get_player_count_async(&self, req: &super::alpha::Empty) -> ::grpcio::Result<::grpcio::ClientUnaryReceiver> { - self.get_player_count_async_opt(req, ::grpcio::CallOption::default()) - } - - pub fn is_player_connected_opt(&self, req: &super::alpha::PlayerID, opt: ::grpcio::CallOption) -> ::grpcio::Result { - self.client.unary_call(&METHOD_SDK_IS_PLAYER_CONNECTED, req, opt) - } - - pub fn is_player_connected(&self, req: &super::alpha::PlayerID) -> ::grpcio::Result { - self.is_player_connected_opt(req, ::grpcio::CallOption::default()) - } - - pub fn is_player_connected_async_opt(&self, req: &super::alpha::PlayerID, opt: ::grpcio::CallOption) -> ::grpcio::Result<::grpcio::ClientUnaryReceiver> { - self.client.unary_call_async(&METHOD_SDK_IS_PLAYER_CONNECTED, req, opt) - } - - pub fn is_player_connected_async(&self, req: &super::alpha::PlayerID) -> ::grpcio::Result<::grpcio::ClientUnaryReceiver> { - self.is_player_connected_async_opt(req, ::grpcio::CallOption::default()) - } - - pub fn get_connected_players_opt(&self, req: &super::alpha::Empty, opt: ::grpcio::CallOption) -> ::grpcio::Result { - self.client.unary_call(&METHOD_SDK_GET_CONNECTED_PLAYERS, req, opt) - } - - pub fn get_connected_players(&self, req: &super::alpha::Empty) -> ::grpcio::Result { - self.get_connected_players_opt(req, ::grpcio::CallOption::default()) - } - - pub fn get_connected_players_async_opt(&self, req: &super::alpha::Empty, opt: ::grpcio::CallOption) -> ::grpcio::Result<::grpcio::ClientUnaryReceiver> { - self.client.unary_call_async(&METHOD_SDK_GET_CONNECTED_PLAYERS, req, opt) - } - - pub fn get_connected_players_async(&self, req: &super::alpha::Empty) -> ::grpcio::Result<::grpcio::ClientUnaryReceiver> { - self.get_connected_players_async_opt(req, ::grpcio::CallOption::default()) - } - pub fn spawn(&self, f: F) where F: ::futures::Future + Send + 'static { - self.client.spawn(f) - } -} - -pub trait Sdk { - fn player_connect(&mut self, ctx: ::grpcio::RpcContext, req: super::alpha::PlayerID, sink: ::grpcio::UnarySink); - fn player_disconnect(&mut self, ctx: ::grpcio::RpcContext, req: super::alpha::PlayerID, sink: ::grpcio::UnarySink); - fn set_player_capacity(&mut self, ctx: ::grpcio::RpcContext, req: super::alpha::Count, sink: ::grpcio::UnarySink); - fn get_player_capacity(&mut self, ctx: ::grpcio::RpcContext, req: super::alpha::Empty, sink: ::grpcio::UnarySink); - fn get_player_count(&mut self, ctx: ::grpcio::RpcContext, req: super::alpha::Empty, sink: ::grpcio::UnarySink); - fn is_player_connected(&mut self, ctx: ::grpcio::RpcContext, req: super::alpha::PlayerID, sink: ::grpcio::UnarySink); - fn get_connected_players(&mut self, ctx: ::grpcio::RpcContext, req: super::alpha::Empty, sink: ::grpcio::UnarySink); -} - -pub fn create_sdk(s: S) -> ::grpcio::Service { - let mut builder = ::grpcio::ServiceBuilder::new(); - let mut instance = s.clone(); - builder = builder.add_unary_handler(&METHOD_SDK_PLAYER_CONNECT, move |ctx, req, resp| { - instance.player_connect(ctx, req, resp) - }); - let mut instance = s.clone(); - builder = builder.add_unary_handler(&METHOD_SDK_PLAYER_DISCONNECT, move |ctx, req, resp| { - instance.player_disconnect(ctx, req, resp) - }); - let mut instance = s.clone(); - builder = builder.add_unary_handler(&METHOD_SDK_SET_PLAYER_CAPACITY, move |ctx, req, resp| { - instance.set_player_capacity(ctx, req, resp) - }); - let mut instance = s.clone(); - builder = builder.add_unary_handler(&METHOD_SDK_GET_PLAYER_CAPACITY, move |ctx, req, resp| { - instance.get_player_capacity(ctx, req, resp) - }); - let mut instance = s.clone(); - builder = builder.add_unary_handler(&METHOD_SDK_GET_PLAYER_COUNT, move |ctx, req, resp| { - instance.get_player_count(ctx, req, resp) - }); - let mut instance = s.clone(); - builder = builder.add_unary_handler(&METHOD_SDK_IS_PLAYER_CONNECTED, move |ctx, req, resp| { - instance.is_player_connected(ctx, req, resp) - }); - let mut instance = s; - builder = builder.add_unary_handler(&METHOD_SDK_GET_CONNECTED_PLAYERS, move |ctx, req, resp| { - instance.get_connected_players(ctx, req, resp) - }); - builder.build() -} diff --git a/sdks/rust/src/grpc/mod.rs b/sdks/rust/src/grpc/mod.rs deleted file mode 100644 index 340d2db509..0000000000 --- a/sdks/rust/src/grpc/mod.rs +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2017 Google LLC All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -pub mod alpha; -pub mod alpha_grpc; -pub mod sdk; -pub mod sdk_grpc; diff --git a/sdks/rust/src/grpc/sdk.rs b/sdks/rust/src/grpc/sdk.rs deleted file mode 100644 index 4a00ef2b99..0000000000 --- a/sdks/rust/src/grpc/sdk.rs +++ /dev/null @@ -1,2694 +0,0 @@ -// Copyright 2020 Google LLC All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// This code was autogenerated. Do not edit directly. -// This file is generated by rust-protobuf 2.16.2. Do not edit -// @generated - -// https://github.com/rust-lang/rust-clippy/issues/702 -#![allow(unknown_lints)] -#![allow(clippy::all)] - -#![allow(unused_attributes)] -#![rustfmt::skip] - -#![allow(box_pointers)] -#![allow(dead_code)] -#![allow(missing_docs)] -#![allow(non_camel_case_types)] -#![allow(non_snake_case)] -#![allow(non_upper_case_globals)] -#![allow(trivial_casts)] -#![allow(unused_imports)] -#![allow(unused_results)] -//! Generated file from `sdk.proto` - -/// Generated files are compatible only with the same version -/// of protobuf runtime. -// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_16_2; - -#[derive(PartialEq,Clone,Default)] -pub struct Empty { - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a Empty { - fn default() -> &'a Empty { - ::default_instance() - } -} - -impl Empty { - pub fn new() -> Empty { - ::std::default::Default::default() - } -} - -impl ::protobuf::Message for Empty { - fn is_initialized(&self) -> bool { - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> Empty { - Empty::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let fields = ::std::vec::Vec::new(); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "Empty", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static Empty { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(Empty::new) - } -} - -impl ::protobuf::Clear for Empty { - fn clear(&mut self) { - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for Empty { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for Empty { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct KeyValue { - // message fields - pub key: ::std::string::String, - pub value: ::std::string::String, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a KeyValue { - fn default() -> &'a KeyValue { - ::default_instance() - } -} - -impl KeyValue { - pub fn new() -> KeyValue { - ::std::default::Default::default() - } - - // string key = 1; - - - pub fn get_key(&self) -> &str { - &self.key - } - pub fn clear_key(&mut self) { - self.key.clear(); - } - - // Param is passed by value, moved - pub fn set_key(&mut self, v: ::std::string::String) { - self.key = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_key(&mut self) -> &mut ::std::string::String { - &mut self.key - } - - // Take field - pub fn take_key(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.key, ::std::string::String::new()) - } - - // string value = 2; - - - pub fn get_value(&self) -> &str { - &self.value - } - pub fn clear_value(&mut self) { - self.value.clear(); - } - - // Param is passed by value, moved - pub fn set_value(&mut self, v: ::std::string::String) { - self.value = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_value(&mut self) -> &mut ::std::string::String { - &mut self.value - } - - // Take field - pub fn take_value(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.value, ::std::string::String::new()) - } -} - -impl ::protobuf::Message for KeyValue { - fn is_initialized(&self) -> bool { - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.key)?; - }, - 2 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.value)?; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if !self.key.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.key); - } - if !self.value.is_empty() { - my_size += ::protobuf::rt::string_size(2, &self.value); - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.key.is_empty() { - os.write_string(1, &self.key)?; - } - if !self.value.is_empty() { - os.write_string(2, &self.value)?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> KeyValue { - KeyValue::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "key", - |m: &KeyValue| { &m.key }, - |m: &mut KeyValue| { &mut m.key }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "value", - |m: &KeyValue| { &m.value }, - |m: &mut KeyValue| { &mut m.value }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "KeyValue", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static KeyValue { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(KeyValue::new) - } -} - -impl ::protobuf::Clear for KeyValue { - fn clear(&mut self) { - self.key.clear(); - self.value.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for KeyValue { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for KeyValue { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct Duration { - // message fields - pub seconds: i64, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a Duration { - fn default() -> &'a Duration { - ::default_instance() - } -} - -impl Duration { - pub fn new() -> Duration { - ::std::default::Default::default() - } - - // int64 seconds = 1; - - - pub fn get_seconds(&self) -> i64 { - self.seconds - } - pub fn clear_seconds(&mut self) { - self.seconds = 0; - } - - // Param is passed by value, moved - pub fn set_seconds(&mut self, v: i64) { - self.seconds = v; - } -} - -impl ::protobuf::Message for Duration { - fn is_initialized(&self) -> bool { - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_int64()?; - self.seconds = tmp; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if self.seconds != 0 { - my_size += ::protobuf::rt::value_size(1, self.seconds, ::protobuf::wire_format::WireTypeVarint); - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if self.seconds != 0 { - os.write_int64(1, self.seconds)?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> Duration { - Duration::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt64>( - "seconds", - |m: &Duration| { &m.seconds }, - |m: &mut Duration| { &mut m.seconds }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "Duration", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static Duration { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(Duration::new) - } -} - -impl ::protobuf::Clear for Duration { - fn clear(&mut self) { - self.seconds = 0; - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for Duration { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for Duration { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct GameServer { - // message fields - pub object_meta: ::protobuf::SingularPtrField, - pub spec: ::protobuf::SingularPtrField, - pub status: ::protobuf::SingularPtrField, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a GameServer { - fn default() -> &'a GameServer { - ::default_instance() - } -} - -impl GameServer { - pub fn new() -> GameServer { - ::std::default::Default::default() - } - - // .agones.dev.sdk.GameServer.ObjectMeta object_meta = 1; - - - pub fn get_object_meta(&self) -> &GameServer_ObjectMeta { - self.object_meta.as_ref().unwrap_or_else(|| ::default_instance()) - } - pub fn clear_object_meta(&mut self) { - self.object_meta.clear(); - } - - pub fn has_object_meta(&self) -> bool { - self.object_meta.is_some() - } - - // Param is passed by value, moved - pub fn set_object_meta(&mut self, v: GameServer_ObjectMeta) { - self.object_meta = ::protobuf::SingularPtrField::some(v); - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_object_meta(&mut self) -> &mut GameServer_ObjectMeta { - if self.object_meta.is_none() { - self.object_meta.set_default(); - } - self.object_meta.as_mut().unwrap() - } - - // Take field - pub fn take_object_meta(&mut self) -> GameServer_ObjectMeta { - self.object_meta.take().unwrap_or_else(|| GameServer_ObjectMeta::new()) - } - - // .agones.dev.sdk.GameServer.Spec spec = 2; - - - pub fn get_spec(&self) -> &GameServer_Spec { - self.spec.as_ref().unwrap_or_else(|| ::default_instance()) - } - pub fn clear_spec(&mut self) { - self.spec.clear(); - } - - pub fn has_spec(&self) -> bool { - self.spec.is_some() - } - - // Param is passed by value, moved - pub fn set_spec(&mut self, v: GameServer_Spec) { - self.spec = ::protobuf::SingularPtrField::some(v); - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_spec(&mut self) -> &mut GameServer_Spec { - if self.spec.is_none() { - self.spec.set_default(); - } - self.spec.as_mut().unwrap() - } - - // Take field - pub fn take_spec(&mut self) -> GameServer_Spec { - self.spec.take().unwrap_or_else(|| GameServer_Spec::new()) - } - - // .agones.dev.sdk.GameServer.Status status = 3; - - - pub fn get_status(&self) -> &GameServer_Status { - self.status.as_ref().unwrap_or_else(|| ::default_instance()) - } - pub fn clear_status(&mut self) { - self.status.clear(); - } - - pub fn has_status(&self) -> bool { - self.status.is_some() - } - - // Param is passed by value, moved - pub fn set_status(&mut self, v: GameServer_Status) { - self.status = ::protobuf::SingularPtrField::some(v); - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_status(&mut self) -> &mut GameServer_Status { - if self.status.is_none() { - self.status.set_default(); - } - self.status.as_mut().unwrap() - } - - // Take field - pub fn take_status(&mut self) -> GameServer_Status { - self.status.take().unwrap_or_else(|| GameServer_Status::new()) - } -} - -impl ::protobuf::Message for GameServer { - fn is_initialized(&self) -> bool { - for v in &self.object_meta { - if !v.is_initialized() { - return false; - } - }; - for v in &self.spec { - if !v.is_initialized() { - return false; - } - }; - for v in &self.status { - if !v.is_initialized() { - return false; - } - }; - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.object_meta)?; - }, - 2 => { - ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.spec)?; - }, - 3 => { - ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.status)?; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if let Some(ref v) = self.object_meta.as_ref() { - let len = v.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - } - if let Some(ref v) = self.spec.as_ref() { - let len = v.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - } - if let Some(ref v) = self.status.as_ref() { - let len = v.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if let Some(ref v) = self.object_meta.as_ref() { - os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - } - if let Some(ref v) = self.spec.as_ref() { - os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - } - if let Some(ref v) = self.status.as_ref() { - os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> GameServer { - GameServer::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "object_meta", - |m: &GameServer| { &m.object_meta }, - |m: &mut GameServer| { &mut m.object_meta }, - )); - fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "spec", - |m: &GameServer| { &m.spec }, - |m: &mut GameServer| { &mut m.spec }, - )); - fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "status", - |m: &GameServer| { &m.status }, - |m: &mut GameServer| { &mut m.status }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "GameServer", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static GameServer { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(GameServer::new) - } -} - -impl ::protobuf::Clear for GameServer { - fn clear(&mut self) { - self.object_meta.clear(); - self.spec.clear(); - self.status.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for GameServer { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for GameServer { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct GameServer_ObjectMeta { - // message fields - pub name: ::std::string::String, - pub namespace: ::std::string::String, - pub uid: ::std::string::String, - pub resource_version: ::std::string::String, - pub generation: i64, - pub creation_timestamp: i64, - pub deletion_timestamp: i64, - pub annotations: ::std::collections::HashMap<::std::string::String, ::std::string::String>, - pub labels: ::std::collections::HashMap<::std::string::String, ::std::string::String>, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a GameServer_ObjectMeta { - fn default() -> &'a GameServer_ObjectMeta { - ::default_instance() - } -} - -impl GameServer_ObjectMeta { - pub fn new() -> GameServer_ObjectMeta { - ::std::default::Default::default() - } - - // string name = 1; - - - pub fn get_name(&self) -> &str { - &self.name - } - pub fn clear_name(&mut self) { - self.name.clear(); - } - - // Param is passed by value, moved - pub fn set_name(&mut self, v: ::std::string::String) { - self.name = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_name(&mut self) -> &mut ::std::string::String { - &mut self.name - } - - // Take field - pub fn take_name(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.name, ::std::string::String::new()) - } - - // string namespace = 2; - - - pub fn get_namespace(&self) -> &str { - &self.namespace - } - pub fn clear_namespace(&mut self) { - self.namespace.clear(); - } - - // Param is passed by value, moved - pub fn set_namespace(&mut self, v: ::std::string::String) { - self.namespace = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_namespace(&mut self) -> &mut ::std::string::String { - &mut self.namespace - } - - // Take field - pub fn take_namespace(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.namespace, ::std::string::String::new()) - } - - // string uid = 3; - - - pub fn get_uid(&self) -> &str { - &self.uid - } - pub fn clear_uid(&mut self) { - self.uid.clear(); - } - - // Param is passed by value, moved - pub fn set_uid(&mut self, v: ::std::string::String) { - self.uid = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_uid(&mut self) -> &mut ::std::string::String { - &mut self.uid - } - - // Take field - pub fn take_uid(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.uid, ::std::string::String::new()) - } - - // string resource_version = 4; - - - pub fn get_resource_version(&self) -> &str { - &self.resource_version - } - pub fn clear_resource_version(&mut self) { - self.resource_version.clear(); - } - - // Param is passed by value, moved - pub fn set_resource_version(&mut self, v: ::std::string::String) { - self.resource_version = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_resource_version(&mut self) -> &mut ::std::string::String { - &mut self.resource_version - } - - // Take field - pub fn take_resource_version(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.resource_version, ::std::string::String::new()) - } - - // int64 generation = 5; - - - pub fn get_generation(&self) -> i64 { - self.generation - } - pub fn clear_generation(&mut self) { - self.generation = 0; - } - - // Param is passed by value, moved - pub fn set_generation(&mut self, v: i64) { - self.generation = v; - } - - // int64 creation_timestamp = 6; - - - pub fn get_creation_timestamp(&self) -> i64 { - self.creation_timestamp - } - pub fn clear_creation_timestamp(&mut self) { - self.creation_timestamp = 0; - } - - // Param is passed by value, moved - pub fn set_creation_timestamp(&mut self, v: i64) { - self.creation_timestamp = v; - } - - // int64 deletion_timestamp = 7; - - - pub fn get_deletion_timestamp(&self) -> i64 { - self.deletion_timestamp - } - pub fn clear_deletion_timestamp(&mut self) { - self.deletion_timestamp = 0; - } - - // Param is passed by value, moved - pub fn set_deletion_timestamp(&mut self, v: i64) { - self.deletion_timestamp = v; - } - - // repeated .agones.dev.sdk.GameServer.ObjectMeta.AnnotationsEntry annotations = 8; - - - pub fn get_annotations(&self) -> &::std::collections::HashMap<::std::string::String, ::std::string::String> { - &self.annotations - } - pub fn clear_annotations(&mut self) { - self.annotations.clear(); - } - - // Param is passed by value, moved - pub fn set_annotations(&mut self, v: ::std::collections::HashMap<::std::string::String, ::std::string::String>) { - self.annotations = v; - } - - // Mutable pointer to the field. - pub fn mut_annotations(&mut self) -> &mut ::std::collections::HashMap<::std::string::String, ::std::string::String> { - &mut self.annotations - } - - // Take field - pub fn take_annotations(&mut self) -> ::std::collections::HashMap<::std::string::String, ::std::string::String> { - ::std::mem::replace(&mut self.annotations, ::std::collections::HashMap::new()) - } - - // repeated .agones.dev.sdk.GameServer.ObjectMeta.LabelsEntry labels = 9; - - - pub fn get_labels(&self) -> &::std::collections::HashMap<::std::string::String, ::std::string::String> { - &self.labels - } - pub fn clear_labels(&mut self) { - self.labels.clear(); - } - - // Param is passed by value, moved - pub fn set_labels(&mut self, v: ::std::collections::HashMap<::std::string::String, ::std::string::String>) { - self.labels = v; - } - - // Mutable pointer to the field. - pub fn mut_labels(&mut self) -> &mut ::std::collections::HashMap<::std::string::String, ::std::string::String> { - &mut self.labels - } - - // Take field - pub fn take_labels(&mut self) -> ::std::collections::HashMap<::std::string::String, ::std::string::String> { - ::std::mem::replace(&mut self.labels, ::std::collections::HashMap::new()) - } -} - -impl ::protobuf::Message for GameServer_ObjectMeta { - fn is_initialized(&self) -> bool { - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.name)?; - }, - 2 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.namespace)?; - }, - 3 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.uid)?; - }, - 4 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.resource_version)?; - }, - 5 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_int64()?; - self.generation = tmp; - }, - 6 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_int64()?; - self.creation_timestamp = tmp; - }, - 7 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_int64()?; - self.deletion_timestamp = tmp; - }, - 8 => { - ::protobuf::rt::read_map_into::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeString>(wire_type, is, &mut self.annotations)?; - }, - 9 => { - ::protobuf::rt::read_map_into::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeString>(wire_type, is, &mut self.labels)?; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if !self.name.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.name); - } - if !self.namespace.is_empty() { - my_size += ::protobuf::rt::string_size(2, &self.namespace); - } - if !self.uid.is_empty() { - my_size += ::protobuf::rt::string_size(3, &self.uid); - } - if !self.resource_version.is_empty() { - my_size += ::protobuf::rt::string_size(4, &self.resource_version); - } - if self.generation != 0 { - my_size += ::protobuf::rt::value_size(5, self.generation, ::protobuf::wire_format::WireTypeVarint); - } - if self.creation_timestamp != 0 { - my_size += ::protobuf::rt::value_size(6, self.creation_timestamp, ::protobuf::wire_format::WireTypeVarint); - } - if self.deletion_timestamp != 0 { - my_size += ::protobuf::rt::value_size(7, self.deletion_timestamp, ::protobuf::wire_format::WireTypeVarint); - } - my_size += ::protobuf::rt::compute_map_size::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeString>(8, &self.annotations); - my_size += ::protobuf::rt::compute_map_size::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeString>(9, &self.labels); - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.name.is_empty() { - os.write_string(1, &self.name)?; - } - if !self.namespace.is_empty() { - os.write_string(2, &self.namespace)?; - } - if !self.uid.is_empty() { - os.write_string(3, &self.uid)?; - } - if !self.resource_version.is_empty() { - os.write_string(4, &self.resource_version)?; - } - if self.generation != 0 { - os.write_int64(5, self.generation)?; - } - if self.creation_timestamp != 0 { - os.write_int64(6, self.creation_timestamp)?; - } - if self.deletion_timestamp != 0 { - os.write_int64(7, self.deletion_timestamp)?; - } - ::protobuf::rt::write_map_with_cached_sizes::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeString>(8, &self.annotations, os)?; - ::protobuf::rt::write_map_with_cached_sizes::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeString>(9, &self.labels, os)?; - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> GameServer_ObjectMeta { - GameServer_ObjectMeta::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "name", - |m: &GameServer_ObjectMeta| { &m.name }, - |m: &mut GameServer_ObjectMeta| { &mut m.name }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "namespace", - |m: &GameServer_ObjectMeta| { &m.namespace }, - |m: &mut GameServer_ObjectMeta| { &mut m.namespace }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "uid", - |m: &GameServer_ObjectMeta| { &m.uid }, - |m: &mut GameServer_ObjectMeta| { &mut m.uid }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "resource_version", - |m: &GameServer_ObjectMeta| { &m.resource_version }, - |m: &mut GameServer_ObjectMeta| { &mut m.resource_version }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt64>( - "generation", - |m: &GameServer_ObjectMeta| { &m.generation }, - |m: &mut GameServer_ObjectMeta| { &mut m.generation }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt64>( - "creation_timestamp", - |m: &GameServer_ObjectMeta| { &m.creation_timestamp }, - |m: &mut GameServer_ObjectMeta| { &mut m.creation_timestamp }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt64>( - "deletion_timestamp", - |m: &GameServer_ObjectMeta| { &m.deletion_timestamp }, - |m: &mut GameServer_ObjectMeta| { &mut m.deletion_timestamp }, - )); - fields.push(::protobuf::reflect::accessor::make_map_accessor::<_, ::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeString>( - "annotations", - |m: &GameServer_ObjectMeta| { &m.annotations }, - |m: &mut GameServer_ObjectMeta| { &mut m.annotations }, - )); - fields.push(::protobuf::reflect::accessor::make_map_accessor::<_, ::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeString>( - "labels", - |m: &GameServer_ObjectMeta| { &m.labels }, - |m: &mut GameServer_ObjectMeta| { &mut m.labels }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "GameServer.ObjectMeta", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static GameServer_ObjectMeta { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(GameServer_ObjectMeta::new) - } -} - -impl ::protobuf::Clear for GameServer_ObjectMeta { - fn clear(&mut self) { - self.name.clear(); - self.namespace.clear(); - self.uid.clear(); - self.resource_version.clear(); - self.generation = 0; - self.creation_timestamp = 0; - self.deletion_timestamp = 0; - self.annotations.clear(); - self.labels.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for GameServer_ObjectMeta { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for GameServer_ObjectMeta { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct GameServer_Spec { - // message fields - pub health: ::protobuf::SingularPtrField, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a GameServer_Spec { - fn default() -> &'a GameServer_Spec { - ::default_instance() - } -} - -impl GameServer_Spec { - pub fn new() -> GameServer_Spec { - ::std::default::Default::default() - } - - // .agones.dev.sdk.GameServer.Spec.Health health = 1; - - - pub fn get_health(&self) -> &GameServer_Spec_Health { - self.health.as_ref().unwrap_or_else(|| ::default_instance()) - } - pub fn clear_health(&mut self) { - self.health.clear(); - } - - pub fn has_health(&self) -> bool { - self.health.is_some() - } - - // Param is passed by value, moved - pub fn set_health(&mut self, v: GameServer_Spec_Health) { - self.health = ::protobuf::SingularPtrField::some(v); - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_health(&mut self) -> &mut GameServer_Spec_Health { - if self.health.is_none() { - self.health.set_default(); - } - self.health.as_mut().unwrap() - } - - // Take field - pub fn take_health(&mut self) -> GameServer_Spec_Health { - self.health.take().unwrap_or_else(|| GameServer_Spec_Health::new()) - } -} - -impl ::protobuf::Message for GameServer_Spec { - fn is_initialized(&self) -> bool { - for v in &self.health { - if !v.is_initialized() { - return false; - } - }; - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.health)?; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if let Some(ref v) = self.health.as_ref() { - let len = v.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if let Some(ref v) = self.health.as_ref() { - os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> GameServer_Spec { - GameServer_Spec::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "health", - |m: &GameServer_Spec| { &m.health }, - |m: &mut GameServer_Spec| { &mut m.health }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "GameServer.Spec", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static GameServer_Spec { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(GameServer_Spec::new) - } -} - -impl ::protobuf::Clear for GameServer_Spec { - fn clear(&mut self) { - self.health.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for GameServer_Spec { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for GameServer_Spec { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct GameServer_Spec_Health { - // message fields - pub disabled: bool, - pub period_seconds: i32, - pub failure_threshold: i32, - pub initial_delay_seconds: i32, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a GameServer_Spec_Health { - fn default() -> &'a GameServer_Spec_Health { - ::default_instance() - } -} - -impl GameServer_Spec_Health { - pub fn new() -> GameServer_Spec_Health { - ::std::default::Default::default() - } - - // bool disabled = 1; - - - pub fn get_disabled(&self) -> bool { - self.disabled - } - pub fn clear_disabled(&mut self) { - self.disabled = false; - } - - // Param is passed by value, moved - pub fn set_disabled(&mut self, v: bool) { - self.disabled = v; - } - - // int32 period_seconds = 2; - - - pub fn get_period_seconds(&self) -> i32 { - self.period_seconds - } - pub fn clear_period_seconds(&mut self) { - self.period_seconds = 0; - } - - // Param is passed by value, moved - pub fn set_period_seconds(&mut self, v: i32) { - self.period_seconds = v; - } - - // int32 failure_threshold = 3; - - - pub fn get_failure_threshold(&self) -> i32 { - self.failure_threshold - } - pub fn clear_failure_threshold(&mut self) { - self.failure_threshold = 0; - } - - // Param is passed by value, moved - pub fn set_failure_threshold(&mut self, v: i32) { - self.failure_threshold = v; - } - - // int32 initial_delay_seconds = 4; - - - pub fn get_initial_delay_seconds(&self) -> i32 { - self.initial_delay_seconds - } - pub fn clear_initial_delay_seconds(&mut self) { - self.initial_delay_seconds = 0; - } - - // Param is passed by value, moved - pub fn set_initial_delay_seconds(&mut self, v: i32) { - self.initial_delay_seconds = v; - } -} - -impl ::protobuf::Message for GameServer_Spec_Health { - fn is_initialized(&self) -> bool { - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_bool()?; - self.disabled = tmp; - }, - 2 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_int32()?; - self.period_seconds = tmp; - }, - 3 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_int32()?; - self.failure_threshold = tmp; - }, - 4 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_int32()?; - self.initial_delay_seconds = tmp; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if self.disabled != false { - my_size += 2; - } - if self.period_seconds != 0 { - my_size += ::protobuf::rt::value_size(2, self.period_seconds, ::protobuf::wire_format::WireTypeVarint); - } - if self.failure_threshold != 0 { - my_size += ::protobuf::rt::value_size(3, self.failure_threshold, ::protobuf::wire_format::WireTypeVarint); - } - if self.initial_delay_seconds != 0 { - my_size += ::protobuf::rt::value_size(4, self.initial_delay_seconds, ::protobuf::wire_format::WireTypeVarint); - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if self.disabled != false { - os.write_bool(1, self.disabled)?; - } - if self.period_seconds != 0 { - os.write_int32(2, self.period_seconds)?; - } - if self.failure_threshold != 0 { - os.write_int32(3, self.failure_threshold)?; - } - if self.initial_delay_seconds != 0 { - os.write_int32(4, self.initial_delay_seconds)?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> GameServer_Spec_Health { - GameServer_Spec_Health::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( - "disabled", - |m: &GameServer_Spec_Health| { &m.disabled }, - |m: &mut GameServer_Spec_Health| { &mut m.disabled }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( - "period_seconds", - |m: &GameServer_Spec_Health| { &m.period_seconds }, - |m: &mut GameServer_Spec_Health| { &mut m.period_seconds }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( - "failure_threshold", - |m: &GameServer_Spec_Health| { &m.failure_threshold }, - |m: &mut GameServer_Spec_Health| { &mut m.failure_threshold }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( - "initial_delay_seconds", - |m: &GameServer_Spec_Health| { &m.initial_delay_seconds }, - |m: &mut GameServer_Spec_Health| { &mut m.initial_delay_seconds }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "GameServer.Spec.Health", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static GameServer_Spec_Health { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(GameServer_Spec_Health::new) - } -} - -impl ::protobuf::Clear for GameServer_Spec_Health { - fn clear(&mut self) { - self.disabled = false; - self.period_seconds = 0; - self.failure_threshold = 0; - self.initial_delay_seconds = 0; - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for GameServer_Spec_Health { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for GameServer_Spec_Health { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct GameServer_Status { - // message fields - pub state: ::std::string::String, - pub address: ::std::string::String, - pub ports: ::protobuf::RepeatedField, - pub players: ::protobuf::SingularPtrField, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a GameServer_Status { - fn default() -> &'a GameServer_Status { - ::default_instance() - } -} - -impl GameServer_Status { - pub fn new() -> GameServer_Status { - ::std::default::Default::default() - } - - // string state = 1; - - - pub fn get_state(&self) -> &str { - &self.state - } - pub fn clear_state(&mut self) { - self.state.clear(); - } - - // Param is passed by value, moved - pub fn set_state(&mut self, v: ::std::string::String) { - self.state = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_state(&mut self) -> &mut ::std::string::String { - &mut self.state - } - - // Take field - pub fn take_state(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.state, ::std::string::String::new()) - } - - // string address = 2; - - - pub fn get_address(&self) -> &str { - &self.address - } - pub fn clear_address(&mut self) { - self.address.clear(); - } - - // Param is passed by value, moved - pub fn set_address(&mut self, v: ::std::string::String) { - self.address = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_address(&mut self) -> &mut ::std::string::String { - &mut self.address - } - - // Take field - pub fn take_address(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.address, ::std::string::String::new()) - } - - // repeated .agones.dev.sdk.GameServer.Status.Port ports = 3; - - - pub fn get_ports(&self) -> &[GameServer_Status_Port] { - &self.ports - } - pub fn clear_ports(&mut self) { - self.ports.clear(); - } - - // Param is passed by value, moved - pub fn set_ports(&mut self, v: ::protobuf::RepeatedField) { - self.ports = v; - } - - // Mutable pointer to the field. - pub fn mut_ports(&mut self) -> &mut ::protobuf::RepeatedField { - &mut self.ports - } - - // Take field - pub fn take_ports(&mut self) -> ::protobuf::RepeatedField { - ::std::mem::replace(&mut self.ports, ::protobuf::RepeatedField::new()) - } - - // .agones.dev.sdk.GameServer.Status.PlayerStatus players = 4; - - - pub fn get_players(&self) -> &GameServer_Status_PlayerStatus { - self.players.as_ref().unwrap_or_else(|| ::default_instance()) - } - pub fn clear_players(&mut self) { - self.players.clear(); - } - - pub fn has_players(&self) -> bool { - self.players.is_some() - } - - // Param is passed by value, moved - pub fn set_players(&mut self, v: GameServer_Status_PlayerStatus) { - self.players = ::protobuf::SingularPtrField::some(v); - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_players(&mut self) -> &mut GameServer_Status_PlayerStatus { - if self.players.is_none() { - self.players.set_default(); - } - self.players.as_mut().unwrap() - } - - // Take field - pub fn take_players(&mut self) -> GameServer_Status_PlayerStatus { - self.players.take().unwrap_or_else(|| GameServer_Status_PlayerStatus::new()) - } -} - -impl ::protobuf::Message for GameServer_Status { - fn is_initialized(&self) -> bool { - for v in &self.ports { - if !v.is_initialized() { - return false; - } - }; - for v in &self.players { - if !v.is_initialized() { - return false; - } - }; - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.state)?; - }, - 2 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.address)?; - }, - 3 => { - ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.ports)?; - }, - 4 => { - ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.players)?; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if !self.state.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.state); - } - if !self.address.is_empty() { - my_size += ::protobuf::rt::string_size(2, &self.address); - } - for value in &self.ports { - let len = value.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - }; - if let Some(ref v) = self.players.as_ref() { - let len = v.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.state.is_empty() { - os.write_string(1, &self.state)?; - } - if !self.address.is_empty() { - os.write_string(2, &self.address)?; - } - for v in &self.ports { - os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - }; - if let Some(ref v) = self.players.as_ref() { - os.write_tag(4, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> GameServer_Status { - GameServer_Status::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "state", - |m: &GameServer_Status| { &m.state }, - |m: &mut GameServer_Status| { &mut m.state }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "address", - |m: &GameServer_Status| { &m.address }, - |m: &mut GameServer_Status| { &mut m.address }, - )); - fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "ports", - |m: &GameServer_Status| { &m.ports }, - |m: &mut GameServer_Status| { &mut m.ports }, - )); - fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "players", - |m: &GameServer_Status| { &m.players }, - |m: &mut GameServer_Status| { &mut m.players }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "GameServer.Status", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static GameServer_Status { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(GameServer_Status::new) - } -} - -impl ::protobuf::Clear for GameServer_Status { - fn clear(&mut self) { - self.state.clear(); - self.address.clear(); - self.ports.clear(); - self.players.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for GameServer_Status { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for GameServer_Status { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct GameServer_Status_Port { - // message fields - pub name: ::std::string::String, - pub port: i32, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a GameServer_Status_Port { - fn default() -> &'a GameServer_Status_Port { - ::default_instance() - } -} - -impl GameServer_Status_Port { - pub fn new() -> GameServer_Status_Port { - ::std::default::Default::default() - } - - // string name = 1; - - - pub fn get_name(&self) -> &str { - &self.name - } - pub fn clear_name(&mut self) { - self.name.clear(); - } - - // Param is passed by value, moved - pub fn set_name(&mut self, v: ::std::string::String) { - self.name = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_name(&mut self) -> &mut ::std::string::String { - &mut self.name - } - - // Take field - pub fn take_name(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.name, ::std::string::String::new()) - } - - // int32 port = 2; - - - pub fn get_port(&self) -> i32 { - self.port - } - pub fn clear_port(&mut self) { - self.port = 0; - } - - // Param is passed by value, moved - pub fn set_port(&mut self, v: i32) { - self.port = v; - } -} - -impl ::protobuf::Message for GameServer_Status_Port { - fn is_initialized(&self) -> bool { - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.name)?; - }, - 2 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_int32()?; - self.port = tmp; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if !self.name.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.name); - } - if self.port != 0 { - my_size += ::protobuf::rt::value_size(2, self.port, ::protobuf::wire_format::WireTypeVarint); - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.name.is_empty() { - os.write_string(1, &self.name)?; - } - if self.port != 0 { - os.write_int32(2, self.port)?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> GameServer_Status_Port { - GameServer_Status_Port::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "name", - |m: &GameServer_Status_Port| { &m.name }, - |m: &mut GameServer_Status_Port| { &mut m.name }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( - "port", - |m: &GameServer_Status_Port| { &m.port }, - |m: &mut GameServer_Status_Port| { &mut m.port }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "GameServer.Status.Port", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static GameServer_Status_Port { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(GameServer_Status_Port::new) - } -} - -impl ::protobuf::Clear for GameServer_Status_Port { - fn clear(&mut self) { - self.name.clear(); - self.port = 0; - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for GameServer_Status_Port { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for GameServer_Status_Port { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct GameServer_Status_PlayerStatus { - // message fields - pub count: i64, - pub capacity: i64, - pub ids: ::protobuf::RepeatedField<::std::string::String>, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a GameServer_Status_PlayerStatus { - fn default() -> &'a GameServer_Status_PlayerStatus { - ::default_instance() - } -} - -impl GameServer_Status_PlayerStatus { - pub fn new() -> GameServer_Status_PlayerStatus { - ::std::default::Default::default() - } - - // int64 count = 1; - - - pub fn get_count(&self) -> i64 { - self.count - } - pub fn clear_count(&mut self) { - self.count = 0; - } - - // Param is passed by value, moved - pub fn set_count(&mut self, v: i64) { - self.count = v; - } - - // int64 capacity = 2; - - - pub fn get_capacity(&self) -> i64 { - self.capacity - } - pub fn clear_capacity(&mut self) { - self.capacity = 0; - } - - // Param is passed by value, moved - pub fn set_capacity(&mut self, v: i64) { - self.capacity = v; - } - - // repeated string ids = 3; - - - pub fn get_ids(&self) -> &[::std::string::String] { - &self.ids - } - pub fn clear_ids(&mut self) { - self.ids.clear(); - } - - // Param is passed by value, moved - pub fn set_ids(&mut self, v: ::protobuf::RepeatedField<::std::string::String>) { - self.ids = v; - } - - // Mutable pointer to the field. - pub fn mut_ids(&mut self) -> &mut ::protobuf::RepeatedField<::std::string::String> { - &mut self.ids - } - - // Take field - pub fn take_ids(&mut self) -> ::protobuf::RepeatedField<::std::string::String> { - ::std::mem::replace(&mut self.ids, ::protobuf::RepeatedField::new()) - } -} - -impl ::protobuf::Message for GameServer_Status_PlayerStatus { - fn is_initialized(&self) -> bool { - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_int64()?; - self.count = tmp; - }, - 2 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_int64()?; - self.capacity = tmp; - }, - 3 => { - ::protobuf::rt::read_repeated_string_into(wire_type, is, &mut self.ids)?; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if self.count != 0 { - my_size += ::protobuf::rt::value_size(1, self.count, ::protobuf::wire_format::WireTypeVarint); - } - if self.capacity != 0 { - my_size += ::protobuf::rt::value_size(2, self.capacity, ::protobuf::wire_format::WireTypeVarint); - } - for value in &self.ids { - my_size += ::protobuf::rt::string_size(3, &value); - }; - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if self.count != 0 { - os.write_int64(1, self.count)?; - } - if self.capacity != 0 { - os.write_int64(2, self.capacity)?; - } - for v in &self.ids { - os.write_string(3, &v)?; - }; - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> GameServer_Status_PlayerStatus { - GameServer_Status_PlayerStatus::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt64>( - "count", - |m: &GameServer_Status_PlayerStatus| { &m.count }, - |m: &mut GameServer_Status_PlayerStatus| { &mut m.count }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt64>( - "capacity", - |m: &GameServer_Status_PlayerStatus| { &m.capacity }, - |m: &mut GameServer_Status_PlayerStatus| { &mut m.capacity }, - )); - fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "ids", - |m: &GameServer_Status_PlayerStatus| { &m.ids }, - |m: &mut GameServer_Status_PlayerStatus| { &mut m.ids }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "GameServer.Status.PlayerStatus", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static GameServer_Status_PlayerStatus { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(GameServer_Status_PlayerStatus::new) - } -} - -impl ::protobuf::Clear for GameServer_Status_PlayerStatus { - fn clear(&mut self) { - self.count = 0; - self.capacity = 0; - self.ids.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for GameServer_Status_PlayerStatus { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for GameServer_Status_PlayerStatus { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -static file_descriptor_proto_data: &'static [u8] = b"\ - \n\tsdk.proto\x12\x0eagones.dev.sdk\x1a\x1cgoogle/api/annotations.proto\ - \"\x07\n\x05Empty\"2\n\x08KeyValue\x12\x10\n\x03key\x18\x01\x20\x01(\tR\ - \x03key\x12\x14\n\x05value\x18\x02\x20\x01(\tR\x05value\"$\n\x08Duration\ - \x12\x18\n\x07seconds\x18\x01\x20\x01(\x03R\x07seconds\"\x9f\n\n\nGameSe\ - rver\x12F\n\x0bobject_meta\x18\x01\x20\x01(\x0b2%.agones.dev.sdk.GameSer\ - ver.ObjectMetaR\nobjectMeta\x123\n\x04spec\x18\x02\x20\x01(\x0b2\x1f.ago\ - nes.dev.sdk.GameServer.SpecR\x04spec\x129\n\x06status\x18\x03\x20\x01(\ - \x0b2!.agones.dev.sdk.GameServer.StatusR\x06status\x1a\x99\x04\n\nObject\ - Meta\x12\x12\n\x04name\x18\x01\x20\x01(\tR\x04name\x12\x1c\n\tnamespace\ - \x18\x02\x20\x01(\tR\tnamespace\x12\x10\n\x03uid\x18\x03\x20\x01(\tR\x03\ - uid\x12)\n\x10resource_version\x18\x04\x20\x01(\tR\x0fresourceVersion\ - \x12\x1e\n\ngeneration\x18\x05\x20\x01(\x03R\ngeneration\x12-\n\x12creat\ - ion_timestamp\x18\x06\x20\x01(\x03R\x11creationTimestamp\x12-\n\x12delet\ - ion_timestamp\x18\x07\x20\x01(\x03R\x11deletionTimestamp\x12X\n\x0bannot\ - ations\x18\x08\x20\x03(\x0b26.agones.dev.sdk.GameServer.ObjectMeta.Annot\ - ationsEntryR\x0bannotations\x12I\n\x06labels\x18\t\x20\x03(\x0b21.agones\ - .dev.sdk.GameServer.ObjectMeta.LabelsEntryR\x06labels\x1a>\n\x10Annotati\ - onsEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\x14\n\x05value\ - \x18\x02\x20\x01(\tR\x05value:\x028\x01\x1a9\n\x0bLabelsEntry\x12\x10\n\ - \x03key\x18\x01\x20\x01(\tR\x03key\x12\x14\n\x05value\x18\x02\x20\x01(\t\ - R\x05value:\x028\x01\x1a\xf5\x01\n\x04Spec\x12>\n\x06health\x18\x01\x20\ - \x01(\x0b2&.agones.dev.sdk.GameServer.Spec.HealthR\x06health\x1a\xac\x01\ - \n\x06Health\x12\x1a\n\x08disabled\x18\x01\x20\x01(\x08R\x08disabled\x12\ - %\n\x0eperiod_seconds\x18\x02\x20\x01(\x05R\rperiodSeconds\x12+\n\x11fai\ - lure_threshold\x18\x03\x20\x01(\x05R\x10failureThreshold\x122\n\x15initi\ - al_delay_seconds\x18\x04\x20\x01(\x05R\x13initialDelaySeconds\x1a\xc4\ - \x02\n\x06Status\x12\x14\n\x05state\x18\x01\x20\x01(\tR\x05state\x12\x18\ - \n\x07address\x18\x02\x20\x01(\tR\x07address\x12<\n\x05ports\x18\x03\x20\ - \x03(\x0b2&.agones.dev.sdk.GameServer.Status.PortR\x05ports\x12H\n\x07pl\ - ayers\x18\x04\x20\x01(\x0b2..agones.dev.sdk.GameServer.Status.PlayerStat\ - usR\x07players\x1a.\n\x04Port\x12\x12\n\x04name\x18\x01\x20\x01(\tR\x04n\ - ame\x12\x12\n\x04port\x18\x02\x20\x01(\x05R\x04port\x1aR\n\x0cPlayerStat\ - us\x12\x14\n\x05count\x18\x01\x20\x01(\x03R\x05count\x12\x1a\n\x08capaci\ - ty\x18\x02\x20\x01(\x03R\x08capacity\x12\x10\n\x03ids\x18\x03\x20\x03(\t\ - R\x03ids2\x86\x06\n\x03SDK\x12H\n\x05Ready\x12\x15.agones.dev.sdk.Empty\ - \x1a\x15.agones.dev.sdk.Empty\"\x11\x82\xd3\xe4\x93\x02\x0b\"\x06/ready:\ - \x01*\x12N\n\x08Allocate\x12\x15.agones.dev.sdk.Empty\x1a\x15.agones.dev\ - .sdk.Empty\"\x14\x82\xd3\xe4\x93\x02\x0e\"\t/allocate:\x01*\x12N\n\x08Sh\ - utdown\x12\x15.agones.dev.sdk.Empty\x1a\x15.agones.dev.sdk.Empty\"\x14\ - \x82\xd3\xe4\x93\x02\x0e\"\t/shutdown:\x01*\x12L\n\x06Health\x12\x15.ago\ - nes.dev.sdk.Empty\x1a\x15.agones.dev.sdk.Empty\"\x12\x82\xd3\xe4\x93\x02\ - \x0c\"\x07/health:\x01*(\x01\x12W\n\rGetGameServer\x12\x15.agones.dev.sd\ - k.Empty\x1a\x1a.agones.dev.sdk.GameServer\"\x13\x82\xd3\xe4\x93\x02\r\ - \x12\x0b/gameserver\x12a\n\x0fWatchGameServer\x12\x15.agones.dev.sdk.Emp\ - ty\x1a\x1a.agones.dev.sdk.GameServer\"\x19\x82\xd3\xe4\x93\x02\x13\x12\ - \x11/watch/gameserver0\x01\x12W\n\x08SetLabel\x12\x18.agones.dev.sdk.Key\ - Value\x1a\x15.agones.dev.sdk.Empty\"\x1a\x82\xd3\xe4\x93\x02\x14\x1a\x0f\ - /metadata/label:\x01*\x12a\n\rSetAnnotation\x12\x18.agones.dev.sdk.KeyVa\ - lue\x1a\x15.agones.dev.sdk.Empty\"\x1f\x82\xd3\xe4\x93\x02\x19\x1a\x14/m\ - etadata/annotation:\x01*\x12O\n\x07Reserve\x12\x18.agones.dev.sdk.Durati\ - on\x1a\x15.agones.dev.sdk.Empty\"\x13\x82\xd3\xe4\x93\x02\r\"\x08/reserv\ - e:\x01*B\x05Z\x03sdkJ\xf3(\n\x07\x12\x05\x0e\0\xa1\x01\x01\n\xd1\x04\n\ - \x01\x0c\x12\x03\x0e\0\x122\xc6\x04\x20Copyright\x202017\x20Google\x20LL\ - C\x20All\x20Rights\x20Reserved.\n\n\x20Licensed\x20under\x20the\x20Apach\ - e\x20License,\x20Version\x202.0\x20(the\x20\"License\");\n\x20you\x20may\ - \x20not\x20use\x20this\x20file\x20except\x20in\x20compliance\x20with\x20\ - the\x20License.\n\x20You\x20may\x20obtain\x20a\x20copy\x20of\x20the\x20L\ - icense\x20at\n\n\x20\x20\x20\x20\x20http://www.apache.org/licenses/LICEN\ - SE-2.0\n\n\x20Unless\x20required\x20by\x20applicable\x20law\x20or\x20agr\ - eed\x20to\x20in\x20writing,\x20software\n\x20distributed\x20under\x20the\ - \x20License\x20is\x20distributed\x20on\x20an\x20\"AS\x20IS\"\x20BASIS,\n\ - \x20WITHOUT\x20WARRANTIES\x20OR\x20CONDITIONS\x20OF\x20ANY\x20KIND,\x20e\ - ither\x20express\x20or\x20implied.\n\x20See\x20the\x20License\x20for\x20\ - the\x20specific\x20language\x20governing\x20permissions\x20and\n\x20limi\ - tations\x20under\x20the\x20License.\n\n\x08\n\x01\x02\x12\x03\x10\0\x17\ - \n\x08\n\x01\x08\x12\x03\x11\0\x1a\n\t\n\x02\x08\x0b\x12\x03\x11\0\x1a\n\ - \t\n\x02\x03\0\x12\x03\x13\0&\nM\n\x02\x06\0\x12\x04\x16\0Y\x01\x1aA\x20\ - SDK\x20service\x20to\x20be\x20used\x20in\x20the\x20GameServer\x20SDK\x20\ - to\x20the\x20Pod\x20Sidecar\n\n\n\n\x03\x06\0\x01\x12\x03\x16\x08\x0b\n1\ - \n\x04\x06\0\x02\0\x12\x04\x18\x04\x1d\x05\x1a#\x20Call\x20when\x20the\ - \x20GameServer\x20is\x20ready\n\n\x0c\n\x05\x06\0\x02\0\x01\x12\x03\x18\ - \x08\r\n\x0c\n\x05\x06\0\x02\0\x02\x12\x03\x18\x0f\x14\n\x0c\n\x05\x06\0\ - \x02\0\x03\x12\x03\x18\x1f$\n\r\n\x05\x06\0\x02\0\x04\x12\x04\x19\x08\ - \x1c\n\n\x11\n\t\x06\0\x02\0\x04\xb0\xca\xbc\"\x12\x04\x19\x08\x1c\n\n6\ - \n\x04\x06\0\x02\x01\x12\x04\x20\x04%\x05\x1a(\x20Call\x20to\x20self\x20\ - Allocation\x20the\x20GameServer\n\n\x0c\n\x05\x06\0\x02\x01\x01\x12\x03\ - \x20\x08\x10\n\x0c\n\x05\x06\0\x02\x01\x02\x12\x03\x20\x11\x16\n\x0c\n\ - \x05\x06\0\x02\x01\x03\x12\x03\x20!&\n\r\n\x05\x06\0\x02\x01\x04\x12\x04\ - !\x08$\n\n\x11\n\t\x06\0\x02\x01\x04\xb0\xca\xbc\"\x12\x04!\x08$\n\n9\n\ - \x04\x06\0\x02\x02\x12\x04(\x04-\x05\x1a+\x20Call\x20when\x20the\x20Game\ - Server\x20is\x20shutting\x20down\n\n\x0c\n\x05\x06\0\x02\x02\x01\x12\x03\ - (\x08\x10\n\x0c\n\x05\x06\0\x02\x02\x02\x12\x03(\x12\x17\n\x0c\n\x05\x06\ - \0\x02\x02\x03\x12\x03(\"'\n\r\n\x05\x06\0\x02\x02\x04\x12\x04)\x08,\n\n\ - \x11\n\t\x06\0\x02\x02\x04\xb0\xca\xbc\"\x12\x04)\x08,\n\nW\n\x04\x06\0\ - \x02\x03\x12\x04/\x044\x05\x1aI\x20Send\x20a\x20Empty\x20every\x20d\x20D\ - uration\x20to\x20declare\x20that\x20this\x20GameSever\x20is\x20healthy\n\ - \n\x0c\n\x05\x06\0\x02\x03\x01\x12\x03/\x08\x0e\n\x0c\n\x05\x06\0\x02\ - \x03\x05\x12\x03/\x10\x16\n\x0c\n\x05\x06\0\x02\x03\x02\x12\x03/\x17\x1c\ - \n\x0c\n\x05\x06\0\x02\x03\x03\x12\x03/',\n\r\n\x05\x06\0\x02\x03\x04\ - \x12\x040\x083\x12\n\x11\n\t\x06\0\x02\x03\x04\xb0\xca\xbc\"\x12\x040\ - \x083\x12\n4\n\x04\x06\0\x02\x04\x12\x046\x04:\x05\x1a&\x20Retrieve\x20t\ - he\x20current\x20GameServer\x20data\n\n\x0c\n\x05\x06\0\x02\x04\x01\x12\ - \x036\x08\x15\n\x0c\n\x05\x06\0\x02\x04\x02\x12\x036\x17\x1c\n\x0c\n\x05\ - \x06\0\x02\x04\x03\x12\x036'1\n\r\n\x05\x06\0\x02\x04\x04\x12\x047\x089\ - \n\n\x11\n\t\x06\0\x02\x04\x04\xb0\xca\xbc\"\x12\x047\x089\n\nJ\n\x04\ - \x06\0\x02\x05\x12\x04<\x04@\x05\x1a<\x20Send\x20GameServer\x20details\ - \x20whenever\x20the\x20GameServer\x20is\x20updated\n\n\x0c\n\x05\x06\0\ - \x02\x05\x01\x12\x03<\x08\x17\n\x0c\n\x05\x06\0\x02\x05\x02\x12\x03<\x19\ - \x1e\n\x0c\n\x05\x06\0\x02\x05\x06\x12\x03<)/\n\x0c\n\x05\x06\0\x02\x05\ - \x03\x12\x03<0:\n\r\n\x05\x06\0\x02\x05\x04\x12\x04=\x08?\n\n\x11\n\t\ - \x06\0\x02\x05\x04\xb0\xca\xbc\"\x12\x04=\x08?\n\n@\n\x04\x06\0\x02\x06\ - \x12\x04C\x04H\x05\x1a2\x20Apply\x20a\x20Label\x20to\x20the\x20backing\ - \x20GameServer\x20metadata\n\n\x0c\n\x05\x06\0\x02\x06\x01\x12\x03C\x08\ - \x10\n\x0c\n\x05\x06\0\x02\x06\x02\x12\x03C\x11\x19\n\x0c\n\x05\x06\0\ - \x02\x06\x03\x12\x03C$)\n\r\n\x05\x06\0\x02\x06\x04\x12\x04D\x08G\x12\n\ - \x11\n\t\x06\0\x02\x06\x04\xb0\xca\xbc\"\x12\x04D\x08G\x12\nE\n\x04\x06\ - \0\x02\x07\x12\x04K\x04P\x05\x1a7\x20Apply\x20a\x20Annotation\x20to\x20t\ - he\x20backing\x20GameServer\x20metadata\n\n\x0c\n\x05\x06\0\x02\x07\x01\ - \x12\x03K\x08\x15\n\x0c\n\x05\x06\0\x02\x07\x02\x12\x03K\x16\x1e\n\x0c\n\ - \x05\x06\0\x02\x07\x03\x12\x03K).\n\r\n\x05\x06\0\x02\x07\x04\x12\x04L\ - \x08O\x12\n\x11\n\t\x06\0\x02\x07\x04\xb0\xca\xbc\"\x12\x04L\x08O\x12\nG\ - \n\x04\x06\0\x02\x08\x12\x04S\x04X\x05\x1a9\x20Marks\x20the\x20GameServe\ - r\x20as\x20the\x20Reserved\x20state\x20for\x20Duration\n\n\x0c\n\x05\x06\ - \0\x02\x08\x01\x12\x03S\x08\x0f\n\x0c\n\x05\x06\0\x02\x08\x02\x12\x03S\ - \x10\x18\n\x0c\n\x05\x06\0\x02\x08\x03\x12\x03S#(\n\r\n\x05\x06\0\x02\ - \x08\x04\x12\x04T\x08W\n\n\x11\n\t\x06\0\x02\x08\x04\xb0\xca\xbc\"\x12\ - \x04T\x08W\n\n\x18\n\x02\x04\0\x12\x04\\\0]\x01\x1a\x0c\x20I\x20am\x20Em\ - pty\n\n\n\n\x03\x04\0\x01\x12\x03\\\x08\r\n\x1e\n\x02\x04\x01\x12\x04`\0\ - c\x01\x1a\x12\x20Key,\x20Value\x20entry\n\n\n\n\x03\x04\x01\x01\x12\x03`\ - \x08\x10\n\x0b\n\x04\x04\x01\x02\0\x12\x03a\x04\x13\n\r\n\x05\x04\x01\ - \x02\0\x04\x12\x04a\x04`\x12\n\x0c\n\x05\x04\x01\x02\0\x05\x12\x03a\x04\ - \n\n\x0c\n\x05\x04\x01\x02\0\x01\x12\x03a\x0b\x0e\n\x0c\n\x05\x04\x01\ - \x02\0\x03\x12\x03a\x11\x12\n\x0b\n\x04\x04\x01\x02\x01\x12\x03b\x04\x15\ - \n\r\n\x05\x04\x01\x02\x01\x04\x12\x04b\x04a\x13\n\x0c\n\x05\x04\x01\x02\ - \x01\x05\x12\x03b\x04\n\n\x0c\n\x05\x04\x01\x02\x01\x01\x12\x03b\x0b\x10\ - \n\x0c\n\x05\x04\x01\x02\x01\x03\x12\x03b\x13\x14\n'\n\x02\x04\x02\x12\ - \x04f\0h\x01\x1a\x1b\x20time\x20duration,\x20in\x20seconds\n\n\n\n\x03\ - \x04\x02\x01\x12\x03f\x08\x10\n\x0b\n\x04\x04\x02\x02\0\x12\x03g\x04\x16\ - \n\r\n\x05\x04\x02\x02\0\x04\x12\x04g\x04f\x12\n\x0c\n\x05\x04\x02\x02\0\ - \x05\x12\x03g\x04\t\n\x0c\n\x05\x04\x02\x02\0\x01\x12\x03g\n\x11\n\x0c\n\ - \x05\x04\x02\x02\0\x03\x12\x03g\x14\x15\n\xa3\x01\n\x02\x04\x03\x12\x05m\ - \0\xa1\x01\x01\x1a\x95\x01\x20A\x20GameServer\x20Custom\x20Resource\x20D\ - efinition\x20object\n\x20We\x20will\x20only\x20export\x20those\x20resour\ - ces\x20that\x20make\x20the\x20most\n\x20sense.\x20Can\x20always\x20expan\ - d\x20to\x20more\x20as\x20needed.\n\n\n\n\x03\x04\x03\x01\x12\x03m\x08\ - \x12\n\x0b\n\x04\x04\x03\x02\0\x12\x03n\x04\x1f\n\r\n\x05\x04\x03\x02\0\ - \x04\x12\x04n\x04m\x14\n\x0c\n\x05\x04\x03\x02\0\x06\x12\x03n\x04\x0e\n\ - \x0c\n\x05\x04\x03\x02\0\x01\x12\x03n\x0f\x1a\n\x0c\n\x05\x04\x03\x02\0\ - \x03\x12\x03n\x1d\x1e\n\x0b\n\x04\x04\x03\x02\x01\x12\x03o\x04\x12\n\r\n\ - \x05\x04\x03\x02\x01\x04\x12\x04o\x04n\x1f\n\x0c\n\x05\x04\x03\x02\x01\ - \x06\x12\x03o\x04\x08\n\x0c\n\x05\x04\x03\x02\x01\x01\x12\x03o\t\r\n\x0c\ - \n\x05\x04\x03\x02\x01\x03\x12\x03o\x10\x11\n\x0b\n\x04\x04\x03\x02\x02\ - \x12\x03p\x04\x16\n\r\n\x05\x04\x03\x02\x02\x04\x12\x04p\x04o\x12\n\x0c\ - \n\x05\x04\x03\x02\x02\x06\x12\x03p\x04\n\n\x0c\n\x05\x04\x03\x02\x02\ - \x01\x12\x03p\x0b\x11\n\x0c\n\x05\x04\x03\x02\x02\x03\x12\x03p\x14\x15\n\ - =\n\x04\x04\x03\x03\0\x12\x04s\x04\x7f\x05\x1a/\x20representation\x20of\ - \x20the\x20K8s\x20ObjectMeta\x20resource\n\n\x0c\n\x05\x04\x03\x03\0\x01\ - \x12\x03s\x0c\x16\n\r\n\x06\x04\x03\x03\0\x02\0\x12\x03t\x08\x18\n\x0f\n\ - \x07\x04\x03\x03\0\x02\0\x04\x12\x04t\x08s\x18\n\x0e\n\x07\x04\x03\x03\0\ - \x02\0\x05\x12\x03t\x08\x0e\n\x0e\n\x07\x04\x03\x03\0\x02\0\x01\x12\x03t\ - \x0f\x13\n\x0e\n\x07\x04\x03\x03\0\x02\0\x03\x12\x03t\x16\x17\n\r\n\x06\ - \x04\x03\x03\0\x02\x01\x12\x03u\x08\x1d\n\x0f\n\x07\x04\x03\x03\0\x02\ - \x01\x04\x12\x04u\x08t\x18\n\x0e\n\x07\x04\x03\x03\0\x02\x01\x05\x12\x03\ - u\x08\x0e\n\x0e\n\x07\x04\x03\x03\0\x02\x01\x01\x12\x03u\x0f\x18\n\x0e\n\ - \x07\x04\x03\x03\0\x02\x01\x03\x12\x03u\x1b\x1c\n\r\n\x06\x04\x03\x03\0\ - \x02\x02\x12\x03v\x08\x17\n\x0f\n\x07\x04\x03\x03\0\x02\x02\x04\x12\x04v\ - \x08u\x1d\n\x0e\n\x07\x04\x03\x03\0\x02\x02\x05\x12\x03v\x08\x0e\n\x0e\n\ - \x07\x04\x03\x03\0\x02\x02\x01\x12\x03v\x0f\x12\n\x0e\n\x07\x04\x03\x03\ - \0\x02\x02\x03\x12\x03v\x15\x16\n\r\n\x06\x04\x03\x03\0\x02\x03\x12\x03w\ - \x08$\n\x0f\n\x07\x04\x03\x03\0\x02\x03\x04\x12\x04w\x08v\x17\n\x0e\n\ - \x07\x04\x03\x03\0\x02\x03\x05\x12\x03w\x08\x0e\n\x0e\n\x07\x04\x03\x03\ - \0\x02\x03\x01\x12\x03w\x0f\x1f\n\x0e\n\x07\x04\x03\x03\0\x02\x03\x03\ - \x12\x03w\"#\n\r\n\x06\x04\x03\x03\0\x02\x04\x12\x03x\x08\x1d\n\x0f\n\ - \x07\x04\x03\x03\0\x02\x04\x04\x12\x04x\x08w$\n\x0e\n\x07\x04\x03\x03\0\ - \x02\x04\x05\x12\x03x\x08\r\n\x0e\n\x07\x04\x03\x03\0\x02\x04\x01\x12\ - \x03x\x0e\x18\n\x0e\n\x07\x04\x03\x03\0\x02\x04\x03\x12\x03x\x1b\x1c\n<\ - \n\x06\x04\x03\x03\0\x02\x05\x12\x03z\x08%\x1a-\x20timestamp\x20is\x20in\ - \x20Epoch\x20format,\x20unit:\x20seconds\n\n\x0f\n\x07\x04\x03\x03\0\x02\ - \x05\x04\x12\x04z\x08x\x1d\n\x0e\n\x07\x04\x03\x03\0\x02\x05\x05\x12\x03\ - z\x08\r\n\x0e\n\x07\x04\x03\x03\0\x02\x05\x01\x12\x03z\x0e\x20\n\x0e\n\ - \x07\x04\x03\x03\0\x02\x05\x03\x12\x03z#$\nK\n\x06\x04\x03\x03\0\x02\x06\ - \x12\x03|\x08%\x1a<\x20optional\x20deletion\x20timestamp\x20in\x20Epoch\ - \x20format,\x20unit:\x20seconds\n\n\x0f\n\x07\x04\x03\x03\0\x02\x06\x04\ - \x12\x04|\x08z%\n\x0e\n\x07\x04\x03\x03\0\x02\x06\x05\x12\x03|\x08\r\n\ - \x0e\n\x07\x04\x03\x03\0\x02\x06\x01\x12\x03|\x0e\x20\n\x0e\n\x07\x04\ - \x03\x03\0\x02\x06\x03\x12\x03|#$\n\r\n\x06\x04\x03\x03\0\x02\x07\x12\ - \x03}\x08,\n\x0f\n\x07\x04\x03\x03\0\x02\x07\x04\x12\x04}\x08|%\n\x0e\n\ - \x07\x04\x03\x03\0\x02\x07\x06\x12\x03}\x08\x1b\n\x0e\n\x07\x04\x03\x03\ - \0\x02\x07\x01\x12\x03}\x1c'\n\x0e\n\x07\x04\x03\x03\0\x02\x07\x03\x12\ - \x03}*+\n\r\n\x06\x04\x03\x03\0\x02\x08\x12\x03~\x08'\n\x0f\n\x07\x04\ - \x03\x03\0\x02\x08\x04\x12\x04~\x08},\n\x0e\n\x07\x04\x03\x03\0\x02\x08\ - \x06\x12\x03~\x08\x1b\n\x0e\n\x07\x04\x03\x03\0\x02\x08\x01\x12\x03~\x1c\ - \"\n\x0e\n\x07\x04\x03\x03\0\x02\x08\x03\x12\x03~%&\n\x0e\n\x04\x04\x03\ - \x03\x01\x12\x06\x81\x01\x04\x8a\x01\x05\n\r\n\x05\x04\x03\x03\x01\x01\ - \x12\x04\x81\x01\x0c\x10\n\x0e\n\x06\x04\x03\x03\x01\x02\0\x12\x04\x82\ - \x01\x08\x1a\n\x11\n\x07\x04\x03\x03\x01\x02\0\x04\x12\x06\x82\x01\x08\ - \x81\x01\x12\n\x0f\n\x07\x04\x03\x03\x01\x02\0\x06\x12\x04\x82\x01\x08\ - \x0e\n\x0f\n\x07\x04\x03\x03\x01\x02\0\x01\x12\x04\x82\x01\x0f\x15\n\x0f\ - \n\x07\x04\x03\x03\x01\x02\0\x03\x12\x04\x82\x01\x18\x19\n\x10\n\x06\x04\ - \x03\x03\x01\x03\0\x12\x06\x84\x01\x08\x89\x01\t\n\x0f\n\x07\x04\x03\x03\ - \x01\x03\0\x01\x12\x04\x84\x01\x10\x16\n\x10\n\x08\x04\x03\x03\x01\x03\0\ - \x02\0\x12\x04\x85\x01\x0c\x1e\n\x13\n\t\x04\x03\x03\x01\x03\0\x02\0\x04\ - \x12\x06\x85\x01\x0c\x84\x01\x18\n\x11\n\t\x04\x03\x03\x01\x03\0\x02\0\ - \x05\x12\x04\x85\x01\x0c\x10\n\x11\n\t\x04\x03\x03\x01\x03\0\x02\0\x01\ - \x12\x04\x85\x01\x11\x19\n\x11\n\t\x04\x03\x03\x01\x03\0\x02\0\x03\x12\ - \x04\x85\x01\x1c\x1d\n\x10\n\x08\x04\x03\x03\x01\x03\0\x02\x01\x12\x04\ - \x86\x01\x0c%\n\x13\n\t\x04\x03\x03\x01\x03\0\x02\x01\x04\x12\x06\x86\ - \x01\x0c\x85\x01\x1e\n\x11\n\t\x04\x03\x03\x01\x03\0\x02\x01\x05\x12\x04\ - \x86\x01\x0c\x11\n\x11\n\t\x04\x03\x03\x01\x03\0\x02\x01\x01\x12\x04\x86\ - \x01\x12\x20\n\x11\n\t\x04\x03\x03\x01\x03\0\x02\x01\x03\x12\x04\x86\x01\ - #$\n\x10\n\x08\x04\x03\x03\x01\x03\0\x02\x02\x12\x04\x87\x01\x0c(\n\x13\ - \n\t\x04\x03\x03\x01\x03\0\x02\x02\x04\x12\x06\x87\x01\x0c\x86\x01%\n\ - \x11\n\t\x04\x03\x03\x01\x03\0\x02\x02\x05\x12\x04\x87\x01\x0c\x11\n\x11\ - \n\t\x04\x03\x03\x01\x03\0\x02\x02\x01\x12\x04\x87\x01\x12#\n\x11\n\t\ - \x04\x03\x03\x01\x03\0\x02\x02\x03\x12\x04\x87\x01&'\n\x10\n\x08\x04\x03\ - \x03\x01\x03\0\x02\x03\x12\x04\x88\x01\x0c,\n\x13\n\t\x04\x03\x03\x01\ - \x03\0\x02\x03\x04\x12\x06\x88\x01\x0c\x87\x01(\n\x11\n\t\x04\x03\x03\ - \x01\x03\0\x02\x03\x05\x12\x04\x88\x01\x0c\x11\n\x11\n\t\x04\x03\x03\x01\ - \x03\0\x02\x03\x01\x12\x04\x88\x01\x12'\n\x11\n\t\x04\x03\x03\x01\x03\0\ - \x02\x03\x03\x12\x04\x88\x01*+\n\x0e\n\x04\x04\x03\x03\x02\x12\x06\x8c\ - \x01\x04\xa0\x01\x05\n\r\n\x05\x04\x03\x03\x02\x01\x12\x04\x8c\x01\x0c\ - \x12\n\x10\n\x06\x04\x03\x03\x02\x03\0\x12\x06\x8d\x01\x08\x90\x01\t\n\ - \x0f\n\x07\x04\x03\x03\x02\x03\0\x01\x12\x04\x8d\x01\x10\x14\n\x10\n\x08\ - \x04\x03\x03\x02\x03\0\x02\0\x12\x04\x8e\x01\x0c\x1c\n\x13\n\t\x04\x03\ - \x03\x02\x03\0\x02\0\x04\x12\x06\x8e\x01\x0c\x8d\x01\x16\n\x11\n\t\x04\ - \x03\x03\x02\x03\0\x02\0\x05\x12\x04\x8e\x01\x0c\x12\n\x11\n\t\x04\x03\ - \x03\x02\x03\0\x02\0\x01\x12\x04\x8e\x01\x13\x17\n\x11\n\t\x04\x03\x03\ - \x02\x03\0\x02\0\x03\x12\x04\x8e\x01\x1a\x1b\n\x10\n\x08\x04\x03\x03\x02\ - \x03\0\x02\x01\x12\x04\x8f\x01\x0c\x1b\n\x13\n\t\x04\x03\x03\x02\x03\0\ - \x02\x01\x04\x12\x06\x8f\x01\x0c\x8e\x01\x1c\n\x11\n\t\x04\x03\x03\x02\ - \x03\0\x02\x01\x05\x12\x04\x8f\x01\x0c\x11\n\x11\n\t\x04\x03\x03\x02\x03\ - \0\x02\x01\x01\x12\x04\x8f\x01\x12\x16\n\x11\n\t\x04\x03\x03\x02\x03\0\ - \x02\x01\x03\x12\x04\x8f\x01\x19\x1a\n?\n\x06\x04\x03\x03\x02\x03\x01\ - \x12\x06\x93\x01\x08\x97\x01\t\x1a-\x20[Stage:Alpha]\n\x20[FeatureFlag:P\ - layerTracking]\n\n\x0f\n\x07\x04\x03\x03\x02\x03\x01\x01\x12\x04\x93\x01\ - \x10\x1c\n\x10\n\x08\x04\x03\x03\x02\x03\x01\x02\0\x12\x04\x94\x01\x0c\ - \x1c\n\x13\n\t\x04\x03\x03\x02\x03\x01\x02\0\x04\x12\x06\x94\x01\x0c\x93\ - \x01\x1e\n\x11\n\t\x04\x03\x03\x02\x03\x01\x02\0\x05\x12\x04\x94\x01\x0c\ - \x11\n\x11\n\t\x04\x03\x03\x02\x03\x01\x02\0\x01\x12\x04\x94\x01\x12\x17\ - \n\x11\n\t\x04\x03\x03\x02\x03\x01\x02\0\x03\x12\x04\x94\x01\x1a\x1b\n\ - \x10\n\x08\x04\x03\x03\x02\x03\x01\x02\x01\x12\x04\x95\x01\x0c\x1f\n\x13\ - \n\t\x04\x03\x03\x02\x03\x01\x02\x01\x04\x12\x06\x95\x01\x0c\x94\x01\x1c\ - \n\x11\n\t\x04\x03\x03\x02\x03\x01\x02\x01\x05\x12\x04\x95\x01\x0c\x11\n\ - \x11\n\t\x04\x03\x03\x02\x03\x01\x02\x01\x01\x12\x04\x95\x01\x12\x1a\n\ - \x11\n\t\x04\x03\x03\x02\x03\x01\x02\x01\x03\x12\x04\x95\x01\x1d\x1e\n\ - \x10\n\x08\x04\x03\x03\x02\x03\x01\x02\x02\x12\x04\x96\x01\x0c$\n\x11\n\ - \t\x04\x03\x03\x02\x03\x01\x02\x02\x04\x12\x04\x96\x01\x0c\x14\n\x11\n\t\ - \x04\x03\x03\x02\x03\x01\x02\x02\x05\x12\x04\x96\x01\x15\x1b\n\x11\n\t\ - \x04\x03\x03\x02\x03\x01\x02\x02\x01\x12\x04\x96\x01\x1c\x1f\n\x11\n\t\ - \x04\x03\x03\x02\x03\x01\x02\x02\x03\x12\x04\x96\x01\"#\n\x0e\n\x06\x04\ - \x03\x03\x02\x02\0\x12\x04\x99\x01\x08\x19\n\x11\n\x07\x04\x03\x03\x02\ - \x02\0\x04\x12\x06\x99\x01\x08\x97\x01\t\n\x0f\n\x07\x04\x03\x03\x02\x02\ - \0\x05\x12\x04\x99\x01\x08\x0e\n\x0f\n\x07\x04\x03\x03\x02\x02\0\x01\x12\ - \x04\x99\x01\x0f\x14\n\x0f\n\x07\x04\x03\x03\x02\x02\0\x03\x12\x04\x99\ - \x01\x17\x18\n\x0e\n\x06\x04\x03\x03\x02\x02\x01\x12\x04\x9a\x01\x08\x1b\ - \n\x11\n\x07\x04\x03\x03\x02\x02\x01\x04\x12\x06\x9a\x01\x08\x99\x01\x19\ - \n\x0f\n\x07\x04\x03\x03\x02\x02\x01\x05\x12\x04\x9a\x01\x08\x0e\n\x0f\n\ - \x07\x04\x03\x03\x02\x02\x01\x01\x12\x04\x9a\x01\x0f\x16\n\x0f\n\x07\x04\ - \x03\x03\x02\x02\x01\x03\x12\x04\x9a\x01\x19\x1a\n\x0e\n\x06\x04\x03\x03\ - \x02\x02\x02\x12\x04\x9b\x01\x08\x20\n\x0f\n\x07\x04\x03\x03\x02\x02\x02\ - \x04\x12\x04\x9b\x01\x08\x10\n\x0f\n\x07\x04\x03\x03\x02\x02\x02\x06\x12\ - \x04\x9b\x01\x11\x15\n\x0f\n\x07\x04\x03\x03\x02\x02\x02\x01\x12\x04\x9b\ - \x01\x16\x1b\n\x0f\n\x07\x04\x03\x03\x02\x02\x02\x03\x12\x04\x9b\x01\x1e\ - \x1f\n=\n\x06\x04\x03\x03\x02\x02\x03\x12\x04\x9f\x01\x08!\x1a-\x20[Stag\ - e:Alpha]\n\x20[FeatureFlag:PlayerTracking]\n\n\x11\n\x07\x04\x03\x03\x02\ - \x02\x03\x04\x12\x06\x9f\x01\x08\x9b\x01\x20\n\x0f\n\x07\x04\x03\x03\x02\ - \x02\x03\x06\x12\x04\x9f\x01\x08\x14\n\x0f\n\x07\x04\x03\x03\x02\x02\x03\ - \x01\x12\x04\x9f\x01\x15\x1c\n\x0f\n\x07\x04\x03\x03\x02\x02\x03\x03\x12\ - \x04\x9f\x01\x1f\x20b\x06proto3\ -"; - -static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; - -fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto { - ::protobuf::parse_from_bytes(file_descriptor_proto_data).unwrap() -} - -pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto { - file_descriptor_proto_lazy.get(|| { - parse_descriptor_proto() - }) -} diff --git a/sdks/rust/src/grpc/sdk_grpc.rs b/sdks/rust/src/grpc/sdk_grpc.rs deleted file mode 100644 index 6288776f67..0000000000 --- a/sdks/rust/src/grpc/sdk_grpc.rs +++ /dev/null @@ -1,294 +0,0 @@ -// Copyright 2020 Google LLC All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// This code was autogenerated. Do not edit directly. -// This file is generated. Do not edit -// @generated - -// https://github.com/Manishearth/rust-clippy/issues/702 -#![allow(unknown_lints)] -#![allow(clippy::all)] - -#![cfg_attr(rustfmt, rustfmt_skip)] - -#![allow(box_pointers)] -#![allow(dead_code)] -#![allow(missing_docs)] -#![allow(non_camel_case_types)] -#![allow(non_snake_case)] -#![allow(non_upper_case_globals)] -#![allow(trivial_casts)] -#![allow(unsafe_code)] -#![allow(unused_imports)] -#![allow(unused_results)] - -const METHOD_SDK_READY: ::grpcio::Method = ::grpcio::Method { - ty: ::grpcio::MethodType::Unary, - name: "/agones.dev.sdk.SDK/Ready", - req_mar: ::grpcio::Marshaller { ser: ::grpcio::pb_ser, de: ::grpcio::pb_de }, - resp_mar: ::grpcio::Marshaller { ser: ::grpcio::pb_ser, de: ::grpcio::pb_de }, -}; - -const METHOD_SDK_ALLOCATE: ::grpcio::Method = ::grpcio::Method { - ty: ::grpcio::MethodType::Unary, - name: "/agones.dev.sdk.SDK/Allocate", - req_mar: ::grpcio::Marshaller { ser: ::grpcio::pb_ser, de: ::grpcio::pb_de }, - resp_mar: ::grpcio::Marshaller { ser: ::grpcio::pb_ser, de: ::grpcio::pb_de }, -}; - -const METHOD_SDK_SHUTDOWN: ::grpcio::Method = ::grpcio::Method { - ty: ::grpcio::MethodType::Unary, - name: "/agones.dev.sdk.SDK/Shutdown", - req_mar: ::grpcio::Marshaller { ser: ::grpcio::pb_ser, de: ::grpcio::pb_de }, - resp_mar: ::grpcio::Marshaller { ser: ::grpcio::pb_ser, de: ::grpcio::pb_de }, -}; - -const METHOD_SDK_HEALTH: ::grpcio::Method = ::grpcio::Method { - ty: ::grpcio::MethodType::ClientStreaming, - name: "/agones.dev.sdk.SDK/Health", - req_mar: ::grpcio::Marshaller { ser: ::grpcio::pb_ser, de: ::grpcio::pb_de }, - resp_mar: ::grpcio::Marshaller { ser: ::grpcio::pb_ser, de: ::grpcio::pb_de }, -}; - -const METHOD_SDK_GET_GAME_SERVER: ::grpcio::Method = ::grpcio::Method { - ty: ::grpcio::MethodType::Unary, - name: "/agones.dev.sdk.SDK/GetGameServer", - req_mar: ::grpcio::Marshaller { ser: ::grpcio::pb_ser, de: ::grpcio::pb_de }, - resp_mar: ::grpcio::Marshaller { ser: ::grpcio::pb_ser, de: ::grpcio::pb_de }, -}; - -const METHOD_SDK_WATCH_GAME_SERVER: ::grpcio::Method = ::grpcio::Method { - ty: ::grpcio::MethodType::ServerStreaming, - name: "/agones.dev.sdk.SDK/WatchGameServer", - req_mar: ::grpcio::Marshaller { ser: ::grpcio::pb_ser, de: ::grpcio::pb_de }, - resp_mar: ::grpcio::Marshaller { ser: ::grpcio::pb_ser, de: ::grpcio::pb_de }, -}; - -const METHOD_SDK_SET_LABEL: ::grpcio::Method = ::grpcio::Method { - ty: ::grpcio::MethodType::Unary, - name: "/agones.dev.sdk.SDK/SetLabel", - req_mar: ::grpcio::Marshaller { ser: ::grpcio::pb_ser, de: ::grpcio::pb_de }, - resp_mar: ::grpcio::Marshaller { ser: ::grpcio::pb_ser, de: ::grpcio::pb_de }, -}; - -const METHOD_SDK_SET_ANNOTATION: ::grpcio::Method = ::grpcio::Method { - ty: ::grpcio::MethodType::Unary, - name: "/agones.dev.sdk.SDK/SetAnnotation", - req_mar: ::grpcio::Marshaller { ser: ::grpcio::pb_ser, de: ::grpcio::pb_de }, - resp_mar: ::grpcio::Marshaller { ser: ::grpcio::pb_ser, de: ::grpcio::pb_de }, -}; - -const METHOD_SDK_RESERVE: ::grpcio::Method = ::grpcio::Method { - ty: ::grpcio::MethodType::Unary, - name: "/agones.dev.sdk.SDK/Reserve", - req_mar: ::grpcio::Marshaller { ser: ::grpcio::pb_ser, de: ::grpcio::pb_de }, - resp_mar: ::grpcio::Marshaller { ser: ::grpcio::pb_ser, de: ::grpcio::pb_de }, -}; - -#[derive(Clone)] -pub struct SdkClient { - client: ::grpcio::Client, -} - -impl SdkClient { - pub fn new(channel: ::grpcio::Channel) -> Self { - SdkClient { - client: ::grpcio::Client::new(channel), - } - } - - pub fn ready_opt(&self, req: &super::sdk::Empty, opt: ::grpcio::CallOption) -> ::grpcio::Result { - self.client.unary_call(&METHOD_SDK_READY, req, opt) - } - - pub fn ready(&self, req: &super::sdk::Empty) -> ::grpcio::Result { - self.ready_opt(req, ::grpcio::CallOption::default()) - } - - pub fn ready_async_opt(&self, req: &super::sdk::Empty, opt: ::grpcio::CallOption) -> ::grpcio::Result<::grpcio::ClientUnaryReceiver> { - self.client.unary_call_async(&METHOD_SDK_READY, req, opt) - } - - pub fn ready_async(&self, req: &super::sdk::Empty) -> ::grpcio::Result<::grpcio::ClientUnaryReceiver> { - self.ready_async_opt(req, ::grpcio::CallOption::default()) - } - - pub fn allocate_opt(&self, req: &super::sdk::Empty, opt: ::grpcio::CallOption) -> ::grpcio::Result { - self.client.unary_call(&METHOD_SDK_ALLOCATE, req, opt) - } - - pub fn allocate(&self, req: &super::sdk::Empty) -> ::grpcio::Result { - self.allocate_opt(req, ::grpcio::CallOption::default()) - } - - pub fn allocate_async_opt(&self, req: &super::sdk::Empty, opt: ::grpcio::CallOption) -> ::grpcio::Result<::grpcio::ClientUnaryReceiver> { - self.client.unary_call_async(&METHOD_SDK_ALLOCATE, req, opt) - } - - pub fn allocate_async(&self, req: &super::sdk::Empty) -> ::grpcio::Result<::grpcio::ClientUnaryReceiver> { - self.allocate_async_opt(req, ::grpcio::CallOption::default()) - } - - pub fn shutdown_opt(&self, req: &super::sdk::Empty, opt: ::grpcio::CallOption) -> ::grpcio::Result { - self.client.unary_call(&METHOD_SDK_SHUTDOWN, req, opt) - } - - pub fn shutdown(&self, req: &super::sdk::Empty) -> ::grpcio::Result { - self.shutdown_opt(req, ::grpcio::CallOption::default()) - } - - pub fn shutdown_async_opt(&self, req: &super::sdk::Empty, opt: ::grpcio::CallOption) -> ::grpcio::Result<::grpcio::ClientUnaryReceiver> { - self.client.unary_call_async(&METHOD_SDK_SHUTDOWN, req, opt) - } - - pub fn shutdown_async(&self, req: &super::sdk::Empty) -> ::grpcio::Result<::grpcio::ClientUnaryReceiver> { - self.shutdown_async_opt(req, ::grpcio::CallOption::default()) - } - - pub fn health_opt(&self, opt: ::grpcio::CallOption) -> ::grpcio::Result<(::grpcio::ClientCStreamSender, ::grpcio::ClientCStreamReceiver)> { - self.client.client_streaming(&METHOD_SDK_HEALTH, opt) - } - - pub fn health(&self) -> ::grpcio::Result<(::grpcio::ClientCStreamSender, ::grpcio::ClientCStreamReceiver)> { - self.health_opt(::grpcio::CallOption::default()) - } - - pub fn get_game_server_opt(&self, req: &super::sdk::Empty, opt: ::grpcio::CallOption) -> ::grpcio::Result { - self.client.unary_call(&METHOD_SDK_GET_GAME_SERVER, req, opt) - } - - pub fn get_game_server(&self, req: &super::sdk::Empty) -> ::grpcio::Result { - self.get_game_server_opt(req, ::grpcio::CallOption::default()) - } - - pub fn get_game_server_async_opt(&self, req: &super::sdk::Empty, opt: ::grpcio::CallOption) -> ::grpcio::Result<::grpcio::ClientUnaryReceiver> { - self.client.unary_call_async(&METHOD_SDK_GET_GAME_SERVER, req, opt) - } - - pub fn get_game_server_async(&self, req: &super::sdk::Empty) -> ::grpcio::Result<::grpcio::ClientUnaryReceiver> { - self.get_game_server_async_opt(req, ::grpcio::CallOption::default()) - } - - pub fn watch_game_server_opt(&self, req: &super::sdk::Empty, opt: ::grpcio::CallOption) -> ::grpcio::Result<::grpcio::ClientSStreamReceiver> { - self.client.server_streaming(&METHOD_SDK_WATCH_GAME_SERVER, req, opt) - } - - pub fn watch_game_server(&self, req: &super::sdk::Empty) -> ::grpcio::Result<::grpcio::ClientSStreamReceiver> { - self.watch_game_server_opt(req, ::grpcio::CallOption::default()) - } - - pub fn set_label_opt(&self, req: &super::sdk::KeyValue, opt: ::grpcio::CallOption) -> ::grpcio::Result { - self.client.unary_call(&METHOD_SDK_SET_LABEL, req, opt) - } - - pub fn set_label(&self, req: &super::sdk::KeyValue) -> ::grpcio::Result { - self.set_label_opt(req, ::grpcio::CallOption::default()) - } - - pub fn set_label_async_opt(&self, req: &super::sdk::KeyValue, opt: ::grpcio::CallOption) -> ::grpcio::Result<::grpcio::ClientUnaryReceiver> { - self.client.unary_call_async(&METHOD_SDK_SET_LABEL, req, opt) - } - - pub fn set_label_async(&self, req: &super::sdk::KeyValue) -> ::grpcio::Result<::grpcio::ClientUnaryReceiver> { - self.set_label_async_opt(req, ::grpcio::CallOption::default()) - } - - pub fn set_annotation_opt(&self, req: &super::sdk::KeyValue, opt: ::grpcio::CallOption) -> ::grpcio::Result { - self.client.unary_call(&METHOD_SDK_SET_ANNOTATION, req, opt) - } - - pub fn set_annotation(&self, req: &super::sdk::KeyValue) -> ::grpcio::Result { - self.set_annotation_opt(req, ::grpcio::CallOption::default()) - } - - pub fn set_annotation_async_opt(&self, req: &super::sdk::KeyValue, opt: ::grpcio::CallOption) -> ::grpcio::Result<::grpcio::ClientUnaryReceiver> { - self.client.unary_call_async(&METHOD_SDK_SET_ANNOTATION, req, opt) - } - - pub fn set_annotation_async(&self, req: &super::sdk::KeyValue) -> ::grpcio::Result<::grpcio::ClientUnaryReceiver> { - self.set_annotation_async_opt(req, ::grpcio::CallOption::default()) - } - - pub fn reserve_opt(&self, req: &super::sdk::Duration, opt: ::grpcio::CallOption) -> ::grpcio::Result { - self.client.unary_call(&METHOD_SDK_RESERVE, req, opt) - } - - pub fn reserve(&self, req: &super::sdk::Duration) -> ::grpcio::Result { - self.reserve_opt(req, ::grpcio::CallOption::default()) - } - - pub fn reserve_async_opt(&self, req: &super::sdk::Duration, opt: ::grpcio::CallOption) -> ::grpcio::Result<::grpcio::ClientUnaryReceiver> { - self.client.unary_call_async(&METHOD_SDK_RESERVE, req, opt) - } - - pub fn reserve_async(&self, req: &super::sdk::Duration) -> ::grpcio::Result<::grpcio::ClientUnaryReceiver> { - self.reserve_async_opt(req, ::grpcio::CallOption::default()) - } - pub fn spawn(&self, f: F) where F: ::futures::Future + Send + 'static { - self.client.spawn(f) - } -} - -pub trait Sdk { - fn ready(&mut self, ctx: ::grpcio::RpcContext, req: super::sdk::Empty, sink: ::grpcio::UnarySink); - fn allocate(&mut self, ctx: ::grpcio::RpcContext, req: super::sdk::Empty, sink: ::grpcio::UnarySink); - fn shutdown(&mut self, ctx: ::grpcio::RpcContext, req: super::sdk::Empty, sink: ::grpcio::UnarySink); - fn health(&mut self, ctx: ::grpcio::RpcContext, stream: ::grpcio::RequestStream, sink: ::grpcio::ClientStreamingSink); - fn get_game_server(&mut self, ctx: ::grpcio::RpcContext, req: super::sdk::Empty, sink: ::grpcio::UnarySink); - fn watch_game_server(&mut self, ctx: ::grpcio::RpcContext, req: super::sdk::Empty, sink: ::grpcio::ServerStreamingSink); - fn set_label(&mut self, ctx: ::grpcio::RpcContext, req: super::sdk::KeyValue, sink: ::grpcio::UnarySink); - fn set_annotation(&mut self, ctx: ::grpcio::RpcContext, req: super::sdk::KeyValue, sink: ::grpcio::UnarySink); - fn reserve(&mut self, ctx: ::grpcio::RpcContext, req: super::sdk::Duration, sink: ::grpcio::UnarySink); -} - -pub fn create_sdk(s: S) -> ::grpcio::Service { - let mut builder = ::grpcio::ServiceBuilder::new(); - let mut instance = s.clone(); - builder = builder.add_unary_handler(&METHOD_SDK_READY, move |ctx, req, resp| { - instance.ready(ctx, req, resp) - }); - let mut instance = s.clone(); - builder = builder.add_unary_handler(&METHOD_SDK_ALLOCATE, move |ctx, req, resp| { - instance.allocate(ctx, req, resp) - }); - let mut instance = s.clone(); - builder = builder.add_unary_handler(&METHOD_SDK_SHUTDOWN, move |ctx, req, resp| { - instance.shutdown(ctx, req, resp) - }); - let mut instance = s.clone(); - builder = builder.add_client_streaming_handler(&METHOD_SDK_HEALTH, move |ctx, req, resp| { - instance.health(ctx, req, resp) - }); - let mut instance = s.clone(); - builder = builder.add_unary_handler(&METHOD_SDK_GET_GAME_SERVER, move |ctx, req, resp| { - instance.get_game_server(ctx, req, resp) - }); - let mut instance = s.clone(); - builder = builder.add_server_streaming_handler(&METHOD_SDK_WATCH_GAME_SERVER, move |ctx, req, resp| { - instance.watch_game_server(ctx, req, resp) - }); - let mut instance = s.clone(); - builder = builder.add_unary_handler(&METHOD_SDK_SET_LABEL, move |ctx, req, resp| { - instance.set_label(ctx, req, resp) - }); - let mut instance = s.clone(); - builder = builder.add_unary_handler(&METHOD_SDK_SET_ANNOTATION, move |ctx, req, resp| { - instance.set_annotation(ctx, req, resp) - }); - let mut instance = s; - builder = builder.add_unary_handler(&METHOD_SDK_RESERVE, move |ctx, req, resp| { - instance.reserve(ctx, req, resp) - }); - builder.build() -} diff --git a/sdks/rust/src/lib.rs b/sdks/rust/src/lib.rs index 3cc88ad0c6..c218799d1e 100644 --- a/sdks/rust/src/lib.rs +++ b/sdks/rust/src/lib.rs @@ -13,13 +13,9 @@ // limitations under the License. //! the Rust game server SDK -#[macro_use] -extern crate error_chain; pub mod alpha; pub mod errors; -mod grpc; mod sdk; -pub mod types; pub use sdk::Sdk; diff --git a/sdks/rust/src/sdk.rs b/sdks/rust/src/sdk.rs index ed400f1aef..a7ae935389 100644 --- a/sdks/rust/src/sdk.rs +++ b/sdks/rust/src/sdk.rs @@ -12,349 +12,198 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::env; -use std::sync::{Arc, Mutex}; -use std::thread::sleep; -use std::time::Duration; +use std::{env, time::Duration}; +use tonic::transport::Channel; -use futures::future::TryFutureExt; -use futures::prelude::*; -use futures::FutureExt; -use futures01::future::Future; +mod api { + tonic::include_proto!("agones.dev.sdk"); +} + +use api::sdk_client::SdkClient; +pub use api::GameServer; -use grpcio; -use protobuf::Message; +pub type WatchStream = tonic::Streaming; -use super::alpha::*; -use super::errors::*; -use super::grpc::sdk; -use super::grpc::sdk_grpc; -use super::types::*; +use crate::{ + alpha::Alpha, + errors::{Error, Result}, +}; + +#[inline] +fn empty() -> api::Empty { + api::Empty {} +} /// SDK is an instance of the Agones SDK +#[derive(Clone)] pub struct Sdk { - client: Arc, - health: Arc>>>, - health_receiver: Arc>>>, - alpha: Arc, + client: SdkClient, + health: tokio::sync::mpsc::Sender, + alpha: Alpha, } impl Sdk { - /// Starts a new SDK instance, and connects to localhost on port 9357. - /// Blocks until connection and handshake are made. - /// Times out after ~30 seconds. - pub fn new() -> Result { - let port = env::var("AGONES_SDK_GRPC_PORT").unwrap_or("9357".to_string()); - let addr = format!("localhost:{}", port); - let env = Arc::new(grpcio::EnvBuilder::new().build()); - let ch = grpcio::ChannelBuilder::new(env) - .keepalive_timeout(Duration::new(30, 0)) - .connect(&addr); - let cli = sdk_grpc::SdkClient::new(ch.clone()); - let alpha = Alpha::new(ch); - let req = sdk::Empty::new(); + /// Starts a new SDK instance, and connects to localhost on the port specified + /// in the `AGONES_SDK_GRPC_PORT` environment variable, or defaults to 9357. + pub async fn new(keep_alive: Option) -> Result { + // TODO: Add TLS? For some reason the original Cargo.toml was enabling + // grpcio's openssl features, but AFAICT the SDK and sidecar only ever + // communicate via a non-TLS connection, so seems like we could just + // use the simpler client setup code if TLS is absolutely never needed + let addr: http::Uri = format!( + "http://localhost:{}", + env::var("AGONES_SDK_GRPC_PORT") + .ok() + .and_then(|s| s.parse().ok()) + .unwrap_or(9357) + ) + .parse()?; + + let builder = tonic::transport::channel::Channel::builder(addr) + .keep_alive_timeout(keep_alive.unwrap_or_else(|| Duration::from_secs(30))); + + // let mut root_store = rustls::RootCertStore::empty(); + // root_store.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS); + // let mut rusttls_config = rustls::ClientConfig::new(); + // rusttls_config.alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec()]; + // rusttls_config.root_store = root_store; + // let tls_config = + // tonic::transport::ClientTlsConfig::new().rustls_client_config(rusttls_config); + // builder = builder.tls_config(tls_config)?; + + let channel = builder.connect().await?; + let mut client = SdkClient::new(channel.clone()); + let alpha = Alpha::new(channel); + + // Loop until we connect. The original implementation just looped once + // every second up to a maximum of 30 seconds, but it's better for the + // external caller to wrap this in their own timeout, eg + // https://docs.rs/tokio/1.6.0/tokio/time/fn.timeout.html + let mut connect_interval = tokio::time::interval(Duration::from_millis(100)); - // Unfortunately there isn't a native way to block until connected - // so we had to roll our own. - let mut counter = 0; loop { - counter += 1; - match cli.get_game_server(&req) { - Ok(_) => break, - Err(e) => { - if counter > 30 { - return Err(ErrorKind::Grpc(e).into()); - } - sleep(Duration::from_secs(1)); - continue; - } + connect_interval.tick().await; + + if client.get_game_server(empty()).await.is_ok() { + break; } } // Keep both sender and receiver as RPC is canceled when sender or receiver is dropped - let (sender, receiver) = cli.health()?; - Ok(Sdk { - client: Arc::new(cli), - health: Arc::new(Mutex::new(Some(sender))), - health_receiver: Arc::new(Mutex::new(Some(receiver))), - alpha: Arc::new(alpha), + let (sender, mut receiver) = tokio::sync::mpsc::channel(10); + + let health_stream = async_stream::stream! { + while let Some(item) = receiver.recv().await { + yield item; + } + }; + + client.health(health_stream).await?; + + Ok(Self { + client, + health: sender, + alpha, }) } /// Alpha returns the Alpha SDK - pub fn alpha(&self) -> &Arc { + #[inline] + pub fn alpha(&self) -> &Alpha { &self.alpha } /// Marks the Game Server as ready to receive connections - pub fn ready(&self) -> Result<()> { - let req = sdk::Empty::default_instance(); - let res = self.client.ready(req).map(|_| ())?; - Ok(res) + #[inline] + pub async fn ready(&mut self) -> Result<()> { + Ok(self.client.ready(empty()).await.map(|_| ())?) } /// Allocate the Game Server - pub fn allocate(&self) -> Result<()> { - let req = sdk::Empty::default_instance(); - let res = self.client.allocate(req).map(|_| ())?; - Ok(res) + #[inline] + pub async fn allocate(&mut self) -> Result<()> { + Ok(self.client.allocate(empty()).await.map(|_| ())?) } /// Marks the Game Server as ready to shutdown - pub fn shutdown(&self) -> Result<()> { - let req = sdk::Empty::default_instance(); - let res = self.client.shutdown(req).map(|_| ())?; - Ok(res) + #[inline] + pub async fn shutdown(&mut self) -> Result<()> { + Ok(self.client.shutdown(empty()).await.map(|_| ())?) } /// Sends a ping to the health check to indicate that this server is healthy - pub fn health(mut self) -> (Self, Result<()>) { - // Avoid `cannot move out of borrowed content` compile error for self.health - let h = self.health.lock().unwrap().take(); - if h.is_none() { - return ( - self, - Err(ErrorKind::HealthPingConnectionFailure( - "failed to hold client stream for health ping".to_string(), - ) - .into()), - ); - } - let mut h = h.unwrap(); - - let req = sdk::Empty::new(); - let result = h - .send((req, grpcio::WriteFlags::default())) - .boxed_local() - .compat() - .wait(); - match result { - Ok(_) => { - self.health = Arc::new(Mutex::new(Some(h))); - (self, Ok(())) - } - Err(e) => (self, Err(ErrorKind::Grpc(e).into())), - } + #[inline] + pub async fn health(&self) -> Result<()> { + self.health.send(empty()).await.map(|_| ()).map_err(|_| { + Error::HealthPingConnectionFailure("tonic receiver was dropped".to_string()) + }) } /// Set a Label value on the backing GameServer record that is stored in Kubernetes - pub fn set_label(&self, key: S, value: S) -> Result<()> - where - S: Into, - { - let mut kv = sdk::KeyValue::new(); - kv.set_key(key.into()); - kv.set_value(value.into()); - let res = self.client.set_label(&kv).map(|_| ())?; - Ok(res) + #[inline] + pub async fn set_label( + &mut self, + key: impl Into, + value: impl Into, + ) -> Result<()> { + Ok(self + .client + .set_label(api::KeyValue { + key: key.into(), + value: value.into(), + }) + .await + .map(|_| ())?) } /// Set a Annotation value on the backing Gameserver record that is stored in Kubernetes - pub fn set_annotation(&self, key: S, value: S) -> Result<()> - where - S: Into, - { - let mut kv = sdk::KeyValue::new(); - kv.set_key(key.into()); - kv.set_value(value.into()); - let res = self.client.set_annotation(&kv).map(|_| ())?; - Ok(res) - } - - /// Returns most of the backing GameServer configuration and Status - pub fn get_gameserver(&self) -> Result { - let req = sdk::Empty::new(); - let res = self + #[inline] + pub async fn set_annotation( + &mut self, + key: impl Into, + value: impl Into, + ) -> Result<()> { + Ok(self .client - .get_game_server(&req) - .map(|e| GameServer::from_message(e))?; - Ok(res) - } - - /// Reserve marks the Game Server as Reserved for a given duration, at which point - /// it will return the GameServer to a Ready state. - /// Do note, the smallest unit available in the time.Duration argument is a second. - pub fn reserve(&self, duration: Duration) -> Result<()> { - let mut d = sdk::Duration::new(); - d.set_seconds(duration.as_secs() as i64); - - let res = self.client.reserve(&d).map(|_| ())?; - Ok(res) - } - - /// Watch the backing GameServer configuration on updated - pub fn watch_gameserver(&self, mut watcher: F) -> Result<()> - where - F: FnMut(GameServer) -> (), - { - let req = sdk::Empty::new(); - let mut receiver = self.client.watch_game_server(&req)?; - loop { - let res = receiver.try_next().boxed_local().compat().wait(); - match res { - Ok(res) => match res { - Some(res) => watcher(GameServer::from_message(res)), - None => break, - }, - Err(e) => { - return Err(e.into()); - } - } - } - Ok(()) - } - - /// Starts a new SDK instance, and connects to localhost on port 9357. - /// Blocks until connection and handshake are made. - /// Times out after ~30 seconds. - pub async fn new_async() -> Result { - let port = env::var("AGONES_SDK_GRPC_PORT").unwrap_or("9357".to_string()); - let addr = format!("localhost:{}", port); - let env = Arc::new(grpcio::EnvBuilder::new().build()); - let ch = grpcio::ChannelBuilder::new(env) - .keepalive_timeout(Duration::new(30, 0)) - .connect(&addr); - let cli = sdk_grpc::SdkClient::new(ch.clone()); - let alpha = Alpha::new(ch); - let req = sdk::Empty::new(); - - // Unfortunately there isn't a native way to block until connected - // so we had to roll our own. - let mut counter = 0; - loop { - counter += 1; - match cli.get_game_server_async(&req)?.await { - Ok(_) => break, - Err(e) => { - if counter > 30 { - return Err(ErrorKind::Grpc(e).into()); - } - sleep(Duration::from_secs(1)); - continue; - } - } - } - - // Keep both sender and receiver as RPC is canceled when sender or receiver is dropped - let (sender, receiver) = cli.health()?; - Ok(Sdk { - client: Arc::new(cli), - health: Arc::new(Mutex::new(Some(sender))), - health_receiver: Arc::new(Mutex::new(Some(receiver))), - alpha: Arc::new(alpha), - }) - } - - /// Marks the Game Server as ready to receive connections - pub async fn ready_async(&self) -> Result<()> { - let req = sdk::Empty::default_instance(); - let res = self.client.ready_async(req)?.await.map(|_| ())?; - Ok(res) - } - - /// Allocate the Game Server - pub async fn allocate_async(&self) -> Result<()> { - let req = sdk::Empty::default_instance(); - let res = self.client.allocate_async(req)?.await.map(|_| ())?; - Ok(res) - } - - /// Marks the Game Server as ready to shutdown - pub async fn shutdown_async(&self) -> Result<()> { - let req = sdk::Empty::default_instance(); - let res = self.client.shutdown_async(req)?.await.map(|_| ())?; - Ok(res) - } - - /// Sends a ping to the health check to indicate that this server is healthy - pub async fn health_async(&mut self) -> Result<()> { - // Avoid `cannot move out of borrowed content` compile error for self.health - let h = self.health.lock().unwrap().take(); - if h.is_none() { - return Err(ErrorKind::HealthPingConnectionFailure( - "failed to hold client stream for health ping".to_string(), - ) - .into()); - } - let mut h = h.unwrap(); - - let req = sdk::Empty::new(); - match h.send((req, grpcio::WriteFlags::default())).await { - Ok(_) => { - self.health = Arc::new(Mutex::new(Some(h))); - Ok(()) - } - Err(e) => Err(ErrorKind::Grpc(e).into()), - } - } - - /// Set a Label value on the backing GameServer record that is stored in Kubernetes with the prefix 'agones.dev/sdk-' - pub async fn set_label_async(&self, key: S, value: S) -> Result<()> - where - S: Into, - { - let mut kv = sdk::KeyValue::new(); - kv.set_key(key.into()); - kv.set_value(value.into()); - let res = self.client.set_label_async(&kv)?.await.map(|_| ())?; - Ok(res) - } - - /// Set a Annotation value on the backing Gameserver record that is stored in Kubernetes with the prefix 'agones.dev/sdk-' - pub async fn set_annotation_async(&self, key: S, value: S) -> Result<()> - where - S: Into, - { - let mut kv = sdk::KeyValue::new(); - kv.set_key(key.into()); - kv.set_value(value.into()); - let res = self.client.set_annotation_async(&kv)?.await.map(|_| ())?; - Ok(res) + .set_annotation(api::KeyValue { + key: key.into(), + value: value.into(), + }) + .await + .map(|_| ())?) } /// Returns most of the backing GameServer configuration and Status - pub async fn get_gameserver_async(&self) -> Result { - let req = sdk::Empty::new(); - let res = self + #[inline] + pub async fn get_gameserver(&mut self) -> Result { + Ok(self .client - .get_game_server_async(&req)? + .get_game_server(empty()) .await - .map(|e| GameServer::from_message(e))?; - Ok(res) + .map(|res| res.into_inner())?) } /// Reserve marks the Game Server as Reserved for a given duration, at which point /// it will return the GameServer to a Ready state. - /// Do note, the smallest unit available in the time.Duration argument is a second. - pub async fn reserve_async(&self, duration: Duration) -> Result<()> { - let mut d = sdk::Duration::new(); - d.set_seconds(duration.as_secs() as i64); - - let res = self.client.reserve_async(&d)?.await.map(|_| ())?; - Ok(res) + /// Do note, the smallest unit available in the time.Duration argument is one second. + #[inline] + pub async fn reserve(&mut self, duration: Duration) -> Result<()> { + Ok(self + .client + .reserve(api::Duration { + seconds: std::cmp::max(duration.as_secs() as i64, 1), + }) + .await + .map(|_| ())?) } /// Watch the backing GameServer configuration on updated - pub async fn watch_gameserver_async(&self, mut watcher: F) -> Result<()> - where - F: FnMut(GameServer) -> (), - { - let req = sdk::Empty::new(); - let mut receiver = self.client.watch_game_server(&req)?; - while let Some(e) = receiver.try_next().await? { - watcher(GameServer::from_message(e)); - } - Ok(()) - } -} - -impl Clone for Sdk { - fn clone(&self) -> Self { - Self { - client: Arc::clone(&self.client), - health: self.health.clone(), - health_receiver: self.health_receiver.clone(), - alpha: Arc::clone(&self.alpha), - } + #[inline] + pub async fn watch_gameserver(&mut self) -> Result { + Ok(self + .client + .watch_game_server(empty()) + .await + .map(|stream| stream.into_inner())?) } } diff --git a/sdks/rust/src/types.rs b/sdks/rust/src/types.rs deleted file mode 100644 index cd75162eef..0000000000 --- a/sdks/rust/src/types.rs +++ /dev/null @@ -1,166 +0,0 @@ -// Copyright 2019 Google LLC All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -use std::collections::HashMap; - -use super::grpc::sdk; - -#[derive(PartialEq, Clone, Default)] -pub struct GameServer { - // message fields - pub object_meta: Option, - pub spec: Option, - pub status: Option, -} - -impl GameServer { - pub fn from_message(msg: sdk::GameServer) -> GameServer { - GameServer { - object_meta: msg - .object_meta - .into_option() - .map(|e| GameServerObjectMeta::from_message(e)), - spec: msg - .spec - .into_option() - .map(|e| GameServerSpec::from_message(e)), - status: msg - .status - .into_option() - .map(|e| GameServerStatus::from_message(e)), - } - } -} - -#[derive(PartialEq, Clone, Default)] -pub struct GameServerObjectMeta { - pub name: String, - pub namespace: String, - pub uid: String, - pub resource_version: String, - pub generation: i64, - pub creation_timestamp: i64, - pub deletion_timestamp: i64, - pub annotations: HashMap, - pub labels: HashMap, -} - -impl GameServerObjectMeta { - pub fn from_message(msg: sdk::GameServer_ObjectMeta) -> GameServerObjectMeta { - GameServerObjectMeta { - name: msg.name, - namespace: msg.namespace, - uid: msg.uid, - resource_version: msg.resource_version, - generation: msg.generation, - creation_timestamp: msg.creation_timestamp, - deletion_timestamp: msg.deletion_timestamp, - annotations: msg.annotations, - labels: msg.labels, - } - } -} - -#[derive(PartialEq, Clone, Default)] -pub struct GameServerSpec { - pub health: Option, -} - -impl GameServerSpec { - pub fn from_message(msg: sdk::GameServer_Spec) -> GameServerSpec { - GameServerSpec { - health: msg - .health - .into_option() - .map(|e| GameServerSpecHealth::from_message(e)), - } - } -} - -#[derive(PartialEq, Clone, Default)] -pub struct GameServerSpecHealth { - // message fields - pub disabled: bool, - pub period_seconds: i32, - pub failure_threshold: i32, - pub initial_delay_seconds: i32, -} - -impl GameServerSpecHealth { - pub fn from_message(msg: sdk::GameServer_Spec_Health) -> GameServerSpecHealth { - GameServerSpecHealth { - disabled: msg.disabled, - period_seconds: msg.period_seconds, - failure_threshold: msg.failure_threshold, - initial_delay_seconds: msg.initial_delay_seconds, - } - } -} - -#[derive(PartialEq, Clone, Default)] -pub struct GameServerStatus { - pub state: String, - pub address: String, - pub ports: Vec, - pub players: Option, -} - -impl GameServerStatus { - pub fn from_message(msg: sdk::GameServer_Status) -> GameServerStatus { - GameServerStatus { - state: msg.state, - address: msg.address, - ports: msg - .ports - .into_iter() - .map(|e| GameServerStatusPort::from_message(e)) - .collect(), - players: msg - .players - .into_option() - .map(|e| GameServerStatusPlayersStatus::from_message(e)), - } - } -} - -#[derive(PartialEq, Clone, Default)] -pub struct GameServerStatusPort { - pub name: String, - pub port: i32, -} - -impl GameServerStatusPort { - pub fn from_message(msg: sdk::GameServer_Status_Port) -> GameServerStatusPort { - GameServerStatusPort { - name: msg.name, - port: msg.port, - } - } -} - -#[derive(PartialEq, Clone, Default)] -pub struct GameServerStatusPlayersStatus { - pub count: i64, - pub capacity: i64, - pub ids: Vec, -} - -impl GameServerStatusPlayersStatus { - pub fn from_message(msg: sdk::GameServer_Status_PlayerStatus) -> GameServerStatusPlayersStatus { - GameServerStatusPlayersStatus { - count: msg.count, - capacity: msg.capacity, - ids: msg.ids.into(), - } - } -} From 1be03ed5863e4492ab8fea98b3c5ae746c0aa03d Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Wed, 26 May 2021 09:17:24 +0200 Subject: [PATCH 03/24] Add metadata fields to manifest --- sdks/rust/Cargo.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sdks/rust/Cargo.toml b/sdks/rust/Cargo.toml index 19fbdb8ef2..e8c37e094b 100644 --- a/sdks/rust/Cargo.toml +++ b/sdks/rust/Cargo.toml @@ -16,6 +16,10 @@ name = "agones" version = "0.1.0" edition = "2018" +license = "Apache-2.0" +repository = "https://github.com/googleforgames/agones" +docs = "https://docs.rs/agones" +homepage = "https://agones.dev/site/" [dependencies] async-stream = "0.3" From 2fedfac64da46ef8eebc936fccfe3f71b247d7be Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Thu, 27 May 2021 14:49:25 +0200 Subject: [PATCH 04/24] Allow optional port assignment --- sdks/rust/src/sdk.rs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/sdks/rust/src/sdk.rs b/sdks/rust/src/sdk.rs index a7ae935389..abbf5945f6 100644 --- a/sdks/rust/src/sdk.rs +++ b/sdks/rust/src/sdk.rs @@ -44,18 +44,21 @@ pub struct Sdk { impl Sdk { /// Starts a new SDK instance, and connects to localhost on the port specified - /// in the `AGONES_SDK_GRPC_PORT` environment variable, or defaults to 9357. - pub async fn new(keep_alive: Option) -> Result { + /// or else falls back to the `AGONES_SDK_GRPC_PORT` environment variable, + /// or defaults to 9357. + pub async fn new(port: Option, keep_alive: Option) -> Result { // TODO: Add TLS? For some reason the original Cargo.toml was enabling // grpcio's openssl features, but AFAICT the SDK and sidecar only ever // communicate via a non-TLS connection, so seems like we could just // use the simpler client setup code if TLS is absolutely never needed let addr: http::Uri = format!( "http://localhost:{}", - env::var("AGONES_SDK_GRPC_PORT") - .ok() - .and_then(|s| s.parse().ok()) - .unwrap_or(9357) + port.unwrap_or_else(|| { + env::var("AGONES_SDK_GRPC_PORT") + .ok() + .and_then(|s| s.parse().ok()) + .unwrap_or(9357) + }) ) .parse()?; From 4aa3db4bbedceb274fc15c9f06091c82df60c2ae Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Thu, 27 May 2021 14:49:35 +0200 Subject: [PATCH 05/24] Fix field name --- sdks/rust/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdks/rust/Cargo.toml b/sdks/rust/Cargo.toml index e8c37e094b..cefed1b482 100644 --- a/sdks/rust/Cargo.toml +++ b/sdks/rust/Cargo.toml @@ -18,7 +18,7 @@ version = "0.1.0" edition = "2018" license = "Apache-2.0" repository = "https://github.com/googleforgames/agones" -docs = "https://docs.rs/agones" +documentation = "https://docs.rs/agones" homepage = "https://agones.dev/site/" [dependencies] From defc1eeb51eeea2d1dd240b2a6c3abd2bce59e16 Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Thu, 27 May 2021 15:39:13 +0200 Subject: [PATCH 06/24] Remove unused generic --- sdks/rust/src/sdk.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdks/rust/src/sdk.rs b/sdks/rust/src/sdk.rs index abbf5945f6..8d87c46f6b 100644 --- a/sdks/rust/src/sdk.rs +++ b/sdks/rust/src/sdk.rs @@ -161,7 +161,7 @@ impl Sdk { /// Set a Annotation value on the backing Gameserver record that is stored in Kubernetes #[inline] - pub async fn set_annotation( + pub async fn set_annotation( &mut self, key: impl Into, value: impl Into, From 46a27e5ed4776a5cb30ee3354b59982bb0b49ba7 Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Thu, 27 May 2021 15:49:46 +0200 Subject: [PATCH 07/24] Print out error when unable to get game server --- sdks/rust/src/sdk.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/sdks/rust/src/sdk.rs b/sdks/rust/src/sdk.rs index 8d87c46f6b..e12c92fa85 100644 --- a/sdks/rust/src/sdk.rs +++ b/sdks/rust/src/sdk.rs @@ -87,8 +87,11 @@ impl Sdk { loop { connect_interval.tick().await; - if client.get_game_server(empty()).await.is_ok() { - break; + match client.get_game_server(empty()).await { + Err(e) => { + println!("unable to retrieve game server: {:#?}", e); + } + Ok(_) => break, } } From 410f81833fb658403d999f8965f8030a8f90b247 Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Thu, 27 May 2021 17:47:39 +0200 Subject: [PATCH 08/24] Pull out health check into its own separate task --- sdks/rust/src/sdk.rs | 59 +++++++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 26 deletions(-) diff --git a/sdks/rust/src/sdk.rs b/sdks/rust/src/sdk.rs index e12c92fa85..98812cc7d5 100644 --- a/sdks/rust/src/sdk.rs +++ b/sdks/rust/src/sdk.rs @@ -26,7 +26,7 @@ pub type WatchStream = tonic::Streaming; use crate::{ alpha::Alpha, - errors::{Error, Result}, + errors::{Result}, }; #[inline] @@ -38,7 +38,6 @@ fn empty() -> api::Empty { #[derive(Clone)] pub struct Sdk { client: SdkClient, - health: tokio::sync::mpsc::Sender, alpha: Alpha, } @@ -46,6 +45,10 @@ impl Sdk { /// Starts a new SDK instance, and connects to localhost on the port specified /// or else falls back to the `AGONES_SDK_GRPC_PORT` environment variable, /// or defaults to 9357. + /// + /// Note that this function will loop indefinitely until a connection is made + /// to the SDK server, so it is recommended to wrap this in a + /// [timeout](https://docs.rs/tokio/1.6.0/tokio/time/fn.timeout.html). pub async fn new(port: Option, keep_alive: Option) -> Result { // TODO: Add TLS? For some reason the original Cargo.toml was enabling // grpcio's openssl features, but AFAICT the SDK and sidecar only ever @@ -80,35 +83,19 @@ impl Sdk { // Loop until we connect. The original implementation just looped once // every second up to a maximum of 30 seconds, but it's better for the - // external caller to wrap this in their own timeout, eg - // https://docs.rs/tokio/1.6.0/tokio/time/fn.timeout.html + // external caller to wrap this in their own timeout let mut connect_interval = tokio::time::interval(Duration::from_millis(100)); loop { connect_interval.tick().await; - match client.get_game_server(empty()).await { - Err(e) => { - println!("unable to retrieve game server: {:#?}", e); - } - Ok(_) => break, + if client.get_game_server(empty()).await.is_ok() { + break; } } - // Keep both sender and receiver as RPC is canceled when sender or receiver is dropped - let (sender, mut receiver) = tokio::sync::mpsc::channel(10); - - let health_stream = async_stream::stream! { - while let Some(item) = receiver.recv().await { - yield item; - } - }; - - client.health(health_stream).await?; - Ok(Self { client, - health: sender, alpha, }) } @@ -137,12 +124,32 @@ impl Sdk { Ok(self.client.shutdown(empty()).await.map(|_| ())?) } - /// Sends a ping to the health check to indicate that this server is healthy + /// Creates a task that sends a health ping to the SDK server on every interval + /// tick. It is recommended to only have 1 of these at a time. #[inline] - pub async fn health(&self) -> Result<()> { - self.health.send(empty()).await.map(|_| ()).map_err(|_| { - Error::HealthPingConnectionFailure("tonic receiver was dropped".to_string()) - }) + pub fn spawn_health_task(&self, interval: Duration) -> tokio::sync::oneshot::Sender<()> { + let mut health_client = self.clone(); + let (tx, mut rx) = tokio::sync::oneshot::channel(); + + tokio::task::spawn(async move { + let health_stream = async_stream::stream! { + let mut health_interval = tokio::time::interval(interval); + loop { + tokio::select! { + _ = health_interval.tick() => { + yield empty(); + } + _ = &mut rx => { + break; + } + } + } + }; + + let _ = health_client.client.health(health_stream).await; + }); + + tx } /// Set a Label value on the backing GameServer record that is stored in Kubernetes From 89d5ffd04db164d0e3e815c710ef8ecdf984615d Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Fri, 28 May 2021 11:24:48 +0200 Subject: [PATCH 09/24] Update rust-simple example to work with updated SDK --- examples/rust-simple/Cargo.toml | 11 ++++ examples/rust-simple/src/main.rs | 103 +++++++++++++++++++------------ 2 files changed, 73 insertions(+), 41 deletions(-) diff --git a/examples/rust-simple/Cargo.toml b/examples/rust-simple/Cargo.toml index 59be2c392d..5f6ada8966 100644 --- a/examples/rust-simple/Cargo.toml +++ b/examples/rust-simple/Cargo.toml @@ -15,6 +15,17 @@ [package] name = "rust-simple" version = "0.1.0" +edition = "2018" [dependencies] agones = { path = "../../sdks/rust" } + +[dependencies.tokio] +version = "1.6" +default-features = false +features = [ + "macros", + "rt-multi-thread", + "sync", + "time", +] \ No newline at end of file diff --git a/examples/rust-simple/src/main.rs b/examples/rust-simple/src/main.rs index afa21631ad..264429815a 100644 --- a/examples/rust-simple/src/main.rs +++ b/examples/rust-simple/src/main.rs @@ -12,25 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -extern crate agones; - -use std::result::Result; -use std::thread; use std::time::Duration; -macro_rules! enclose { - ( ($( $x:ident ),*) $y:expr ) => { - { - $(let mut $x = $x.clone();)* - $y - } - }; -} - -fn main() { +#[tokio::main(flavor = "multi_thread", worker_threads = 4)] +async fn main() { println!("Rust Game Server has started!"); - ::std::process::exit(match run() { + ::std::process::exit(match run().await { Ok(_) => { println!("Rust Game Server finished."); 0 @@ -42,57 +30,89 @@ fn main() { }); } -fn run() -> Result<(), String> { +async fn run() -> Result<(), String> { println!("Creating SDK instance"); - let sdk = agones::Sdk::new().map_err(|_| "Could not connect to the sidecar. Exiting!")?; - - let _health = thread::spawn(enclose! {(sdk) move || { - loop { - match sdk.health() { - (s, Ok(_)) => { - println!("Health ping sent"); - sdk = s; - }, - (s, Err(e)) => { - println!("Health ping failed : {:?}", e); - sdk = s; - } - } - thread::sleep(Duration::from_secs(2)); + let mut sdk = match tokio::time::timeout( + Duration::from_secs(30), + agones::Sdk::new(None /* default port */, None /* keep_alive */), + ) + .await + { + Ok(sdk) => sdk.map_err(|e| format!("unable to create sdk client: {}", e))?, + Err(_) => { + return Err("timed out attempting to connect to the sidecar".to_owned()); } - }}); + }; - let _watch = thread::spawn(enclose! {(sdk) move || { - println!("Starting to watch GameServer updates..."); - let _ = sdk.watch_gameserver(|gameserver| { - println!("GameServer Update, name: {}", gameserver.object_meta.unwrap().name); - println!("GameServer Update, state: {}", gameserver.status.unwrap().state); + let _health = sdk.spawn_health_task(Duration::from_secs(2)); + + let _watch = { + let mut watch_client = sdk.clone(); + let (tx, mut rx) = tokio::sync::oneshot::channel::<()>(); + + tokio::task::spawn(async move { + println!("Starting to watch GameServer updates..."); + match watch_client.watch_gameserver().await { + Err(e) => println!("Failed to watch for GameServer updates: {}", e), + Ok(mut stream) => loop { + tokio::select! { + gs = stream.message() => { + match gs { + Ok(Some(gs)) => { + println!("GameServer Update, name: {}", gs.object_meta.unwrap().name); + println!("GameServer Update, state: {}", gs.status.unwrap().state); + } + Ok(None) => { + println!("Server closed the GameServer watch stream"); + break; + } + Err(e) => { + eprintln!("GameServer Update stream encountered an error: {}", e); + } + } + + } + _ = &mut rx => { + println!("Shutting down GameServer watch loop"); + break; + } + } + }, + } }); - }}); + + tx + }; println!("Setting a label"); sdk.set_label("test-label", "test-value") + .await .map_err(|e| format!("Could not run SetLabel(): {}. Exiting!", e))?; println!("Setting an annotation"); sdk.set_annotation("test-annotation", "test value") + .await .map_err(|e| format!("Could not run SetAnnotation(): {}. Exiting!", e))?; println!("Marking server as ready..."); sdk.ready() + .await .map_err(|e| format!("Could not run Ready(): {}. Exiting!", e))?; println!("...marked Ready"); println!("Setting as Reserved for 5 seconds"); - sdk.reserve(Duration::new(5, 0)).map_err(|e| format!("Could not run Reserve(): {}. Exiting!", e))?; + sdk.reserve(Duration::from_secs(5)) + .await + .map_err(|e| format!("Could not run Reserve(): {}. Exiting!", e))?; println!("...Reserved"); - thread::sleep(Duration::new(6, 0)); + tokio::time::sleep(Duration::from_secs(6)).await; println!("Getting GameServer details..."); let gameserver = sdk .get_gameserver() + .await .map_err(|e| format!("Could not run GameServer(): {}. Exiting!", e))?; println!("GameServer name: {}", gameserver.object_meta.unwrap().name); @@ -101,11 +121,12 @@ fn run() -> Result<(), String> { let time = i * 10; println!("Running for {} seconds", time); - thread::sleep(Duration::from_secs(10)); + tokio::time::sleep(Duration::from_secs(10)).await; if i == 5 { println!("Shutting down after 60 seconds..."); sdk.shutdown() + .await .map_err(|e| format!("Could not run Shutdown: {}. Exiting!", e))?; println!("...marked for Shutdown"); } From ee05aef514316475e397e9917cef60d6e6d4d0c7 Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Fri, 28 May 2021 11:25:21 +0200 Subject: [PATCH 10/24] Remove unused generic parameter --- sdks/rust/src/sdk.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdks/rust/src/sdk.rs b/sdks/rust/src/sdk.rs index 98812cc7d5..67094d30b8 100644 --- a/sdks/rust/src/sdk.rs +++ b/sdks/rust/src/sdk.rs @@ -212,7 +212,7 @@ impl Sdk { /// Watch the backing GameServer configuration on updated #[inline] - pub async fn watch_gameserver(&mut self) -> Result { + pub async fn watch_gameserver(&mut self) -> Result { Ok(self .client .watch_game_server(empty()) From 410940d9534b3dd0d8157f0da1ea75e2d2a14981 Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Fri, 28 May 2021 12:35:10 +0200 Subject: [PATCH 11/24] Fix rust tests --- test/sdk/rust/Cargo.toml | 11 +- test/sdk/rust/src/main.rs | 483 +++++++++++++++++++++----------------- 2 files changed, 275 insertions(+), 219 deletions(-) diff --git a/test/sdk/rust/Cargo.toml b/test/sdk/rust/Cargo.toml index 52d3b921d3..886d563bf9 100644 --- a/test/sdk/rust/Cargo.toml +++ b/test/sdk/rust/Cargo.toml @@ -22,4 +22,13 @@ edition = "2018" [dependencies] agones = { path = "../../../sdks/rust" } -async-std = "1.6.2" + +[dependencies.tokio] +version = "1.6" +default-features = false +features = [ + "macros", + "rt-multi-thread", + "sync", + "time", +] diff --git a/test/sdk/rust/src/main.rs b/test/sdk/rust/src/main.rs index 0121d0de9b..2703560e21 100644 --- a/test/sdk/rust/src/main.rs +++ b/test/sdk/rust/src/main.rs @@ -12,28 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -extern crate agones; +use std::{env, thread, time::Duration}; -use std::env; -use std::result::Result; -use std::thread; -use std::time::Duration; - -use async_std::task; - -macro_rules! enclose { - ( ($( $x:ident ),*) $y:expr ) => { - { - $(let mut $x = $x.clone();)* - $y - } - }; -} - -fn main() { +#[tokio::main(flavor = "multi_thread", worker_threads = 4)] +async fn main() { println!("Rust Game Server has started!"); - ::std::process::exit(match run() { + ::std::process::exit(match run().await { Ok(_) => { println!("Rust Game Server finished."); 0 @@ -45,76 +30,107 @@ fn main() { }); } -fn run() -> Result<(), String> { - let env_run_async = env::var("RUN_ASYNC").unwrap_or("false".to_string()); +async fn run() -> Result<(), String> { + let env_run_async = env::var("RUN_ASYNC").unwrap_or_default(); if env_run_async.contains("true") { println!("RUN_ASYNC is set to true, so run test for async functions"); - run_async() + run_async().await } else { - run_sync() + tokio::task::block_in_place(run_sync) } } fn run_sync() -> Result<(), String> { + use tokio::runtime::Handle; + println!("Creating SDK instance"); - let sdk = agones::Sdk::new().map_err(|_| "Could not connect to the sidecar. Exiting!")?; - - let _health = thread::spawn(enclose! {(sdk) move || { - loop { - match sdk.health() { - (s, Ok(_)) => { - println!("Health ping sent"); - sdk = s; - }, - (s, Err(e)) => { - println!("Health ping failed : {:?}", e); - sdk = s; - } - } - thread::sleep(Duration::from_secs(2)); + let mut sdk = Handle::current().block_on(async move { + match tokio::time::timeout( + Duration::from_secs(30), + agones::Sdk::new(None /* default port */, None /* keep_alive */), + ) + .await + { + Ok(sdk) => sdk.map_err(|e| format!("unable to create sdk client: {}", e)), + Err(_) => Err("timed out attempting to connect to the sidecar".to_owned()), } - }}); - - #[allow(unused_mut)] - let _watch = thread::spawn(enclose! {(sdk) move || { - println!("Starting to watch GameServer updates..."); - let mut once = true; - let _ = sdk.watch_gameserver(|gameserver| { - println!("GameServer Update, name: {}", gameserver.object_meta.clone().unwrap().name); - println!("GameServer Update, state: {}", gameserver.status.clone().unwrap().state); - if once { - println!("Setting an annotation"); - let uid = gameserver.object_meta.clone().unwrap().uid.clone(); - let _ = sdk.set_annotation("test-annotation", &uid.to_string()); - once = false; + })?; + + let _health = sdk.spawn_health_task(Duration::from_secs(2)); + + let _watch = { + let mut watch_client = sdk.clone(); + let (tx, mut rx) = tokio::sync::oneshot::channel::<()>(); + + tokio::task::spawn(async move { + println!("Starting to watch GameServer updates..."); + match watch_client.watch_gameserver().await { + Err(e) => println!("Failed to watch for GameServer updates: {}", e), + Ok(mut stream) => loop { + tokio::select! { + gs = stream.message() => { + match gs { + Ok(Some(gs)) => { + println!("GameServer Update, name: {}", gs.object_meta.unwrap().name); + println!("GameServer Update, state: {}", gs.status.unwrap().state); + } + Ok(None) => { + println!("Server closed the GameServer watch stream"); + break; + } + Err(e) => { + eprintln!("GameServer Update stream encountered an error: {}", e); + } + } + + } + _ = &mut rx => { + println!("Shutting down GameServer watch loop"); + break; + } + } + }, } }); - }}); + + tx + }; // Waiting for a thread to spawn thread::sleep(Duration::from_secs(2)); println!("Marking server as ready..."); - sdk.ready() - .map_err(|e| format!("Could not run Ready(): {}. Exiting!", e))?; + Handle::current().block_on(async { + sdk.ready() + .await + .map_err(|e| format!("Could not run Ready(): {}. Exiting!", e)) + })?; println!("...marked Ready"); println!("Reserving for 5 seconds"); - sdk.reserve(Duration::new(5, 0)) - .map_err(|e| format!("Could not run Reserve(): {}. Exiting!", e))?; + Handle::current().block_on(async { + sdk.reserve(Duration::from_secs(5)) + .await + .map_err(|e| format!("Could not run Reserve(): {}. Exiting!", e)) + })?; println!("...Reserved"); println!("Allocate game server ..."); - sdk.allocate() - .map_err(|e| format!("Could not run Allocate(): {}. Exiting!", e))?; + Handle::current().block_on(async { + sdk.allocate() + .await + .map_err(|e| format!("Could not run Allocate(): {}. Exiting!", e)) + })?; println!("...marked Allocated"); println!("Getting GameServer details..."); - let gameserver = sdk - .get_gameserver() - .map_err(|e| format!("Could not run GameServer(): {}. Exiting!", e))?; + let gameserver = Handle::current().block_on(async { + sdk.get_gameserver() + .await + .map_err(|e| format!("Could not run GameServer(): {}. Exiting!", e)) + })?; println!( "GameServer name: {}", @@ -122,13 +138,16 @@ fn run_sync() -> Result<(), String> { ); println!("Setting a label"); - let creation_ts = gameserver.object_meta.clone().unwrap().creation_timestamp; - sdk.set_label("test-label", &creation_ts.to_string()) - .map_err(|e| format!("Could not run SetLabel(): {}. Exiting!", e))?; + let creation_ts = gameserver.object_meta.unwrap().creation_timestamp; + Handle::current().block_on(async { + sdk.set_label("test-label", &creation_ts.to_string()) + .await + .map_err(|e| format!("Could not run SetLabel(): {}. Exiting!", e)) + })?; - let feature_gates = env::var("FEATURE_GATES").unwrap_or("".to_string()); + let feature_gates = env::var("FEATURE_GATES").unwrap_or_default(); if feature_gates.contains("PlayerTracking=true") { - run_player_tracking_features(&sdk)?; + run_player_tracking_features(sdk.alpha().clone())?; } for i in 0..1 { @@ -139,209 +158,242 @@ fn run_sync() -> Result<(), String> { } println!("Shutting down..."); - sdk.shutdown() - .map_err(|e| format!("Could not run Shutdown: {}. Exiting!", e))?; + Handle::current().block_on(async { + sdk.shutdown() + .await + .map_err(|e| format!("Could not run Shutdown: {}. Exiting!", e)) + })?; println!("...marked for Shutdown"); Ok(()) } -fn run_player_tracking_features(sdk: &agones::Sdk) -> Result<(), String> { +fn run_player_tracking_features(mut alpha: agones::alpha::Alpha) -> Result<(), String> { + use tokio::runtime::Handle; + println!("Setting player capacity..."); - sdk.alpha() - .set_player_capacity(10) - .map_err(|e| format!("Could not run SetPlayerCapacity(): {}. Exiting!", e))?; + Handle::current().block_on(async { + alpha + .set_player_capacity(10) + .await + .map_err(|e| format!("Could not run SetPlayerCapacity(): {:#?}. Exiting!", e)) + })?; println!("Getting player capacity..."); - let capacity = sdk - .alpha() - .get_player_capacity() - .map_err(|e| format!("Could not run GetPlayerCapacity(): {}. Exiting!", e))?; + let capacity = Handle::current().block_on(async { + alpha + .get_player_capacity() + .await + .map_err(|e| format!("Could not run GetPlayerCapacity(): {}. Exiting!", e)) + })?; println!("Player capacity: {}", capacity); println!("Increasing the player count..."); let player_id = "1234".to_string(); - let added = sdk - .alpha() - .player_connect(&player_id) - .map_err(|e| format!("Could not run PlayerConnect(): {}. Exiting!", e))?; + + let added = Handle::current().block_on(async { + alpha + .player_connect(&player_id) + .await + .map_err(|e| format!("Could not run PlayerConnect(): {}. Exiting!", e)) + })?; if added { println!("Added player"); } else { panic!("Failed to add player. Exiting!"); } - let connected = sdk - .alpha() - .is_player_connected(&player_id) - .map_err(|e| format!("Could not run IsPlayerConnected(): {}. Exiting!", e))?; + let connected = Handle::current().block_on(async { + alpha + .is_player_connected(&player_id) + .await + .map_err(|e| format!("Could not run IsPlayerConnected(): {}. Exiting!", e)) + })?; if connected { println!("{} is connected", player_id); } else { panic!("{} is not connected. Exiting!", player_id); } - let player_ids = sdk - .alpha() - .get_connected_players() - .map_err(|e| format!("Could not run GetConnectedPlayers(): {}. Exiting!", e))?; + let player_ids = Handle::current().block_on(async { + alpha + .get_connected_players() + .await + .map_err(|e| format!("Could not run GetConnectedPlayers(): {}. Exiting!", e)) + })?; println!("Connected players: {:?}", player_ids); - let player_count = sdk - .alpha() - .get_player_count() - .map_err(|e| format!("Could not run GetConnectedPlayers(): {}. Exiting!", e))?; + let player_count = Handle::current().block_on(async { + alpha + .get_player_count() + .await + .map_err(|e| format!("Could not run GetConnectedPlayers(): {}. Exiting!", e)) + })?; println!("Current player count: {}", player_count); println!("Decreasing the player count..."); - let removed = sdk - .alpha() - .player_disconnect(&player_id) - .map_err(|e| format!("Could not run PlayerDisconnect(): {}. Exiting!", e))?; + let removed = Handle::current().block_on(async { + alpha + .player_disconnect(&player_id) + .await + .map_err(|e| format!("Could not run PlayerDisconnect(): {}. Exiting!", e)) + })?; if removed { println!("Removed player"); } else { panic!("Failed to remove player. Exiting!"); } - let player_count = sdk - .alpha() - .get_player_count() - .map_err(|e| format!("Could not GetPlayerCount(): {}. Exiting!", e))?; + let player_count = Handle::current().block_on(async { + alpha + .get_player_count() + .await + .map_err(|e| format!("Could not GetPlayerCount(): {}. Exiting!", e)) + })?; println!("Current player count: {}", player_count); Ok(()) } -fn run_async() -> Result<(), String> { - let sdk = task::block_on(async { agones::Sdk::new_async().await }) - .map_err(|_| "Could not connect to the sidecar. Exiting!")?; - - task::spawn(enclose! {(sdk) async move { - loop { - match sdk.health_async().await { - Ok(_) => { - println!("Health ping sent"); - } - Err(e) => { - println!("Health ping failed : {:?}", e); - } - } - task::sleep(Duration::from_secs(2)).await; - } - }}); - - #[allow(unused_mut)] - task::spawn(enclose! {(sdk) async move { - println!("Starting to watch GameServer updates..."); - let mut once = true; - let _ = sdk.watch_gameserver_async(|gameserver| { - println!( - "GameServer Update, name: {}", - gameserver.object_meta.clone().unwrap().name - ); - println!( - "GameServer Update, state: {}", - gameserver.status.clone().unwrap().state - ); - if once { - println!("Setting an annotation"); - let uid = gameserver.object_meta.clone().unwrap().uid.clone(); - #[allow(unused_mut)] - task::spawn(enclose! {(sdk) async move { - let _ = sdk.set_annotation_async("test-annotation", &uid.to_string()) - .await; - }}); - once = false; - } - }) - .await; - }}); +async fn run_async() -> Result<(), String> { + let mut sdk = match tokio::time::timeout( + Duration::from_secs(30), + agones::Sdk::new(None /* default port */, None /* keep_alive */), + ) + .await + { + Ok(sdk) => sdk.map_err(|e| format!("unable to create sdk client: {}", e))?, + Err(_) => return Err("timed out attempting to connect to the sidecar".to_owned()), + }; - task::block_on(task::sleep(Duration::from_secs(2))); + let _health = sdk.spawn_health_task(Duration::from_secs(2)); + + let _watch = { + let mut watch_client = sdk.clone(); + let (tx, mut rx) = tokio::sync::oneshot::channel::<()>(); + + tokio::task::spawn(async move { + println!("Starting to watch GameServer updates..."); + let mut once = true; + match watch_client.watch_gameserver().await { + Err(e) => println!("Failed to watch for GameServer updates: {}", e), + Ok(mut stream) => loop { + tokio::select! { + gs = stream.message() => { + match gs { + Ok(Some(gs)) => { + let om = gs.object_meta.unwrap(); + println!("GameServer Update, name: {}", om.name); + println!("GameServer Update, state: {}", gs.status.unwrap().state); + + if once { + println!("Setting an annotation"); + let uid = om.uid.clone(); + + if let Err(e) = watch_client.set_annotation("test-annotation", uid).await { + eprintln!("Failed to set annotation from watch task: {}", e); + } + + once = false; + } + } + Ok(None) => { + println!("Server closed the GameServer watch stream"); + break; + } + Err(e) => { + eprintln!("GameServer Update stream encountered an error: {}", e); + } + } + + } + _ = &mut rx => { + println!("Shutting down GameServer watch loop"); + break; + } + } + }, + } + }); - #[allow(unused_mut)] - let handle: task::JoinHandle> = task::spawn(enclose! {(sdk) async move { - println!("Marking server as ready..."); - sdk.ready_async() - .await - .map_err(|e| format!("Could not run Ready(): {}. Exiting!", e))?; + tx + }; - println!("...marked Ready"); + tokio::time::sleep(Duration::from_secs(2)).await; - println!("Reserving for 5 seconds"); - sdk.reserve_async(Duration::new(5, 0)) - .await - .map_err(|e| format!("Could not run Reserve(): {}. Exiting!", e))?; - println!("...Reserved"); + println!("Marking server as ready..."); + sdk.ready() + .await + .map_err(|e| format!("Could not run Ready(): {}. Exiting!", e))?; + println!("...marked Ready"); - println!("Allocate game server ..."); - sdk.allocate_async() - .await - .map_err(|e| format!("Could not run Allocate(): {}. Exiting!", e))?; + println!("Reserving for 5 seconds"); + sdk.reserve(Duration::new(5, 0)) + .await + .map_err(|e| format!("Could not run Reserve(): {}. Exiting!", e))?; + println!("...Reserved"); - println!("...marked Allocated"); + println!("Allocate game server ..."); + sdk.allocate() + .await + .map_err(|e| format!("Could not run Allocate(): {}. Exiting!", e))?; - println!("Getting GameServer details..."); - let gameserver = sdk - .get_gameserver_async() - .await - .map_err(|e| format!("Could not run GameServer(): {}. Exiting!", e))?; + println!("...marked Allocated"); - println!( - "GameServer name: {}", - gameserver.object_meta.clone().unwrap().name - ); + println!("Getting GameServer details..."); + let gameserver = sdk + .get_gameserver() + .await + .map_err(|e| format!("Could not run GameServer(): {}. Exiting!", e))?; - println!("Setting a label"); - let creation_ts = gameserver.object_meta.clone().unwrap().creation_timestamp; - sdk.set_label_async("test-label", &creation_ts.to_string()) - .await - .map_err(|e| format!("Could not run SetLabel(): {}. Exiting!", e))?; + println!( + "GameServer name: {}", + gameserver.object_meta.clone().unwrap().name + ); - let feature_gates = env::var("FEATURE_GATES").unwrap_or("".to_string()); - if feature_gates.contains("PlayerTracking=true") { - run_player_tracking_features_async(&sdk).await?; - } + println!("Setting a label"); + let creation_ts = gameserver.object_meta.clone().unwrap().creation_timestamp; + sdk.set_label("test-label", &creation_ts.to_string()) + .await + .map_err(|e| format!("Could not run SetLabel(): {}. Exiting!", e))?; - for i in 0..1 { - let time = i * 5; - println!("Running for {} seconds", time); + let feature_gates = env::var("FEATURE_GATES").unwrap_or_default(); + if feature_gates.contains("PlayerTracking=true") { + run_player_tracking_features_async(sdk.alpha().clone()).await?; + } - task::sleep(Duration::from_secs(5)).await; - } + for i in 0..1 { + let time = i * 5; + println!("Running for {} seconds", time); - println!("Shutting down..."); - sdk.shutdown_async() - .await - .map_err(|e| format!("Could not run Shutdown: {}. Exiting!", e))?; - println!("...marked for Shutdown"); - Ok(()) - }}); - task::block_on(handle).map_err(|e| format!("{}", e))?; + tokio::time::sleep(Duration::from_secs(5)).await; + } + println!("Shutting down..."); + sdk.shutdown() + .await + .map_err(|e| format!("Could not run Shutdown: {}. Exiting!", e))?; + println!("...marked for Shutdown"); Ok(()) } -async fn run_player_tracking_features_async(sdk: &agones::Sdk) -> Result<(), String> { +async fn run_player_tracking_features_async(mut alpha: agones::alpha::Alpha) -> Result<(), String> { println!("Setting player capacity..."); - sdk.alpha() - .set_player_capacity_async(10) + alpha + .set_player_capacity(10) .await .map_err(|e| format!("Could not run SetPlayerCapacity(): {}. Exiting!", e))?; println!("Getting player capacity..."); - let capacity = sdk - .alpha() - .get_player_capacity_async() + let capacity = alpha + .get_player_capacity() .await .map_err(|e| format!("Could not run GetPlayerCapacity(): {}. Exiting!", e))?; println!("Player capacity: {}", capacity); println!("Increasing the player count..."); let player_id = "1234".to_string(); - let added = sdk - .alpha() - .player_connect_async(&player_id) + let added = alpha + .player_connect(&player_id) .await .map_err(|e| format!("Could not run PlayerConnect(): {}. Exiting!", e))?; if added { @@ -350,9 +402,8 @@ async fn run_player_tracking_features_async(sdk: &agones::Sdk) -> Result<(), Str panic!("Failed to add player. Exiting!"); } - let connected = sdk - .alpha() - .is_player_connected_async(&player_id) + let connected = alpha + .is_player_connected(&player_id) .await .map_err(|e| format!("Could not run IsPlayerConnected(): {}. Exiting!", e))?; if connected { @@ -361,24 +412,21 @@ async fn run_player_tracking_features_async(sdk: &agones::Sdk) -> Result<(), Str panic!("{} is not connected. Exiting!", player_id); } - let player_ids = sdk - .alpha() - .get_connected_players_async() + let player_ids = alpha + .get_connected_players() .await .map_err(|e| format!("Could not run GetConnectedPlayers(): {}. Exiting!", e))?; println!("Connected players: {:?}", player_ids); - let player_count = sdk - .alpha() - .get_player_count_async() + let player_count = alpha + .get_player_count() .await .map_err(|e| format!("Could not run GetConnectedPlayers(): {}. Exiting!", e))?; println!("Current player count: {}", player_count); println!("Decreasing the player count..."); - let removed = sdk - .alpha() - .player_disconnect_async(&player_id) + let removed = alpha + .player_disconnect(&player_id) .await .map_err(|e| format!("Could not run PlayerDisconnect(): {}. Exiting!", e))?; if removed { @@ -387,9 +435,8 @@ async fn run_player_tracking_features_async(sdk: &agones::Sdk) -> Result<(), Str panic!("Failed to remove player. Exiting!"); } - let player_count = sdk - .alpha() - .get_player_count_async() + let player_count = alpha + .get_player_count() .await .map_err(|e| format!("Could not GetPlayerCount(): {}. Exiting!", e))?; println!("Current player count: {}", player_count); From c30a32c7cfd2a8e52bc5cdee0075df7067657679 Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Fri, 28 May 2021 13:19:29 +0200 Subject: [PATCH 12/24] Remove unneeded cruft from rust build image --- build/build-sdk-images/rust/Dockerfile | 19 ------------------- build/build-sdk-images/rust/gen.sh | 23 +---------------------- 2 files changed, 1 insertion(+), 41 deletions(-) diff --git a/build/build-sdk-images/rust/Dockerfile b/build/build-sdk-images/rust/Dockerfile index 5b9234d361..e3c999dc64 100644 --- a/build/build-sdk-images/rust/Dockerfile +++ b/build/build-sdk-images/rust/Dockerfile @@ -31,25 +31,6 @@ RUN wget -q https://static.rust-lang.org/rustup/dist/x86_64-unknown-linux-gnu/ru cargo --version; \ rustc --version; -# install rust tooling for SDK generation -RUN cargo install protobuf-codegen --vers 2.16.2 -RUN cargo install grpcio-compiler --vers 0.6.0 - -RUN wget -q https://cmake.org/files/v3.14/cmake-3.14.1-Linux-x86_64.sh -RUN mkdir /opt/cmake -RUN sh cmake-3.14.1-Linux-x86_64.sh --prefix=/opt/cmake --skip-license -RUN ln -s /opt/cmake/bin/cmake /usr/local/bin/cmake -RUN cmake --version - -ENV GO_VERSION=1.10.2 \ - GO_CHECKSUM=4b677d698c65370afa33757b6954ade60347aaca310ea92a63ed717d7cb0c2ff -RUN mkdir -p /usr/local/go \ - && curl -fSO https://dl.google.com/go/go${GO_VERSION}.linux-amd64.tar.gz \ - && shasum -a 256 go${GO_VERSION}.linux-amd64.tar.gz | grep ${GO_CHECKSUM} \ - && tar xf go${GO_VERSION}.linux-amd64.tar.gz -C /usr/local/go --strip-components=1 \ - && rm -f go${GO_VERSION}.linux-amd64.tar.gz -ENV PATH $PATH:/usr/local/go/bin - # code generation scripts COPY *.sh /root/ RUN chmod +x /root/*.sh \ No newline at end of file diff --git a/build/build-sdk-images/rust/gen.sh b/build/build-sdk-images/rust/gen.sh index c7b674f214..b526c4c78f 100644 --- a/build/build-sdk-images/rust/gen.sh +++ b/build/build-sdk-images/rust/gen.sh @@ -16,25 +16,4 @@ set -ex -googleapis=/go/src/agones.dev/agones/proto/googleapis - -sdk=/go/src/agones.dev/agones/proto/sdk -cd /go/src/agones.dev/agones - -protoc \ - -I ${googleapis} -I ${sdk} sdk.proto \ - --rust_out=sdks/rust/src/grpc --grpc_out=sdks/rust/src/grpc \ - --plugin=protoc-gen-grpc=`which grpc_rust_plugin` -protoc \ - -I ${googleapis} -I ${sdk}/alpha alpha.proto \ - --rust_out=sdks/rust/src/grpc --grpc_out=sdks/rust/src/grpc \ - --plugin=protoc-gen-grpc=`which grpc_rust_plugin` - -cat ./build/boilerplate.go.txt ./sdks/rust/src/grpc/sdk.rs >> ./sdk.rs -cat ./build/boilerplate.go.txt ./sdks/rust/src/grpc/sdk_grpc.rs >> ./sdk_grpc.rs -cat ./build/boilerplate.go.txt ./sdks/rust/src/grpc/alpha.rs >> ./alpha.rs -cat ./build/boilerplate.go.txt ./sdks/rust/src/grpc/alpha_grpc.rs >> ./alpha_grpc.rs -mv ./sdk.rs ./sdks/rust/src/grpc/ -mv ./sdk_grpc.rs ./sdks/rust/src/grpc/ -mv ./alpha.rs ./sdks/rust/src/grpc/ -mv ./alpha_grpc.rs ./sdks/rust/src/grpc/ +echo "Rust code is generated at build time" From dafdd74809156d3a294ffa45e4087a2c51080826 Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Fri, 28 May 2021 17:38:55 +0200 Subject: [PATCH 13/24] Remove lines causing excessive rebuilds --- sdks/rust/build.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/sdks/rust/build.rs b/sdks/rust/build.rs index 402691cfc8..5bac47cd62 100644 --- a/sdks/rust/build.rs +++ b/sdks/rust/build.rs @@ -1,7 +1,4 @@ fn main() { - println!("cargo:rerun-if-changed=build.rs"); - println!("cargo:rerun-if-changed=protos"); - tonic_build::configure() // The SDK is just a client, no need to build the server types .build_server(false) From 82269bdc1c55971446adf16a65cba9aa4b78d86b Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Mon, 31 May 2021 14:52:36 +0200 Subject: [PATCH 14/24] Fix rust CI test, add prefix to log messages The logs from CD runs are incredibly hard to read since they are just intermixed with all tests, so I prefixed all of the print messages from the rust example so I can actually read the output more easily. --- test/sdk/rust/src/main.rs | 155 +++++++++++++++++++++----------------- 1 file changed, 85 insertions(+), 70 deletions(-) diff --git a/test/sdk/rust/src/main.rs b/test/sdk/rust/src/main.rs index 2703560e21..eea2789e49 100644 --- a/test/sdk/rust/src/main.rs +++ b/test/sdk/rust/src/main.rs @@ -24,7 +24,7 @@ async fn main() { 0 } Err(msg) => { - println!("{}", msg); + println!("rust: {}", msg); 1 } }); @@ -33,7 +33,7 @@ async fn main() { async fn run() -> Result<(), String> { let env_run_async = env::var("RUN_ASYNC").unwrap_or_default(); if env_run_async.contains("true") { - println!("RUN_ASYNC is set to true, so run test for async functions"); + println!("rust: RUN_ASYNC is set to true, so run test for async functions"); run_async().await } else { tokio::task::block_in_place(run_sync) @@ -43,7 +43,7 @@ async fn run() -> Result<(), String> { fn run_sync() -> Result<(), String> { use tokio::runtime::Handle; - println!("Creating SDK instance"); + println!("rust: Creating SDK instance"); let mut sdk = Handle::current().block_on(async move { match tokio::time::timeout( Duration::from_secs(30), @@ -63,29 +63,42 @@ fn run_sync() -> Result<(), String> { let (tx, mut rx) = tokio::sync::oneshot::channel::<()>(); tokio::task::spawn(async move { - println!("Starting to watch GameServer updates..."); + println!("rust: Starting to watch GameServer updates..."); + let mut once = true; match watch_client.watch_gameserver().await { - Err(e) => println!("Failed to watch for GameServer updates: {}", e), + Err(e) => eprintln!("rust: Failed to watch for GameServer updates: {}", e), Ok(mut stream) => loop { tokio::select! { gs = stream.message() => { match gs { Ok(Some(gs)) => { - println!("GameServer Update, name: {}", gs.object_meta.unwrap().name); - println!("GameServer Update, state: {}", gs.status.unwrap().state); + let om = gs.object_meta.unwrap(); + println!("rust: GameServer Update, name: {}", om.name); + println!("rust: GameServer Update, state: {}", gs.status.unwrap().state); + + if once { + println!("rust: Setting an annotation"); + let uid = om.uid.clone(); + + if let Err(e) = watch_client.set_annotation("test-annotation", uid).await { + eprintln!("rust: Failed to set annotation from watch task: {}", e); + } + + once = false; + } } Ok(None) => { - println!("Server closed the GameServer watch stream"); + println!("rust: Server closed the GameServer watch stream"); break; } Err(e) => { - eprintln!("GameServer Update stream encountered an error: {}", e); + eprintln!("rust: GameServer Update stream encountered an error: {}", e); } } } _ = &mut rx => { - println!("Shutting down GameServer watch loop"); + println!("rust: Shutting down GameServer watch loop"); break; } } @@ -99,33 +112,33 @@ fn run_sync() -> Result<(), String> { // Waiting for a thread to spawn thread::sleep(Duration::from_secs(2)); - println!("Marking server as ready..."); + println!("rust: Marking server as ready..."); Handle::current().block_on(async { sdk.ready() .await .map_err(|e| format!("Could not run Ready(): {}. Exiting!", e)) })?; - println!("...marked Ready"); + println!("rust: ...marked Ready"); - println!("Reserving for 5 seconds"); + println!("rust: Reserving for 5 seconds"); Handle::current().block_on(async { sdk.reserve(Duration::from_secs(5)) .await .map_err(|e| format!("Could not run Reserve(): {}. Exiting!", e)) })?; - println!("...Reserved"); + println!("rust: ...Reserved"); - println!("Allocate game server ..."); + println!("rust: Allocate game server ..."); Handle::current().block_on(async { sdk.allocate() .await .map_err(|e| format!("Could not run Allocate(): {}. Exiting!", e)) })?; - println!("...marked Allocated"); + println!("rust: ...marked Allocated"); - println!("Getting GameServer details..."); + println!("rust: Getting GameServer details..."); let gameserver = Handle::current().block_on(async { sdk.get_gameserver() .await @@ -133,11 +146,11 @@ fn run_sync() -> Result<(), String> { })?; println!( - "GameServer name: {}", + "rust: GameServer name: {}", gameserver.object_meta.clone().unwrap().name ); - println!("Setting a label"); + println!("rust: Setting a label"); let creation_ts = gameserver.object_meta.unwrap().creation_timestamp; Handle::current().block_on(async { sdk.set_label("test-label", &creation_ts.to_string()) @@ -152,25 +165,26 @@ fn run_sync() -> Result<(), String> { for i in 0..1 { let time = i * 5; - println!("Running for {} seconds", time); + println!("rust: Running for {} seconds", time); thread::sleep(Duration::from_secs(5)); } - println!("Shutting down..."); + println!("rust: Shutting down..."); Handle::current().block_on(async { sdk.shutdown() .await .map_err(|e| format!("Could not run Shutdown: {}. Exiting!", e)) })?; - println!("...marked for Shutdown"); + println!("rust: ...marked for Shutdown"); + Ok(()) } fn run_player_tracking_features(mut alpha: agones::alpha::Alpha) -> Result<(), String> { use tokio::runtime::Handle; - println!("Setting player capacity..."); + println!("rust: Setting player capacity..."); Handle::current().block_on(async { alpha .set_player_capacity(10) @@ -178,16 +192,16 @@ fn run_player_tracking_features(mut alpha: agones::alpha::Alpha) -> Result<(), S .map_err(|e| format!("Could not run SetPlayerCapacity(): {:#?}. Exiting!", e)) })?; - println!("Getting player capacity..."); + println!("rust: Getting player capacity..."); let capacity = Handle::current().block_on(async { alpha .get_player_capacity() .await .map_err(|e| format!("Could not run GetPlayerCapacity(): {}. Exiting!", e)) })?; - println!("Player capacity: {}", capacity); + println!("rust: Player capacity: {}", capacity); - println!("Increasing the player count..."); + println!("rust: Increasing the player count..."); let player_id = "1234".to_string(); let added = Handle::current().block_on(async { @@ -197,9 +211,9 @@ fn run_player_tracking_features(mut alpha: agones::alpha::Alpha) -> Result<(), S .map_err(|e| format!("Could not run PlayerConnect(): {}. Exiting!", e)) })?; if added { - println!("Added player"); + println!("rust: Added player"); } else { - panic!("Failed to add player. Exiting!"); + panic!("rust: Failed to add player. Exiting!"); } let connected = Handle::current().block_on(async { @@ -209,9 +223,9 @@ fn run_player_tracking_features(mut alpha: agones::alpha::Alpha) -> Result<(), S .map_err(|e| format!("Could not run IsPlayerConnected(): {}. Exiting!", e)) })?; if connected { - println!("{} is connected", player_id); + println!("rust: {} is connected", player_id); } else { - panic!("{} is not connected. Exiting!", player_id); + panic!("rust: {} is not connected. Exiting!", player_id); } let player_ids = Handle::current().block_on(async { @@ -220,7 +234,7 @@ fn run_player_tracking_features(mut alpha: agones::alpha::Alpha) -> Result<(), S .await .map_err(|e| format!("Could not run GetConnectedPlayers(): {}. Exiting!", e)) })?; - println!("Connected players: {:?}", player_ids); + println!("rust: Connected players: {:?}", player_ids); let player_count = Handle::current().block_on(async { alpha @@ -228,9 +242,9 @@ fn run_player_tracking_features(mut alpha: agones::alpha::Alpha) -> Result<(), S .await .map_err(|e| format!("Could not run GetConnectedPlayers(): {}. Exiting!", e)) })?; - println!("Current player count: {}", player_count); + println!("rust: Current player count: {}", player_count); - println!("Decreasing the player count..."); + println!("rust: Decreasing the player count..."); let removed = Handle::current().block_on(async { alpha .player_disconnect(&player_id) @@ -238,9 +252,9 @@ fn run_player_tracking_features(mut alpha: agones::alpha::Alpha) -> Result<(), S .map_err(|e| format!("Could not run PlayerDisconnect(): {}. Exiting!", e)) })?; if removed { - println!("Removed player"); + println!("rust: Removed player"); } else { - panic!("Failed to remove player. Exiting!"); + panic!("rust: Failed to remove player. Exiting!"); } let player_count = Handle::current().block_on(async { @@ -249,7 +263,7 @@ fn run_player_tracking_features(mut alpha: agones::alpha::Alpha) -> Result<(), S .await .map_err(|e| format!("Could not GetPlayerCount(): {}. Exiting!", e)) })?; - println!("Current player count: {}", player_count); + println!("rust: Current player count: {}", player_count); Ok(()) } @@ -272,42 +286,42 @@ async fn run_async() -> Result<(), String> { let (tx, mut rx) = tokio::sync::oneshot::channel::<()>(); tokio::task::spawn(async move { - println!("Starting to watch GameServer updates..."); + println!("rust_async: Starting to watch GameServer updates..."); let mut once = true; match watch_client.watch_gameserver().await { - Err(e) => println!("Failed to watch for GameServer updates: {}", e), + Err(e) => eprintln!("rust_async: Failed to watch for GameServer updates: {}", e), Ok(mut stream) => loop { tokio::select! { gs = stream.message() => { match gs { Ok(Some(gs)) => { let om = gs.object_meta.unwrap(); - println!("GameServer Update, name: {}", om.name); - println!("GameServer Update, state: {}", gs.status.unwrap().state); + println!("rust_async: GameServer Update, name: {}", om.name); + println!("rust_async: GameServer Update, state: {}", gs.status.unwrap().state); if once { - println!("Setting an annotation"); + println!("rust_async: Setting an annotation"); let uid = om.uid.clone(); if let Err(e) = watch_client.set_annotation("test-annotation", uid).await { - eprintln!("Failed to set annotation from watch task: {}", e); + eprintln!("rust_async: Failed to set annotation from watch task: {}", e); } once = false; } } Ok(None) => { - println!("Server closed the GameServer watch stream"); + println!("rust_async: Server closed the GameServer watch stream"); break; } Err(e) => { - eprintln!("GameServer Update stream encountered an error: {}", e); + eprintln!("rust_async: GameServer Update stream encountered an error: {}", e); } } } _ = &mut rx => { - println!("Shutting down GameServer watch loop"); + println!("rust_async: Shutting down GameServer watch loop"); break; } } @@ -320,37 +334,37 @@ async fn run_async() -> Result<(), String> { tokio::time::sleep(Duration::from_secs(2)).await; - println!("Marking server as ready..."); + println!("rust_async: Marking server as ready..."); sdk.ready() .await .map_err(|e| format!("Could not run Ready(): {}. Exiting!", e))?; - println!("...marked Ready"); + println!("rust_async: ...marked Ready"); - println!("Reserving for 5 seconds"); + println!("rust_async: Reserving for 5 seconds"); sdk.reserve(Duration::new(5, 0)) .await .map_err(|e| format!("Could not run Reserve(): {}. Exiting!", e))?; - println!("...Reserved"); + println!("rust_async: ...Reserved"); - println!("Allocate game server ..."); + println!("rust_async: Allocate game server ..."); sdk.allocate() .await .map_err(|e| format!("Could not run Allocate(): {}. Exiting!", e))?; - println!("...marked Allocated"); + println!("rust_async: ...marked Allocated"); - println!("Getting GameServer details..."); + println!("rust_async: Getting GameServer details..."); let gameserver = sdk .get_gameserver() .await .map_err(|e| format!("Could not run GameServer(): {}. Exiting!", e))?; println!( - "GameServer name: {}", + "rust_async: GameServer name: {}", gameserver.object_meta.clone().unwrap().name ); - println!("Setting a label"); + println!("rust_async: Setting a label"); let creation_ts = gameserver.object_meta.clone().unwrap().creation_timestamp; sdk.set_label("test-label", &creation_ts.to_string()) .await @@ -363,34 +377,35 @@ async fn run_async() -> Result<(), String> { for i in 0..1 { let time = i * 5; - println!("Running for {} seconds", time); + println!("rust_async: Running for {} seconds", time); tokio::time::sleep(Duration::from_secs(5)).await; } - println!("Shutting down..."); + println!("rust_async: Shutting down..."); sdk.shutdown() .await .map_err(|e| format!("Could not run Shutdown: {}. Exiting!", e))?; - println!("...marked for Shutdown"); + println!("rust_async: ...marked for Shutdown"); + Ok(()) } async fn run_player_tracking_features_async(mut alpha: agones::alpha::Alpha) -> Result<(), String> { - println!("Setting player capacity..."); + println!("rust_async: Setting player capacity..."); alpha .set_player_capacity(10) .await .map_err(|e| format!("Could not run SetPlayerCapacity(): {}. Exiting!", e))?; - println!("Getting player capacity..."); + println!("rust_async: Getting player capacity..."); let capacity = alpha .get_player_capacity() .await .map_err(|e| format!("Could not run GetPlayerCapacity(): {}. Exiting!", e))?; - println!("Player capacity: {}", capacity); + println!("rust_async: Player capacity: {}", capacity); - println!("Increasing the player count..."); + println!("rust_async: Increasing the player count..."); let player_id = "1234".to_string(); let added = alpha .player_connect(&player_id) @@ -399,7 +414,7 @@ async fn run_player_tracking_features_async(mut alpha: agones::alpha::Alpha) -> if added { println!("Added player"); } else { - panic!("Failed to add player. Exiting!"); + panic!("rust_async: Failed to add player. Exiting!"); } let connected = alpha @@ -407,39 +422,39 @@ async fn run_player_tracking_features_async(mut alpha: agones::alpha::Alpha) -> .await .map_err(|e| format!("Could not run IsPlayerConnected(): {}. Exiting!", e))?; if connected { - println!("{} is connected", player_id); + println!("rust_async: {} is connected", player_id); } else { - panic!("{} is not connected. Exiting!", player_id); + panic!("rust_async: {} is not connected. Exiting!", player_id); } let player_ids = alpha .get_connected_players() .await .map_err(|e| format!("Could not run GetConnectedPlayers(): {}. Exiting!", e))?; - println!("Connected players: {:?}", player_ids); + println!("rust_async: Connected players: {:?}", player_ids); let player_count = alpha .get_player_count() .await .map_err(|e| format!("Could not run GetConnectedPlayers(): {}. Exiting!", e))?; - println!("Current player count: {}", player_count); + println!("rust_async: Current player count: {}", player_count); - println!("Decreasing the player count..."); + println!("rust_async: Decreasing the player count..."); let removed = alpha .player_disconnect(&player_id) .await .map_err(|e| format!("Could not run PlayerDisconnect(): {}. Exiting!", e))?; if removed { - println!("Removed player"); + println!("rust_async: Removed player"); } else { - panic!("Failed to remove player. Exiting!"); + panic!("rust_async: Failed to remove player. Exiting!"); } let player_count = alpha .get_player_count() .await .map_err(|e| format!("Could not GetPlayerCount(): {}. Exiting!", e))?; - println!("Current player count: {}", player_count); + println!("rust_async: Current player count: {}", player_count); Ok(()) } From dec667dabdd3ec66cad14d840eb9085728c4ed0b Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Wed, 16 Jun 2021 08:53:29 +0200 Subject: [PATCH 15/24] Address PR feedback --- sdks/rust/src/sdk.rs | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/sdks/rust/src/sdk.rs b/sdks/rust/src/sdk.rs index 67094d30b8..e32b792cec 100644 --- a/sdks/rust/src/sdk.rs +++ b/sdks/rust/src/sdk.rs @@ -50,10 +50,6 @@ impl Sdk { /// to the SDK server, so it is recommended to wrap this in a /// [timeout](https://docs.rs/tokio/1.6.0/tokio/time/fn.timeout.html). pub async fn new(port: Option, keep_alive: Option) -> Result { - // TODO: Add TLS? For some reason the original Cargo.toml was enabling - // grpcio's openssl features, but AFAICT the SDK and sidecar only ever - // communicate via a non-TLS connection, so seems like we could just - // use the simpler client setup code if TLS is absolutely never needed let addr: http::Uri = format!( "http://localhost:{}", port.unwrap_or_else(|| { @@ -68,15 +64,6 @@ impl Sdk { let builder = tonic::transport::channel::Channel::builder(addr) .keep_alive_timeout(keep_alive.unwrap_or_else(|| Duration::from_secs(30))); - // let mut root_store = rustls::RootCertStore::empty(); - // root_store.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS); - // let mut rusttls_config = rustls::ClientConfig::new(); - // rusttls_config.alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec()]; - // rusttls_config.root_store = root_store; - // let tls_config = - // tonic::transport::ClientTlsConfig::new().rustls_client_config(rusttls_config); - // builder = builder.tls_config(tls_config)?; - let channel = builder.connect().await?; let mut client = SdkClient::new(channel.clone()); let alpha = Alpha::new(channel); @@ -107,26 +94,22 @@ impl Sdk { } /// Marks the Game Server as ready to receive connections - #[inline] pub async fn ready(&mut self) -> Result<()> { Ok(self.client.ready(empty()).await.map(|_| ())?) } /// Allocate the Game Server - #[inline] pub async fn allocate(&mut self) -> Result<()> { Ok(self.client.allocate(empty()).await.map(|_| ())?) } /// Marks the Game Server as ready to shutdown - #[inline] pub async fn shutdown(&mut self) -> Result<()> { Ok(self.client.shutdown(empty()).await.map(|_| ())?) } /// Creates a task that sends a health ping to the SDK server on every interval /// tick. It is recommended to only have 1 of these at a time. - #[inline] pub fn spawn_health_task(&self, interval: Duration) -> tokio::sync::oneshot::Sender<()> { let mut health_client = self.clone(); let (tx, mut rx) = tokio::sync::oneshot::channel(); @@ -153,7 +136,6 @@ impl Sdk { } /// Set a Label value on the backing GameServer record that is stored in Kubernetes - #[inline] pub async fn set_label( &mut self, key: impl Into, @@ -170,7 +152,6 @@ impl Sdk { } /// Set a Annotation value on the backing Gameserver record that is stored in Kubernetes - #[inline] pub async fn set_annotation( &mut self, key: impl Into, @@ -187,7 +168,6 @@ impl Sdk { } /// Returns most of the backing GameServer configuration and Status - #[inline] pub async fn get_gameserver(&mut self) -> Result { Ok(self .client @@ -199,7 +179,6 @@ impl Sdk { /// Reserve marks the Game Server as Reserved for a given duration, at which point /// it will return the GameServer to a Ready state. /// Do note, the smallest unit available in the time.Duration argument is one second. - #[inline] pub async fn reserve(&mut self, duration: Duration) -> Result<()> { Ok(self .client @@ -211,7 +190,6 @@ impl Sdk { } /// Watch the backing GameServer configuration on updated - #[inline] pub async fn watch_gameserver(&mut self) -> Result { Ok(self .client From fd38ddaf68b1a0ccd1aaa956a6117f5fe87f5a0e Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Wed, 16 Jun 2021 09:53:04 +0200 Subject: [PATCH 16/24] Update rust SDK documentation --- .../en/docs/Guides/Client SDKs/rust.md | 140 +++++++++++++++++- 1 file changed, 137 insertions(+), 3 deletions(-) diff --git a/site/content/en/docs/Guides/Client SDKs/rust.md b/site/content/en/docs/Guides/Client SDKs/rust.md index eddf72e395..c506bcd03a 100644 --- a/site/content/en/docs/Guides/Client SDKs/rust.md +++ b/site/content/en/docs/Guides/Client SDKs/rust.md @@ -35,23 +35,155 @@ Download the source {{< ghlink href="sdks/rust" >}}directly from GitHub{{< /ghli ## Prerequisites +{{% feature publishVersion="1.16.0" %}} +- [Rust >= 1.50](https://www.rust-lang.org/tools/install) +{{% /feature %}} + +{{% feature expiryVersion="1.16.0" %}} - CMake >= 3.8.0 - Rust >= 1.19.0 - Go (>=1.7) The SDK needs the above for building to [gRPC-rs](https://github.com/pingcap/grpc-rs). +{{% /feature %}} ## Usage -Add this crate to `dependencies` section in your Cargo.toml. -Specify a directory where this README.md is located to the `path`. +{{% feature publishVersion="1.16.0" %}} +Add this crate to `dependencies` section in your Cargo.toml. Specify a directory where this README.md is located to the `path`. + +Also note that the SDK is [`async`](https://doc.rust-lang.org/std/keyword.async.html) only, so you will need an async runtime to execute the futures exposed by the SDK. It is recommended to use [tokio](https://docs.rs/tokio) as the SDK already depends on tokio due to its choice of gRPC library, [tonic](https://docs.rs/tonic). ```toml [dependencies] agones = { path = "../agones/sdks/rust" } +tokio = { version = "1.7", features = ["macros", "sync", "time"] } +``` + +To begin working with the SDK, create an instance of it. Note that this function will try to connect and handshake indefinitely, so it's recommended to wrap it in a [`timeout`](https://docs.rs/tokio/1.7.0/tokio/time/fn.timeout.html). + +```rust +use std::time::Duration; + +#[tokio::main] +async fn main() { + let mut sdk = tokio::time::timeout( + Duration::from_secs(30), + agones::Sdk::new(None /* default port */, None /* keep_alive */), + ) + .await + .expect("timed out connecting to SDK server") + .expect("failedt to connect to SDK server"); +} ``` -Add `extern crate agones` to your crate root. +To send [health checks]({{< relref "_index.md#health" >}}), call `sdk.spawn_health_task`, which will create a [`tokio::task`](https://docs.rs/tokio/1.7.0/tokio/task/index.html) that will send a health ping at the specified cadence until the task is dropped/cancelled. + +```rust +// Send a health ping ever 2 seconds +let _health = sdk.spawn_health_task(Duration::from_secs(2)); +``` + +To mark the [game session as ready]({{< relref "_index.md#ready" >}}) call `sdk.ready()`. + +```rust +sdk.ready().await?; +``` + +To mark the game server as [reserved]({{< relref "_index.md#reserveseconds" >}}) for a period of time, call `sdk.reserve(duration)`. + +```rust +sdk.reserve(Duration::new(5, 0)).await?; +``` + +To mark that the [game session is completed]({{< relref "_index.md#shutdown" >}}) and the game server should be shut down call `sdk.shutdown()`. + +```rust +if let Err(e) = sdk.shutdown().await { + eprintln!("Could not run Shutdown: {}", e); +} +``` + +To [set a Label]({{< relref "_index.md#setlabelkey-value" >}}) on the backing `GameServer` call `sdk.set_label(key, value)`. + +```rust +sdk.set_label("test-label", "test-value").await?; +``` + +To [set an Annotation]({{< relref "_index.md#setannotationkey-value" >}}) on the backing `GameServer` call `sdk.set_annotation(key, value)`. + +```rust +sdk.set_annotation("test-annotation", "test value").await?; +``` + +To get [details of the backing `GameServer`]({{< relref "_index.md#gameserver" >}}) call `sdk.get_gameserver()`. + +The function will return an instance of `agones::types::GameServer` including `GameServer` configuration info. + +```rust +let gameserver = sdk.get_gameserver().await?; +``` + +To get [updates on the backing `GameServer`]({{< relref "_index.md#watchgameserverfunctiongameserver" >}}) as they happen, call `sdk.watch_gameserver`. + +This will stream updates and endlessly until the stream is closed, so it is recommended to push this into its own async task. + +```rust +let _watch = { + // We need to clone the SDK as we are moving it to another task + let mut watch_client = sdk.clone(); + // We use a simple oneshot to signal to the task when we want it to shutdown + // and stop watching the gameserver update stream + let (tx, mut rx) = tokio::sync::oneshot::channel::<()>(); + + tokio::task::spawn(async move { + println!("Starting to watch GameServer updates..."); + match watch_client.watch_gameserver().await { + Err(e) => eprintln!("Failed to watch for GameServer updates: {}", e), + Ok(mut stream) => loop { + tokio::select! { + // We've received a new update, or the stream is shutting down + gs = stream.message() => { + match gs { + Ok(Some(gs)) => { + println!("GameServer Update, name: {}", gs.object_meta.unwrap().name); + println!("GameServer Update, state: {}", gs.status.unwrap().state); + } + Ok(None) => { + println!("Server closed the GameServer watch stream"); + break; + } + Err(e) => { + eprintln!("GameServer Update stream encountered an error: {}", e); + } + } + + } + // The watch is being dropped so we're going to shutdown the task + // and the watch stream + _ = &mut rx => { + println!("Shutting down GameServer watch loop"); + break; + } + } + }, + } + }); + + tx +}; +``` + +{{% /feature %}} + +{{% feature expiryVersion="1.16.0" %}} + +Add this crate to `dependencies` section in your Cargo.toml. Specify a directory where this README.md is located to the `path`. + +```toml +[dependencies] +agones = { path = "../agones/sdks/rust" } +``` To begin working with the SDK, create an instance of it. This function blocks until connection and handshake are made. @@ -118,4 +250,6 @@ sdk.watch_gameserver(|gameserver| { })?; ``` +{{% /feature %}} + For more information, please read the [SDK Overview]({{< relref "_index.md" >}}), check out {{< ghlink href="sdks/rust/src/sdk.rs" >}}agones sdk implementation{{< /ghlink >}} and also look at the {{< ghlink href="examples/rust-simple" >}}Rust example{{< / >}}. From d650d4ba7f3b47e5deddef0567cb889c96abc8f3 Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Wed, 16 Jun 2021 10:37:30 +0200 Subject: [PATCH 17/24] spawn_health_task => health_check Removed the auto health check task since that actually made health checking meaningless since it's _supposed_ to be sent by the application itself when it working properly, not automatically --- examples/rust-simple/src/main.rs | 3 ++- sdks/rust/src/sdk.rs | 20 ++++++------------- .../en/docs/Guides/Client SDKs/rust.md | 8 +++++--- test/sdk/rust/src/main.rs | 8 ++++++-- 4 files changed, 19 insertions(+), 20 deletions(-) diff --git a/examples/rust-simple/src/main.rs b/examples/rust-simple/src/main.rs index 264429815a..4d97f9491e 100644 --- a/examples/rust-simple/src/main.rs +++ b/examples/rust-simple/src/main.rs @@ -44,7 +44,8 @@ async fn run() -> Result<(), String> { } }; - let _health = sdk.spawn_health_task(Duration::from_secs(2)); + let health = sdk.health_check(); + health.send(()).await.map_err(|_| "health receiver closed".to_owned())?; let _watch = { let mut watch_client = sdk.clone(); diff --git a/sdks/rust/src/sdk.rs b/sdks/rust/src/sdk.rs index e32b792cec..e66fb8521d 100644 --- a/sdks/rust/src/sdk.rs +++ b/sdks/rust/src/sdk.rs @@ -108,24 +108,16 @@ impl Sdk { Ok(self.client.shutdown(empty()).await.map(|_| ())?) } - /// Creates a task that sends a health ping to the SDK server on every interval - /// tick. It is recommended to only have 1 of these at a time. - pub fn spawn_health_task(&self, interval: Duration) -> tokio::sync::oneshot::Sender<()> { + /// Returns a [`tokio::sync::mpsc::Sender`] that will emit a health check + /// every time a message is sent on the channel. + pub fn health_check(&self) -> tokio::sync::mpsc::Sender<()> { let mut health_client = self.clone(); - let (tx, mut rx) = tokio::sync::oneshot::channel(); + let (tx, mut rx) = tokio::sync::mpsc::channel(10); tokio::task::spawn(async move { let health_stream = async_stream::stream! { - let mut health_interval = tokio::time::interval(interval); - loop { - tokio::select! { - _ = health_interval.tick() => { - yield empty(); - } - _ = &mut rx => { - break; - } - } + while rx.recv().await.is_some() { + yield empty(); } }; diff --git a/site/content/en/docs/Guides/Client SDKs/rust.md b/site/content/en/docs/Guides/Client SDKs/rust.md index c506bcd03a..9c561b31e6 100644 --- a/site/content/en/docs/Guides/Client SDKs/rust.md +++ b/site/content/en/docs/Guides/Client SDKs/rust.md @@ -77,11 +77,13 @@ async fn main() { } ``` -To send [health checks]({{< relref "_index.md#health" >}}), call `sdk.spawn_health_task`, which will create a [`tokio::task`](https://docs.rs/tokio/1.7.0/tokio/task/index.html) that will send a health ping at the specified cadence until the task is dropped/cancelled. +To send [health checks]({{< relref "_index.md#health" >}}), call `sdk.health_check`, which will return a [`tokio::sync::mpsc::Sender::<()>`](https://docs.rs/tokio/1.7.0/tokio/sync/mpsc/struct.Sender.html) which will send a health check every time a message is posted to the channel. ```rust -// Send a health ping ever 2 seconds -let _health = sdk.spawn_health_task(Duration::from_secs(2)); +let health = sdk.health_check(); +if health.send(()).await.is_err() { + eprintln!("the health receiver was closed"); +} ``` To mark the [game session as ready]({{< relref "_index.md#ready" >}}) call `sdk.ready()`. diff --git a/test/sdk/rust/src/main.rs b/test/sdk/rust/src/main.rs index eea2789e49..a5235dbf48 100644 --- a/test/sdk/rust/src/main.rs +++ b/test/sdk/rust/src/main.rs @@ -56,7 +56,10 @@ fn run_sync() -> Result<(), String> { } })?; - let _health = sdk.spawn_health_task(Duration::from_secs(2)); + let health = sdk.health_check(); + Handle::current().block_on(async { + health.send(()).await.map_err(|_| "health receiver closed".to_owned()) + })?; let _watch = { let mut watch_client = sdk.clone(); @@ -279,7 +282,8 @@ async fn run_async() -> Result<(), String> { Err(_) => return Err("timed out attempting to connect to the sidecar".to_owned()), }; - let _health = sdk.spawn_health_task(Duration::from_secs(2)); + let health = sdk.health_check(); + health.send(()).await.map_err(|_| "health receiver closed".to_owned())?; let _watch = { let mut watch_client = sdk.clone(); From 905fdf57957a458fac897a652ed66e984e76c156 Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Wed, 16 Jun 2021 15:23:13 +0200 Subject: [PATCH 18/24] Use internal timeout for SDK connection --- examples/rust-simple/src/main.rs | 19 ++++++-------- sdks/rust/src/errors.rs | 2 ++ sdks/rust/src/sdk.rs | 25 ++++++++++--------- .../en/docs/Guides/Client SDKs/rust.md | 14 ++++------- test/sdk/rust/src/main.rs | 22 ++++++++-------- 5 files changed, 37 insertions(+), 45 deletions(-) diff --git a/examples/rust-simple/src/main.rs b/examples/rust-simple/src/main.rs index 4d97f9491e..00cd0fc38f 100644 --- a/examples/rust-simple/src/main.rs +++ b/examples/rust-simple/src/main.rs @@ -32,20 +32,15 @@ async fn main() { async fn run() -> Result<(), String> { println!("Creating SDK instance"); - let mut sdk = match tokio::time::timeout( - Duration::from_secs(30), - agones::Sdk::new(None /* default port */, None /* keep_alive */), - ) - .await - { - Ok(sdk) => sdk.map_err(|e| format!("unable to create sdk client: {}", e))?, - Err(_) => { - return Err("timed out attempting to connect to the sidecar".to_owned()); - } - }; + let mut sdk = agones::Sdk::new(None /* default port */, None /* keep_alive */) + .await + .map_err(|e| format!("unable to create sdk client: {}", e))?; let health = sdk.health_check(); - health.send(()).await.map_err(|_| "health receiver closed".to_owned())?; + health + .send(()) + .await + .map_err(|_| "health receiver closed".to_owned())?; let _watch = { let mut watch_client = sdk.clone(); diff --git a/sdks/rust/src/errors.rs b/sdks/rust/src/errors.rs index e75bf52244..93711be4de 100644 --- a/sdks/rust/src/errors.rs +++ b/sdks/rust/src/errors.rs @@ -18,6 +18,8 @@ pub type Result = std::result::Result; pub enum Error { #[error("health ping connection failure: `{0}`")] HealthPingConnectionFailure(String), + #[error(transparent)] + TimedOut(#[from] tokio::time::error::Elapsed), #[error("failed to parse connection uri")] InvalidUri(#[from] http::uri::InvalidUri), #[error("rpc failure")] diff --git a/sdks/rust/src/sdk.rs b/sdks/rust/src/sdk.rs index e66fb8521d..b57e7e81bc 100644 --- a/sdks/rust/src/sdk.rs +++ b/sdks/rust/src/sdk.rs @@ -46,9 +46,11 @@ impl Sdk { /// or else falls back to the `AGONES_SDK_GRPC_PORT` environment variable, /// or defaults to 9357. /// - /// Note that this function will loop indefinitely until a connection is made - /// to the SDK server, so it is recommended to wrap this in a - /// [timeout](https://docs.rs/tokio/1.6.0/tokio/time/fn.timeout.html). + /// # Errors + /// + /// - The port specified in `AGONES_SDK_GRPC_PORT` can't be parsed as a `u16`. + /// - A connection cannot be established with an Agones SDK server + /// - The handshake takes longer than 30 seconds pub async fn new(port: Option, keep_alive: Option) -> Result { let addr: http::Uri = format!( "http://localhost:{}", @@ -68,18 +70,17 @@ impl Sdk { let mut client = SdkClient::new(channel.clone()); let alpha = Alpha::new(channel); - // Loop until we connect. The original implementation just looped once - // every second up to a maximum of 30 seconds, but it's better for the - // external caller to wrap this in their own timeout - let mut connect_interval = tokio::time::interval(Duration::from_millis(100)); + tokio::time::timeout(Duration::from_secs(30), async { + let mut connect_interval = tokio::time::interval(Duration::from_millis(100)); - loop { - connect_interval.tick().await; + loop { + connect_interval.tick().await; - if client.get_game_server(empty()).await.is_ok() { - break; + if client.get_game_server(empty()).await.is_ok() { + break; + } } - } + }).await?; Ok(Self { client, diff --git a/site/content/en/docs/Guides/Client SDKs/rust.md b/site/content/en/docs/Guides/Client SDKs/rust.md index 9c561b31e6..6b1b64dc6e 100644 --- a/site/content/en/docs/Guides/Client SDKs/rust.md +++ b/site/content/en/docs/Guides/Client SDKs/rust.md @@ -57,23 +57,19 @@ Also note that the SDK is [`async`](https://doc.rust-lang.org/std/keyword.async. ```toml [dependencies] agones = { path = "../agones/sdks/rust" } -tokio = { version = "1.7", features = ["macros", "sync", "time"] } +tokio = { version = "1.7", features = ["macros", "sync"] } ``` -To begin working with the SDK, create an instance of it. Note that this function will try to connect and handshake indefinitely, so it's recommended to wrap it in a [`timeout`](https://docs.rs/tokio/1.7.0/tokio/time/fn.timeout.html). +To begin working with the SDK, create an instance of it. ```rust use std::time::Duration; #[tokio::main] async fn main() { - let mut sdk = tokio::time::timeout( - Duration::from_secs(30), - agones::Sdk::new(None /* default port */, None /* keep_alive */), - ) - .await - .expect("timed out connecting to SDK server") - .expect("failedt to connect to SDK server"); + let mut sdk = agones::Sdk::new(None /* default port */, None /* keep_alive */) + .await + .expect("failedt to connect to SDK server"); } ``` diff --git a/test/sdk/rust/src/main.rs b/test/sdk/rust/src/main.rs index a5235dbf48..58f638a36f 100644 --- a/test/sdk/rust/src/main.rs +++ b/test/sdk/rust/src/main.rs @@ -45,20 +45,15 @@ fn run_sync() -> Result<(), String> { println!("rust: Creating SDK instance"); let mut sdk = Handle::current().block_on(async move { - match tokio::time::timeout( - Duration::from_secs(30), - agones::Sdk::new(None /* default port */, None /* keep_alive */), - ) - .await - { - Ok(sdk) => sdk.map_err(|e| format!("unable to create sdk client: {}", e)), - Err(_) => Err("timed out attempting to connect to the sidecar".to_owned()), - } + agones::Sdk::new(None /* default port */, None /* keep_alive */) + .await + .map_err(|e| format!("unable to create sdk client: {}", e)) })?; let health = sdk.health_check(); - Handle::current().block_on(async { - health.send(()).await.map_err(|_| "health receiver closed".to_owned()) + health.try_send(()).map_err(|e| match e { + tokio::sync::mpsc::error::TrySendError::Full(_) => "health receiver full".to_owned(), + tokio::sync::mpsc::error::TrySendError::Closed(_) => "health receiver closed".to_owned(), })?; let _watch = { @@ -283,7 +278,10 @@ async fn run_async() -> Result<(), String> { }; let health = sdk.health_check(); - health.send(()).await.map_err(|_| "health receiver closed".to_owned())?; + health + .send(()) + .await + .map_err(|_| "health receiver closed".to_owned())?; let _watch = { let mut watch_client = sdk.clone(); From b7a9eba1cd5459aee2d16a56b64b4baf98bddf82 Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Fri, 18 Jun 2021 09:28:14 +0200 Subject: [PATCH 19/24] Do continuous health checks This method should be better than the previous test/examples as the health check will actually be canceled if the task/thread the health check is owned by is canceled for any reason --- examples/rust-simple/src/main.rs | 34 +++++++++++++--- test/sdk/rust/src/main.rs | 66 +++++++++++++++++++++++++++----- 2 files changed, 85 insertions(+), 15 deletions(-) diff --git a/examples/rust-simple/src/main.rs b/examples/rust-simple/src/main.rs index 00cd0fc38f..b71ee2a4ad 100644 --- a/examples/rust-simple/src/main.rs +++ b/examples/rust-simple/src/main.rs @@ -36,11 +36,35 @@ async fn run() -> Result<(), String> { .await .map_err(|e| format!("unable to create sdk client: {}", e))?; - let health = sdk.health_check(); - health - .send(()) - .await - .map_err(|_| "health receiver closed".to_owned())?; + // Spawn a task that will send health checks every 2 seconds. If this current + // thread/task panics or dropped, the health check will also be stopped + let _health = { + let health_tx = sdk.health_check(); + let (tx, mut rx) = tokio::sync::oneshot::channel::<()>(); + + tokio::task::spawn(async move { + let mut interval = tokio::time::interval(Duration::from_secs(2)); + + loop { + tokio::select! { + _ = interval.tick() => { + if health_tx + .send(()) + .await.is_err() { + eprintln!("Health check receiver was dropped"); + break; + } + } + _ = &mut rx => { + println!("Health check task canceled"); + break; + } + } + } + }); + + tx + }; let _watch = { let mut watch_client = sdk.clone(); diff --git a/test/sdk/rust/src/main.rs b/test/sdk/rust/src/main.rs index 58f638a36f..d6c3c13c87 100644 --- a/test/sdk/rust/src/main.rs +++ b/test/sdk/rust/src/main.rs @@ -50,11 +50,35 @@ fn run_sync() -> Result<(), String> { .map_err(|e| format!("unable to create sdk client: {}", e)) })?; - let health = sdk.health_check(); - health.try_send(()).map_err(|e| match e { - tokio::sync::mpsc::error::TrySendError::Full(_) => "health receiver full".to_owned(), - tokio::sync::mpsc::error::TrySendError::Closed(_) => "health receiver closed".to_owned(), - })?; + // Spawn a task that will send health checks every 2 seconds. If this current + // thread/task panics or dropped, the health check will also be stopped + let _health = { + let health_tx = sdk.health_check(); + let (tx, mut rx) = tokio::sync::oneshot::channel::<()>(); + + Handle::current().spawn(async move { + let mut interval = tokio::time::interval(Duration::from_secs(2)); + + loop { + tokio::select! { + _ = interval.tick() => { + if health_tx + .send(()) + .await.is_err() { + eprintln!("Health check receiver was dropped"); + break; + } + } + _ = &mut rx => { + println!("Health check task canceled"); + break; + } + } + } + }); + + tx + }; let _watch = { let mut watch_client = sdk.clone(); @@ -277,11 +301,33 @@ async fn run_async() -> Result<(), String> { Err(_) => return Err("timed out attempting to connect to the sidecar".to_owned()), }; - let health = sdk.health_check(); - health - .send(()) - .await - .map_err(|_| "health receiver closed".to_owned())?; + let _health = { + let health_tx = sdk.health_check(); + let (tx, mut rx) = tokio::sync::oneshot::channel::<()>(); + + tokio::task::spawn(async move { + let mut interval = tokio::time::interval(Duration::from_secs(2)); + + loop { + tokio::select! { + _ = interval.tick() => { + if health_tx + .send(()) + .await.is_err() { + eprintln!("Health check receiver was dropped"); + break; + } + } + _ = &mut rx => { + println!("Health check task canceled"); + break; + } + } + } + }); + + tx + }; let _watch = { let mut watch_client = sdk.clone(); From 8b8f2912be8a34860f94550488fb0ac1afaef2fb Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Fri, 18 Jun 2021 09:50:57 +0200 Subject: [PATCH 20/24] Copy protobuffers before build --- build/build-sdk-images/rust/gen.sh | 6 + sdks/rust/.gitignore | 6 +- sdks/rust/copy-protos.sh | 8 + sdks/rust/proto/allocation/allocation.proto | 92 ----- .../googleapis/google/api/annotations.proto | 31 -- .../proto/googleapis/google/api/http.proto | 318 ------------------ sdks/rust/proto/sdk/alpha/alpha.proto | 138 -------- sdks/rust/proto/sdk/beta/beta.proto | 23 -- sdks/rust/proto/sdk/sdk.proto | 165 --------- 9 files changed, 19 insertions(+), 768 deletions(-) create mode 100755 sdks/rust/copy-protos.sh delete mode 100644 sdks/rust/proto/allocation/allocation.proto delete mode 100644 sdks/rust/proto/googleapis/google/api/annotations.proto delete mode 100644 sdks/rust/proto/googleapis/google/api/http.proto delete mode 100644 sdks/rust/proto/sdk/alpha/alpha.proto delete mode 100644 sdks/rust/proto/sdk/beta/beta.proto delete mode 100644 sdks/rust/proto/sdk/sdk.proto diff --git a/build/build-sdk-images/rust/gen.sh b/build/build-sdk-images/rust/gen.sh index b526c4c78f..93ec403a6e 100644 --- a/build/build-sdk-images/rust/gen.sh +++ b/build/build-sdk-images/rust/gen.sh @@ -16,4 +16,10 @@ set -ex +protos=/go/src/agones.dev/agones/proto +dest=/go/src/agones.dev/agones/sdks/rust + +echo "Copying protobuffers to rust sdk" +cp -r ${protos} ${dest} + echo "Rust code is generated at build time" diff --git a/sdks/rust/.gitignore b/sdks/rust/.gitignore index 2ace67fe0f..5a408da74a 100644 --- a/sdks/rust/.gitignore +++ b/sdks/rust/.gitignore @@ -13,5 +13,9 @@ Cargo.lock # These are backup files generated by rustfmt **/*.rs.bk - # End of https://www.gitignore.io/api/rust + +# The protocol buffers need to be adjacent to the cargo manifest when publishing +# due to cargo protections, but for local iteration (without going through images) +# we don't want to accidentally check them in +/proto/ \ No newline at end of file diff --git a/sdks/rust/copy-protos.sh b/sdks/rust/copy-protos.sh new file mode 100755 index 0000000000..6379d58802 --- /dev/null +++ b/sdks/rust/copy-protos.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +set -e + +dir=$(dirname "$0") + +rm -rf "${dir}/proto" + +cp -r "${dir}/../../proto" "${dir}" diff --git a/sdks/rust/proto/allocation/allocation.proto b/sdks/rust/proto/allocation/allocation.proto deleted file mode 100644 index 79015130b2..0000000000 --- a/sdks/rust/proto/allocation/allocation.proto +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright 2020 Google LLC All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package allocation; - -import "google/api/annotations.proto"; - -service AllocationService { - rpc Allocate(AllocationRequest) returns (AllocationResponse) { - option (google.api.http) = { - post: "/gameserverallocation" - body: "*" - }; - } -} - -message AllocationRequest { - // The k8s namespace that is hosting the targeted fleet of gameservers to be allocated - string namespace = 1; - - // If specified, multi-cluster policies are applied. Otherwise, allocation will happen locally. - MultiClusterSetting multiClusterSetting = 2; - - // The required allocation. Defaults to all GameServers. - LabelSelector requiredGameServerSelector = 3; - - // The ordered list of preferred allocations out of the `required` set. - // If the first selector is not matched, the selection attempts the second selector, and so on. - repeated LabelSelector preferredGameServerSelectors = 4; - - // Scheduling strategy. Defaults to "Packed". - SchedulingStrategy scheduling = 5; - enum SchedulingStrategy { - Packed = 0; - Distributed = 1; - } - - // Deprecated: Please use metadata instead. This field is ignored if the - // metadata field is set - MetaPatch metaPatch = 6; - - // Metadata is optional custom metadata that is added to the game server at - // allocation. You can use this to tell the server necessary session data - MetaPatch metadata = 7; -} - -message AllocationResponse { - string gameServerName = 2; - repeated GameServerStatusPort ports = 3; - string address = 4; - string nodeName = 5; - - // The gameserver port info that is allocated. - message GameServerStatusPort { - string name = 1; - int32 port = 2; - } -} - -// Specifies settings for multi-cluster allocation. -message MultiClusterSetting { - // If set to true, multi-cluster allocation is enabled. - bool enabled = 1; - - // Selects multi-cluster allocation policies to apply. If not specified, all multi-cluster allocation policies are to be applied. - LabelSelector policySelector = 2; -} - -// MetaPatch is the metadata used to patch the GameServer metadata on allocation -message MetaPatch { - map labels = 1; - map annotations = 2; -} - -// LabelSelector used for finding a GameServer with matching labels. -message LabelSelector { - // Labels to match. - map matchLabels = 1; -} \ No newline at end of file diff --git a/sdks/rust/proto/googleapis/google/api/annotations.proto b/sdks/rust/proto/googleapis/google/api/annotations.proto deleted file mode 100644 index 85c361b47f..0000000000 --- a/sdks/rust/proto/googleapis/google/api/annotations.proto +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) 2015, Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.api; - -import "google/api/http.proto"; -import "google/protobuf/descriptor.proto"; - -option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; -option java_multiple_files = true; -option java_outer_classname = "AnnotationsProto"; -option java_package = "com.google.api"; -option objc_class_prefix = "GAPI"; - -extend google.protobuf.MethodOptions { - // See `HttpRule`. - HttpRule http = 72295728; -} diff --git a/sdks/rust/proto/googleapis/google/api/http.proto b/sdks/rust/proto/googleapis/google/api/http.proto deleted file mode 100644 index 2bd3a19bfa..0000000000 --- a/sdks/rust/proto/googleapis/google/api/http.proto +++ /dev/null @@ -1,318 +0,0 @@ -// Copyright 2018 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.api; - -option cc_enable_arenas = true; -option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; -option java_multiple_files = true; -option java_outer_classname = "HttpProto"; -option java_package = "com.google.api"; -option objc_class_prefix = "GAPI"; - - -// Defines the HTTP configuration for an API service. It contains a list of -// [HttpRule][google.api.HttpRule], each specifying the mapping of an RPC method -// to one or more HTTP REST API methods. -message Http { - // A list of HTTP configuration rules that apply to individual API methods. - // - // **NOTE:** All service configuration rules follow "last one wins" order. - repeated HttpRule rules = 1; - - // When set to true, URL path parmeters will be fully URI-decoded except in - // cases of single segment matches in reserved expansion, where "%2F" will be - // left encoded. - // - // The default behavior is to not decode RFC 6570 reserved characters in multi - // segment matches. - bool fully_decode_reserved_expansion = 2; -} - -// `HttpRule` defines the mapping of an RPC method to one or more HTTP -// REST API methods. The mapping specifies how different portions of the RPC -// request message are mapped to URL path, URL query parameters, and -// HTTP request body. The mapping is typically specified as an -// `google.api.http` annotation on the RPC method, -// see "google/api/annotations.proto" for details. -// -// The mapping consists of a field specifying the path template and -// method kind. The path template can refer to fields in the request -// message, as in the example below which describes a REST GET -// operation on a resource collection of messages: -// -// -// service Messaging { -// rpc GetMessage(GetMessageRequest) returns (Message) { -// option (google.api.http).get = "/v1/messages/{message_id}/{sub.subfield}"; -// } -// } -// message GetMessageRequest { -// message SubMessage { -// string subfield = 1; -// } -// string message_id = 1; // mapped to the URL -// SubMessage sub = 2; // `sub.subfield` is url-mapped -// } -// message Message { -// string text = 1; // content of the resource -// } -// -// The same http annotation can alternatively be expressed inside the -// `GRPC API Configuration` YAML file. -// -// http: -// rules: -// - selector: .Messaging.GetMessage -// get: /v1/messages/{message_id}/{sub.subfield} -// -// This definition enables an automatic, bidrectional mapping of HTTP -// JSON to RPC. Example: -// -// HTTP | RPC -// -----|----- -// `GET /v1/messages/123456/foo` | `GetMessage(message_id: "123456" sub: SubMessage(subfield: "foo"))` -// -// In general, not only fields but also field paths can be referenced -// from a path pattern. Fields mapped to the path pattern cannot be -// repeated and must have a primitive (non-message) type. -// -// Any fields in the request message which are not bound by the path -// pattern automatically become (optional) HTTP query -// parameters. Assume the following definition of the request message: -// -// -// service Messaging { -// rpc GetMessage(GetMessageRequest) returns (Message) { -// option (google.api.http).get = "/v1/messages/{message_id}"; -// } -// } -// message GetMessageRequest { -// message SubMessage { -// string subfield = 1; -// } -// string message_id = 1; // mapped to the URL -// int64 revision = 2; // becomes a parameter -// SubMessage sub = 3; // `sub.subfield` becomes a parameter -// } -// -// -// This enables a HTTP JSON to RPC mapping as below: -// -// HTTP | RPC -// -----|----- -// `GET /v1/messages/123456?revision=2&sub.subfield=foo` | `GetMessage(message_id: "123456" revision: 2 sub: SubMessage(subfield: "foo"))` -// -// Note that fields which are mapped to HTTP parameters must have a -// primitive type or a repeated primitive type. Message types are not -// allowed. In the case of a repeated type, the parameter can be -// repeated in the URL, as in `...?param=A¶m=B`. -// -// For HTTP method kinds which allow a request body, the `body` field -// specifies the mapping. Consider a REST update method on the -// message resource collection: -// -// -// service Messaging { -// rpc UpdateMessage(UpdateMessageRequest) returns (Message) { -// option (google.api.http) = { -// put: "/v1/messages/{message_id}" -// body: "message" -// }; -// } -// } -// message UpdateMessageRequest { -// string message_id = 1; // mapped to the URL -// Message message = 2; // mapped to the body -// } -// -// -// The following HTTP JSON to RPC mapping is enabled, where the -// representation of the JSON in the request body is determined by -// protos JSON encoding: -// -// HTTP | RPC -// -----|----- -// `PUT /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: "123456" message { text: "Hi!" })` -// -// The special name `*` can be used in the body mapping to define that -// every field not bound by the path template should be mapped to the -// request body. This enables the following alternative definition of -// the update method: -// -// service Messaging { -// rpc UpdateMessage(Message) returns (Message) { -// option (google.api.http) = { -// put: "/v1/messages/{message_id}" -// body: "*" -// }; -// } -// } -// message Message { -// string message_id = 1; -// string text = 2; -// } -// -// -// The following HTTP JSON to RPC mapping is enabled: -// -// HTTP | RPC -// -----|----- -// `PUT /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: "123456" text: "Hi!")` -// -// Note that when using `*` in the body mapping, it is not possible to -// have HTTP parameters, as all fields not bound by the path end in -// the body. This makes this option more rarely used in practice of -// defining REST APIs. The common usage of `*` is in custom methods -// which don't use the URL at all for transferring data. -// -// It is possible to define multiple HTTP methods for one RPC by using -// the `additional_bindings` option. Example: -// -// service Messaging { -// rpc GetMessage(GetMessageRequest) returns (Message) { -// option (google.api.http) = { -// get: "/v1/messages/{message_id}" -// additional_bindings { -// get: "/v1/users/{user_id}/messages/{message_id}" -// } -// }; -// } -// } -// message GetMessageRequest { -// string message_id = 1; -// string user_id = 2; -// } -// -// -// This enables the following two alternative HTTP JSON to RPC -// mappings: -// -// HTTP | RPC -// -----|----- -// `GET /v1/messages/123456` | `GetMessage(message_id: "123456")` -// `GET /v1/users/me/messages/123456` | `GetMessage(user_id: "me" message_id: "123456")` -// -// # Rules for HTTP mapping -// -// The rules for mapping HTTP path, query parameters, and body fields -// to the request message are as follows: -// -// 1. The `body` field specifies either `*` or a field path, or is -// omitted. If omitted, it indicates there is no HTTP request body. -// 2. Leaf fields (recursive expansion of nested messages in the -// request) can be classified into three types: -// (a) Matched in the URL template. -// (b) Covered by body (if body is `*`, everything except (a) fields; -// else everything under the body field) -// (c) All other fields. -// 3. URL query parameters found in the HTTP request are mapped to (c) fields. -// 4. Any body sent with an HTTP request can contain only (b) fields. -// -// The syntax of the path template is as follows: -// -// Template = "/" Segments [ Verb ] ; -// Segments = Segment { "/" Segment } ; -// Segment = "*" | "**" | LITERAL | Variable ; -// Variable = "{" FieldPath [ "=" Segments ] "}" ; -// FieldPath = IDENT { "." IDENT } ; -// Verb = ":" LITERAL ; -// -// The syntax `*` matches a single path segment. The syntax `**` matches zero -// or more path segments, which must be the last part of the path except the -// `Verb`. The syntax `LITERAL` matches literal text in the path. -// -// The syntax `Variable` matches part of the URL path as specified by its -// template. A variable template must not contain other variables. If a variable -// matches a single path segment, its template may be omitted, e.g. `{var}` -// is equivalent to `{var=*}`. -// -// If a variable contains exactly one path segment, such as `"{var}"` or -// `"{var=*}"`, when such a variable is expanded into a URL path, all characters -// except `[-_.~0-9a-zA-Z]` are percent-encoded. Such variables show up in the -// Discovery Document as `{var}`. -// -// If a variable contains one or more path segments, such as `"{var=foo/*}"` -// or `"{var=**}"`, when such a variable is expanded into a URL path, all -// characters except `[-_.~/0-9a-zA-Z]` are percent-encoded. Such variables -// show up in the Discovery Document as `{+var}`. -// -// NOTE: While the single segment variable matches the semantics of -// [RFC 6570](https://tools.ietf.org/html/rfc6570) Section 3.2.2 -// Simple String Expansion, the multi segment variable **does not** match -// RFC 6570 Reserved Expansion. The reason is that the Reserved Expansion -// does not expand special characters like `?` and `#`, which would lead -// to invalid URLs. -// -// NOTE: the field paths in variables and in the `body` must not refer to -// repeated fields or map fields. -message HttpRule { - // Selects methods to which this rule applies. - // - // Refer to [selector][google.api.DocumentationRule.selector] for syntax details. - string selector = 1; - - // Determines the URL pattern is matched by this rules. This pattern can be - // used with any of the {get|put|post|delete|patch} methods. A custom method - // can be defined using the 'custom' field. - oneof pattern { - // Used for listing and getting information about resources. - string get = 2; - - // Used for updating a resource. - string put = 3; - - // Used for creating a resource. - string post = 4; - - // Used for deleting a resource. - string delete = 5; - - // Used for updating a resource. - string patch = 6; - - // The custom pattern is used for specifying an HTTP method that is not - // included in the `pattern` field, such as HEAD, or "*" to leave the - // HTTP method unspecified for this rule. The wild-card rule is useful - // for services that provide content to Web (HTML) clients. - CustomHttpPattern custom = 8; - } - - // The name of the request field whose value is mapped to the HTTP body, or - // `*` for mapping all fields not captured by the path pattern to the HTTP - // body. NOTE: the referred field must not be a repeated field and must be - // present at the top-level of request message type. - string body = 7; - - // Optional. The name of the response field whose value is mapped to the HTTP - // body of response. Other response fields are ignored. When - // not set, the response message will be used as HTTP body of response. - string response_body = 12; - - // Additional HTTP bindings for the selector. Nested bindings must - // not contain an `additional_bindings` field themselves (that is, - // the nesting may only be one level deep). - repeated HttpRule additional_bindings = 11; -} - -// A custom pattern is used for defining custom HTTP verb. -message CustomHttpPattern { - // The name of this custom HTTP verb. - string kind = 1; - - // The path matched by this custom verb. - string path = 2; -} diff --git a/sdks/rust/proto/sdk/alpha/alpha.proto b/sdks/rust/proto/sdk/alpha/alpha.proto deleted file mode 100644 index 7811e0903b..0000000000 --- a/sdks/rust/proto/sdk/alpha/alpha.proto +++ /dev/null @@ -1,138 +0,0 @@ -// Copyright 2020 Google LLC All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package agones.dev.sdk.alpha; -option go_package = "alpha"; - -import "google/api/annotations.proto"; - -// SDK service to be used in the GameServer SDK to the Pod Sidecar. -service SDK { - // PlayerConnect increases the SDK’s stored player count by one, and appends this playerID to GameServer.Status.Players.IDs. - // - // GameServer.Status.Players.Count and GameServer.Status.Players.IDs are then set to update the player count and id list a second from now, - // unless there is already an update pending, in which case the update joins that batch operation. - // - // PlayerConnect returns true and adds the playerID to the list of playerIDs if this playerID was not already in the - // list of connected playerIDs. - // - // If the playerID exists within the list of connected playerIDs, PlayerConnect will return false, and the list of - // connected playerIDs will be left unchanged. - // - // An error will be returned if the playerID was not already in the list of connected playerIDs but the player capacity for - // the server has been reached. The playerID will not be added to the list of playerIDs. - // - // Warning: Do not use this method if you are manually managing GameServer.Status.Players.IDs and GameServer.Status.Players.Count - // through the Kubernetes API, as indeterminate results will occur. - rpc PlayerConnect (PlayerID) returns (Bool) { - option (google.api.http) = { - post: "/alpha/player/connect" - body: "*" - }; - } - - // Decreases the SDK’s stored player count by one, and removes the playerID from GameServer.Status.Players.IDs. - // - // GameServer.Status.Players.Count and GameServer.Status.Players.IDs are then set to update the player count and id list a second from now, - // unless there is already an update pending, in which case the update joins that batch operation. - // - // PlayerDisconnect will return true and remove the supplied playerID from the list of connected playerIDs if the - // playerID value exists within the list. - // - // If the playerID was not in the list of connected playerIDs, the call will return false, and the connected playerID list - // will be left unchanged. - // - // Warning: Do not use this method if you are manually managing GameServer.status.players.IDs and GameServer.status.players.Count - // through the Kubernetes API, as indeterminate results will occur. - rpc PlayerDisconnect (PlayerID) returns (Bool) { - option (google.api.http) = { - post: "/alpha/player/disconnect" - body: "*" - }; - } - - // Update the GameServer.Status.Players.Capacity value with a new capacity. - rpc SetPlayerCapacity (Count) returns (Empty) { - option (google.api.http) = { - put: "/alpha/player/capacity" - body: "*" - }; - } - - // Retrieves the current player capacity. This is always accurate from what has been set through this SDK, - // even if the value has yet to be updated on the GameServer status resource. - // - // If GameServer.Status.Players.Capacity is set manually through the Kubernetes API, use SDK.GameServer() or SDK.WatchGameServer() instead to view this value. - rpc GetPlayerCapacity (Empty) returns (Count) { - option (google.api.http) = { - get: "/alpha/player/capacity" - }; - } - - // Retrieves the current player count. This is always accurate from what has been set through this SDK, - // even if the value has yet to be updated on the GameServer status resource. - // - // If GameServer.Status.Players.Count is set manually through the Kubernetes API, use SDK.GameServer() or SDK.WatchGameServer() instead to view this value. - rpc GetPlayerCount (Empty) returns (Count) { - option (google.api.http) = { - get: "/alpha/player/count" - }; - } - - // Returns if the playerID is currently connected to the GameServer. This is always accurate from what has been set through this SDK, - // even if the value has yet to be updated on the GameServer status resource. - // - // If GameServer.Status.Players.IDs is set manually through the Kubernetes API, use SDK.GameServer() or SDK.WatchGameServer() instead to determine connected status. - rpc IsPlayerConnected (PlayerID) returns (Bool) { - option (google.api.http) = { - get: "/alpha/player/connected/{playerID}" - }; - } - - // Returns the list of the currently connected player ids. This is always accurate from what has been set through this SDK, - // even if the value has yet to be updated on the GameServer status resource. - // - // If GameServer.Status.Players.IDs is set manually through the Kubernetes API, use SDK.GameServer() or SDK.WatchGameServer() instead to view this value. - rpc GetConnectedPlayers(Empty) returns (PlayerIDList) { - option (google.api.http) = { - get: "/alpha/player/connected" - }; - } -} - -// I am Empty -message Empty { -} - -// Store a count variable. -message Count { - int64 count = 1; -} - -// Store a boolean result -message Bool { - bool bool = 1; -} - -// The unique identifier for a given player. -message PlayerID { - string playerID = 1; -} - -// List of Player IDs -message PlayerIDList { - repeated string list = 1; -} diff --git a/sdks/rust/proto/sdk/beta/beta.proto b/sdks/rust/proto/sdk/beta/beta.proto deleted file mode 100644 index d55fbabdb6..0000000000 --- a/sdks/rust/proto/sdk/beta/beta.proto +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2020 Google LLC All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package agones.dev.sdk.beta; -option go_package = "beta"; - -import "google/api/annotations.proto"; - -// SDK service to be used in the GameServer SDK to the Pod Sidecar -service SDK {} \ No newline at end of file diff --git a/sdks/rust/proto/sdk/sdk.proto b/sdks/rust/proto/sdk/sdk.proto deleted file mode 100644 index 355729c9a0..0000000000 --- a/sdks/rust/proto/sdk/sdk.proto +++ /dev/null @@ -1,165 +0,0 @@ -// Copyright 2017 Google LLC All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package agones.dev.sdk; -option go_package = "sdk"; - -import "google/api/annotations.proto"; - -// SDK service to be used in the GameServer SDK to the Pod Sidecar -service SDK { - // Call when the GameServer is ready - rpc Ready (Empty) returns (Empty) { - option (google.api.http) = { - post: "/ready" - body: "*" - }; - } - - // Call to self Allocation the GameServer - rpc Allocate(Empty) returns (Empty) { - option (google.api.http) = { - post: "/allocate" - body: "*" - }; - } - - // Call when the GameServer is shutting down - rpc Shutdown (Empty) returns (Empty) { - option (google.api.http) = { - post: "/shutdown" - body: "*" - }; - } - - // Send a Empty every d Duration to declare that this GameSever is healthy - rpc Health (stream Empty) returns (Empty) { - option (google.api.http) = { - post: "/health" - body: "*" - }; - } - - // Retrieve the current GameServer data - rpc GetGameServer (Empty) returns (GameServer) { - option (google.api.http) = { - get: "/gameserver" - }; - } - - // Send GameServer details whenever the GameServer is updated - rpc WatchGameServer (Empty) returns (stream GameServer) { - option (google.api.http) = { - get: "/watch/gameserver" - }; - } - - // Apply a Label to the backing GameServer metadata - rpc SetLabel(KeyValue) returns (Empty) { - option (google.api.http) = { - put: "/metadata/label" - body: "*" - }; - } - - // Apply a Annotation to the backing GameServer metadata - rpc SetAnnotation(KeyValue) returns (Empty) { - option (google.api.http) = { - put: "/metadata/annotation" - body: "*" - }; - } - - // Marks the GameServer as the Reserved state for Duration - rpc Reserve(Duration) returns (Empty) { - option (google.api.http) = { - post: "/reserve" - body: "*" - }; - } -} - -// I am Empty -message Empty { -} - -// Key, Value entry -message KeyValue { - string key = 1; - string value = 2; -} - -// time duration, in seconds -message Duration { - int64 seconds = 1; -} - -// A GameServer Custom Resource Definition object -// We will only export those resources that make the most -// sense. Can always expand to more as needed. -message GameServer { - ObjectMeta object_meta = 1; - Spec spec = 2; - Status status = 3; - - // representation of the K8s ObjectMeta resource - message ObjectMeta { - string name = 1; - string namespace = 2; - string uid = 3; - string resource_version = 4; - int64 generation = 5; - // timestamp is in Epoch format, unit: seconds - int64 creation_timestamp = 6; - // optional deletion timestamp in Epoch format, unit: seconds - int64 deletion_timestamp = 7; - map annotations = 8; - map labels = 9; - } - - message Spec { - Health health = 1; - - message Health { - bool disabled = 1; - int32 period_seconds = 2; - int32 failure_threshold = 3; - int32 initial_delay_seconds = 4; - } - } - - message Status { - message Port { - string name = 1; - int32 port = 2; - } - // [Stage:Alpha] - // [FeatureFlag:PlayerTracking] - message PlayerStatus { - int64 count = 1; - int64 capacity = 2; - repeated string ids = 3; - } - - string state = 1; - string address = 2; - repeated Port ports = 3; - - // [Stage:Alpha] - // [FeatureFlag:PlayerTracking] - PlayerStatus players = 4; - } -} From 5df8948b832090dd2833339a8408b502704914ff Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Fri, 18 Jun 2021 09:51:04 +0200 Subject: [PATCH 21/24] Bump example version --- examples/rust-simple/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/rust-simple/Makefile b/examples/rust-simple/Makefile index d0870ac6f5..92236f79ae 100644 --- a/examples/rust-simple/Makefile +++ b/examples/rust-simple/Makefile @@ -27,7 +27,7 @@ REPOSITORY ?= gcr.io/agones-images mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST))) project_path := $(dir $(mkfile_path)) -server_tag = $(REPOSITORY)/rust-simple-server:0.8 +server_tag = $(REPOSITORY)/rust-simple-server:0.9 # _____ _ # |_ _|_ _ _ __ __ _ ___| |_ ___ From 776c861c17d045f46d4ff62606d010e164f445ff Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Fri, 18 Jun 2021 09:51:10 +0200 Subject: [PATCH 22/24] Add trailing newline --- examples/rust-simple/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/rust-simple/Cargo.toml b/examples/rust-simple/Cargo.toml index 5f6ada8966..375051ab13 100644 --- a/examples/rust-simple/Cargo.toml +++ b/examples/rust-simple/Cargo.toml @@ -28,4 +28,4 @@ features = [ "rt-multi-thread", "sync", "time", -] \ No newline at end of file +] From 3982b07504d6bea186e4ccf65902a961e6c0074c Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Fri, 18 Jun 2021 10:58:58 +0200 Subject: [PATCH 23/24] Ensure protos are copied for the test --- build/build-sdk-images/rust/build-sdk-test.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/build/build-sdk-images/rust/build-sdk-test.sh b/build/build-sdk-images/rust/build-sdk-test.sh index a515e54909..7fb6f7b790 100644 --- a/build/build-sdk-images/rust/build-sdk-test.sh +++ b/build/build-sdk-images/rust/build-sdk-test.sh @@ -15,6 +15,11 @@ # limitations under the License. set -ex + +# We need to copy the proto files to the SDK otherwise the build will fail if +# we only run this script +"$(dirname "$0")/gen.sh" + mkdir -p /go/src/agones.dev/agones/test/sdk/rust/.cargo mkdir -p /go/src/agones.dev/agones/test/sdk/rust/.cargo-targets cd /go/src/agones.dev/agones/test/sdk/rust From ed847f36faffbc78793c425fa111f44cd6256cf5 Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Tue, 22 Jun 2021 10:44:22 +0200 Subject: [PATCH 24/24] Vendor protos again --- build/build-sdk-images/rust/build-sdk-test.sh | 4 - build/build-sdk-images/rust/gen.sh | 2 + sdks/rust/.gitignore | 5 - sdks/rust/copy-protos.sh | 8 - sdks/rust/proto/allocation/allocation.proto | 92 +++++ .../googleapis/google/api/annotations.proto | 31 ++ .../proto/googleapis/google/api/http.proto | 318 ++++++++++++++++++ sdks/rust/proto/sdk/alpha/alpha.proto | 138 ++++++++ sdks/rust/proto/sdk/beta/beta.proto | 23 ++ sdks/rust/proto/sdk/sdk.proto | 162 +++++++++ 10 files changed, 766 insertions(+), 17 deletions(-) delete mode 100755 sdks/rust/copy-protos.sh create mode 100644 sdks/rust/proto/allocation/allocation.proto create mode 100644 sdks/rust/proto/googleapis/google/api/annotations.proto create mode 100644 sdks/rust/proto/googleapis/google/api/http.proto create mode 100644 sdks/rust/proto/sdk/alpha/alpha.proto create mode 100644 sdks/rust/proto/sdk/beta/beta.proto create mode 100644 sdks/rust/proto/sdk/sdk.proto diff --git a/build/build-sdk-images/rust/build-sdk-test.sh b/build/build-sdk-images/rust/build-sdk-test.sh index 7fb6f7b790..c76d05dc0e 100644 --- a/build/build-sdk-images/rust/build-sdk-test.sh +++ b/build/build-sdk-images/rust/build-sdk-test.sh @@ -16,10 +16,6 @@ set -ex -# We need to copy the proto files to the SDK otherwise the build will fail if -# we only run this script -"$(dirname "$0")/gen.sh" - mkdir -p /go/src/agones.dev/agones/test/sdk/rust/.cargo mkdir -p /go/src/agones.dev/agones/test/sdk/rust/.cargo-targets cd /go/src/agones.dev/agones/test/sdk/rust diff --git a/build/build-sdk-images/rust/gen.sh b/build/build-sdk-images/rust/gen.sh index 93ec403a6e..e574084a35 100644 --- a/build/build-sdk-images/rust/gen.sh +++ b/build/build-sdk-images/rust/gen.sh @@ -19,6 +19,8 @@ set -ex protos=/go/src/agones.dev/agones/proto dest=/go/src/agones.dev/agones/sdks/rust +rm -rf ${dest}/proto + echo "Copying protobuffers to rust sdk" cp -r ${protos} ${dest} diff --git a/sdks/rust/.gitignore b/sdks/rust/.gitignore index 5a408da74a..438618e594 100644 --- a/sdks/rust/.gitignore +++ b/sdks/rust/.gitignore @@ -14,8 +14,3 @@ Cargo.lock **/*.rs.bk # End of https://www.gitignore.io/api/rust - -# The protocol buffers need to be adjacent to the cargo manifest when publishing -# due to cargo protections, but for local iteration (without going through images) -# we don't want to accidentally check them in -/proto/ \ No newline at end of file diff --git a/sdks/rust/copy-protos.sh b/sdks/rust/copy-protos.sh deleted file mode 100755 index 6379d58802..0000000000 --- a/sdks/rust/copy-protos.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash -set -e - -dir=$(dirname "$0") - -rm -rf "${dir}/proto" - -cp -r "${dir}/../../proto" "${dir}" diff --git a/sdks/rust/proto/allocation/allocation.proto b/sdks/rust/proto/allocation/allocation.proto new file mode 100644 index 0000000000..79015130b2 --- /dev/null +++ b/sdks/rust/proto/allocation/allocation.proto @@ -0,0 +1,92 @@ +// Copyright 2020 Google LLC All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package allocation; + +import "google/api/annotations.proto"; + +service AllocationService { + rpc Allocate(AllocationRequest) returns (AllocationResponse) { + option (google.api.http) = { + post: "/gameserverallocation" + body: "*" + }; + } +} + +message AllocationRequest { + // The k8s namespace that is hosting the targeted fleet of gameservers to be allocated + string namespace = 1; + + // If specified, multi-cluster policies are applied. Otherwise, allocation will happen locally. + MultiClusterSetting multiClusterSetting = 2; + + // The required allocation. Defaults to all GameServers. + LabelSelector requiredGameServerSelector = 3; + + // The ordered list of preferred allocations out of the `required` set. + // If the first selector is not matched, the selection attempts the second selector, and so on. + repeated LabelSelector preferredGameServerSelectors = 4; + + // Scheduling strategy. Defaults to "Packed". + SchedulingStrategy scheduling = 5; + enum SchedulingStrategy { + Packed = 0; + Distributed = 1; + } + + // Deprecated: Please use metadata instead. This field is ignored if the + // metadata field is set + MetaPatch metaPatch = 6; + + // Metadata is optional custom metadata that is added to the game server at + // allocation. You can use this to tell the server necessary session data + MetaPatch metadata = 7; +} + +message AllocationResponse { + string gameServerName = 2; + repeated GameServerStatusPort ports = 3; + string address = 4; + string nodeName = 5; + + // The gameserver port info that is allocated. + message GameServerStatusPort { + string name = 1; + int32 port = 2; + } +} + +// Specifies settings for multi-cluster allocation. +message MultiClusterSetting { + // If set to true, multi-cluster allocation is enabled. + bool enabled = 1; + + // Selects multi-cluster allocation policies to apply. If not specified, all multi-cluster allocation policies are to be applied. + LabelSelector policySelector = 2; +} + +// MetaPatch is the metadata used to patch the GameServer metadata on allocation +message MetaPatch { + map labels = 1; + map annotations = 2; +} + +// LabelSelector used for finding a GameServer with matching labels. +message LabelSelector { + // Labels to match. + map matchLabels = 1; +} \ No newline at end of file diff --git a/sdks/rust/proto/googleapis/google/api/annotations.proto b/sdks/rust/proto/googleapis/google/api/annotations.proto new file mode 100644 index 0000000000..85c361b47f --- /dev/null +++ b/sdks/rust/proto/googleapis/google/api/annotations.proto @@ -0,0 +1,31 @@ +// Copyright (c) 2015, Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +import "google/api/http.proto"; +import "google/protobuf/descriptor.proto"; + +option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; +option java_multiple_files = true; +option java_outer_classname = "AnnotationsProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +extend google.protobuf.MethodOptions { + // See `HttpRule`. + HttpRule http = 72295728; +} diff --git a/sdks/rust/proto/googleapis/google/api/http.proto b/sdks/rust/proto/googleapis/google/api/http.proto new file mode 100644 index 0000000000..2bd3a19bfa --- /dev/null +++ b/sdks/rust/proto/googleapis/google/api/http.proto @@ -0,0 +1,318 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +option cc_enable_arenas = true; +option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; +option java_multiple_files = true; +option java_outer_classname = "HttpProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + + +// Defines the HTTP configuration for an API service. It contains a list of +// [HttpRule][google.api.HttpRule], each specifying the mapping of an RPC method +// to one or more HTTP REST API methods. +message Http { + // A list of HTTP configuration rules that apply to individual API methods. + // + // **NOTE:** All service configuration rules follow "last one wins" order. + repeated HttpRule rules = 1; + + // When set to true, URL path parmeters will be fully URI-decoded except in + // cases of single segment matches in reserved expansion, where "%2F" will be + // left encoded. + // + // The default behavior is to not decode RFC 6570 reserved characters in multi + // segment matches. + bool fully_decode_reserved_expansion = 2; +} + +// `HttpRule` defines the mapping of an RPC method to one or more HTTP +// REST API methods. The mapping specifies how different portions of the RPC +// request message are mapped to URL path, URL query parameters, and +// HTTP request body. The mapping is typically specified as an +// `google.api.http` annotation on the RPC method, +// see "google/api/annotations.proto" for details. +// +// The mapping consists of a field specifying the path template and +// method kind. The path template can refer to fields in the request +// message, as in the example below which describes a REST GET +// operation on a resource collection of messages: +// +// +// service Messaging { +// rpc GetMessage(GetMessageRequest) returns (Message) { +// option (google.api.http).get = "/v1/messages/{message_id}/{sub.subfield}"; +// } +// } +// message GetMessageRequest { +// message SubMessage { +// string subfield = 1; +// } +// string message_id = 1; // mapped to the URL +// SubMessage sub = 2; // `sub.subfield` is url-mapped +// } +// message Message { +// string text = 1; // content of the resource +// } +// +// The same http annotation can alternatively be expressed inside the +// `GRPC API Configuration` YAML file. +// +// http: +// rules: +// - selector: .Messaging.GetMessage +// get: /v1/messages/{message_id}/{sub.subfield} +// +// This definition enables an automatic, bidrectional mapping of HTTP +// JSON to RPC. Example: +// +// HTTP | RPC +// -----|----- +// `GET /v1/messages/123456/foo` | `GetMessage(message_id: "123456" sub: SubMessage(subfield: "foo"))` +// +// In general, not only fields but also field paths can be referenced +// from a path pattern. Fields mapped to the path pattern cannot be +// repeated and must have a primitive (non-message) type. +// +// Any fields in the request message which are not bound by the path +// pattern automatically become (optional) HTTP query +// parameters. Assume the following definition of the request message: +// +// +// service Messaging { +// rpc GetMessage(GetMessageRequest) returns (Message) { +// option (google.api.http).get = "/v1/messages/{message_id}"; +// } +// } +// message GetMessageRequest { +// message SubMessage { +// string subfield = 1; +// } +// string message_id = 1; // mapped to the URL +// int64 revision = 2; // becomes a parameter +// SubMessage sub = 3; // `sub.subfield` becomes a parameter +// } +// +// +// This enables a HTTP JSON to RPC mapping as below: +// +// HTTP | RPC +// -----|----- +// `GET /v1/messages/123456?revision=2&sub.subfield=foo` | `GetMessage(message_id: "123456" revision: 2 sub: SubMessage(subfield: "foo"))` +// +// Note that fields which are mapped to HTTP parameters must have a +// primitive type or a repeated primitive type. Message types are not +// allowed. In the case of a repeated type, the parameter can be +// repeated in the URL, as in `...?param=A¶m=B`. +// +// For HTTP method kinds which allow a request body, the `body` field +// specifies the mapping. Consider a REST update method on the +// message resource collection: +// +// +// service Messaging { +// rpc UpdateMessage(UpdateMessageRequest) returns (Message) { +// option (google.api.http) = { +// put: "/v1/messages/{message_id}" +// body: "message" +// }; +// } +// } +// message UpdateMessageRequest { +// string message_id = 1; // mapped to the URL +// Message message = 2; // mapped to the body +// } +// +// +// The following HTTP JSON to RPC mapping is enabled, where the +// representation of the JSON in the request body is determined by +// protos JSON encoding: +// +// HTTP | RPC +// -----|----- +// `PUT /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: "123456" message { text: "Hi!" })` +// +// The special name `*` can be used in the body mapping to define that +// every field not bound by the path template should be mapped to the +// request body. This enables the following alternative definition of +// the update method: +// +// service Messaging { +// rpc UpdateMessage(Message) returns (Message) { +// option (google.api.http) = { +// put: "/v1/messages/{message_id}" +// body: "*" +// }; +// } +// } +// message Message { +// string message_id = 1; +// string text = 2; +// } +// +// +// The following HTTP JSON to RPC mapping is enabled: +// +// HTTP | RPC +// -----|----- +// `PUT /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: "123456" text: "Hi!")` +// +// Note that when using `*` in the body mapping, it is not possible to +// have HTTP parameters, as all fields not bound by the path end in +// the body. This makes this option more rarely used in practice of +// defining REST APIs. The common usage of `*` is in custom methods +// which don't use the URL at all for transferring data. +// +// It is possible to define multiple HTTP methods for one RPC by using +// the `additional_bindings` option. Example: +// +// service Messaging { +// rpc GetMessage(GetMessageRequest) returns (Message) { +// option (google.api.http) = { +// get: "/v1/messages/{message_id}" +// additional_bindings { +// get: "/v1/users/{user_id}/messages/{message_id}" +// } +// }; +// } +// } +// message GetMessageRequest { +// string message_id = 1; +// string user_id = 2; +// } +// +// +// This enables the following two alternative HTTP JSON to RPC +// mappings: +// +// HTTP | RPC +// -----|----- +// `GET /v1/messages/123456` | `GetMessage(message_id: "123456")` +// `GET /v1/users/me/messages/123456` | `GetMessage(user_id: "me" message_id: "123456")` +// +// # Rules for HTTP mapping +// +// The rules for mapping HTTP path, query parameters, and body fields +// to the request message are as follows: +// +// 1. The `body` field specifies either `*` or a field path, or is +// omitted. If omitted, it indicates there is no HTTP request body. +// 2. Leaf fields (recursive expansion of nested messages in the +// request) can be classified into three types: +// (a) Matched in the URL template. +// (b) Covered by body (if body is `*`, everything except (a) fields; +// else everything under the body field) +// (c) All other fields. +// 3. URL query parameters found in the HTTP request are mapped to (c) fields. +// 4. Any body sent with an HTTP request can contain only (b) fields. +// +// The syntax of the path template is as follows: +// +// Template = "/" Segments [ Verb ] ; +// Segments = Segment { "/" Segment } ; +// Segment = "*" | "**" | LITERAL | Variable ; +// Variable = "{" FieldPath [ "=" Segments ] "}" ; +// FieldPath = IDENT { "." IDENT } ; +// Verb = ":" LITERAL ; +// +// The syntax `*` matches a single path segment. The syntax `**` matches zero +// or more path segments, which must be the last part of the path except the +// `Verb`. The syntax `LITERAL` matches literal text in the path. +// +// The syntax `Variable` matches part of the URL path as specified by its +// template. A variable template must not contain other variables. If a variable +// matches a single path segment, its template may be omitted, e.g. `{var}` +// is equivalent to `{var=*}`. +// +// If a variable contains exactly one path segment, such as `"{var}"` or +// `"{var=*}"`, when such a variable is expanded into a URL path, all characters +// except `[-_.~0-9a-zA-Z]` are percent-encoded. Such variables show up in the +// Discovery Document as `{var}`. +// +// If a variable contains one or more path segments, such as `"{var=foo/*}"` +// or `"{var=**}"`, when such a variable is expanded into a URL path, all +// characters except `[-_.~/0-9a-zA-Z]` are percent-encoded. Such variables +// show up in the Discovery Document as `{+var}`. +// +// NOTE: While the single segment variable matches the semantics of +// [RFC 6570](https://tools.ietf.org/html/rfc6570) Section 3.2.2 +// Simple String Expansion, the multi segment variable **does not** match +// RFC 6570 Reserved Expansion. The reason is that the Reserved Expansion +// does not expand special characters like `?` and `#`, which would lead +// to invalid URLs. +// +// NOTE: the field paths in variables and in the `body` must not refer to +// repeated fields or map fields. +message HttpRule { + // Selects methods to which this rule applies. + // + // Refer to [selector][google.api.DocumentationRule.selector] for syntax details. + string selector = 1; + + // Determines the URL pattern is matched by this rules. This pattern can be + // used with any of the {get|put|post|delete|patch} methods. A custom method + // can be defined using the 'custom' field. + oneof pattern { + // Used for listing and getting information about resources. + string get = 2; + + // Used for updating a resource. + string put = 3; + + // Used for creating a resource. + string post = 4; + + // Used for deleting a resource. + string delete = 5; + + // Used for updating a resource. + string patch = 6; + + // The custom pattern is used for specifying an HTTP method that is not + // included in the `pattern` field, such as HEAD, or "*" to leave the + // HTTP method unspecified for this rule. The wild-card rule is useful + // for services that provide content to Web (HTML) clients. + CustomHttpPattern custom = 8; + } + + // The name of the request field whose value is mapped to the HTTP body, or + // `*` for mapping all fields not captured by the path pattern to the HTTP + // body. NOTE: the referred field must not be a repeated field and must be + // present at the top-level of request message type. + string body = 7; + + // Optional. The name of the response field whose value is mapped to the HTTP + // body of response. Other response fields are ignored. When + // not set, the response message will be used as HTTP body of response. + string response_body = 12; + + // Additional HTTP bindings for the selector. Nested bindings must + // not contain an `additional_bindings` field themselves (that is, + // the nesting may only be one level deep). + repeated HttpRule additional_bindings = 11; +} + +// A custom pattern is used for defining custom HTTP verb. +message CustomHttpPattern { + // The name of this custom HTTP verb. + string kind = 1; + + // The path matched by this custom verb. + string path = 2; +} diff --git a/sdks/rust/proto/sdk/alpha/alpha.proto b/sdks/rust/proto/sdk/alpha/alpha.proto new file mode 100644 index 0000000000..b9f2bb6524 --- /dev/null +++ b/sdks/rust/proto/sdk/alpha/alpha.proto @@ -0,0 +1,138 @@ +// Copyright 2020 Google LLC All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package agones.dev.sdk.alpha; +option go_package = "alpha"; + +import "google/api/annotations.proto"; + +// SDK service to be used in the GameServer SDK to the Pod Sidecar. +service SDK { + // PlayerConnect increases the SDK’s stored player count by one, and appends this playerID to GameServer.Status.Players.IDs. + // + // GameServer.Status.Players.Count and GameServer.Status.Players.IDs are then set to update the player count and id list a second from now, + // unless there is already an update pending, in which case the update joins that batch operation. + // + // PlayerConnect returns true and adds the playerID to the list of playerIDs if this playerID was not already in the + // list of connected playerIDs. + // + // If the playerID exists within the list of connected playerIDs, PlayerConnect will return false, and the list of + // connected playerIDs will be left unchanged. + // + // An error will be returned if the playerID was not already in the list of connected playerIDs but the player capacity for + // the server has been reached. The playerID will not be added to the list of playerIDs. + // + // Warning: Do not use this method if you are manually managing GameServer.Status.Players.IDs and GameServer.Status.Players.Count + // through the Kubernetes API, as indeterminate results will occur. + rpc PlayerConnect (PlayerID) returns (Bool) { + option (google.api.http) = { + post: "/alpha/player/connect" + body: "*" + }; + } + + // Decreases the SDK’s stored player count by one, and removes the playerID from GameServer.Status.Players.IDs. + // + // GameServer.Status.Players.Count and GameServer.Status.Players.IDs are then set to update the player count and id list a second from now, + // unless there is already an update pending, in which case the update joins that batch operation. + // + // PlayerDisconnect will return true and remove the supplied playerID from the list of connected playerIDs if the + // playerID value exists within the list. + // + // If the playerID was not in the list of connected playerIDs, the call will return false, and the connected playerID list + // will be left unchanged. + // + // Warning: Do not use this method if you are manually managing GameServer.status.players.IDs and GameServer.status.players.Count + // through the Kubernetes API, as indeterminate results will occur. + rpc PlayerDisconnect (PlayerID) returns (Bool) { + option (google.api.http) = { + post: "/alpha/player/disconnect" + body: "*" + }; + } + + // Update the GameServer.Status.Players.Capacity value with a new capacity. + rpc SetPlayerCapacity (Count) returns (Empty) { + option (google.api.http) = { + put: "/alpha/player/capacity" + body: "*" + }; + } + + // Retrieves the current player capacity. This is always accurate from what has been set through this SDK, + // even if the value has yet to be updated on the GameServer status resource. + // + // If GameServer.Status.Players.Capacity is set manually through the Kubernetes API, use SDK.GameServer() or SDK.WatchGameServer() instead to view this value. + rpc GetPlayerCapacity (Empty) returns (Count) { + option (google.api.http) = { + get: "/alpha/player/capacity" + }; + } + + // Retrieves the current player count. This is always accurate from what has been set through this SDK, + // even if the value has yet to be updated on the GameServer status resource. + // + // If GameServer.Status.Players.Count is set manually through the Kubernetes API, use SDK.GameServer() or SDK.WatchGameServer() instead to view this value. + rpc GetPlayerCount (Empty) returns (Count) { + option (google.api.http) = { + get: "/alpha/player/count" + }; + } + + // Returns if the playerID is currently connected to the GameServer. This is always accurate from what has been set through this SDK, + // even if the value has yet to be updated on the GameServer status resource. + // + // If GameServer.Status.Players.IDs is set manually through the Kubernetes API, use SDK.GameServer() or SDK.WatchGameServer() instead to determine connected status. + rpc IsPlayerConnected (PlayerID) returns (Bool) { + option (google.api.http) = { + get: "/alpha/player/connected/{playerID}" + }; + } + + // Returns the list of the currently connected player ids. This is always accurate from what has been set through this SDK, + // even if the value has yet to be updated on the GameServer status resource. + // + // If GameServer.Status.Players.IDs is set manually through the Kubernetes API, use SDK.GameServer() or SDK.WatchGameServer() instead to view this value. + rpc GetConnectedPlayers(Empty) returns (PlayerIDList) { + option (google.api.http) = { + get: "/alpha/player/connected" + }; + } +} + +// I am Empty +message Empty { +} + +// Store a count variable. +message Count { + int64 count = 1; +} + +// Store a boolean result +message Bool { + bool bool = 1; +} + +// The unique identifier for a given player. +message PlayerID { + string playerID = 1; +} + +// List of Player IDs +message PlayerIDList { + repeated string list = 1; +} \ No newline at end of file diff --git a/sdks/rust/proto/sdk/beta/beta.proto b/sdks/rust/proto/sdk/beta/beta.proto new file mode 100644 index 0000000000..d55fbabdb6 --- /dev/null +++ b/sdks/rust/proto/sdk/beta/beta.proto @@ -0,0 +1,23 @@ +// Copyright 2020 Google LLC All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package agones.dev.sdk.beta; +option go_package = "beta"; + +import "google/api/annotations.proto"; + +// SDK service to be used in the GameServer SDK to the Pod Sidecar +service SDK {} \ No newline at end of file diff --git a/sdks/rust/proto/sdk/sdk.proto b/sdks/rust/proto/sdk/sdk.proto new file mode 100644 index 0000000000..0d7c65d299 --- /dev/null +++ b/sdks/rust/proto/sdk/sdk.proto @@ -0,0 +1,162 @@ +// Copyright 2017 Google LLC All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package agones.dev.sdk; +option go_package = "sdk"; + +import "google/api/annotations.proto"; + +// SDK service to be used in the GameServer SDK to the Pod Sidecar +service SDK { + // Call when the GameServer is ready + rpc Ready (Empty) returns (Empty) { + option (google.api.http) = { + post: "/ready" + body: "*" + }; + } + + // Call to self Allocation the GameServer + rpc Allocate(Empty) returns (Empty) { + option (google.api.http) = { + post: "/allocate" + body: "*" + }; + } + + // Call when the GameServer is shutting down + rpc Shutdown (Empty) returns (Empty) { + option (google.api.http) = { + post: "/shutdown" + body: "*" + }; + } + // Send a Empty every d Duration to declare that this GameSever is healthy + rpc Health (stream Empty) returns (Empty) { + option (google.api.http) = { + post: "/health" + body: "*" + }; + } + // Retrieve the current GameServer data + rpc GetGameServer (Empty) returns (GameServer) { + option (google.api.http) = { + get: "/gameserver" + }; + } + // Send GameServer details whenever the GameServer is updated + rpc WatchGameServer (Empty) returns (stream GameServer) { + option (google.api.http) = { + get: "/watch/gameserver" + }; + } + + // Apply a Label to the backing GameServer metadata + rpc SetLabel(KeyValue) returns (Empty) { + option (google.api.http) = { + put: "/metadata/label" + body: "*" + }; + } + + // Apply a Annotation to the backing GameServer metadata + rpc SetAnnotation(KeyValue) returns (Empty) { + option (google.api.http) = { + put: "/metadata/annotation" + body: "*" + }; + } + + // Marks the GameServer as the Reserved state for Duration + rpc Reserve(Duration) returns (Empty) { + option (google.api.http) = { + post: "/reserve" + body: "*" + }; + } +} + +// I am Empty +message Empty { +} + +// Key, Value entry +message KeyValue { + string key = 1; + string value = 2; +} + +// time duration, in seconds +message Duration { + int64 seconds = 1; +} + +// A GameServer Custom Resource Definition object +// We will only export those resources that make the most +// sense. Can always expand to more as needed. +message GameServer { + ObjectMeta object_meta = 1; + Spec spec = 2; + Status status = 3; + + // representation of the K8s ObjectMeta resource + message ObjectMeta { + string name = 1; + string namespace = 2; + string uid = 3; + string resource_version = 4; + int64 generation = 5; + // timestamp is in Epoch format, unit: seconds + int64 creation_timestamp = 6; + // optional deletion timestamp in Epoch format, unit: seconds + int64 deletion_timestamp = 7; + map annotations = 8; + map labels = 9; + } + + message Spec { + Health health = 1; + + message Health { + bool disabled = 1; + int32 period_seconds = 2; + int32 failure_threshold = 3; + int32 initial_delay_seconds = 4; + } + } + + message Status { + message Port { + string name = 1; + int32 port = 2; + } + // [Stage:Alpha] + // [FeatureFlag:PlayerTracking] + message PlayerStatus { + int64 count = 1; + int64 capacity = 2; + repeated string ids = 3; + } + + string state = 1; + string address = 2; + repeated Port ports = 3; + + // [Stage:Alpha] + // [FeatureFlag:PlayerTracking] + PlayerStatus players = 4; + } +}