grpc: example: tweak example package to show off new retry logic (#59218)

Reply to https://github.com/sourcegraph/sourcegraph/pull/59111

This PR changes our example package to show off the new automatic retry logic, and its limitations.

## Test plan

This is an example package that is not compiled into the main application. 

I saw the expected behavior when running the `run-server.sh` and `run-client.sh` scripts.:

(snippet from the client)
```
INFO weather-client client/main.go:55 The call to GetCurrentWeather for New York failed. Retrying... {"attempt": 0, "error": "rpc error: code = Unavailable desc = simulated service outage"}
```
This commit is contained in:
Geoffrey Gilmore 2023-12-22 16:20:49 -08:00 committed by GitHub
parent d43909f630
commit 7a3ef7fea0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 381 additions and 177 deletions

View File

@ -2,15 +2,20 @@ load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
go_library(
name = "client_lib",
srcs = ["main.go"],
srcs = [
"main.go",
"retry.go",
],
embedsrcs = ["sun.svg"],
importpath = "github.com/sourcegraph/sourcegraph/internal/grpc/example/client",
visibility = ["//visibility:private"],
deps = [
"//internal/grpc/defaults",
"//internal/grpc/example/weather/v1:weather",
"//internal/grpc/retry",
"//internal/grpc/streamio",
"@com_github_sourcegraph_log//:log",
"@org_golang_google_grpc//:go_default_library",
"@org_golang_google_grpc//codes",
"@org_golang_google_grpc//status",
],

View File

@ -10,11 +10,13 @@ import (
"time"
"github.com/sourcegraph/log"
"github.com/sourcegraph/sourcegraph/internal/grpc/defaults"
pb "github.com/sourcegraph/sourcegraph/internal/grpc/example/weather/v1"
"github.com/sourcegraph/sourcegraph/internal/grpc/streamio"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"github.com/sourcegraph/sourcegraph/internal/grpc/defaults"
pb "github.com/sourcegraph/sourcegraph/internal/grpc/example/weather/v1"
"github.com/sourcegraph/sourcegraph/internal/grpc/retry"
"github.com/sourcegraph/sourcegraph/internal/grpc/streamio"
)
// From https://commons.wikimedia.org/w/index.php?title=File:Sun-soleil.svg&oldid=456041378
@ -40,13 +42,21 @@ func main() {
defer conn.Close()
client := pb.NewWeatherServiceClient(conn)
client = &automaticRetryClient{base: client} // Wrap the client with our automatic retry logic
// Demonstrate Unary RPCs (single request, single response): Get weather for a specific location
//
// This example demonstrates a basic client server RPC, as well as error handling tactics.
{
// You can pass call options to each unique RPC invocation.
// In this example, we use this to demonstrate the automatic retry logic.
retryCallback := func(ctx context.Context, attempt uint, err error) {
logger.Info("The call to GetCurrentWeather for New York failed. Retrying...", log.Uint("attempt", attempt), log.Error(err))
}
// Normal case
weather, err := client.GetCurrentWeather(context.Background(), &pb.GetCurrentWeatherRequest{Location: "New York"})
weather, err := client.GetCurrentWeather(context.Background(), &pb.GetCurrentWeatherRequest{Location: "New York"}, retry.WithOnRetryCallback(retryCallback))
if err != nil {
logger.Fatal("Could not get weather", log.Error(err))
}

View File

@ -0,0 +1,65 @@
package main
import (
"context"
"google.golang.org/grpc"
"github.com/sourcegraph/sourcegraph/internal/grpc/defaults"
proto "github.com/sourcegraph/sourcegraph/internal/grpc/example/weather/v1"
)
// automaticRetryClient is a convenience wrapper around a base proto.WeatherServiceClient that automatically retries
// idempotent ("safe") methods in accordance to the policy defined in internal/grpc/defaults.RetryPolicy.
//
// Read the implementation of this type for more details on what kinds of RPCs are automatically retried (and why).
//
// Callers are free to override the default retry behavior by proving their own grpc.CallOptions when invoking the RPC.
// (example: providing retry.WithMax(0) will disable retries even when invoking GetCurrentWeather - which is idempotent).
type automaticRetryClient struct {
base proto.WeatherServiceClient
}
// Unsupported methods.
func (a *automaticRetryClient) UploadWeatherData(ctx context.Context, opts ...grpc.CallOption) (proto.WeatherService_UploadWeatherDataClient, error) {
// UploadWeatherData is a client streaming method, which isn't supported by our automatic retry logic.
// Trying to use our automatic retry logic with this method immediately returns the following error (fail fast):
//
// code = Unimplemented desc = grpc_retry: cannot retry on ClientStreams, set grpc_retry.Disable()
return a.base.UploadWeatherData(ctx, opts...)
}
func (a *automaticRetryClient) RealTimeWeather(ctx context.Context, opts ...grpc.CallOption) (proto.WeatherService_RealTimeWeatherClient, error) {
// RealTimeWeather is a bidirectional streaming method, which isn't supported by our automatic retry logic.
// Trying to use our automatic retry logic with this method immediately returns the following error (fail fast):
//
// code = Unimplemented desc = grpc_retry: cannot retry on ClientStreams, set grpc_retry.Disable()
return a.base.RealTimeWeather(ctx, opts...)
}
// Non idempotent methods.
func (a *automaticRetryClient) UploadWeatherPhoto(ctx context.Context, opts ...grpc.CallOption) (proto.WeatherService_UploadWeatherPhotoClient, error) {
// UploadWeatherPhoto's RPC documentation states that it is not idempotent because it doesn't do any deduplication.
return a.base.UploadWeatherPhoto(ctx, opts...)
}
// Idempotent methods.
func (a *automaticRetryClient) GetCurrentWeather(ctx context.Context, in *proto.GetCurrentWeatherRequest, opts ...grpc.CallOption) (*proto.GetCurrentWeatherResponse, error) {
opts = append(defaults.RetryPolicy, opts...)
return a.base.GetCurrentWeather(ctx, in, opts...)
}
func (a *automaticRetryClient) SubscribeWeatherAlerts(ctx context.Context, in *proto.SubscribeWeatherAlertsRequest, opts ...grpc.CallOption) (proto.WeatherService_SubscribeWeatherAlertsClient, error) {
opts = append(defaults.RetryPolicy, opts...)
return a.base.SubscribeWeatherAlerts(ctx, in, opts...)
}
func (a *automaticRetryClient) GetCurrentWeatherOld(ctx context.Context, in *proto.GetCurrentWeatherOldRequest, opts ...grpc.CallOption) (*proto.GetCurrentWeatherOldResponse, error) {
opts = append(defaults.RetryPolicy, opts...)
return a.base.GetCurrentWeatherOld(ctx, in, opts...)
}
var _ proto.WeatherServiceClient = &automaticRetryClient{}

View File

@ -5,6 +5,7 @@ go_library(
name = "server_lib",
srcs = [
"conversion.go",
"faulty.go",
"main.go",
],
importpath = "github.com/sourcegraph/sourcegraph/internal/grpc/example/server",

View File

@ -0,0 +1,51 @@
package main
import (
"context"
"sync/atomic"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
proto "github.com/sourcegraph/sourcegraph/internal/grpc/example/weather/v1"
)
// flakyWeatherService is a wrapper around a WeatherServiceServer that simulates
// a flaky service by returning an error on the first call to GetCurrentWeather.
type flakyWeatherService struct {
getCurrentWeatherCallCounter atomic.Int64
base proto.WeatherServiceServer
proto.UnimplementedWeatherServiceServer
}
func (f *flakyWeatherService) GetCurrentWeather(ctx context.Context, request *proto.GetCurrentWeatherRequest) (*proto.GetCurrentWeatherResponse, error) {
count := f.getCurrentWeatherCallCounter.Add(1)
if count == 1 {
return nil, status.Error(codes.Unavailable, "simulated service outage")
}
return f.base.GetCurrentWeather(ctx, request)
}
func (f *flakyWeatherService) SubscribeWeatherAlerts(request *proto.SubscribeWeatherAlertsRequest, server proto.WeatherService_SubscribeWeatherAlertsServer) error {
return f.base.SubscribeWeatherAlerts(request, server)
}
func (f *flakyWeatherService) UploadWeatherData(server proto.WeatherService_UploadWeatherDataServer) error {
return f.base.UploadWeatherData(server)
}
func (f *flakyWeatherService) RealTimeWeather(server proto.WeatherService_RealTimeWeatherServer) error {
return f.base.RealTimeWeather(server)
}
func (f *flakyWeatherService) UploadWeatherPhoto(server proto.WeatherService_UploadWeatherPhotoServer) error {
return f.base.UploadWeatherPhoto(server)
}
func (f *flakyWeatherService) GetCurrentWeatherOld(ctx context.Context, request *proto.GetCurrentWeatherOldRequest) (*proto.GetCurrentWeatherOldResponse, error) {
return f.base.GetCurrentWeatherOld(ctx, request)
}
var _ proto.WeatherServiceServer = &flakyWeatherService{}

View File

@ -6,14 +6,16 @@ import (
"net"
"github.com/sourcegraph/log"
"google.golang.org/grpc"
"github.com/sourcegraph/sourcegraph/internal/grpc/example/server/service"
pb "github.com/sourcegraph/sourcegraph/internal/grpc/example/weather/v1"
"github.com/sourcegraph/sourcegraph/internal/grpc/streamio"
"google.golang.org/grpc"
"github.com/sourcegraph/sourcegraph/lib/errors"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"github.com/sourcegraph/sourcegraph/lib/errors"
)
type weatherGRPCServer struct {
@ -194,7 +196,9 @@ func (w *weatherGRPCServer) UploadWeatherPhoto(stream pb.WeatherService_UploadWe
w.logger.Info("Received screenshot metadata",
log.String("sensorID", v.Metadata.GetSensorId()),
log.String("filename", v.Metadata.GetFileName()),
log.String("location", v.Metadata.GetLocation()))
log.String("location", v.Metadata.GetLocation()),
log.Time("timestamp", v.Metadata.GetTimestamp().AsTime()),
)
default:
return errors.Errorf("expected first message to be image metadata, instead got unexpected message type %T", v)
}
@ -241,9 +245,13 @@ func main() {
}
s := grpc.NewServer()
pb.RegisterWeatherServiceServer(s, &weatherGRPCServer{
logger: logger,
})
flaky := &flakyWeatherService{
base: &weatherGRPCServer{
logger: logger,
},
}
pb.RegisterWeatherServiceServer(s, flaky)
logger.Info("Server listening", log.String("address", lis.Addr().String()))
if err := s.Serve(lis); err != nil {

View File

@ -13,6 +13,7 @@ proto_library(
name = "grpc_example_weather_v1_proto",
srcs = ["weather.proto"],
visibility = ["//:__subpackages__"],
deps = ["@com_google_protobuf//:timestamp_proto"],
)
go_proto_library(

View File

@ -9,6 +9,7 @@ package v1
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
timestamppb "google.golang.org/protobuf/types/known/timestamppb"
reflect "reflect"
sync "sync"
)
@ -511,9 +512,10 @@ type UploadWeatherDataRequest struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
SensorId string `protobuf:"bytes,1,opt,name=sensor_id,json=sensorId,proto3" json:"sensor_id,omitempty"`
Temperature *Temperature `protobuf:"bytes,2,opt,name=temperature,proto3" json:"temperature,omitempty"`
Humidity float64 `protobuf:"fixed64,3,opt,name=humidity,proto3" json:"humidity,omitempty"`
SensorId string `protobuf:"bytes,1,opt,name=sensor_id,json=sensorId,proto3" json:"sensor_id,omitempty"`
Temperature *Temperature `protobuf:"bytes,2,opt,name=temperature,proto3" json:"temperature,omitempty"`
Humidity float64 `protobuf:"fixed64,3,opt,name=humidity,proto3" json:"humidity,omitempty"`
Timestamp *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
}
func (x *UploadWeatherDataRequest) Reset() {
@ -569,6 +571,13 @@ func (x *UploadWeatherDataRequest) GetHumidity() float64 {
return 0
}
func (x *UploadWeatherDataRequest) GetTimestamp() *timestamppb.Timestamp {
if x != nil {
return x.Timestamp
}
return nil
}
type UploadWeatherPhotoResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@ -825,9 +834,10 @@ type UploadWeatherPhotoRequest_Metadata struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Location string `protobuf:"bytes,1,opt,name=location,proto3" json:"location,omitempty"`
SensorId string `protobuf:"bytes,2,opt,name=sensor_id,json=sensorId,proto3" json:"sensor_id,omitempty"`
FileName string `protobuf:"bytes,3,opt,name=file_name,json=fileName,proto3" json:"file_name,omitempty"`
Location string `protobuf:"bytes,1,opt,name=location,proto3" json:"location,omitempty"`
SensorId string `protobuf:"bytes,2,opt,name=sensor_id,json=sensorId,proto3" json:"sensor_id,omitempty"`
FileName string `protobuf:"bytes,3,opt,name=file_name,json=fileName,proto3" json:"file_name,omitempty"`
Timestamp *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
}
func (x *UploadWeatherPhotoRequest_Metadata) Reset() {
@ -883,6 +893,13 @@ func (x *UploadWeatherPhotoRequest_Metadata) GetFileName() string {
return ""
}
func (x *UploadWeatherPhotoRequest_Metadata) GetTimestamp() *timestamppb.Timestamp {
if x != nil {
return x.Timestamp
}
return nil
}
type UploadWeatherPhotoRequest_Payload struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@ -935,131 +952,141 @@ var File_weather_proto protoreflect.FileDescriptor
var file_weather_proto_rawDesc = []byte{
0x0a, 0x0d, 0x77, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12,
0x17, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x77, 0x65,
0x61, 0x74, 0x68, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x22, 0x36, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x43,
0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x57, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x22, 0x85, 0x01, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x57,
0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x20,
0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e,
0x12, 0x46, 0x0a, 0x0b, 0x74, 0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18,
0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x65, 0x78, 0x61,
0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x77, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e,
0x54, 0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x0b, 0x74, 0x65, 0x6d,
0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0xb8, 0x01, 0x0a, 0x0b, 0x54, 0x65, 0x6d,
0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75,
0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x3d,
0x0a, 0x04, 0x75, 0x6e, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x29, 0x2e, 0x67,
0x72, 0x70, 0x63, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x77, 0x65, 0x61, 0x74,
0x68, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75,
0x72, 0x65, 0x2e, 0x55, 0x6e, 0x69, 0x74, 0x52, 0x04, 0x75, 0x6e, 0x69, 0x74, 0x22, 0x54, 0x0a,
0x04, 0x55, 0x6e, 0x69, 0x74, 0x12, 0x14, 0x0a, 0x10, 0x55, 0x4e, 0x49, 0x54, 0x5f, 0x55, 0x4e,
0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x55,
0x4e, 0x49, 0x54, 0x5f, 0x43, 0x45, 0x4c, 0x53, 0x49, 0x55, 0x53, 0x10, 0x01, 0x12, 0x13, 0x0a,
0x0f, 0x55, 0x4e, 0x49, 0x54, 0x5f, 0x46, 0x41, 0x48, 0x52, 0x45, 0x4e, 0x48, 0x45, 0x49, 0x54,
0x10, 0x02, 0x12, 0x0f, 0x0a, 0x0b, 0x55, 0x4e, 0x49, 0x54, 0x5f, 0x4b, 0x45, 0x4c, 0x56, 0x49,
0x4e, 0x10, 0x03, 0x22, 0x4b, 0x0a, 0x12, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x4f, 0x66, 0x66,
0x6c, 0x69, 0x6e, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x65, 0x6e,
0x73, 0x6f, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x65,
0x6e, 0x73, 0x6f, 0x72, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67,
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
0x22, 0xda, 0x02, 0x0a, 0x19, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x57, 0x65, 0x61, 0x74, 0x68,
0x65, 0x72, 0x50, 0x68, 0x6f, 0x74, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x59,
0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x3b, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e,
0x77, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61,
0x64, 0x57, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x50, 0x68, 0x6f, 0x74, 0x6f, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x48, 0x00, 0x52,
0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x56, 0x0a, 0x07, 0x70, 0x61, 0x79,
0x6c, 0x6f, 0x61, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x67, 0x72, 0x70,
0x63, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x77, 0x65, 0x61, 0x74, 0x68, 0x65,
0x72, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x57, 0x65, 0x61, 0x74, 0x68,
0x65, 0x72, 0x50, 0x68, 0x6f, 0x74, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x50,
0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x48, 0x00, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61,
0x64, 0x1a, 0x60, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x1a, 0x0a,
0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x65, 0x6e,
0x73, 0x6f, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x65,
0x6e, 0x73, 0x6f, 0x72, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x6e,
0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x4e,
0x61, 0x6d, 0x65, 0x1a, 0x1d, 0x0a, 0x07, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x12,
0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61,
0x74, 0x61, 0x42, 0x09, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x35, 0x0a,
0x19, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x57, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x44, 0x61,
0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65,
0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73,
0x73, 0x61, 0x67, 0x65, 0x22, 0x37, 0x0a, 0x1d, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62,
0x65, 0x57, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x18,
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x22, 0x36, 0x0a,
0x1e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x57, 0x65, 0x61, 0x74, 0x68, 0x65,
0x72, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
0x14, 0x0a, 0x05, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05,
0x61, 0x6c, 0x65, 0x72, 0x74, 0x22, 0x9b, 0x01, 0x0a, 0x18, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64,
0x57, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x5f, 0x69, 0x64, 0x18,
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x49, 0x64, 0x12,
0x46, 0x0a, 0x0b, 0x74, 0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x65, 0x78, 0x61, 0x6d,
0x70, 0x6c, 0x65, 0x2e, 0x77, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x54,
0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x0b, 0x74, 0x65, 0x6d, 0x70,
0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x68, 0x75, 0x6d, 0x69, 0x64,
0x69, 0x74, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x08, 0x68, 0x75, 0x6d, 0x69, 0x64,
0x69, 0x74, 0x79, 0x22, 0x36, 0x0a, 0x1a, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x57, 0x65, 0x61,
0x74, 0x68, 0x65, 0x72, 0x50, 0x68, 0x6f, 0x74, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01,
0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x34, 0x0a, 0x16, 0x52,
0x65, 0x61, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x57, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x52, 0x65,
0x61, 0x74, 0x68, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74,
0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x36, 0x0a, 0x18, 0x47, 0x65, 0x74,
0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x57, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f,
0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f,
0x6e, 0x22, 0x83, 0x01, 0x0a, 0x17, 0x52, 0x65, 0x61, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x57, 0x65,
0x61, 0x74, 0x68, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x20, 0x0a,
0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01,
0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12,
0x46, 0x0a, 0x0b, 0x74, 0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x65, 0x78, 0x61, 0x6d,
0x70, 0x6c, 0x65, 0x2e, 0x77, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x54,
0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x0b, 0x74, 0x65, 0x6d, 0x70,
0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x39, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x43, 0x75,
0x72, 0x72, 0x65, 0x6e, 0x74, 0x57, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x4f, 0x6c, 0x64, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69,
0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69,
0x6f, 0x6e, 0x22, 0x88, 0x01, 0x0a, 0x1c, 0x47, 0x65, 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e,
0x74, 0x57, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x4f, 0x6c, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x22, 0x85, 0x01, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74,
0x57, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01,
0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f,
0x6e, 0x12, 0x46, 0x0a, 0x0b, 0x74, 0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65,
0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x65, 0x78,
0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x77, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x2e, 0x76, 0x31,
0x2e, 0x54, 0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x0b, 0x74, 0x65,
0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0xb8, 0x01, 0x0a, 0x0b, 0x54, 0x65,
0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c,
0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12,
0x3d, 0x0a, 0x04, 0x75, 0x6e, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x29, 0x2e,
0x67, 0x72, 0x70, 0x63, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x77, 0x65, 0x61,
0x74, 0x68, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74,
0x75, 0x72, 0x65, 0x2e, 0x55, 0x6e, 0x69, 0x74, 0x52, 0x04, 0x75, 0x6e, 0x69, 0x74, 0x22, 0x54,
0x0a, 0x04, 0x55, 0x6e, 0x69, 0x74, 0x12, 0x14, 0x0a, 0x10, 0x55, 0x4e, 0x49, 0x54, 0x5f, 0x55,
0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c,
0x55, 0x4e, 0x49, 0x54, 0x5f, 0x43, 0x45, 0x4c, 0x53, 0x49, 0x55, 0x53, 0x10, 0x01, 0x12, 0x13,
0x0a, 0x0f, 0x55, 0x4e, 0x49, 0x54, 0x5f, 0x46, 0x41, 0x48, 0x52, 0x45, 0x4e, 0x48, 0x45, 0x49,
0x54, 0x10, 0x02, 0x12, 0x0f, 0x0a, 0x0b, 0x55, 0x4e, 0x49, 0x54, 0x5f, 0x4b, 0x45, 0x4c, 0x56,
0x49, 0x4e, 0x10, 0x03, 0x22, 0x4b, 0x0a, 0x12, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x4f, 0x66,
0x66, 0x6c, 0x69, 0x6e, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x65,
0x6e, 0x73, 0x6f, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73,
0x65, 0x6e, 0x73, 0x6f, 0x72, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61,
0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67,
0x65, 0x22, 0x95, 0x03, 0x0a, 0x19, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x57, 0x65, 0x61, 0x74,
0x68, 0x65, 0x72, 0x50, 0x68, 0x6f, 0x74, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
0x59, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x3b, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
0x2e, 0x77, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x6c, 0x6f,
0x61, 0x64, 0x57, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x50, 0x68, 0x6f, 0x74, 0x6f, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x48, 0x00,
0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x56, 0x0a, 0x07, 0x70, 0x61,
0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x67, 0x72,
0x70, 0x63, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x77, 0x65, 0x61, 0x74, 0x68,
0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x57, 0x65, 0x61, 0x74,
0x68, 0x65, 0x72, 0x50, 0x68, 0x6f, 0x74, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e,
0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x48, 0x00, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f,
0x61, 0x64, 0x1a, 0x9a, 0x01, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12,
0x1a, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x73,
0x65, 0x6e, 0x73, 0x6f, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08,
0x73, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x69, 0x6c, 0x65,
0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c,
0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61,
0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73,
0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x1a,
0x1d, 0x0a, 0x07, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61,
0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x42, 0x09,
0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x35, 0x0a, 0x19, 0x55, 0x70, 0x6c,
0x6f, 0x61, 0x64, 0x57, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67,
0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
0x22, 0x37, 0x0a, 0x1d, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x57, 0x65, 0x61,
0x74, 0x68, 0x65, 0x72, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x52, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x22, 0x36, 0x0a, 0x1e, 0x53, 0x75, 0x62,
0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x57, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x41, 0x6c, 0x65,
0x72, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x61,
0x6c, 0x65, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x6c, 0x65, 0x72,
0x74, 0x22, 0xd5, 0x01, 0x0a, 0x18, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x57, 0x65, 0x61, 0x74,
0x68, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b,
0x0a, 0x09, 0x73, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x52, 0x08, 0x73, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x49, 0x64, 0x12, 0x46, 0x0a, 0x0b, 0x74,
0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x24, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e,
0x77, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x6d, 0x70, 0x65,
0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x0b, 0x74, 0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74,
0x75, 0x72, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x68, 0x75, 0x6d, 0x69, 0x64, 0x69, 0x74, 0x79, 0x18,
0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x08, 0x68, 0x75, 0x6d, 0x69, 0x64, 0x69, 0x74, 0x79, 0x12,
0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09,
0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x36, 0x0a, 0x1a, 0x55, 0x70, 0x6c,
0x6f, 0x61, 0x64, 0x57, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x50, 0x68, 0x6f, 0x74, 0x6f, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61,
0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67,
0x65, 0x22, 0x34, 0x0a, 0x16, 0x52, 0x65, 0x61, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x57, 0x65, 0x61,
0x74, 0x68, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6c,
0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c,
0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x83, 0x01, 0x0a, 0x17, 0x52, 0x65, 0x61, 0x6c,
0x54, 0x69, 0x6d, 0x65, 0x57, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69,
0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69,
0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x46, 0x0a, 0x0b, 0x74, 0x65, 0x6d, 0x70, 0x65, 0x72, 0x61,
0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x72, 0x70,
0x63, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x77, 0x65, 0x61, 0x74, 0x68, 0x65,
0x72, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65,
0x52, 0x0b, 0x74, 0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x32, 0xa9, 0x06,
0x0a, 0x0e, 0x57, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
0x12, 0x7c, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x57, 0x65,
0x61, 0x74, 0x68, 0x65, 0x72, 0x12, 0x31, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x65, 0x78, 0x61,
0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x77, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e,
0x47, 0x65, 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x57, 0x65, 0x61, 0x74, 0x68, 0x65,
0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e,
0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x77, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x2e,
0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x57, 0x65, 0x61,
0x74, 0x68, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x8d,
0x01, 0x0a, 0x16, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x57, 0x65, 0x61, 0x74,
0x68, 0x65, 0x72, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x12, 0x36, 0x2e, 0x67, 0x72, 0x70, 0x63,
0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x77, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72,
0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x57, 0x65, 0x61,
0x74, 0x68, 0x65, 0x72, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x1a, 0x37, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
0x2e, 0x77, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x73,
0x52, 0x0b, 0x74, 0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x39, 0x0a,
0x1b, 0x47, 0x65, 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x57, 0x65, 0x61, 0x74, 0x68,
0x65, 0x72, 0x4f, 0x6c, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08,
0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08,
0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x88, 0x01, 0x0a, 0x1c, 0x47, 0x65, 0x74,
0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x57, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x4f, 0x6c,
0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73,
0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b,
0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x46, 0x0a, 0x0b, 0x74,
0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x24, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e,
0x77, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x6d, 0x70, 0x65,
0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x0b, 0x74, 0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74,
0x75, 0x72, 0x65, 0x32, 0xb9, 0x06, 0x0a, 0x0e, 0x57, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x53,
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x7f, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x43, 0x75, 0x72,
0x72, 0x65, 0x6e, 0x74, 0x57, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x12, 0x31, 0x2e, 0x67, 0x72,
0x70, 0x63, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x77, 0x65, 0x61, 0x74, 0x68,
0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74,
0x57, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32,
0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x77, 0x65,
0x61, 0x74, 0x68, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x75, 0x72, 0x72,
0x65, 0x6e, 0x74, 0x57, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x22, 0x03, 0x90, 0x02, 0x01, 0x12, 0x90, 0x01, 0x0a, 0x16, 0x53, 0x75, 0x62, 0x73,
0x63, 0x72, 0x69, 0x62, 0x65, 0x57, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x41, 0x6c, 0x65, 0x72,
0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x7e,
0x0a, 0x11, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x57, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x44,
0x61, 0x74, 0x61, 0x12, 0x31, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70,
0x74, 0x73, 0x12, 0x36, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c,
0x65, 0x2e, 0x77, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62,
0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x57, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x41, 0x6c, 0x65,
0x72, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x67, 0x72, 0x70,
0x63, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x77, 0x65, 0x61, 0x74, 0x68, 0x65,
0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x57, 0x65,
0x61, 0x74, 0x68, 0x65, 0x72, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x22, 0x03, 0x90, 0x02, 0x01, 0x30, 0x01, 0x12, 0x81, 0x01, 0x0a, 0x11, 0x55,
0x70, 0x6c, 0x6f, 0x61, 0x64, 0x57, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61,
0x12, 0x31, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e,
0x77, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61,
0x64, 0x57, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70,
0x6c, 0x65, 0x2e, 0x77, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70,
0x6c, 0x6f, 0x61, 0x64, 0x57, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x65, 0x78,
0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x77, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x2e, 0x76, 0x31,
0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x57, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x44, 0x61,
0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x28, 0x01, 0x12, 0x7a,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x90, 0x02, 0x02, 0x28, 0x01, 0x12, 0x7d,
0x0a, 0x0f, 0x52, 0x65, 0x61, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x57, 0x65, 0x61, 0x74, 0x68, 0x65,
0x72, 0x12, 0x2f, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
0x2e, 0x77, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x61, 0x6c,
@ -1067,29 +1094,29 @@ var file_weather_proto_rawDesc = []byte{
0x73, 0x74, 0x1a, 0x30, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c,
0x65, 0x2e, 0x77, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x61,
0x6c, 0x54, 0x69, 0x6d, 0x65, 0x57, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x12, 0x81, 0x01, 0x0a, 0x12, 0x55,
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x90, 0x02, 0x01, 0x28, 0x01, 0x30, 0x01, 0x12, 0x81, 0x01,
0x0a, 0x12, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x57, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x50,
0x68, 0x6f, 0x74, 0x6f, 0x12, 0x32, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x65, 0x78, 0x61, 0x6d,
0x70, 0x6c, 0x65, 0x2e, 0x77, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x55,
0x70, 0x6c, 0x6f, 0x61, 0x64, 0x57, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x50, 0x68, 0x6f, 0x74,
0x6f, 0x12, 0x32, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
0x2e, 0x77, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x6c, 0x6f,
0x61, 0x64, 0x57, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x50, 0x68, 0x6f, 0x74, 0x6f, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x65, 0x78, 0x61,
0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x77, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e,
0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x57, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x50, 0x68, 0x6f,
0x74, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x28, 0x01, 0x12, 0x88,
0x01, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x57, 0x65, 0x61,
0x74, 0x68, 0x65, 0x72, 0x4f, 0x6c, 0x64, 0x12, 0x34, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x65,
0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x77, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x2e, 0x76,
0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x57, 0x65, 0x61, 0x74,
0x68, 0x65, 0x72, 0x4f, 0x6c, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e,
0x67, 0x72, 0x70, 0x63, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x77, 0x65, 0x61,
0x74, 0x68, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x75, 0x72, 0x72, 0x65,
0x6e, 0x74, 0x57, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x4f, 0x6c, 0x64, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x88, 0x02, 0x01, 0x42, 0x45, 0x5a, 0x43, 0x67, 0x69, 0x74,
0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x67, 0x72,
0x61, 0x70, 0x68, 0x2f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2f,
0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x65, 0x78,
0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x77, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x2f, 0x76, 0x31,
0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e,
0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x77, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x2e,
0x76, 0x31, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x57, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72,
0x50, 0x68, 0x6f, 0x74, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x28,
0x01, 0x12, 0x8b, 0x01, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74,
0x57, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x4f, 0x6c, 0x64, 0x12, 0x34, 0x2e, 0x67, 0x72, 0x70,
0x63, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x77, 0x65, 0x61, 0x74, 0x68, 0x65,
0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x57,
0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x4f, 0x6c, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x1a, 0x35, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e,
0x77, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x75,
0x72, 0x72, 0x65, 0x6e, 0x74, 0x57, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x4f, 0x6c, 0x64, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0x88, 0x02, 0x01, 0x90, 0x02, 0x02, 0x42,
0x45, 0x5a, 0x43, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x6f,
0x75, 0x72, 0x63, 0x65, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
0x67, 0x72, 0x61, 0x70, 0x68, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x67,
0x72, 0x70, 0x63, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x77, 0x65, 0x61, 0x74,
0x68, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@ -1124,6 +1151,7 @@ var file_weather_proto_goTypes = []interface{}{
(*GetCurrentWeatherOldResponse)(nil), // 14: grpc.example.weather.v1.GetCurrentWeatherOldResponse
(*UploadWeatherPhotoRequest_Metadata)(nil), // 15: grpc.example.weather.v1.UploadWeatherPhotoRequest.Metadata
(*UploadWeatherPhotoRequest_Payload)(nil), // 16: grpc.example.weather.v1.UploadWeatherPhotoRequest.Payload
(*timestamppb.Timestamp)(nil), // 17: google.protobuf.Timestamp
}
var file_weather_proto_depIdxs = []int32{
3, // 0: grpc.example.weather.v1.GetCurrentWeatherResponse.temperature:type_name -> grpc.example.weather.v1.Temperature
@ -1131,25 +1159,27 @@ var file_weather_proto_depIdxs = []int32{
15, // 2: grpc.example.weather.v1.UploadWeatherPhotoRequest.metadata:type_name -> grpc.example.weather.v1.UploadWeatherPhotoRequest.Metadata
16, // 3: grpc.example.weather.v1.UploadWeatherPhotoRequest.payload:type_name -> grpc.example.weather.v1.UploadWeatherPhotoRequest.Payload
3, // 4: grpc.example.weather.v1.UploadWeatherDataRequest.temperature:type_name -> grpc.example.weather.v1.Temperature
3, // 5: grpc.example.weather.v1.RealTimeWeatherResponse.temperature:type_name -> grpc.example.weather.v1.Temperature
3, // 6: grpc.example.weather.v1.GetCurrentWeatherOldResponse.temperature:type_name -> grpc.example.weather.v1.Temperature
1, // 7: grpc.example.weather.v1.WeatherService.GetCurrentWeather:input_type -> grpc.example.weather.v1.GetCurrentWeatherRequest
7, // 8: grpc.example.weather.v1.WeatherService.SubscribeWeatherAlerts:input_type -> grpc.example.weather.v1.SubscribeWeatherAlertsRequest
9, // 9: grpc.example.weather.v1.WeatherService.UploadWeatherData:input_type -> grpc.example.weather.v1.UploadWeatherDataRequest
11, // 10: grpc.example.weather.v1.WeatherService.RealTimeWeather:input_type -> grpc.example.weather.v1.RealTimeWeatherRequest
5, // 11: grpc.example.weather.v1.WeatherService.UploadWeatherPhoto:input_type -> grpc.example.weather.v1.UploadWeatherPhotoRequest
13, // 12: grpc.example.weather.v1.WeatherService.GetCurrentWeatherOld:input_type -> grpc.example.weather.v1.GetCurrentWeatherOldRequest
2, // 13: grpc.example.weather.v1.WeatherService.GetCurrentWeather:output_type -> grpc.example.weather.v1.GetCurrentWeatherResponse
8, // 14: grpc.example.weather.v1.WeatherService.SubscribeWeatherAlerts:output_type -> grpc.example.weather.v1.SubscribeWeatherAlertsResponse
6, // 15: grpc.example.weather.v1.WeatherService.UploadWeatherData:output_type -> grpc.example.weather.v1.UploadWeatherDataResponse
12, // 16: grpc.example.weather.v1.WeatherService.RealTimeWeather:output_type -> grpc.example.weather.v1.RealTimeWeatherResponse
10, // 17: grpc.example.weather.v1.WeatherService.UploadWeatherPhoto:output_type -> grpc.example.weather.v1.UploadWeatherPhotoResponse
14, // 18: grpc.example.weather.v1.WeatherService.GetCurrentWeatherOld:output_type -> grpc.example.weather.v1.GetCurrentWeatherOldResponse
13, // [13:19] is the sub-list for method output_type
7, // [7:13] is the sub-list for method input_type
7, // [7:7] is the sub-list for extension type_name
7, // [7:7] is the sub-list for extension extendee
0, // [0:7] is the sub-list for field type_name
17, // 5: grpc.example.weather.v1.UploadWeatherDataRequest.timestamp:type_name -> google.protobuf.Timestamp
3, // 6: grpc.example.weather.v1.RealTimeWeatherResponse.temperature:type_name -> grpc.example.weather.v1.Temperature
3, // 7: grpc.example.weather.v1.GetCurrentWeatherOldResponse.temperature:type_name -> grpc.example.weather.v1.Temperature
17, // 8: grpc.example.weather.v1.UploadWeatherPhotoRequest.Metadata.timestamp:type_name -> google.protobuf.Timestamp
1, // 9: grpc.example.weather.v1.WeatherService.GetCurrentWeather:input_type -> grpc.example.weather.v1.GetCurrentWeatherRequest
7, // 10: grpc.example.weather.v1.WeatherService.SubscribeWeatherAlerts:input_type -> grpc.example.weather.v1.SubscribeWeatherAlertsRequest
9, // 11: grpc.example.weather.v1.WeatherService.UploadWeatherData:input_type -> grpc.example.weather.v1.UploadWeatherDataRequest
11, // 12: grpc.example.weather.v1.WeatherService.RealTimeWeather:input_type -> grpc.example.weather.v1.RealTimeWeatherRequest
5, // 13: grpc.example.weather.v1.WeatherService.UploadWeatherPhoto:input_type -> grpc.example.weather.v1.UploadWeatherPhotoRequest
13, // 14: grpc.example.weather.v1.WeatherService.GetCurrentWeatherOld:input_type -> grpc.example.weather.v1.GetCurrentWeatherOldRequest
2, // 15: grpc.example.weather.v1.WeatherService.GetCurrentWeather:output_type -> grpc.example.weather.v1.GetCurrentWeatherResponse
8, // 16: grpc.example.weather.v1.WeatherService.SubscribeWeatherAlerts:output_type -> grpc.example.weather.v1.SubscribeWeatherAlertsResponse
6, // 17: grpc.example.weather.v1.WeatherService.UploadWeatherData:output_type -> grpc.example.weather.v1.UploadWeatherDataResponse
12, // 18: grpc.example.weather.v1.WeatherService.RealTimeWeather:output_type -> grpc.example.weather.v1.RealTimeWeatherResponse
10, // 19: grpc.example.weather.v1.WeatherService.UploadWeatherPhoto:output_type -> grpc.example.weather.v1.UploadWeatherPhotoResponse
14, // 20: grpc.example.weather.v1.WeatherService.GetCurrentWeatherOld:output_type -> grpc.example.weather.v1.GetCurrentWeatherOldResponse
15, // [15:21] is the sub-list for method output_type
9, // [9:15] is the sub-list for method input_type
9, // [9:9] is the sub-list for extension type_name
9, // [9:9] is the sub-list for extension extendee
0, // [0:9] is the sub-list for field type_name
}
func init() { file_weather_proto_init() }

View File

@ -2,30 +2,59 @@ syntax = "proto3";
package grpc.example.weather.v1;
import "google/protobuf/timestamp.proto";
option go_package = "github.com/sourcegraph/sourcegraph/internal/grpc/example/weather/v1";
// The weather service definition.
service WeatherService {
// Each of the RPCs in this service documents its idempotency level if applicable. This is useful for client authors
// to know whether they can retry a failed RPC without causing side effects, or if they need to take more care.
//
// When thinking about the difference between IDEMPOTENT and NO_SIDE_EFFECTS, the following StackOverflow answer might be
// helpful: https://softwareengineering.stackexchange.com/a/411619 (quoted below).
//
// > Safe means no side effects. Idempotent means any side effects must be the same, and therefore that it doesn't matter if they are repeated.
// >
// > Say I ask my daughter to check if the oven is preheated. That's a safe operation because it has no side effects. She is just looking.
// >
// > If I ask her to preheat the oven, that's an idempotent operation. If it's already preheating, she is just going to check and leave it in the same state. I can ask her 10 times to preheat the oven, and she will roll her eyes at my terrible memory, but the oven always ends up in the on state.
// >
// > If I ask her to flip the switch on the oven, that is not idempotent. Whether the oven ends up preheating depends on if it was already preheating.
// Unary RPC: Get current weather for a location.
rpc GetCurrentWeather(GetCurrentWeatherRequest) returns (GetCurrentWeatherResponse) {}
rpc GetCurrentWeather(GetCurrentWeatherRequest) returns (GetCurrentWeatherResponse) {
option idempotency_level = NO_SIDE_EFFECTS;
}
// Server Streaming RPC: Subscribe to severe weather alerts in the provided region.
rpc SubscribeWeatherAlerts(SubscribeWeatherAlertsRequest) returns (stream SubscribeWeatherAlertsResponse) {}
rpc SubscribeWeatherAlerts(SubscribeWeatherAlertsRequest) returns (stream SubscribeWeatherAlertsResponse) {
option idempotency_level = NO_SIDE_EFFECTS;
}
// Client Streaming RPC: Send continuous weather data from sensors.
rpc UploadWeatherData(stream UploadWeatherDataRequest) returns (UploadWeatherDataResponse) {}
rpc UploadWeatherData(stream UploadWeatherDataRequest) returns (UploadWeatherDataResponse) {
option idempotency_level = IDEMPOTENT;
}
// Bidirectional Streaming RPC: Get real-time weather updates as the client moves around.
rpc RealTimeWeather(stream RealTimeWeatherRequest) returns (stream RealTimeWeatherResponse) {}
rpc RealTimeWeather(stream RealTimeWeatherRequest) returns (stream RealTimeWeatherResponse) {
option idempotency_level = NO_SIDE_EFFECTS;
}
// Client Streaming RPC: Upload a photo of the current weather from a given sensor.
rpc UploadWeatherPhoto(stream UploadWeatherPhotoRequest) returns (UploadWeatherPhotoResponse) {}
rpc UploadWeatherPhoto(stream UploadWeatherPhotoRequest) returns (UploadWeatherPhotoResponse) {
// This RPC is not idempotent, as the server does not deduplicate the photo uploads.
}
// Deprecated RPC: Get current weather for a location.
rpc GetCurrentWeatherOld(GetCurrentWeatherOldRequest) returns (GetCurrentWeatherOldResponse) {
option deprecated = true; // Mark the RPC as deprecated. Nobody should use this anymore.
// When generating go code, the deprecated option will be translated to a deprecated comment. And gopls and various tools
// will show a warning when using this RPC.
option idempotency_level = IDEMPOTENT;
}
}
@ -63,6 +92,7 @@ message UploadWeatherPhotoRequest {
string location = 1;
string sensor_id = 2;
string file_name = 3;
google.protobuf.Timestamp timestamp = 4;
}
message Payload {
@ -91,6 +121,7 @@ message UploadWeatherDataRequest {
string sensor_id = 1;
Temperature temperature = 2;
double humidity = 3;
google.protobuf.Timestamp timestamp = 4;
}
message UploadWeatherPhotoResponse {

View File

@ -13,6 +13,8 @@
"internal/batches/testing/.*": "ignore batches testing code",
"internal/gitserver/mock\\.go$": "ignore deprecation warning of P4Exec",
"internal/gitserver/retry\\.go$": "ignore deprecation warning of P4Exec",
"internal/grpc/example/client/retry\\.go$": "ignore deprecation warning of GetCurrentWeatherOld",
"internal/grpc/example/server/faulty\\.go$": "ignore deprecation warning of GetCurrentWeatherOld",
"internal/database/dbmocks": "ignore generated database mocks"
}
},