mirror of
https://github.com/googleforgames/open-match.git
synced 2025-03-25 13:24:18 +00:00
Compare commits
152 Commits
release-0.
...
v1.4.0-rc.
Author | SHA1 | Date | |
---|---|---|---|
ec8f757afe | |||
b6e5114715 | |||
23d2fd5042 | |||
2b73d52e0c | |||
47c34587dc | |||
76937b6350 | |||
2e03c1a197 | |||
eca40e3298 | |||
902c9d69b4 | |||
67767cf1cd | |||
6f46731b15 | |||
0d1a77c5de | |||
f2a23f5ba1 | |||
3fa588c1f8 | |||
cc08f39205 | |||
ec9cf00bcf | |||
8b8617f68d | |||
ce9b989e58 | |||
5c00395c78 | |||
faf3eded1f | |||
250d44aefd | |||
13fdf5960f | |||
aa5a1f9da1 | |||
ad1ca16218 | |||
7d849f3f04 | |||
05c8c8aa76 | |||
f50c9eec80 | |||
c6f23f01ca | |||
21efdb6691 | |||
81a1dc38b6 | |||
d0ddf22658 | |||
ee247c6c1a | |||
a17eb3bc72 | |||
3d194f541e | |||
3a0cd7611b | |||
c13b461795 | |||
b9e55fc727 | |||
dd1386a55b | |||
defac9065b | |||
f203384fbf | |||
7ef9c052bd | |||
ea744b8b51 | |||
1a8fc62833 | |||
1d5574b8a3 | |||
75a3d43477 | |||
252fc8090d | |||
2c617f2cb6 | |||
fcd590eca6 | |||
4b3147511b | |||
c85af44567 | |||
688262111d | |||
26d1aa236a | |||
fff37cd82c | |||
98a227b515 | |||
88cd95fe57 | |||
248494c04c | |||
aa4398e786 | |||
fc5c3629e8 | |||
8d86709632 | |||
0a273674b9 | |||
e2247a7f53 | |||
b269896c23 | |||
a210185098 | |||
4df95deb54 | |||
a9b8eec9e0 | |||
afa59327a4 | |||
d86b6c5121 | |||
2eb2921914 | |||
80d882b7c7 | |||
0f34e31778 | |||
d45eb74510 | |||
1765ab7b7e | |||
6f05e526fb | |||
496d156faa | |||
3a3d618c43 | |||
e1cbd855f5 | |||
10b36705f0 | |||
a6fc4724bc | |||
511337088a | |||
5f67bb36a6 | |||
94d2105809 | |||
d85f1f4bc7 | |||
79e9afeca7 | |||
3334f7f74a | |||
85ce954eb9 | |||
679cfb5839 | |||
c53a5b7c88 | |||
cfb316169a | |||
a9365b5333 | |||
93df53201c | |||
eb86841423 | |||
771f706317 | |||
a9f9a2f2e6 | |||
068632285e | |||
113461114e | |||
0ac7ae13ac | |||
29a2dbcf99 | |||
48d3b5c0ee | |||
a5fa651106 | |||
cd84d74ff9 | |||
8c2aa1ea81 | |||
493ff8e520 | |||
8363bc5fc9 | |||
144f646b7f | |||
b518b5cc1b | |||
af0b9fd5f7 | |||
5f4b522ecd | |||
12625d7f53 | |||
3248c8c4ad | |||
10c0c59997 | |||
c17e3e62c0 | |||
8e91be6201 | |||
f6c837d6cd | |||
3c8908aae0 | |||
0689d92d9c | |||
3c9a8f5568 | |||
30204a2d15 | |||
a5b6c0c566 | |||
4a00baf847 | |||
d74262f3ba | |||
2262652ea9 | |||
e15fd47535 | |||
670f38d36e | |||
f0a85633a5 | |||
6cb47ce191 | |||
529c01330e | |||
b36a348db7 | |||
5e277265ad | |||
4420d7add2 | |||
3de052279b | |||
7a4aa3589f | |||
bca6f487cc | |||
d0c373a850 | |||
deb2947ae2 | |||
d889278151 | |||
1b63fa53dc | |||
af02e4818f | |||
cda2d3185f | |||
2317977602 | |||
9ef83ed344 | |||
33bd633b1d | |||
1af8cf1e79 | |||
0ef46fc4d4 | |||
79daf50531 | |||
a9c327b430 | |||
2c637c97b8 | |||
668b10030b | |||
1c7fd24a34 | |||
be0cebd457 | |||
fe7bb4da8f | |||
e80de171a0 | |||
fdd707347e |
.github
.golangci.yamlDockerfile.base-buildDockerfile.ciDockerfile.cmdMakefileREADME.mdapi
backend.protobackend.swagger.jsonevaluator.protoevaluator.swagger.jsonfrontend.protofrontend.swagger.jsonmatchfunction.protomatchfunction.swagger.jsonmessages.protoquery.protoquery.swagger.json
cloudbuild.yamlcmd
backend
default-evaluator
frontend
minimatch
query
scale-backend
scale-frontend
synchronizer
docs
examples
demo
functions/golang
backfill
soloduel
scale
README.md
backend
frontend
mmf
scenarios
install
02-open-match-demo.yaml
helm/open-match
Chart.yaml
subcharts
templates
_helpers.tplbackend.yamlfrontend.yamlom-configmap-default.yamlom-configmap-override.yamlpodsecuritypolicy.yamlquery.yamlservice-account.yamlswaggerui.yamlsynchronizer.yaml
values-production.yamlvalues.yamltests
tls-secret.yamlterraform
internal
api
app
appmain
config
filter
ipb
logging
omerror
rpc
clientcache.goclientcache_test.goclients.goclients_test.goinsecure.goinsecure_test.golistener_holder.golistener_holder_test.goserver.goserver_test.go
testing
tls_server.gotls_server_test.goset
signal
statestore
backfill.gobackfill_test.goinstrumented.gopublic.goredis.goredis_indices.goredis_indices_test.goredis_test.go
testing
ticket.goticket_test.gotelemetry
configz.goconfigz_test.gohelp.gohelp_test.gojaeger.gometrics.gometrics_test.goopencensus_agent.goprobe.goprobe_test.goprometheus.gopublic.gostackdriver.gozpages.go
testing
e2e
backfill_test.gocluster.gocluster_test.gocommon.goconsts.gofetch_matches_test.goin_memory.goquery_backfills_test.goquery_tickets_test.goticket_test.go
evaluator
fake_frontend.gommf
ticket_generator.goutil
pkg
matchfunction
pb
test
e2e
evaluator
matchfunction/mmf
third_party
google
protoc-gen-openapiv2/options
protoc-gen-swagger/options
swaggerui
tools
certgen
reaper/internal
tutorials
custom_evaluator
default_evaluator
director
frontend
matchfunction
solution
matchmaker101
director
frontend
matchfunction
solution
matchmaker102
1
.github/CODEOWNERS
vendored
Normal file
1
.github/CODEOWNERS
vendored
Normal file
@ -0,0 +1 @@
|
||||
* @laremere @aLekSer @HazWard @calebatwd @syntxerror @sawagh @andrewgrundy @scosgrave
|
3
.github/ISSUE_TEMPLATE/release.md
vendored
3
.github/ISSUE_TEMPLATE/release.md
vendored
@ -114,7 +114,6 @@ git push origin release-0.5
|
||||
- [ ] There might be additional references to the old version but be careful not to change it for places that have it for historical purposes.
|
||||
- [ ] Run `make release`
|
||||
- [ ] Run `make api/api.md` in open-match repo to update the auto-generated API references in open-match-docs repo.
|
||||
- [ ] Use the files under the `build/release/` directory for the Open Match installation guide. Make sure the artifacts work as expected - these are the artifacts that will be published to the GCS bucket and used in our release assets.
|
||||
- [ ] Create a PR with the changes, include the release candidate name, and point it to the release branch.
|
||||
- [ ] Go to [open-match-build](https://pantheon.corp.google.com/cloud-build/triggers?project=open-match-build) and update all *post submit* triggers' `_GCB_LATEST_VERSION` value to the `X.Y` of the release. This value should only increase as it's used to determine the latest stable version.
|
||||
- [ ] Merge your changes once the PR is approved.
|
||||
@ -152,6 +151,7 @@ only required once.**
|
||||
- [ ] Go to the History section and find the "Post Submit" build of the merged commit that's running. Wait for it to go Green. If it's red, fix error repeat this section. Take note of the docker image version tag for next step. Example: 0.5.0-a4706cb.
|
||||
- [ ] Run `./docs/governance/templates/release.sh {source version tag} {version}` to copy the images to open-match-public-images.
|
||||
- [ ] If this is a new minor version in the newest major version then run `./docs/governance/templates/release.sh {source version tag} latest`.
|
||||
- [ ] Use the files under the `build/release/` directory for the Open Match installation guide. Make sure the artifacts work as expected - these are the artifacts that will be published to the GCS bucket and used in our release assets.
|
||||
- [ ] Copy the files from `build/release/` generated from `make release` to the release draft you created. You can drag and drop the files using the Github UI.
|
||||
- [ ] Update [Slack invitation link](https://slack.com/help/articles/201330256-invite-new-members-to-your-workspace#share-an-invite-link) in [open-match.dev](https://open-match.dev/site/docs/contribute/#get-involved).
|
||||
- [ ] Test Open Match installation under GKE and Minikube enviroment using YAML files and Helm. Follow the [First Match](https://development.open-match.dev/site/docs/getting-started/first_match/) guide, run `make proxy-demo`, and open `localhost:51507` to make sure everything works.
|
||||
@ -165,6 +165,7 @@ only required once.**
|
||||
- [ ] Save the release as a draft.
|
||||
- [ ] Circulate the draft release to active contributors. Where reasonable, get everyone's ok on the release notes before continuing.
|
||||
- [ ] Publish the [Release](om-release) in Github. This will notify repository watchers.
|
||||
- [ ] Publish the [Release](om-release) on Open Match [Blog](https://open-match.dev/site/blog/).
|
||||
|
||||
## Announce
|
||||
|
||||
|
16
.github/pull_request_template.md
vendored
Normal file
16
.github/pull_request_template.md
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
<!-- Thanks for sending a pull request! Here are some tips for you:
|
||||
If this is your first time, please read our contributor guidelines: https://github.com/googleforgames/open-match/blob/master/CONTRIBUTING.md and developer guide https://github.com/googleforgames/open-match/blob/master/docs/development.md
|
||||
-->
|
||||
|
||||
**What this PR does / Why we need it**:
|
||||
|
||||
**Which issue(s) this PR fixes**:
|
||||
<!--
|
||||
*Automatically closes linked issue when PR is merged.
|
||||
Usage: `Closes #<issue number>`, or `Closes (paste link of issue)`.
|
||||
-->
|
||||
Closes #
|
||||
|
||||
**Special notes for your reviewer**:
|
||||
|
||||
|
@ -171,17 +171,10 @@ linters:
|
||||
- funlen
|
||||
- gochecknoglobals
|
||||
- goconst
|
||||
- gocritic
|
||||
- gocyclo
|
||||
- gofmt
|
||||
- goimports
|
||||
- gosec
|
||||
- interfacer # deprecated - "A tool that suggests interfaces is prone to bad suggestions"
|
||||
- lll
|
||||
- prealloc
|
||||
- scopelint
|
||||
- staticcheck
|
||||
- stylecheck
|
||||
|
||||
#linters:
|
||||
# enable-all: true
|
||||
|
@ -13,7 +13,7 @@
|
||||
# limitations under the License.
|
||||
|
||||
# When updating Go version, update Dockerfile.ci, Dockerfile.base-build, and go.mod
|
||||
FROM golang:1.13.4
|
||||
FROM golang:1.14.0
|
||||
ENV GO111MODULE=on
|
||||
|
||||
WORKDIR /go/src/open-match.dev/open-match
|
||||
|
@ -34,13 +34,13 @@ RUN export CLOUD_SDK_REPO="cloud-sdk-stretch" && \
|
||||
apt-get update -y && apt-get install google-cloud-sdk google-cloud-sdk-app-engine-go -y -qq
|
||||
|
||||
# Install Golang
|
||||
# https://github.com/docker-library/golang/blob/master/1.13/stretch/Dockerfile
|
||||
# https://github.com/docker-library/golang/blob/master/1.14/stretch/Dockerfile
|
||||
RUN mkdir -p /toolchain/golang
|
||||
WORKDIR /toolchain/golang
|
||||
RUN sudo rm -rf /usr/local/go/
|
||||
|
||||
# When updating Go version, update Dockerfile.ci, Dockerfile.base-build, and go.mod
|
||||
RUN curl -L https://golang.org/dl/go1.13.4.linux-amd64.tar.gz | sudo tar -C /usr/local -xz
|
||||
RUN curl -L https://golang.org/dl/go1.14.linux-amd64.tar.gz | sudo tar -C /usr/local -xz
|
||||
|
||||
ENV GOPATH /go
|
||||
ENV PATH $GOPATH/bin:/usr/local/go/bin:$PATH
|
||||
|
@ -18,7 +18,9 @@ WORKDIR /go/src/open-match.dev/open-match
|
||||
|
||||
ARG IMAGE_TITLE
|
||||
|
||||
RUN make "build/cmd/${IMAGE_TITLE}"
|
||||
RUN --mount=type=cache,target=/go/pkg/mod \
|
||||
--mount=type=cache,target=/root/.cache/go-build \
|
||||
make "build/cmd/${IMAGE_TITLE}"
|
||||
|
||||
FROM gcr.io/distroless/static:nonroot
|
||||
ARG IMAGE_TITLE
|
||||
|
330
Makefile
330
Makefile
@ -15,44 +15,45 @@
|
||||
## Open Match Make Help
|
||||
## ====================
|
||||
##
|
||||
## Create a GKE Cluster (requires gcloud installed and initialized, https://cloud.google.com/sdk/docs/quickstarts)
|
||||
## # Create a GKE Cluster (requires gcloud installed and initialized, https://cloud.google.com/sdk/docs/quickstarts)
|
||||
## make activate-gcp-apis
|
||||
## make create-gke-cluster push-helm
|
||||
##
|
||||
## Create a Minikube Cluster (requires VirtualBox)
|
||||
## # Create a Minikube Cluster (requires VirtualBox)
|
||||
## make create-mini-cluster push-helm
|
||||
##
|
||||
## Create a KinD Cluster (Follow instructions to run command before pushing helm.)
|
||||
## # Create a KinD Cluster (Follow instructions to run command before pushing helm.)
|
||||
## make create-kind-cluster get-kind-kubeconfig
|
||||
## Finish KinD setup by installing helm:
|
||||
##
|
||||
## # Finish KinD setup by installing helm:
|
||||
## make push-helm
|
||||
##
|
||||
## Deploy Open Match
|
||||
## # Deploy Open Match
|
||||
## make push-images -j$(nproc)
|
||||
## make install-chart
|
||||
##
|
||||
## Build and Test
|
||||
## # Build and Test
|
||||
## make all -j$(nproc)
|
||||
## make test
|
||||
##
|
||||
## Access telemetry
|
||||
## # Access telemetry
|
||||
## make proxy-prometheus
|
||||
## make proxy-grafana
|
||||
## make proxy-ui
|
||||
##
|
||||
## Teardown
|
||||
## # Teardown
|
||||
## make delete-mini-cluster
|
||||
## make delete-gke-cluster
|
||||
## make delete-kind-cluster && export KUBECONFIG=""
|
||||
##
|
||||
## Prepare a Pull Request
|
||||
## # Prepare a Pull Request
|
||||
## make presubmit
|
||||
##
|
||||
|
||||
# If you want information on how to edit this file checkout,
|
||||
# http://makefiletutorial.com/
|
||||
|
||||
BASE_VERSION = 0.0.0-dev
|
||||
BASE_VERSION = 1.4.0-rc.1
|
||||
SHORT_SHA = $(shell git rev-parse --short=7 HEAD | tr -d [:punct:])
|
||||
BRANCH_NAME = $(shell git rev-parse --abbrev-ref HEAD | tr -d [:punct:])
|
||||
VERSION = $(BASE_VERSION)-$(SHORT_SHA)
|
||||
@ -61,12 +62,14 @@ YEAR_MONTH = $(shell date -u +'%Y%m')
|
||||
YEAR_MONTH_DAY = $(shell date -u +'%Y%m%d')
|
||||
MAJOR_MINOR_VERSION = $(shell echo $(BASE_VERSION) | cut -d '.' -f1).$(shell echo $(BASE_VERSION) | cut -d '.' -f2)
|
||||
PROTOC_VERSION = 3.10.1
|
||||
HELM_VERSION = 3.0.0
|
||||
HELM_VERSION = 3.8.0
|
||||
KUBECTL_VERSION = 1.16.2
|
||||
MINIKUBE_VERSION = latest
|
||||
GOLANGCI_VERSION = 1.18.0
|
||||
KIND_VERSION = 0.5.1
|
||||
SWAGGERUI_VERSION = 3.24.2
|
||||
GOOGLE_APIS_VERSION = aba342359b6743353195ca53f944fe71e6fb6cd4
|
||||
GRPC_GATEWAY_VERSION = 2.3.0
|
||||
TERRAFORM_VERSION = 0.12.13
|
||||
CHART_TESTING_VERSION = 2.4.0
|
||||
|
||||
@ -77,7 +80,6 @@ ENABLE_SECURITY_HARDENING = 0
|
||||
GO = GO111MODULE=on go
|
||||
# Defines the absolute local directory of the open-match project
|
||||
REPOSITORY_ROOT := $(patsubst %/,%,$(dir $(abspath $(MAKEFILE_LIST))))
|
||||
GO_BUILD_COMMAND = CGO_ENABLED=0 $(GO) build -a -installsuffix cgo .
|
||||
BUILD_DIR = $(REPOSITORY_ROOT)/build
|
||||
TOOLCHAIN_DIR = $(BUILD_DIR)/toolchain
|
||||
TOOLCHAIN_BIN = $(TOOLCHAIN_DIR)/bin
|
||||
@ -122,7 +124,7 @@ GCLOUD = gcloud --quiet
|
||||
OPEN_MATCH_HELM_NAME = open-match
|
||||
OPEN_MATCH_KUBERNETES_NAMESPACE = open-match
|
||||
OPEN_MATCH_SECRETS_DIR = $(REPOSITORY_ROOT)/install/helm/open-match/secrets
|
||||
GCLOUD_ACCOUNT_EMAIL = $(shell gcloud auth list --format yaml | grep account: | cut -c 10-)
|
||||
GCLOUD_ACCOUNT_EMAIL = $(shell gcloud auth list --format yaml | grep ACTIVE -a2 | grep account: | cut -c 10-)
|
||||
_GCB_POST_SUBMIT ?= 0
|
||||
# Latest version triggers builds of :latest images.
|
||||
_GCB_LATEST_VERSION ?= undefined
|
||||
@ -186,7 +188,7 @@ else
|
||||
endif
|
||||
endif
|
||||
|
||||
GOLANG_PROTOS = pkg/pb/backend.pb.go pkg/pb/frontend.pb.go pkg/pb/matchfunction.pb.go pkg/pb/query.pb.go pkg/pb/messages.pb.go pkg/pb/extensions.pb.go pkg/pb/evaluator.pb.go internal/ipb/synchronizer.pb.go pkg/pb/backend.pb.gw.go pkg/pb/frontend.pb.gw.go pkg/pb/matchfunction.pb.gw.go pkg/pb/query.pb.gw.go pkg/pb/evaluator.pb.gw.go
|
||||
GOLANG_PROTOS = pkg/pb/backend.pb.go pkg/pb/frontend.pb.go pkg/pb/matchfunction.pb.go pkg/pb/query.pb.go pkg/pb/messages.pb.go pkg/pb/extensions.pb.go pkg/pb/evaluator.pb.go internal/ipb/synchronizer.pb.go internal/ipb/messages.pb.go pkg/pb/backend.pb.gw.go pkg/pb/frontend.pb.gw.go pkg/pb/matchfunction.pb.gw.go pkg/pb/query.pb.gw.go pkg/pb/evaluator.pb.gw.go
|
||||
|
||||
SWAGGER_JSON_DOCS = api/frontend.swagger.json api/backend.swagger.json api/query.swagger.json api/matchfunction.swagger.json api/evaluator.swagger.json
|
||||
|
||||
@ -196,7 +198,7 @@ ALL_PROTOS = $(GOLANG_PROTOS) $(SWAGGER_JSON_DOCS)
|
||||
CMDS = $(notdir $(wildcard cmd/*))
|
||||
|
||||
# Names of the individual images, ommiting the openmatch prefix.
|
||||
IMAGES = $(CMDS) mmf-go-soloduel mmf-go-pool evaluator-go-simple base-build
|
||||
IMAGES = $(CMDS) mmf-go-soloduel mmf-go-backfill base-build
|
||||
|
||||
help:
|
||||
@cat Makefile | grep ^\#\# | grep -v ^\#\#\# |cut -c 4-
|
||||
@ -208,24 +210,28 @@ local-cloud-build: gcloud
|
||||
################################################################################
|
||||
## #############################################################################
|
||||
## Image commands:
|
||||
## These commands are auto-generated based on a complete list of images. All
|
||||
## folders in cmd/ are turned into an image using Dockerfile.cmd. Additional
|
||||
## images are specified by the IMAGES variable. Image commands ommit the
|
||||
## "openmatch-" prefix on the image name and tags.
|
||||
## These commands are auto-generated based on a complete list of images.
|
||||
## All folders in cmd/ are turned into an image using Dockerfile.cmd.
|
||||
## Additional images are specified by the IMAGES variable.
|
||||
## Image commands ommit the "openmatch-" prefix on the image name and tags.
|
||||
##
|
||||
|
||||
list-images:
|
||||
@echo $(IMAGES)
|
||||
|
||||
#######################################
|
||||
## build-images / build-<image name>-image: builds images locally
|
||||
## # Builds images locally
|
||||
## build-images / build-<image name>-image
|
||||
##
|
||||
build-images: $(foreach IMAGE,$(IMAGES),build-$(IMAGE)-image)
|
||||
|
||||
# Include all-protos here so that all dependencies are guaranteed to be downloaded after the base image is created.
|
||||
# This is important so that the repository does not have any mutations while building individual images.
|
||||
build-base-build-image: docker $(ALL_PROTOS)
|
||||
docker build -f Dockerfile.base-build -t open-match-base-build -t $(REGISTRY)/openmatch-base-build:$(TAG) -t $(REGISTRY)/openmatch-base-build:$(ALTERNATE_TAG) .
|
||||
DOCKER_BUILDKIT=1 docker build -f Dockerfile.base-build -t open-match-base-build -t $(REGISTRY)/openmatch-base-build:$(TAG) -t $(REGISTRY)/openmatch-base-build:$(ALTERNATE_TAG) .
|
||||
|
||||
$(foreach CMD,$(CMDS),build-$(CMD)-image): build-%-image: docker build-base-build-image
|
||||
docker build \
|
||||
DOCKER_BUILDKIT=1 docker build \
|
||||
-f Dockerfile.cmd \
|
||||
$(IMAGE_BUILD_ARGS) \
|
||||
--build-arg=IMAGE_TITLE=$* \
|
||||
@ -234,17 +240,14 @@ $(foreach CMD,$(CMDS),build-$(CMD)-image): build-%-image: docker build-base-buil
|
||||
.
|
||||
|
||||
build-mmf-go-soloduel-image: docker build-base-build-image
|
||||
docker build -f examples/functions/golang/soloduel/Dockerfile -t $(REGISTRY)/openmatch-mmf-go-soloduel:$(TAG) -t $(REGISTRY)/openmatch-mmf-go-soloduel:$(ALTERNATE_TAG) .
|
||||
DOCKER_BUILDKIT=1 docker build -f examples/functions/golang/soloduel/Dockerfile -t $(REGISTRY)/openmatch-mmf-go-soloduel:$(TAG) -t $(REGISTRY)/openmatch-mmf-go-soloduel:$(ALTERNATE_TAG) .
|
||||
|
||||
build-mmf-go-pool-image: docker build-base-build-image
|
||||
docker build -f test/matchfunction/Dockerfile -t $(REGISTRY)/openmatch-mmf-go-pool:$(TAG) -t $(REGISTRY)/openmatch-mmf-go-pool:$(ALTERNATE_TAG) .
|
||||
|
||||
build-evaluator-go-simple-image: docker build-base-build-image
|
||||
docker build -f test/evaluator/Dockerfile -t $(REGISTRY)/openmatch-evaluator-go-simple:$(TAG) -t $(REGISTRY)/openmatch-evaluator-go-simple:$(ALTERNATE_TAG) .
|
||||
build-mmf-go-backfill-image: docker build-base-build-image
|
||||
DOCKER_BUILDKIT=1 docker build -f examples/functions/golang/backfill/Dockerfile -t $(REGISTRY)/openmatch-mmf-go-backfill:$(TAG) -t $(REGISTRY)/openmatch-mmf-go-backfill:$(ALTERNATE_TAG) .
|
||||
|
||||
#######################################
|
||||
## push-images / push-<image name>-image: builds and pushes images to your
|
||||
## container registry.
|
||||
## # Builds and pushes images to your container registry.
|
||||
## push-images / push-<image name>-image
|
||||
##
|
||||
push-images: $(foreach IMAGE,$(IMAGES),push-$(IMAGE)-image)
|
||||
|
||||
@ -263,8 +266,9 @@ endif
|
||||
endif
|
||||
|
||||
#######################################
|
||||
## retag-images / retag-<image name>-image: publishes images on the public
|
||||
## container registry. Used for publishing releases.
|
||||
## # Publishes images on the public container registry.
|
||||
## # Used for publishing releases.
|
||||
## retag-images / retag-<image name>-image
|
||||
##
|
||||
retag-images: $(foreach IMAGE,$(IMAGES),retag-$(IMAGE)-image)
|
||||
|
||||
@ -277,7 +281,8 @@ $(foreach IMAGE,$(IMAGES),retag-$(IMAGE)-image): retag-%-image: docker
|
||||
docker push $(TARGET_REGISTRY)/openmatch-$*:$(TAG)
|
||||
|
||||
#######################################
|
||||
## clean-images / clean-<image name>-image: removes images from local docker
|
||||
## # Removes images from local docker
|
||||
## clean-images / clean-<image name>-image
|
||||
##
|
||||
clean-images: docker $(foreach IMAGE,$(IMAGES),clean-$(IMAGE)-image)
|
||||
-docker rmi -f open-match-base-build
|
||||
@ -287,7 +292,7 @@ $(foreach IMAGE,$(IMAGES),clean-$(IMAGE)-image): clean-%-image:
|
||||
|
||||
#####################################################################################################################
|
||||
update-chart-deps: build/toolchain/bin/helm$(EXE_EXTENSION)
|
||||
(cd $(REPOSITORY_ROOT)/install/helm/open-match; $(HELM) repo add incubator https://kubernetes-charts-incubator.storage.googleapis.com; $(HELM) dependency update)
|
||||
(cd $(REPOSITORY_ROOT)/install/helm/open-match; $(HELM) repo add incubator https://charts.helm.sh/incubator; $(HELM) repo add bitnami https://charts.bitnami.com/bitnami;$(HELM) dependency update)
|
||||
|
||||
lint-chart: build/toolchain/bin/helm$(EXE_EXTENSION) build/toolchain/bin/ct$(EXE_EXTENSION)
|
||||
(cd $(REPOSITORY_ROOT)/install/helm; $(HELM) lint $(OPEN_MATCH_HELM_NAME))
|
||||
@ -300,8 +305,8 @@ build/chart/open-match-$(BASE_VERSION).tgz: build/toolchain/bin/helm$(EXE_EXTENS
|
||||
|
||||
build/chart/index.yaml: build/toolchain/bin/helm$(EXE_EXTENSION) gcloud build/chart/open-match-$(BASE_VERSION).tgz
|
||||
mkdir -p $(BUILD_DIR)/chart-index/
|
||||
-gsutil cp gs://open-match-chart/chart/index.yaml $(BUILD_DIR)/chart-index/
|
||||
-gsutil -m cp gs://open-match-chart/chart/open-match-* $(BUILD_DIR)/chart-index/
|
||||
-gsutil cp $(_CHARTS_BUCKET)/chart/index.yaml $(BUILD_DIR)/chart-index/
|
||||
-gsutil -m cp $(_CHARTS_BUCKET)/chart/open-match-* $(BUILD_DIR)/chart-index/
|
||||
$(HELM) repo index $(BUILD_DIR)/chart-index/
|
||||
$(HELM) repo index --merge $(BUILD_DIR)/chart-index/index.yaml $(BUILD_DIR)/chart/
|
||||
|
||||
@ -315,7 +320,7 @@ install-chart-prerequisite: build/toolchain/bin/kubectl$(EXE_EXTENSION) update-c
|
||||
$(KUBECTL) apply -f install/gke-metadata-server-workaround.yaml
|
||||
|
||||
# Used for Open Match development. Install om-configmap-override.yaml by default.
|
||||
HELM_UPGRADE_FLAGS = --cleanup-on-fail -i --no-hooks --debug --timeout=600s --namespace=$(OPEN_MATCH_KUBERNETES_NAMESPACE) --set global.gcpProjectId=$(GCP_PROJECT_ID) --set open-match-override.enabled=true --set redis.password=$(REDIS_DEV_PASSWORD)
|
||||
HELM_UPGRADE_FLAGS = --cleanup-on-fail -i --no-hooks --debug --timeout=600s --namespace=$(OPEN_MATCH_KUBERNETES_NAMESPACE) --set global.gcpProjectId=$(GCP_PROJECT_ID) --set open-match-override.enabled=true --set redis.password=$(REDIS_DEV_PASSWORD) --set redis.auth.enabled=false --set redis.auth.sentinel=false
|
||||
# Used for generate static yamls. Install om-configmap-override.yaml as needed.
|
||||
HELM_TEMPLATE_FLAGS = --no-hooks --namespace $(OPEN_MATCH_KUBERNETES_NAMESPACE) --set usingHelmTemplate=true
|
||||
HELM_IMAGE_FLAGS = --set global.image.registry=$(REGISTRY) --set global.image.tag=$(TAG)
|
||||
@ -359,17 +364,24 @@ install-scale-chart: install-chart-prerequisite build/toolchain/bin/helm$(EXE_EX
|
||||
--set open-match-core.redis.enabled=false \
|
||||
--set global.telemetry.prometheus.enabled=true \
|
||||
--set global.telemetry.grafana.enabled=true \
|
||||
--set open-match-scale.enabled=true | $(KUBECTL) apply -f -
|
||||
--set global.kubernetes.serviceAccount=$(OPEN_MATCH_HELM_NAME)-unprivileged-service \
|
||||
--set open-match-scale.enabled=true \
|
||||
--set open-match-scale.configs.default.configName="\{\{ printf \"$(OPEN_MATCH_HELM_NAME)-configmap-default\" \}\}" \
|
||||
--set open-match-scale.configs.override.configName="\{\{ printf \"$(OPEN_MATCH_HELM_NAME)-configmap-override\" \}\}" | $(KUBECTL) apply -f -
|
||||
|
||||
# install-ci-chart will install open-match-core with pool based mmf for end-to-end in-cluster test.
|
||||
install-ci-chart: install-chart-prerequisite build/toolchain/bin/helm$(EXE_EXTENSION) install/helm/open-match/secrets/
|
||||
$(HELM) upgrade $(OPEN_MATCH_HELM_NAME) $(HELM_UPGRADE_FLAGS) --atomic install/helm/open-match $(HELM_IMAGE_FLAGS) \
|
||||
--set open-match-core.ignoreListTTL=500ms \
|
||||
--set open-match-customize.enabled=true \
|
||||
--set open-match-customize.function.enabled=true \
|
||||
--set open-match-customize.evaluator.enabled=true \
|
||||
--set open-match-customize.function.image=openmatch-mmf-go-pool \
|
||||
--set query.replicas=1,frontend.replicas=1,backend.replicas=1,open-match-customize.evaluator.replicas=1,open-match-customize.function.replicas=1 \
|
||||
--set query.replicas=1,frontend.replicas=1,backend.replicas=1 \
|
||||
--set evaluator.hostName=open-match-test \
|
||||
--set evaluator.grpcPort=50509 \
|
||||
--set evaluator.httpPort=51509 \
|
||||
--set open-match-core.registrationInterval=200ms \
|
||||
--set open-match-core.proposalCollectionInterval=200ms \
|
||||
--set open-match-core.assignedDeleteTimeout=200ms \
|
||||
--set open-match-core.pendingReleaseTimeout=1s \
|
||||
--set open-match-core.queryPageSize=10 \
|
||||
--set global.gcpProjectId=intentionally-invalid-value \
|
||||
--set redis.master.resources.requests.cpu=0.6,redis.master.resources.requests.memory=300Mi \
|
||||
--set ci=true
|
||||
|
||||
@ -381,11 +393,18 @@ delete-chart: build/toolchain/bin/helm$(EXE_EXTENSION) build/toolchain/bin/kubec
|
||||
-$(KUBECTL) delete namespace $(OPEN_MATCH_KUBERNETES_NAMESPACE)
|
||||
-$(KUBECTL) delete namespace $(OPEN_MATCH_KUBERNETES_NAMESPACE)-demo
|
||||
|
||||
ifneq ($(BASE_VERSION), 0.0.0-dev)
|
||||
install/yaml/: REGISTRY = gcr.io/$(OPEN_MATCH_PUBLIC_IMAGES_PROJECT_ID)
|
||||
install/yaml/: TAG = $(BASE_VERSION)
|
||||
endif
|
||||
install/yaml/: update-chart-deps install/yaml/install.yaml install/yaml/01-open-match-core.yaml install/yaml/02-open-match-demo.yaml install/yaml/03-prometheus-chart.yaml install/yaml/04-grafana-chart.yaml install/yaml/05-jaeger-chart.yaml install/yaml/06-open-match-override-configmap.yaml install/yaml/07-open-match-default-evaluator.yaml
|
||||
|
||||
# We have to hard-code the Jaeger endpoints as we are excluding Jaeger, so Helm cannot determine the endpoints from the Jaeger subchart
|
||||
install/yaml/01-open-match-core.yaml: build/toolchain/bin/helm$(EXE_EXTENSION)
|
||||
mkdir -p install/yaml/
|
||||
$(HELM) template $(OPEN_MATCH_HELM_NAME) $(HELM_TEMPLATE_FLAGS) $(HELM_IMAGE_FLAGS) \
|
||||
--set-string global.telemetry.jaeger.agentEndpoint="$(OPEN_MATCH_HELM_NAME)-jaeger-agent:6831" \
|
||||
--set-string global.telemetry.jaeger.collectorEndpoint="http://$(OPEN_MATCH_HELM_NAME)-jaeger-collector:14268/api/traces" \
|
||||
install/helm/open-match > install/yaml/01-open-match-core.yaml
|
||||
|
||||
install/yaml/02-open-match-demo.yaml: build/toolchain/bin/helm$(EXE_EXTENSION)
|
||||
@ -398,22 +417,27 @@ install/yaml/03-prometheus-chart.yaml: build/toolchain/bin/helm$(EXE_EXTENSION)
|
||||
mkdir -p install/yaml/
|
||||
$(HELM) template $(OPEN_MATCH_HELM_NAME) $(HELM_TEMPLATE_FLAGS) $(HELM_IMAGE_FLAGS) \
|
||||
--set open-match-core.enabled=false \
|
||||
--set open-match-core.redis.enabled=false \
|
||||
--set open-match-telemetry.enabled=true \
|
||||
--set global.telemetry.prometheus.enabled=true \
|
||||
install/helm/open-match > install/yaml/03-prometheus-chart.yaml
|
||||
|
||||
# We have to hard-code the Prometheus Server URL as we are excluding Prometheus, so Helm cannot determine the URL from the Prometheus subchart
|
||||
install/yaml/04-grafana-chart.yaml: build/toolchain/bin/helm$(EXE_EXTENSION)
|
||||
mkdir -p install/yaml/
|
||||
$(HELM) template $(OPEN_MATCH_HELM_NAME) $(HELM_TEMPLATE_FLAGS) $(HELM_IMAGE_FLAGS) \
|
||||
--set open-match-core.enabled=false \
|
||||
--set open-match-core.redis.enabled=false \
|
||||
--set open-match-telemetry.enabled=true \
|
||||
--set global.telemetry.grafana.enabled=true \
|
||||
--set-string global.telemetry.grafana.prometheusServer="http://$(OPEN_MATCH_HELM_NAME)-prometheus-server.$(OPEN_MATCH_KUBERNETES_NAMESPACE).svc.cluster.local:80/" \
|
||||
install/helm/open-match > install/yaml/04-grafana-chart.yaml
|
||||
|
||||
install/yaml/05-jaeger-chart.yaml: build/toolchain/bin/helm$(EXE_EXTENSION)
|
||||
mkdir -p install/yaml/
|
||||
$(HELM) template $(OPEN_MATCH_HELM_NAME) $(HELM_TEMPLATE_FLAGS) $(HELM_IMAGE_FLAGS) \
|
||||
--set open-match-core.enabled=false \
|
||||
--set open-match-core.redis.enabled=false \
|
||||
--set open-match-telemetry.enabled=true \
|
||||
--set global.telemetry.jaeger.enabled=true \
|
||||
install/helm/open-match > install/yaml/05-jaeger-chart.yaml
|
||||
@ -422,6 +446,7 @@ install/yaml/06-open-match-override-configmap.yaml: build/toolchain/bin/helm$(EX
|
||||
mkdir -p install/yaml/
|
||||
$(HELM) template $(OPEN_MATCH_HELM_NAME) $(HELM_TEMPLATE_FLAGS) $(HELM_IMAGE_FLAGS) \
|
||||
--set open-match-core.enabled=false \
|
||||
--set open-match-core.redis.enabled=false \
|
||||
--set open-match-override.enabled=true \
|
||||
-s templates/om-configmap-override.yaml \
|
||||
install/helm/open-match > install/yaml/06-open-match-override-configmap.yaml
|
||||
@ -430,6 +455,7 @@ install/yaml/07-open-match-default-evaluator.yaml: build/toolchain/bin/helm$(EXE
|
||||
mkdir -p install/yaml/
|
||||
$(HELM) template $(OPEN_MATCH_HELM_NAME) $(HELM_TEMPLATE_FLAGS) $(HELM_IMAGE_FLAGS) \
|
||||
--set open-match-core.enabled=false \
|
||||
--set open-match-core.redis.enabled=false \
|
||||
--set open-match-customize.enabled=true \
|
||||
--set open-match-customize.evaluator.enabled=true \
|
||||
install/helm/open-match > install/yaml/07-open-match-default-evaluator.yaml
|
||||
@ -451,11 +477,29 @@ set-redis-password:
|
||||
read REDIS_PASSWORD; \
|
||||
stty echo; \
|
||||
printf "\n"; \
|
||||
$(KUBECTL) create secret generic om-redis -n $(OPEN_MATCH_KUBERNETES_NAMESPACE) --from-literal=redis-password=$$REDIS_PASSWORD --dry-run -o yaml | $(KUBECTL) replace -f - --force
|
||||
$(KUBECTL) create secret generic open-match-redis -n $(OPEN_MATCH_KUBERNETES_NAMESPACE) --from-literal=redis-password=$$REDIS_PASSWORD --dry-run -o yaml | $(KUBECTL) replace -f - --force
|
||||
## ####################################
|
||||
## # Tool installation helpers
|
||||
##
|
||||
|
||||
## # Install toolchain. Short for installing K8s, protoc and OpenMatch tools.
|
||||
## make install-toolchain
|
||||
##
|
||||
install-toolchain: install-kubernetes-tools install-protoc-tools install-openmatch-tools
|
||||
|
||||
## # Install Kubernetes tools
|
||||
## make install-kubernetes-tools
|
||||
##
|
||||
install-kubernetes-tools: build/toolchain/bin/kubectl$(EXE_EXTENSION) build/toolchain/bin/helm$(EXE_EXTENSION) build/toolchain/bin/minikube$(EXE_EXTENSION) build/toolchain/bin/terraform$(EXE_EXTENSION)
|
||||
install-protoc-tools: build/toolchain/bin/protoc$(EXE_EXTENSION) build/toolchain/bin/protoc-gen-go$(EXE_EXTENSION) build/toolchain/bin/protoc-gen-grpc-gateway$(EXE_EXTENSION) build/toolchain/bin/protoc-gen-swagger$(EXE_EXTENSION)
|
||||
|
||||
## # Install protoc tools
|
||||
## make install-protoc-tools
|
||||
##
|
||||
install-protoc-tools: build/toolchain/bin/protoc$(EXE_EXTENSION) build/toolchain/bin/protoc-gen-go$(EXE_EXTENSION) build/toolchain/bin/protoc-gen-grpc-gateway$(EXE_EXTENSION) build/toolchain/bin/protoc-gen-openapiv2$(EXE_EXTENSION)
|
||||
|
||||
## # Install OpenMatch tools
|
||||
## make install-openmatch-tools
|
||||
##
|
||||
install-openmatch-tools: build/toolchain/bin/certgen$(EXE_EXTENSION) build/toolchain/bin/reaper$(EXE_EXTENSION)
|
||||
|
||||
build/toolchain/bin/helm$(EXE_EXTENSION):
|
||||
@ -527,19 +571,19 @@ build/toolchain/bin/protoc-gen-go$(EXE_EXTENSION):
|
||||
cd $(TOOLCHAIN_BIN) && $(GO) build -i -pkgdir . github.com/golang/protobuf/protoc-gen-go
|
||||
|
||||
build/toolchain/bin/protoc-gen-grpc-gateway$(EXE_EXTENSION):
|
||||
cd $(TOOLCHAIN_BIN) && $(GO) build -i -pkgdir . github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway
|
||||
cd $(TOOLCHAIN_BIN) && $(GO) build -i -pkgdir . github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway
|
||||
|
||||
build/toolchain/bin/protoc-gen-swagger$(EXE_EXTENSION):
|
||||
build/toolchain/bin/protoc-gen-openapiv2$(EXE_EXTENSION):
|
||||
mkdir -p $(TOOLCHAIN_BIN)
|
||||
cd $(TOOLCHAIN_BIN) && $(GO) build -i -pkgdir . github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger
|
||||
cd $(TOOLCHAIN_BIN) && $(GO) build -i -pkgdir . github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2
|
||||
|
||||
build/toolchain/bin/certgen$(EXE_EXTENSION): tools/certgen/certgen$(EXE_EXTENSION)
|
||||
build/toolchain/bin/certgen$(EXE_EXTENSION):
|
||||
mkdir -p $(TOOLCHAIN_BIN)
|
||||
cp -f $(REPOSITORY_ROOT)/tools/certgen/certgen$(EXE_EXTENSION) $(CERTGEN)
|
||||
cd $(TOOLCHAIN_BIN) && $(GO) build $(REPOSITORY_ROOT)/tools/certgen/
|
||||
|
||||
build/toolchain/bin/reaper$(EXE_EXTENSION): tools/reaper/reaper$(EXE_EXTENSION)
|
||||
build/toolchain/bin/reaper$(EXE_EXTENSION):
|
||||
mkdir -p $(TOOLCHAIN_BIN)
|
||||
cp -f $(REPOSITORY_ROOT)/tools/reaper/reaper$(EXE_EXTENSION) $(TOOLCHAIN_BIN)/reaper$(EXE_EXTENSION)
|
||||
cd $(TOOLCHAIN_BIN) && $(GO) build $(REPOSITORY_ROOT)/tools/reaper/
|
||||
|
||||
# Fake target for docker
|
||||
docker: no-sudo
|
||||
@ -589,16 +633,21 @@ get-kind-kubeconfig: build/toolchain/bin/kind$(EXE_EXTENSION)
|
||||
delete-kind-cluster: build/toolchain/bin/kind$(EXE_EXTENSION) build/toolchain/bin/kubectl$(EXE_EXTENSION)
|
||||
-$(KIND) delete cluster
|
||||
|
||||
create-gke-cluster: GKE_VERSION = 1.14.8-gke.17 # gcloud beta container get-server-config --zone us-west1-a
|
||||
create-gke-cluster: GKE_CLUSTER_SHAPE_FLAGS = --machine-type n1-standard-4 --enable-autoscaling --min-nodes 1 --num-nodes 2 --max-nodes 10 --disk-size 50
|
||||
create-cluster-role-binding:
|
||||
$(KUBECTL) create clusterrolebinding myname-cluster-admin-binding --clusterrole=cluster-admin --user=$(GCLOUD_ACCOUNT_EMAIL)
|
||||
|
||||
create-gke-cluster: GKE_VERSION = 1.20.8-gke.900 # gcloud beta container get-server-config --zone us-west1-a
|
||||
create-gke-cluster: GKE_CLUSTER_SHAPE_FLAGS = --machine-type n1-standard-8 --enable-autoscaling --min-nodes 1 --num-nodes 6 --max-nodes 10 --disk-size 50
|
||||
create-gke-cluster: GKE_FUTURE_COMPAT_FLAGS = --no-enable-basic-auth --no-issue-client-certificate --enable-ip-alias --metadata disable-legacy-endpoints=true --enable-autoupgrade
|
||||
create-gke-cluster: build/toolchain/bin/kubectl$(EXE_EXTENSION) gcloud
|
||||
$(GCLOUD) beta $(GCP_PROJECT_FLAG) container clusters create $(GKE_CLUSTER_NAME) $(GCP_LOCATION_FLAG) $(GKE_CLUSTER_SHAPE_FLAGS) $(GKE_FUTURE_COMPAT_FLAGS) $(GKE_CLUSTER_FLAGS) \
|
||||
--enable-pod-security-policy \
|
||||
--cluster-version $(GKE_VERSION) \
|
||||
--image-type cos_containerd \
|
||||
--tags open-match
|
||||
$(KUBECTL) create clusterrolebinding myname-cluster-admin-binding --clusterrole=cluster-admin --user=$(GCLOUD_ACCOUNT_EMAIL)
|
||||
--tags open-match \
|
||||
--workload-pool $(PROJECT_ID).svc.id.goog
|
||||
$(MAKE) create-cluster-role-binding
|
||||
|
||||
|
||||
delete-gke-cluster: gcloud
|
||||
-$(GCLOUD) $(GCP_PROJECT_FLAG) container clusters delete $(GKE_CLUSTER_NAME) $(GCP_LOCATION_FLAG) $(GCLOUD_EXTRA_FLAGS)
|
||||
@ -612,12 +661,19 @@ delete-mini-cluster: build/toolchain/bin/minikube$(EXE_EXTENSION)
|
||||
gcp-apply-binauthz-policy: build/policies/binauthz.yaml
|
||||
$(GCLOUD) beta $(GCP_PROJECT_FLAG) container binauthz policy import build/policies/binauthz.yaml
|
||||
|
||||
## ####################################
|
||||
## # Protobuf
|
||||
##
|
||||
|
||||
## # Build all protobuf definitions.
|
||||
## make all-protos
|
||||
##
|
||||
all-protos: $(ALL_PROTOS)
|
||||
|
||||
# The proto generator really wants to be run from the $GOPATH root, and doesn't
|
||||
# support methods for directing it to the correct location that's not the proto
|
||||
# file's location. So instead put it in a tempororary directory, then move it
|
||||
# out.
|
||||
# file's location.
|
||||
# So, instead, put it in a tempororary directory, then move it out.
|
||||
pkg/pb/%.pb.go: api/%.proto third_party/ build/toolchain/bin/protoc$(EXE_EXTENSION) build/toolchain/bin/protoc-gen-go$(EXE_EXTENSION) build/toolchain/bin/protoc-gen-grpc-gateway$(EXE_EXTENSION)
|
||||
mkdir -p $(REPOSITORY_ROOT)/build/prototmp $(REPOSITORY_ROOT)/pkg/pb
|
||||
$(PROTOC) $< \
|
||||
@ -639,25 +695,24 @@ pkg/pb/%.pb.gw.go: api/%.proto third_party/ build/toolchain/bin/protoc$(EXE_EXTE
|
||||
--grpc-gateway_out=logtostderr=true,allow_delete_body=true:$(REPOSITORY_ROOT)/build/prototmp
|
||||
mv $(REPOSITORY_ROOT)/build/prototmp/open-match.dev/open-match/$@ $@
|
||||
|
||||
api/%.swagger.json: api/%.proto third_party/ build/toolchain/bin/protoc$(EXE_EXTENSION) build/toolchain/bin/protoc-gen-swagger$(EXE_EXTENSION)
|
||||
api/%.swagger.json: api/%.proto third_party/ build/toolchain/bin/protoc$(EXE_EXTENSION) build/toolchain/bin/protoc-gen-openapiv2$(EXE_EXTENSION)
|
||||
$(PROTOC) $< \
|
||||
-I $(REPOSITORY_ROOT) -I $(PROTOC_INCLUDES) \
|
||||
--swagger_out=logtostderr=true,allow_delete_body=true:$(REPOSITORY_ROOT)
|
||||
--openapiv2_out=json_names_for_fields=false,logtostderr=true,allow_delete_body=true:$(REPOSITORY_ROOT)
|
||||
|
||||
|
||||
## # Build API reference in markdown. Needs open-match-docs repo at the same level as this one.
|
||||
## make api/api.md
|
||||
##
|
||||
api/api.md: third_party/ build/toolchain/bin/protoc-gen-doc$(EXE_EXTENSION)
|
||||
$(PROTOC) api/*.proto \
|
||||
-I $(REPOSITORY_ROOT) -I $(PROTOC_INCLUDES) \
|
||||
--doc_out=. \
|
||||
--doc_opt=markdown,api.md
|
||||
--doc_opt=markdown,api_temp.md
|
||||
# Crazy hack that insert hugo link reference to this API doc -)
|
||||
$(SED_REPLACE) '1 i\---\
|
||||
title: "Open Match API References" \
|
||||
linkTitle: "Open Match API References" \
|
||||
weight: 2 \
|
||||
description: \
|
||||
This document provides API references for Open Match services. \
|
||||
--- \
|
||||
' ./api.md && mv ./api.md $(REPOSITORY_ROOT)/../open-match-docs/site/content/en/docs/Reference/
|
||||
cat ./docs/hugo_apiheader.txt ./api_temp.md >> api.md
|
||||
mv ./api.md $(REPOSITORY_ROOT)/../open-match-docs/site/content/en/docs/Reference/
|
||||
rm ./api_temp.md
|
||||
|
||||
# Include structure of the protos needs to be called out do the dependency chain is run through properly.
|
||||
pkg/pb/backend.pb.go: pkg/pb/messages.pb.go
|
||||
@ -666,14 +721,47 @@ pkg/pb/matchfunction.pb.go: pkg/pb/messages.pb.go
|
||||
pkg/pb/query.pb.go: pkg/pb/messages.pb.go
|
||||
pkg/pb/evaluator.pb.go: pkg/pb/messages.pb.go
|
||||
internal/ipb/synchronizer.pb.go: pkg/pb/messages.pb.go
|
||||
internal/ipb/messages.pb.go: pkg/pb/messages.pb.go
|
||||
|
||||
## ####################################
|
||||
## # Go tasks
|
||||
##
|
||||
|
||||
## # Build assets and binaries
|
||||
## make build
|
||||
##
|
||||
build: assets
|
||||
$(GO) build ./...
|
||||
$(GO) build -tags e2ecluster ./...
|
||||
|
||||
define test_folder
|
||||
$(if $(wildcard $(1)/go.mod), \
|
||||
cd $(1) && \
|
||||
$(GO) test -cover -test.count $(GOLANG_TEST_COUNT) -race ./... && \
|
||||
$(GO) test -cover -test.count $(GOLANG_TEST_COUNT) -run IgnoreRace$$ ./... \
|
||||
)
|
||||
$(foreach dir, $(wildcard $(1)/*/.), $(call test_folder, $(dir)))
|
||||
endef
|
||||
|
||||
define fast_test_folder
|
||||
$(if $(wildcard $(1)/go.mod), \
|
||||
cd $(1) && \
|
||||
$(GO) test ./... \
|
||||
)
|
||||
$(foreach dir, $(wildcard $(1)/*/.), $(call fast_test_folder, $(dir)))
|
||||
endef
|
||||
|
||||
## # Run go tests
|
||||
## make test
|
||||
##
|
||||
test: $(ALL_PROTOS) tls-certs third_party/
|
||||
$(GO) test -cover -test.count $(GOLANG_TEST_COUNT) -race ./...
|
||||
$(GO) test -cover -test.count $(GOLANG_TEST_COUNT) -run IgnoreRace$$ ./...
|
||||
$(call test_folder,.)
|
||||
|
||||
## # Run go tests more quickly, but with worse flake and race detection
|
||||
## make fasttest
|
||||
##
|
||||
fasttest: $(ALL_PROTOS) tls-certs third_party/
|
||||
$(call fast_test_folder,.)
|
||||
|
||||
test-e2e-cluster: all-protos tls-certs third_party/
|
||||
$(HELM) test --timeout 7m30s -v 0 --logs -n $(OPEN_MATCH_KUBERNETES_NAMESPACE) $(OPEN_MATCH_HELM_NAME)
|
||||
@ -688,6 +776,9 @@ vet:
|
||||
golangci: build/toolchain/bin/golangci-lint$(EXE_EXTENSION)
|
||||
GO111MODULE=on $(GOLANGCI) run --config=$(REPOSITORY_ROOT)/.golangci.yaml
|
||||
|
||||
## # Run linter on Go code, charts and terraform
|
||||
## make lint
|
||||
##
|
||||
lint: fmt vet golangci lint-chart terraform-lint
|
||||
|
||||
assets: $(ALL_PROTOS) tls-certs third_party/ build/chart/
|
||||
@ -702,7 +793,7 @@ $(foreach CMD,$(CMDS),build/cmd/$(CMD)): build/cmd/%: build/cmd/%/BUILD_PHONY bu
|
||||
|
||||
build/cmd/%/BUILD_PHONY:
|
||||
mkdir -p $(BUILD_DIR)/cmd/$*
|
||||
CGO_ENABLED=0 $(GO) build -a -installsuffix cgo -o $(BUILD_DIR)/cmd/$*/run open-match.dev/open-match/cmd/$*
|
||||
CGO_ENABLED=0 $(GO) build -v -installsuffix cgo -o $(BUILD_DIR)/cmd/$*/run open-match.dev/open-match/cmd/$*
|
||||
|
||||
# Default is that nothing needs to be copied into the direcotry
|
||||
build/cmd/%/COPY_PHONY:
|
||||
@ -718,58 +809,6 @@ build/cmd/demo-%/COPY_PHONY:
|
||||
mkdir -p $(BUILD_DIR)/cmd/demo-$*/
|
||||
cp -r examples/demo/static $(BUILD_DIR)/cmd/demo-$*/static
|
||||
|
||||
all: service-binaries example-binaries tools-binaries
|
||||
|
||||
service-binaries: cmd/minimatch/minimatch$(EXE_EXTENSION) cmd/swaggerui/swaggerui$(EXE_EXTENSION)
|
||||
service-binaries: cmd/backend/backend$(EXE_EXTENSION) cmd/frontend/frontend$(EXE_EXTENSION)
|
||||
service-binaries: cmd/query/query$(EXE_EXTENSION) cmd/synchronizer/synchronizer$(EXE_EXTENSION)
|
||||
|
||||
example-binaries: example-mmf-binaries example-evaluator-binaries
|
||||
example-mmf-binaries: examples/functions/golang/soloduel/soloduel$(EXE_EXTENSION)
|
||||
example-evaluator-binaries: test/evaluator/evaluator$(EXE_EXTENSION)
|
||||
|
||||
examples/functions/golang/soloduel/soloduel$(EXE_EXTENSION): pkg/pb/query.pb.go pkg/pb/query.pb.gw.go api/query.swagger.json pkg/pb/matchfunction.pb.go pkg/pb/matchfunction.pb.gw.go api/matchfunction.swagger.json
|
||||
cd $(REPOSITORY_ROOT)/examples/functions/golang/soloduel; $(GO_BUILD_COMMAND)
|
||||
|
||||
test/matchfunction/matchfunction$(EXE_EXTENSION): pkg/pb/query.pb.go pkg/pb/query.pb.gw.go api/query.swagger.json pkg/pb/matchfunction.pb.go pkg/pb/matchfunction.pb.gw.go api/matchfunction.swagger.json
|
||||
cd $(REPOSITORY_ROOT)/test/matchfunction; $(GO_BUILD_COMMAND)
|
||||
|
||||
test/evaluator/evaluator$(EXE_EXTENSION): pkg/pb/evaluator.pb.go pkg/pb/evaluator.pb.gw.go api/evaluator.swagger.json
|
||||
cd $(REPOSITORY_ROOT)/test/evaluator; $(GO_BUILD_COMMAND)
|
||||
|
||||
tools-binaries: tools/certgen/certgen$(EXE_EXTENSION) tools/reaper/reaper$(EXE_EXTENSION)
|
||||
|
||||
cmd/backend/backend$(EXE_EXTENSION): pkg/pb/backend.pb.go pkg/pb/backend.pb.gw.go api/backend.swagger.json
|
||||
cd $(REPOSITORY_ROOT)/cmd/backend; $(GO_BUILD_COMMAND)
|
||||
|
||||
cmd/frontend/frontend$(EXE_EXTENSION): pkg/pb/frontend.pb.go pkg/pb/frontend.pb.gw.go api/frontend.swagger.json
|
||||
cd $(REPOSITORY_ROOT)/cmd/frontend; $(GO_BUILD_COMMAND)
|
||||
|
||||
cmd/query/query$(EXE_EXTENSION): pkg/pb/query.pb.go pkg/pb/query.pb.gw.go api/query.swagger.json
|
||||
cd $(REPOSITORY_ROOT)/cmd/query; $(GO_BUILD_COMMAND)
|
||||
|
||||
cmd/synchronizer/synchronizer$(EXE_EXTENSION): internal/ipb/synchronizer.pb.go
|
||||
cd $(REPOSITORY_ROOT)/cmd/synchronizer; $(GO_BUILD_COMMAND)
|
||||
|
||||
# Note: This list of dependencies is long but only add file references here. If you add a .PHONY dependency make will always rebuild it.
|
||||
cmd/minimatch/minimatch$(EXE_EXTENSION): pkg/pb/backend.pb.go pkg/pb/backend.pb.gw.go api/backend.swagger.json
|
||||
cmd/minimatch/minimatch$(EXE_EXTENSION): pkg/pb/frontend.pb.go pkg/pb/frontend.pb.gw.go api/frontend.swagger.json
|
||||
cmd/minimatch/minimatch$(EXE_EXTENSION): pkg/pb/query.pb.go pkg/pb/query.pb.gw.go api/query.swagger.json
|
||||
cmd/minimatch/minimatch$(EXE_EXTENSION): pkg/pb/evaluator.pb.go pkg/pb/evaluator.pb.gw.go api/evaluator.swagger.json
|
||||
cmd/minimatch/minimatch$(EXE_EXTENSION): pkg/pb/matchfunction.pb.go pkg/pb/matchfunction.pb.gw.go api/matchfunction.swagger.json
|
||||
cmd/minimatch/minimatch$(EXE_EXTENSION): pkg/pb/messages.pb.go
|
||||
cmd/minimatch/minimatch$(EXE_EXTENSION): internal/ipb/synchronizer.pb.go
|
||||
cd $(REPOSITORY_ROOT)/cmd/minimatch; $(GO_BUILD_COMMAND)
|
||||
|
||||
cmd/swaggerui/swaggerui$(EXE_EXTENSION): third_party/swaggerui/
|
||||
cd $(REPOSITORY_ROOT)/cmd/swaggerui; $(GO_BUILD_COMMAND)
|
||||
|
||||
tools/certgen/certgen$(EXE_EXTENSION):
|
||||
cd $(REPOSITORY_ROOT)/tools/certgen/ && $(GO_BUILD_COMMAND)
|
||||
|
||||
tools/reaper/reaper$(EXE_EXTENSION):
|
||||
cd $(REPOSITORY_ROOT)/tools/reaper/ && $(GO_BUILD_COMMAND)
|
||||
|
||||
build/policies/binauthz.yaml: install/policies/binauthz.yaml
|
||||
mkdir -p $(BUILD_DIR)/policies
|
||||
cp -f $(REPOSITORY_ROOT)/install/policies/binauthz.yaml $(BUILD_DIR)/policies/binauthz.yaml
|
||||
@ -810,13 +849,13 @@ md-test: docker
|
||||
|
||||
ci-deploy-artifacts: install/yaml/ $(SWAGGER_JSON_DOCS) build/chart/ gcloud
|
||||
ifeq ($(_GCB_POST_SUBMIT),1)
|
||||
gsutil cp -a public-read $(REPOSITORY_ROOT)/install/yaml/* gs://open-match-chart/install/v$(BASE_VERSION)/yaml/
|
||||
gsutil cp -a public-read $(REPOSITORY_ROOT)/api/*.json gs://open-match-chart/api/v$(BASE_VERSION)/
|
||||
gsutil cp -a public-read $(REPOSITORY_ROOT)/install/yaml/* $(_CHARTS_BUCKET)/install/v$(BASE_VERSION)/yaml/
|
||||
gsutil cp -a public-read $(REPOSITORY_ROOT)/api/*.json $(_CHARTS_BUCKET)/api/v$(BASE_VERSION)/
|
||||
# Deploy Helm Chart
|
||||
# Since each build will refresh just it's version we can allow this for every post submit.
|
||||
# Copy the files into multiple locations to keep a backup.
|
||||
gsutil cp -a public-read $(BUILD_DIR)/chart/*.* gs://open-match-chart/chart/by-hash/$(VERSION)/
|
||||
gsutil cp -a public-read $(BUILD_DIR)/chart/*.* gs://open-match-chart/chart/
|
||||
gsutil cp -a public-read $(BUILD_DIR)/chart/*.* $(_CHARTS_BUCKET)/chart/by-hash/$(VERSION)/
|
||||
gsutil cp -a public-read $(BUILD_DIR)/chart/*.* $(_CHARTS_BUCKET)/chart/
|
||||
else
|
||||
@echo "Not deploying build artifacts to open-match.dev because this is not a post commit change."
|
||||
endif
|
||||
@ -826,7 +865,7 @@ ci-reap-namespaces: build/toolchain/bin/reaper$(EXE_EXTENSION)
|
||||
|
||||
# For presubmit we want to update the protobuf generated files and verify that tests are good.
|
||||
presubmit: GOLANG_TEST_COUNT = 5
|
||||
presubmit: clean third_party/ update-chart-deps assets update-deps lint build install-toolchain test md-test terraform-test
|
||||
presubmit: clean third_party/ update-chart-deps assets update-deps lint build test md-test terraform-test
|
||||
|
||||
build/release/: presubmit clean-install-yaml install/yaml/
|
||||
mkdir -p $(BUILD_DIR)/release/
|
||||
@ -860,19 +899,6 @@ clean-protos:
|
||||
rm -rf $(REPOSITORY_ROOT)/pkg/pb/
|
||||
rm -rf $(REPOSITORY_ROOT)/internal/ipb/
|
||||
|
||||
clean-binaries:
|
||||
rm -rf $(REPOSITORY_ROOT)/cmd/backend/backend$(EXE_EXTENSION)
|
||||
rm -rf $(REPOSITORY_ROOT)/cmd/synchronizer/synchronizer$(EXE_EXTENSION)
|
||||
rm -rf $(REPOSITORY_ROOT)/cmd/frontend/frontend$(EXE_EXTENSION)
|
||||
rm -rf $(REPOSITORY_ROOT)/cmd/query/query$(EXE_EXTENSION)
|
||||
rm -rf $(REPOSITORY_ROOT)/cmd/minimatch/minimatch$(EXE_EXTENSION)
|
||||
rm -rf $(REPOSITORY_ROOT)/examples/functions/golang/soloduel/soloduel$(EXE_EXTENSION)
|
||||
rm -rf $(REPOSITORY_ROOT)/test/matchfunction/matchfunction$(EXE_EXTENSION)
|
||||
rm -rf $(REPOSITORY_ROOT)/test/evaluator/evaluator$(EXE_EXTENSION)
|
||||
rm -rf $(REPOSITORY_ROOT)/cmd/swaggerui/swaggerui$(EXE_EXTENSION)
|
||||
rm -rf $(REPOSITORY_ROOT)/tools/certgen/certgen$(EXE_EXTENSION)
|
||||
rm -rf $(REPOSITORY_ROOT)/tools/reaper/reaper$(EXE_EXTENSION)
|
||||
|
||||
clean-terraform:
|
||||
rm -rf $(REPOSITORY_ROOT)/install/terraform/.terraform/
|
||||
|
||||
@ -897,7 +923,7 @@ clean-swagger-docs:
|
||||
clean-third-party:
|
||||
rm -rf $(REPOSITORY_ROOT)/third_party/
|
||||
|
||||
clean: clean-images clean-binaries clean-build clean-install-yaml clean-secrets clean-terraform clean-third-party clean-protos clean-swagger-docs
|
||||
clean: clean-images clean-build clean-install-yaml clean-secrets clean-terraform clean-third-party clean-protos clean-swagger-docs
|
||||
|
||||
proxy-frontend: build/toolchain/bin/kubectl$(EXE_EXTENSION)
|
||||
@echo "Frontend Health: http://localhost:$(FRONTEND_PORT)/healthz"
|
||||
@ -958,24 +984,24 @@ proxy:
|
||||
update-deps:
|
||||
$(GO) mod tidy
|
||||
|
||||
third_party/: third_party/google/api third_party/protoc-gen-swagger/options third_party/swaggerui/
|
||||
third_party/: third_party/google/api third_party/protoc-gen-openapiv2/options third_party/swaggerui/
|
||||
|
||||
third_party/google/api:
|
||||
mkdir -p $(TOOLCHAIN_DIR)/googleapis-temp/
|
||||
mkdir -p $(REPOSITORY_ROOT)/third_party/google/api
|
||||
mkdir -p $(REPOSITORY_ROOT)/third_party/google/rpc
|
||||
curl -o $(TOOLCHAIN_DIR)/googleapis-temp/googleapis.zip -L https://github.com/googleapis/googleapis/archive/master.zip
|
||||
curl -o $(TOOLCHAIN_DIR)/googleapis-temp/googleapis.zip -L https://github.com/googleapis/googleapis/archive/$(GOOGLE_APIS_VERSION).zip
|
||||
(cd $(TOOLCHAIN_DIR)/googleapis-temp/; unzip -q -o googleapis.zip)
|
||||
cp -f $(TOOLCHAIN_DIR)/googleapis-temp/googleapis-master/google/api/*.proto $(REPOSITORY_ROOT)/third_party/google/api/
|
||||
cp -f $(TOOLCHAIN_DIR)/googleapis-temp/googleapis-master/google/rpc/*.proto $(REPOSITORY_ROOT)/third_party/google/rpc/
|
||||
cp -f $(TOOLCHAIN_DIR)/googleapis-temp/googleapis-$(GOOGLE_APIS_VERSION)/google/api/*.proto $(REPOSITORY_ROOT)/third_party/google/api/
|
||||
cp -f $(TOOLCHAIN_DIR)/googleapis-temp/googleapis-$(GOOGLE_APIS_VERSION)/google/rpc/*.proto $(REPOSITORY_ROOT)/third_party/google/rpc/
|
||||
rm -rf $(TOOLCHAIN_DIR)/googleapis-temp
|
||||
|
||||
third_party/protoc-gen-swagger/options:
|
||||
third_party/protoc-gen-openapiv2/options:
|
||||
mkdir -p $(TOOLCHAIN_DIR)/grpc-gateway-temp/
|
||||
mkdir -p $(REPOSITORY_ROOT)/third_party/protoc-gen-swagger/options
|
||||
curl -o $(TOOLCHAIN_DIR)/grpc-gateway-temp/grpc-gateway.zip -L https://github.com/grpc-ecosystem/grpc-gateway/archive/master.zip
|
||||
mkdir -p $(REPOSITORY_ROOT)/third_party/protoc-gen-openapiv2/options
|
||||
curl -o $(TOOLCHAIN_DIR)/grpc-gateway-temp/grpc-gateway.zip -L https://github.com/grpc-ecosystem/grpc-gateway/archive/v$(GRPC_GATEWAY_VERSION).zip
|
||||
(cd $(TOOLCHAIN_DIR)/grpc-gateway-temp/; unzip -q -o grpc-gateway.zip)
|
||||
cp -f $(TOOLCHAIN_DIR)/grpc-gateway-temp/grpc-gateway-master/protoc-gen-swagger/options/*.proto $(REPOSITORY_ROOT)/third_party/protoc-gen-swagger/options/
|
||||
cp -f $(TOOLCHAIN_DIR)/grpc-gateway-temp/grpc-gateway-$(GRPC_GATEWAY_VERSION)/protoc-gen-openapiv2/options/*.proto $(REPOSITORY_ROOT)/third_party/protoc-gen-openapiv2/options/
|
||||
rm -rf $(TOOLCHAIN_DIR)/grpc-gateway-temp
|
||||
|
||||
third_party/swaggerui/:
|
||||
|
@ -24,10 +24,6 @@ The [Open Match Development guide](docs/development.md) has detailed instruction
|
||||
on getting the source code, making changes, testing and submitting a pull request
|
||||
to Open Match.
|
||||
|
||||
## Disclaimer
|
||||
|
||||
This software is currently alpha, and subject to change.
|
||||
|
||||
## Support
|
||||
|
||||
* [Slack Channel](https://open-match.slack.com/) ([Signup](https://join.slack.com/t/open-match/shared_invite/enQtNDM1NjcxNTY4MTgzLTM5ZWQxNjc1YWI3MzJmN2RiMWJmYWI0ZjFiNzNkZmNkMWQ3YWU5OGVkNzA5Yzc4OGVkOGU5MTc0OTA5ZTA5NDU))
|
||||
|
@ -19,9 +19,9 @@ option csharp_namespace = "OpenMatch";
|
||||
|
||||
import "api/messages.proto";
|
||||
import "google/api/annotations.proto";
|
||||
import "protoc-gen-swagger/options/annotations.proto";
|
||||
import "protoc-gen-openapiv2/options/annotations.proto";
|
||||
|
||||
option (grpc.gateway.protoc_gen_swagger.options.openapiv2_swagger) = {
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
|
||||
info: {
|
||||
title: "Backend"
|
||||
version: "1.0"
|
||||
@ -88,7 +88,12 @@ message ReleaseTicketsRequest{
|
||||
|
||||
message ReleaseTicketsResponse {}
|
||||
|
||||
message AssignTicketsRequest {
|
||||
message ReleaseAllTicketsRequest{}
|
||||
|
||||
message ReleaseAllTicketsResponse {}
|
||||
|
||||
// AssignmentGroup contains an Assignment and the Tickets to which it should be applied.
|
||||
message AssignmentGroup {
|
||||
// TicketIds is a list of strings representing Open Match generated Ids which apply to an Assignment.
|
||||
repeated string ticket_ids = 1;
|
||||
|
||||
@ -96,13 +101,34 @@ message AssignTicketsRequest {
|
||||
Assignment assignment = 2;
|
||||
}
|
||||
|
||||
message AssignTicketsResponse {}
|
||||
// AssignmentFailure contains the id of the Ticket that failed the Assignment and the failure status.
|
||||
message AssignmentFailure {
|
||||
enum Cause {
|
||||
UNKNOWN = 0;
|
||||
TICKET_NOT_FOUND = 1;
|
||||
}
|
||||
|
||||
string ticket_id = 1;
|
||||
Cause cause = 2;
|
||||
}
|
||||
|
||||
message AssignTicketsRequest {
|
||||
// Assignments is a list of assignment groups that contain assignment and the Tickets to which they should be applied.
|
||||
repeated AssignmentGroup assignments = 1;
|
||||
}
|
||||
|
||||
message AssignTicketsResponse {
|
||||
// Failures is a list of all the Tickets that failed assignment along with the cause of failure.
|
||||
repeated AssignmentFailure failures = 1;
|
||||
}
|
||||
|
||||
// The BackendService implements APIs to generate matches and handle ticket assignments.
|
||||
service BackendService {
|
||||
// FetchMatches triggers a MatchFunction with the specified MatchProfile and returns a set of match proposals that
|
||||
// match the description of that MatchProfile.
|
||||
// FetchMatches immediately returns an error if it encounters any execution failures.
|
||||
// FetchMatches triggers a MatchFunction with the specified MatchProfile and
|
||||
// returns a set of matches generated by the Match Making Function, and
|
||||
// accepted by the evaluator.
|
||||
// Tickets in matches returned by FetchMatches are moved from active to
|
||||
// pending, and will not be returned by query.
|
||||
rpc FetchMatches(FetchMatchesRequest) returns (stream FetchMatchesResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/v1/backendservice/matches:fetch"
|
||||
@ -118,10 +144,8 @@ service BackendService {
|
||||
};
|
||||
}
|
||||
|
||||
// ReleaseTickets removes the submitted tickets from the list that prevents tickets
|
||||
// that are awaiting assignment from appearing in MMF queries, effectively putting them back into
|
||||
// the matchmaking pool
|
||||
//
|
||||
// ReleaseTickets moves tickets from the pending state, to the active state.
|
||||
// This enables them to be returned by query, and find different matches.
|
||||
// BETA FEATURE WARNING: This call and the associated Request and Response
|
||||
// messages are not finalized and still subject to possible change or removal.
|
||||
rpc ReleaseTickets(ReleaseTicketsRequest) returns (ReleaseTicketsResponse) {
|
||||
@ -130,4 +154,16 @@ service BackendService {
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
|
||||
// ReleaseAllTickets moves all tickets from the pending state, to the active
|
||||
// state. This enables them to be returned by query, and find different
|
||||
// matches.
|
||||
// BETA FEATURE WARNING: This call and the associated Request and Response
|
||||
// messages are not finalized and still subject to possible change or removal.
|
||||
rpc ReleaseAllTickets(ReleaseAllTicketsRequest) returns (ReleaseAllTicketsResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/v1/backendservice/tickets:releaseall"
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,11 @@
|
||||
"url": "https://github.com/googleforgames/open-match/blob/master/LICENSE"
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
{
|
||||
"name": "BackendService"
|
||||
}
|
||||
],
|
||||
"schemes": [
|
||||
"http",
|
||||
"https"
|
||||
@ -26,20 +31,36 @@
|
||||
"paths": {
|
||||
"/v1/backendservice/matches:fetch": {
|
||||
"post": {
|
||||
"summary": "FetchMatches triggers a MatchFunction with the specified MatchProfiles, while each MatchProfile \r\nreturns a set of match proposals. FetchMatches method streams the results back to the caller.\r\nFetchMatches immediately returns an error if it encounters any execution failures.\r\n - If the synchronizer is enabled, FetchMatch will then call the synchronizer to deduplicate proposals with overlapped tickets.",
|
||||
"operationId": "FetchMatches",
|
||||
"summary": "FetchMatches triggers a MatchFunction with the specified MatchProfile and\nreturns a set of matches generated by the Match Making Function, and\naccepted by the evaluator.\nTickets in matches returned by FetchMatches are moved from active to\npending, and will not be returned by query.",
|
||||
"operationId": "BackendService_FetchMatches",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.(streaming responses)",
|
||||
"schema": {
|
||||
"$ref": "#/x-stream-definitions/openmatchFetchMatchesResponse"
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"result": {
|
||||
"$ref": "#/definitions/openmatchFetchMatchesResponse"
|
||||
},
|
||||
"error": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
},
|
||||
"title": "Stream result of openmatchFetchMatchesResponse"
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Returned when the resource does not exist.",
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"format": "string"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
@ -60,7 +81,7 @@
|
||||
"/v1/backendservice/tickets:assign": {
|
||||
"post": {
|
||||
"summary": "AssignTickets overwrites the Assignment field of the input TicketIds.",
|
||||
"operationId": "AssignTickets",
|
||||
"operationId": "BackendService_AssignTickets",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
@ -71,8 +92,15 @@
|
||||
"404": {
|
||||
"description": "Returned when the resource does not exist.",
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"format": "string"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
@ -90,10 +118,10 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"/v1/backend/tickets:release": {
|
||||
"/v1/backendservice/tickets:release": {
|
||||
"post": {
|
||||
"summary": "ReleaseTickets removes the submitted tickets from the list that prevents tickets \r\nthat are awaiting assignment from appearing in MMF queries, effectively putting them back into\r\nthe matchmaking pool",
|
||||
"operationId": "ReleaseTickets",
|
||||
"summary": "ReleaseTickets moves tickets from the pending state, to the active state.\nThis enables them to be returned by query, and find different matches.\nBETA FEATURE WARNING: This call and the associated Request and Response\nmessages are not finalized and still subject to possible change or removal.",
|
||||
"operationId": "BackendService_ReleaseTickets",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
@ -104,8 +132,15 @@
|
||||
"404": {
|
||||
"description": "Returned when the resource does not exist.",
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"format": "string"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
@ -119,30 +154,94 @@
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"Backend"
|
||||
"BackendService"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/v1/backendservice/tickets:releaseall": {
|
||||
"post": {
|
||||
"summary": "ReleaseAllTickets moves all tickets from the pending state, to the active\nstate. This enables them to be returned by query, and find different\nmatches.\nBETA FEATURE WARNING: This call and the associated Request and Response\nmessages are not finalized and still subject to possible change or removal.",
|
||||
"operationId": "BackendService_ReleaseAllTickets",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/openmatchReleaseAllTicketsResponse"
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Returned when the resource does not exist.",
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"format": "string"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/openmatchReleaseAllTicketsRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"BackendService"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"AssignmentFailureCause": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"UNKNOWN",
|
||||
"TICKET_NOT_FOUND"
|
||||
],
|
||||
"default": "UNKNOWN"
|
||||
},
|
||||
"DoubleRangeFilterExclude": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"NONE",
|
||||
"MIN",
|
||||
"MAX",
|
||||
"BOTH"
|
||||
],
|
||||
"default": "NONE",
|
||||
"title": "- NONE: No bounds should be excluded when evaluating the filter, i.e.: MIN \u003c= x \u003c= MAX\n - MIN: Only the minimum bound should be excluded when evaluating the filter, i.e.: MIN \u003c x \u003c= MAX\n - MAX: Only the maximum bound should be excluded when evaluating the filter, i.e.: MIN \u003c= x \u003c MAX\n - BOTH: Both bounds should be excluded when evaluating the filter, i.e.: MIN \u003c x \u003c MAX"
|
||||
},
|
||||
"openmatchAssignTicketsRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"ticket_ids": {
|
||||
"assignments": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
"$ref": "#/definitions/openmatchAssignmentGroup"
|
||||
},
|
||||
"description": "TicketIds is a list of strings representing Open Match generated Ids which apply to an Assignment."
|
||||
},
|
||||
"assignment": {
|
||||
"$ref": "#/definitions/openmatchAssignment",
|
||||
"description": "An Assignment specifies game connection related information to be associated with the TicketIds."
|
||||
"description": "Assignments is a list of assignment groups that contain assignment and the Tickets to which they should be applied."
|
||||
}
|
||||
}
|
||||
},
|
||||
"openmatchAssignTicketsResponse": {
|
||||
"type": "object"
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"failures": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/openmatchAssignmentFailure"
|
||||
},
|
||||
"description": "Failures is a list of all the Tickets that failed assignment along with the cause of failure."
|
||||
}
|
||||
}
|
||||
},
|
||||
"openmatchAssignment": {
|
||||
"type": "object",
|
||||
@ -156,10 +255,70 @@
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/protobufAny"
|
||||
},
|
||||
"description": "Customized information not inspected by Open Match, to be used by the match\r\nmaking function, evaluator, and components making calls to Open Match.\r\nOptional, depending on the requirements of the connected systems."
|
||||
"description": "Customized information not inspected by Open Match, to be used by the match\nmaking function, evaluator, and components making calls to Open Match.\nOptional, depending on the requirements of the connected systems."
|
||||
}
|
||||
},
|
||||
"description": "An Assignment represents a game server assignment associated with a Ticket. Open\r\nmatch does not require or inspect any fields on assignment."
|
||||
"description": "An Assignment represents a game server assignment associated with a Ticket.\nOpen Match does not require or inspect any fields on assignment."
|
||||
},
|
||||
"openmatchAssignmentFailure": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"ticket_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"cause": {
|
||||
"$ref": "#/definitions/AssignmentFailureCause"
|
||||
}
|
||||
},
|
||||
"description": "AssignmentFailure contains the id of the Ticket that failed the Assignment and the failure status."
|
||||
},
|
||||
"openmatchAssignmentGroup": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"ticket_ids": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "TicketIds is a list of strings representing Open Match generated Ids which apply to an Assignment."
|
||||
},
|
||||
"assignment": {
|
||||
"$ref": "#/definitions/openmatchAssignment",
|
||||
"description": "An Assignment specifies game connection related information to be associated with the TicketIds."
|
||||
}
|
||||
},
|
||||
"description": "AssignmentGroup contains an Assignment and the Tickets to which it should be applied."
|
||||
},
|
||||
"openmatchBackfill": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "Id represents an auto-generated Id issued by Open Match."
|
||||
},
|
||||
"search_fields": {
|
||||
"$ref": "#/definitions/openmatchSearchFields",
|
||||
"description": "Search fields are the fields which Open Match is aware of, and can be used\nwhen specifying filters."
|
||||
},
|
||||
"extensions": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/protobufAny"
|
||||
},
|
||||
"description": "Customized information not inspected by Open Match, to be used by\nthe Match Function, evaluator, and components making calls to Open Match.\nOptional, depending on the requirements of the connected systems."
|
||||
},
|
||||
"create_time": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "Create time is the time the Ticket was created. It is populated by Open\nMatch at the time of Ticket creation."
|
||||
},
|
||||
"generation": {
|
||||
"type": "string",
|
||||
"format": "int64",
|
||||
"description": "Generation gets incremented on GameServers update operations.\nPrevents the MMF from overriding a newer version from the game server.\nDo NOT read or write to this field, it is for internal tracking, and changing the value will cause bugs."
|
||||
}
|
||||
},
|
||||
"description": "Represents a backfill entity which is used to fill partially full matches.\n\nBETA FEATURE WARNING: This call and the associated Request and Response\nmessages are not finalized and still subject to possible change or removal."
|
||||
},
|
||||
"openmatchDoubleRangeFilter": {
|
||||
"type": "object",
|
||||
@ -177,20 +336,24 @@
|
||||
"type": "number",
|
||||
"format": "double",
|
||||
"description": "Minimum value."
|
||||
},
|
||||
"exclude": {
|
||||
"$ref": "#/definitions/DoubleRangeFilterExclude",
|
||||
"description": "Defines the bounds to apply when filtering tickets by their search_fields.double_args value.\nBETA FEATURE WARNING: This field and the associated values are\nnot finalized and still subject to possible change or removal."
|
||||
}
|
||||
},
|
||||
"title": "Filters numerical values to only those within a range.\r\n double_arg: \"foo\"\r\n max: 10\r\n min: 5\r\nmatches:\r\n {\"foo\": 5}\r\n {\"foo\": 7.5}\r\n {\"foo\": 10}\r\ndoes not match:\r\n {\"foo\": 4}\r\n {\"foo\": 10.01}\r\n {\"foo\": \"7.5\"}\r\n {}"
|
||||
"title": "Filters numerical values to only those within a range.\n double_arg: \"foo\"\n max: 10\n min: 5\nmatches:\n {\"foo\": 5}\n {\"foo\": 7.5}\n {\"foo\": 10}\ndoes not match:\n {\"foo\": 4}\n {\"foo\": 10.01}\n {\"foo\": \"7.5\"}\n {}"
|
||||
},
|
||||
"openmatchFetchMatchesRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"config": {
|
||||
"$ref": "#/definitions/openmatchFunctionConfig",
|
||||
"title": "FunctionConfig specifies a MMF address and client type for Backend to establish connections with the MMF"
|
||||
"description": "A configuration for the MatchFunction server of this FetchMatches call."
|
||||
},
|
||||
"profile": {
|
||||
"$ref": "#/definitions/openmatchMatchProfile",
|
||||
"description": "MatchProfiles that will be sent to thhe MMF specified in the FunctionConfig."
|
||||
"description": "A MatchProfile that will be sent to the MatchFunction server of this FetchMatches call."
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -199,7 +362,7 @@
|
||||
"properties": {
|
||||
"match": {
|
||||
"$ref": "#/definitions/openmatchMatch",
|
||||
"description": "A Match generated by the user-defined MMF with the specified MatchProfiles.\r\nA valid Match response will contain at least one ticket."
|
||||
"description": "A Match generated by the user-defined MMF with the specified MatchProfiles.\nA valid Match response will contain at least one ticket."
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -254,14 +417,18 @@
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/protobufAny"
|
||||
},
|
||||
"description": "Customized information not inspected by Open Match, to be used by the match\r\nmaking function, evaluator, and components making calls to Open Match.\r\nOptional, depending on the requirements of the connected systems."
|
||||
"description": "Customized information not inspected by Open Match, to be used by the match\nmaking function, evaluator, and components making calls to Open Match.\nOptional, depending on the requirements of the connected systems."
|
||||
},
|
||||
"backfill": {
|
||||
"$ref": "#/definitions/openmatchBackfill",
|
||||
"description": "Backfill request which contains additional information to the match\nand contains an association to a GameServer.\nBETA FEATURE WARNING: This field is not finalized and still subject\nto possible change or removal."
|
||||
},
|
||||
"allocate_gameserver": {
|
||||
"type": "boolean",
|
||||
"description": "AllocateGameServer signalise Director that Backfill is new and it should \nallocate a GameServer, this Backfill would be assigned.\nBETA FEATURE WARNING: This field is not finalized and still subject\nto possible change or removal."
|
||||
}
|
||||
},
|
||||
<<<<<<< HEAD
|
||||
"description": "A Match is used to represent a completed match object. It can be generated by\r\na MatchFunction as a proposal or can be returned by OpenMatch as a result in\r\nresponse to the FetchMatches call.\r\nWhen a match is returned by the FetchMatches call, it should contain at least \r\none ticket to be considered as valid."
|
||||
=======
|
||||
"description": "A Match is used to represent a completed match object. It can be generated by\na MatchFunction as a proposal or can be returned by OpenMatch as a result in\nresponse to the FetchMatches call.\nWhen a match is returned by the FetchMatches call, it should contain at least\none ticket to be considered as valid."
|
||||
>>>>>>> cf8d49052c148a3179904700e12cc8115a47af4e
|
||||
},
|
||||
"openmatchMatchProfile": {
|
||||
"type": "object",
|
||||
@ -275,28 +442,17 @@
|
||||
"items": {
|
||||
"$ref": "#/definitions/openmatchPool"
|
||||
},
|
||||
<<<<<<< HEAD
|
||||
"description": "Set of pools to be queried when generating a match for this MatchProfile.\r\nThe pool names can be used in empty Rosters to specify composition of a\r\nmatch."
|
||||
},
|
||||
"rosters": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/openmatchRoster"
|
||||
},
|
||||
"description": "Set of Rosters for this match request. Could be empty Rosters used to\r\nindicate the composition of the generated Match or they could be partially\r\npre-populated Ticket list to be used in scenarios such as backfill / join\r\nin progress."
|
||||
=======
|
||||
"description": "Set of pools to be queried when generating a match for this MatchProfile."
|
||||
>>>>>>> cf8d49052c148a3179904700e12cc8115a47af4e
|
||||
},
|
||||
"extensions": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/protobufAny"
|
||||
},
|
||||
"description": "Customized information not inspected by Open Match, to be used by the match\r\nmaking function, evaluator, and components making calls to Open Match.\r\nOptional, depending on the requirements of the connected systems."
|
||||
"description": "Customized information not inspected by Open Match, to be used by the match\nmaking function, evaluator, and components making calls to Open Match.\nOptional, depending on the requirements of the connected systems."
|
||||
}
|
||||
},
|
||||
"description": "A MatchProfile is Open Match's representation of a Match specification. It is\r\nused to indicate the criteria for selecting players for a match. A\r\nMatchProfile is the input to the API to get matches and is passed to the\r\nMatchFunction. It contains all the information required by the MatchFunction\r\nto generate match proposals."
|
||||
"description": "A MatchProfile is Open Match's representation of a Match specification. It is\nused to indicate the criteria for selecting players for a match. A\nMatchProfile is the input to the API to get matches and is passed to the\nMatchFunction. It contains all the information required by the MatchFunction\nto generate match proposals."
|
||||
},
|
||||
"openmatchPool": {
|
||||
"type": "object",
|
||||
@ -310,7 +466,7 @@
|
||||
"items": {
|
||||
"$ref": "#/definitions/openmatchDoubleRangeFilter"
|
||||
},
|
||||
"description": "Set of Filters indicating the filtering criteria. Selected players must\r\nmatch every Filter."
|
||||
"description": "Set of Filters indicating the filtering criteria. Selected tickets must\nmatch every Filter."
|
||||
},
|
||||
"string_equals_filters": {
|
||||
"type": "array",
|
||||
@ -323,10 +479,26 @@
|
||||
"items": {
|
||||
"$ref": "#/definitions/openmatchTagPresentFilter"
|
||||
}
|
||||
},
|
||||
"created_before": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "If specified, only Tickets created before the specified time are selected."
|
||||
},
|
||||
"created_after": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "If specified, only Tickets created after the specified time are selected."
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Pool specfies a set of criteria that are used to select a subset of Tickets\nthat meet all the criteria."
|
||||
},
|
||||
"openmatchReleaseAllTicketsRequest": {
|
||||
"type": "object"
|
||||
},
|
||||
"openmatchReleaseAllTicketsResponse": {
|
||||
"type": "object"
|
||||
},
|
||||
<<<<<<< HEAD
|
||||
"openmatchReleaseTicketsRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@ -335,32 +507,13 @@
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"title": "TicketIds is a list of string representing Open Match generated Ids to be re-enabled for MMF querying\r\nbecause they are no longer awaiting assignment from a previous match result"
|
||||
"title": "TicketIds is a list of string representing Open Match generated Ids to be re-enabled for MMF querying\nbecause they are no longer awaiting assignment from a previous match result"
|
||||
}
|
||||
}
|
||||
},
|
||||
"openmatchReleaseTicketsResponse": {
|
||||
"type": "object"
|
||||
},
|
||||
"openmatchRoster": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "A developer-chosen human-readable name for this Roster."
|
||||
},
|
||||
"ticket_ids": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "Tickets belonging to this Roster."
|
||||
}
|
||||
},
|
||||
"description": "A Roster is a named collection of Ticket IDs. It exists so that a Tickets\r\nassociated with a Match can be labelled to belong to a team, sub-team etc. It\r\ncan also be used to represent the current state of a Match in scenarios such\r\nas backfill, join-in-progress etc."
|
||||
},
|
||||
=======
|
||||
>>>>>>> cf8d49052c148a3179904700e12cc8115a47af4e
|
||||
"openmatchSearchFields": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@ -387,7 +540,7 @@
|
||||
"description": "Filterable on presence or absence of given value."
|
||||
}
|
||||
},
|
||||
"description": "Search fields are the fields which Open Match is aware of, and can be used\r\nwhen specifying filters."
|
||||
"description": "Search fields are the fields which Open Match is aware of, and can be used\nwhen specifying filters."
|
||||
},
|
||||
"openmatchStringEqualsFilter": {
|
||||
"type": "object",
|
||||
@ -400,7 +553,7 @@
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"title": "Filters strings exactly equaling a value.\r\n string_arg: \"foo\"\r\n value: \"bar\"\r\nmatches:\r\n {\"foo\": \"bar\"}\r\ndoes not match:\r\n {\"foo\": \"baz\"}\r\n {\"bar\": \"foo\"}\r\n {}"
|
||||
"title": "Filters strings exactly equaling a value.\n string_arg: \"foo\"\n value: \"bar\"\nmatches:\n {\"foo\": \"bar\"}\ndoes not match:\n {\"foo\": \"baz\"}\n {\"bar\": \"foo\"}\n {}"
|
||||
},
|
||||
"openmatchTagPresentFilter": {
|
||||
"type": "object",
|
||||
@ -409,7 +562,7 @@
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"title": "Filters to the tag being present on the search_fields.\r\n tag: \"foo\"\r\nmatches:\r\n [\"foo\"]\r\n [\"bar\",\"foo\"]\r\ndoes not match:\r\n [\"bar\"]\r\n []"
|
||||
"title": "Filters to the tag being present on the search_fields.\n tag: \"foo\"\nmatches:\n [\"foo\"]\n [\"bar\",\"foo\"]\ndoes not match:\n [\"bar\"]\n []"
|
||||
},
|
||||
"openmatchTicket": {
|
||||
"type": "object",
|
||||
@ -420,25 +573,26 @@
|
||||
},
|
||||
"assignment": {
|
||||
"$ref": "#/definitions/openmatchAssignment",
|
||||
<<<<<<< HEAD
|
||||
"description": "An Assignment represents a game server assignment associated with a Ticket. \r\nOpen Match does not require or inspect any fields on Assignment."
|
||||
=======
|
||||
"description": "An Assignment represents a game server assignment associated with a Ticket.\nOpen Match does not require or inspect any fields on Assignment."
|
||||
>>>>>>> cf8d49052c148a3179904700e12cc8115a47af4e
|
||||
"description": "An Assignment represents a game server assignment associated with a Ticket,\nor whatever finalized matched state means for your use case.\nOpen Match does not require or inspect any fields on Assignment."
|
||||
},
|
||||
"search_fields": {
|
||||
"$ref": "#/definitions/openmatchSearchFields",
|
||||
"description": "Search fields are the fields which Open Match is aware of, and can be used\r\nwhen specifying filters."
|
||||
"description": "Search fields are the fields which Open Match is aware of, and can be used\nwhen specifying filters."
|
||||
},
|
||||
"extensions": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/protobufAny"
|
||||
},
|
||||
"description": "Customized information not inspected by Open Match, to be used by the match\r\nmaking function, evaluator, and components making calls to Open Match.\r\nOptional, depending on the requirements of the connected systems."
|
||||
"description": "Customized information not inspected by Open Match, to be used by the match\nmaking function, evaluator, and components making calls to Open Match.\nOptional, depending on the requirements of the connected systems."
|
||||
},
|
||||
"create_time": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "Create time is the time the Ticket was created. It is populated by Open\nMatch at the time of Ticket creation."
|
||||
}
|
||||
},
|
||||
"description": "A Ticket is a basic matchmaking entity in Open Match. A Ticket represents either an\r\nindividual 'Player' or a 'Group' of players. Open Match will not interpret\r\nwhat the Ticket represents but just treat it as a matchmaking unit with a set\r\nof SearchFields. Open Match stores the Ticket in state storage and enables an\r\nAssignment to be associated with this Ticket."
|
||||
"description": "A Ticket is a basic matchmaking entity in Open Match. A Ticket may represent\nan individual 'Player', a 'Group' of players, or any other concepts unique to\nyour use case. Open Match will not interpret what the Ticket represents but\njust treat it as a matchmaking unit with a set of SearchFields. Open Match\nstores the Ticket in state storage and enables an Assignment to be set on the\nTicket."
|
||||
},
|
||||
"protobufAny": {
|
||||
"type": "object",
|
||||
@ -455,69 +609,27 @@
|
||||
},
|
||||
"description": "`Any` contains an arbitrary serialized protocol buffer message along with a\nURL that describes the type of the serialized message.\n\nProtobuf library provides support to pack/unpack Any values in the form\nof utility functions or additional generated methods of the Any type.\n\nExample 1: Pack and unpack a message in C++.\n\n Foo foo = ...;\n Any any;\n any.PackFrom(foo);\n ...\n if (any.UnpackTo(\u0026foo)) {\n ...\n }\n\nExample 2: Pack and unpack a message in Java.\n\n Foo foo = ...;\n Any any = Any.pack(foo);\n ...\n if (any.is(Foo.class)) {\n foo = any.unpack(Foo.class);\n }\n\n Example 3: Pack and unpack a message in Python.\n\n foo = Foo(...)\n any = Any()\n any.Pack(foo)\n ...\n if any.Is(Foo.DESCRIPTOR):\n any.Unpack(foo)\n ...\n\n Example 4: Pack and unpack a message in Go\n\n foo := \u0026pb.Foo{...}\n any, err := ptypes.MarshalAny(foo)\n ...\n foo := \u0026pb.Foo{}\n if err := ptypes.UnmarshalAny(any, foo); err != nil {\n ...\n }\n\nThe pack methods provided by protobuf library will by default use\n'type.googleapis.com/full.type.name' as the type URL and the unpack\nmethods only use the fully qualified type name after the last '/'\nin the type URL, for example \"foo.bar.com/x/y.z\" will yield type\nname \"y.z\".\n\n\nJSON\n====\nThe JSON representation of an `Any` value uses the regular\nrepresentation of the deserialized, embedded message, with an\nadditional field `@type` which contains the type URL. Example:\n\n package google.profile;\n message Person {\n string first_name = 1;\n string last_name = 2;\n }\n\n {\n \"@type\": \"type.googleapis.com/google.profile.Person\",\n \"firstName\": \u003cstring\u003e,\n \"lastName\": \u003cstring\u003e\n }\n\nIf the embedded message type is well-known and has a custom JSON\nrepresentation, that representation will be embedded adding a field\n`value` which holds the custom JSON in addition to the `@type`\nfield. Example (for message [google.protobuf.Duration][]):\n\n {\n \"@type\": \"type.googleapis.com/google.protobuf.Duration\",\n \"value\": \"1.212s\"\n }"
|
||||
},
|
||||
<<<<<<< HEAD
|
||||
"rpcStatus": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"code": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"description": "The status code, which should be an enum value of\r\n[google.rpc.Code][google.rpc.Code]."
|
||||
"description": "The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code]."
|
||||
},
|
||||
"message": {
|
||||
"type": "string",
|
||||
"description": "A developer-facing error message, which should be in English. Any\r\nuser-facing error message should be localized and sent in the\r\n[google.rpc.Status.details][google.rpc.Status.details] field, or localized\r\nby the client."
|
||||
"description": "A developer-facing error message, which should be in English. Any\nuser-facing error message should be localized and sent in the\n[google.rpc.Status.details][google.rpc.Status.details] field, or localized by the client."
|
||||
},
|
||||
"details": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/protobufAny"
|
||||
},
|
||||
"description": "A list of messages that carry the error details. There is a common set of\r\nmessage types for APIs to use."
|
||||
"description": "A list of messages that carry the error details. There is a common set of\nmessage types for APIs to use."
|
||||
}
|
||||
},
|
||||
"description": "The `Status` type defines a logical error model that is suitable for\r\ndifferent programming environments, including REST APIs and RPC APIs. It is\r\nused by [gRPC](https://github.com/grpc). The error model is designed to be:\r\n\r\n- Simple to use and understand for most users\r\n- Flexible enough to meet unexpected needs\r\n\r\n# Overview\r\n\r\nThe `Status` message contains three pieces of data: error code, error\r\nmessage, and error details. The error code should be an enum value of\r\n[google.rpc.Code][google.rpc.Code], but it may accept additional error codes\r\nif needed. The error message should be a developer-facing English message\r\nthat helps developers *understand* and *resolve* the error. If a localized\r\nuser-facing error message is needed, put the localized message in the error\r\ndetails or localize it in the client. The optional error details may contain\r\narbitrary information about the error. There is a predefined set of error\r\ndetail types in the package `google.rpc` that can be used for common error\r\nconditions.\r\n\r\n# Language mapping\r\n\r\nThe `Status` message is the logical representation of the error model, but it\r\nis not necessarily the actual wire format. When the `Status` message is\r\nexposed in different client libraries and different wire protocols, it can be\r\nmapped differently. For example, it will likely be mapped to some exceptions\r\nin Java, but more likely mapped to some error codes in C.\r\n\r\n# Other uses\r\n\r\nThe error model and the `Status` message can be used in a variety of\r\nenvironments, either with or without APIs, to provide a\r\nconsistent developer experience across different environments.\r\n\r\nExample uses of this error model include:\r\n\r\n- Partial errors. If a service needs to return partial errors to the client,\r\n it may embed the `Status` in the normal response to indicate the partial\r\n errors.\r\n\r\n- Workflow errors. A typical workflow has multiple steps. Each step may\r\n have a `Status` message for error reporting.\r\n\r\n- Batch operations. If a client uses batch request and batch response, the\r\n `Status` message should be used directly inside batch response, one for\r\n each error sub-response.\r\n\r\n- Asynchronous operations. If an API call embeds asynchronous operation\r\n results in its response, the status of those operations should be\r\n represented directly using the `Status` message.\r\n\r\n- Logging. If some API errors are stored in logs, the message `Status` could\r\n be used directly after any stripping needed for security/privacy reasons."
|
||||
},
|
||||
=======
|
||||
>>>>>>> cf8d49052c148a3179904700e12cc8115a47af4e
|
||||
"runtimeStreamError": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"grpc_code": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"http_code": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"message": {
|
||||
"type": "string"
|
||||
},
|
||||
"http_status": {
|
||||
"type": "string"
|
||||
},
|
||||
"details": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/protobufAny"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-stream-definitions": {
|
||||
"openmatchFetchMatchesResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"result": {
|
||||
"$ref": "#/definitions/openmatchFetchMatchesResponse"
|
||||
},
|
||||
"error": {
|
||||
"$ref": "#/definitions/runtimeStreamError"
|
||||
}
|
||||
},
|
||||
"title": "Stream result of openmatchFetchMatchesResponse"
|
||||
"description": "The `Status` type defines a logical error model that is suitable for\ndifferent programming environments, including REST APIs and RPC APIs. It is\nused by [gRPC](https://github.com/grpc). Each `Status` message contains\nthree pieces of data: error code, error message, and error details.\n\nYou can find out more about this error model and how to work with it in the\n[API Design Guide](https://cloud.google.com/apis/design/errors)."
|
||||
}
|
||||
},
|
||||
"externalDocs": {
|
||||
|
@ -19,9 +19,9 @@ option csharp_namespace = "OpenMatch";
|
||||
|
||||
import "api/messages.proto";
|
||||
import "google/api/annotations.proto";
|
||||
import "protoc-gen-swagger/options/annotations.proto";
|
||||
import "protoc-gen-openapiv2/options/annotations.proto";
|
||||
|
||||
option (grpc.gateway.protoc_gen_swagger.options.openapiv2_swagger) = {
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
|
||||
info: {
|
||||
title: "Evaluator"
|
||||
version: "1.0"
|
||||
@ -52,7 +52,7 @@ option (grpc.gateway.protoc_gen_swagger.options.openapiv2_swagger) = {
|
||||
}
|
||||
// TODO Add annotations for security_defintiions.
|
||||
// See
|
||||
// https://github.com/grpc-ecosystem/grpc-gateway/blob/master/examples/proto/examplepb/a_bit_of_everything.proto
|
||||
// https://github.com/grpc-ecosystem/grpc-gateway/blob/master/examples/internal/proto/examplepb/a_bit_of_everything.proto
|
||||
};
|
||||
|
||||
message EvaluateRequest {
|
||||
|
@ -13,6 +13,11 @@
|
||||
"url": "https://github.com/googleforgames/open-match/blob/master/LICENSE"
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
{
|
||||
"name": "Evaluator"
|
||||
}
|
||||
],
|
||||
"schemes": [
|
||||
"http",
|
||||
"https"
|
||||
@ -27,12 +32,21 @@
|
||||
"/v1/evaluator/matches:evaluate": {
|
||||
"post": {
|
||||
"summary": "Evaluate evaluates a list of proposed matches based on quality, collision status, and etc, then shortlist the matches and returns the final results.",
|
||||
"operationId": "Evaluate",
|
||||
"operationId": "Evaluator_Evaluate",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.(streaming responses)",
|
||||
"schema": {
|
||||
"$ref": "#/x-stream-definitions/openmatchEvaluateResponse"
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"result": {
|
||||
"$ref": "#/definitions/openmatchEvaluateResponse"
|
||||
},
|
||||
"error": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
},
|
||||
"title": "Stream result of openmatchEvaluateResponse"
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
@ -41,6 +55,12 @@
|
||||
"type": "string",
|
||||
"format": "string"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
@ -76,7 +96,38 @@
|
||||
"description": "Customized information not inspected by Open Match, to be used by the match\nmaking function, evaluator, and components making calls to Open Match.\nOptional, depending on the requirements of the connected systems."
|
||||
}
|
||||
},
|
||||
"description": "An Assignment represents a game server assignment associated with a Ticket. Open\nmatch does not require or inspect any fields on assignment."
|
||||
"description": "An Assignment represents a game server assignment associated with a Ticket.\nOpen Match does not require or inspect any fields on assignment."
|
||||
},
|
||||
"openmatchBackfill": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "Id represents an auto-generated Id issued by Open Match."
|
||||
},
|
||||
"search_fields": {
|
||||
"$ref": "#/definitions/openmatchSearchFields",
|
||||
"description": "Search fields are the fields which Open Match is aware of, and can be used\nwhen specifying filters."
|
||||
},
|
||||
"extensions": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/protobufAny"
|
||||
},
|
||||
"description": "Customized information not inspected by Open Match, to be used by\nthe Match Function, evaluator, and components making calls to Open Match.\nOptional, depending on the requirements of the connected systems."
|
||||
},
|
||||
"create_time": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "Create time is the time the Ticket was created. It is populated by Open\nMatch at the time of Ticket creation."
|
||||
},
|
||||
"generation": {
|
||||
"type": "string",
|
||||
"format": "int64",
|
||||
"description": "Generation gets incremented on GameServers update operations.\nPrevents the MMF from overriding a newer version from the game server.\nDo NOT read or write to this field, it is for internal tracking, and changing the value will cause bugs."
|
||||
}
|
||||
},
|
||||
"description": "Represents a backfill entity which is used to fill partially full matches.\n\nBETA FEATURE WARNING: This call and the associated Request and Response\nmessages are not finalized and still subject to possible change or removal."
|
||||
},
|
||||
"openmatchEvaluateRequest": {
|
||||
"type": "object",
|
||||
@ -124,6 +175,14 @@
|
||||
"$ref": "#/definitions/protobufAny"
|
||||
},
|
||||
"description": "Customized information not inspected by Open Match, to be used by the match\nmaking function, evaluator, and components making calls to Open Match.\nOptional, depending on the requirements of the connected systems."
|
||||
},
|
||||
"backfill": {
|
||||
"$ref": "#/definitions/openmatchBackfill",
|
||||
"description": "Backfill request which contains additional information to the match\nand contains an association to a GameServer.\nBETA FEATURE WARNING: This field is not finalized and still subject\nto possible change or removal."
|
||||
},
|
||||
"allocate_gameserver": {
|
||||
"type": "boolean",
|
||||
"description": "AllocateGameServer signalise Director that Backfill is new and it should \nallocate a GameServer, this Backfill would be assigned.\nBETA FEATURE WARNING: This field is not finalized and still subject\nto possible change or removal."
|
||||
}
|
||||
},
|
||||
"description": "A Match is used to represent a completed match object. It can be generated by\na MatchFunction as a proposal or can be returned by OpenMatch as a result in\nresponse to the FetchMatches call.\nWhen a match is returned by the FetchMatches call, it should contain at least\none ticket to be considered as valid."
|
||||
@ -165,7 +224,7 @@
|
||||
},
|
||||
"assignment": {
|
||||
"$ref": "#/definitions/openmatchAssignment",
|
||||
"description": "An Assignment represents a game server assignment associated with a Ticket.\nOpen Match does not require or inspect any fields on Assignment."
|
||||
"description": "An Assignment represents a game server assignment associated with a Ticket,\nor whatever finalized matched state means for your use case.\nOpen Match does not require or inspect any fields on Assignment."
|
||||
},
|
||||
"search_fields": {
|
||||
"$ref": "#/definitions/openmatchSearchFields",
|
||||
@ -177,9 +236,14 @@
|
||||
"$ref": "#/definitions/protobufAny"
|
||||
},
|
||||
"description": "Customized information not inspected by Open Match, to be used by the match\nmaking function, evaluator, and components making calls to Open Match.\nOptional, depending on the requirements of the connected systems."
|
||||
},
|
||||
"create_time": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "Create time is the time the Ticket was created. It is populated by Open\nMatch at the time of Ticket creation."
|
||||
}
|
||||
},
|
||||
"description": "A Ticket is a basic matchmaking entity in Open Match. A Ticket represents either an\nindividual 'Player' or a 'Group' of players. Open Match will not interpret\nwhat the Ticket represents but just treat it as a matchmaking unit with a set\nof SearchFields. Open Match stores the Ticket in state storage and enables an\nAssignment to be associated with this Ticket."
|
||||
"description": "A Ticket is a basic matchmaking entity in Open Match. A Ticket may represent\nan individual 'Player', a 'Group' of players, or any other concepts unique to\nyour use case. Open Match will not interpret what the Ticket represents but\njust treat it as a matchmaking unit with a set of SearchFields. Open Match\nstores the Ticket in state storage and enables an Assignment to be set on the\nTicket."
|
||||
},
|
||||
"protobufAny": {
|
||||
"type": "object",
|
||||
@ -196,44 +260,27 @@
|
||||
},
|
||||
"description": "`Any` contains an arbitrary serialized protocol buffer message along with a\nURL that describes the type of the serialized message.\n\nProtobuf library provides support to pack/unpack Any values in the form\nof utility functions or additional generated methods of the Any type.\n\nExample 1: Pack and unpack a message in C++.\n\n Foo foo = ...;\n Any any;\n any.PackFrom(foo);\n ...\n if (any.UnpackTo(\u0026foo)) {\n ...\n }\n\nExample 2: Pack and unpack a message in Java.\n\n Foo foo = ...;\n Any any = Any.pack(foo);\n ...\n if (any.is(Foo.class)) {\n foo = any.unpack(Foo.class);\n }\n\n Example 3: Pack and unpack a message in Python.\n\n foo = Foo(...)\n any = Any()\n any.Pack(foo)\n ...\n if any.Is(Foo.DESCRIPTOR):\n any.Unpack(foo)\n ...\n\n Example 4: Pack and unpack a message in Go\n\n foo := \u0026pb.Foo{...}\n any, err := ptypes.MarshalAny(foo)\n ...\n foo := \u0026pb.Foo{}\n if err := ptypes.UnmarshalAny(any, foo); err != nil {\n ...\n }\n\nThe pack methods provided by protobuf library will by default use\n'type.googleapis.com/full.type.name' as the type URL and the unpack\nmethods only use the fully qualified type name after the last '/'\nin the type URL, for example \"foo.bar.com/x/y.z\" will yield type\nname \"y.z\".\n\n\nJSON\n====\nThe JSON representation of an `Any` value uses the regular\nrepresentation of the deserialized, embedded message, with an\nadditional field `@type` which contains the type URL. Example:\n\n package google.profile;\n message Person {\n string first_name = 1;\n string last_name = 2;\n }\n\n {\n \"@type\": \"type.googleapis.com/google.profile.Person\",\n \"firstName\": \u003cstring\u003e,\n \"lastName\": \u003cstring\u003e\n }\n\nIf the embedded message type is well-known and has a custom JSON\nrepresentation, that representation will be embedded adding a field\n`value` which holds the custom JSON in addition to the `@type`\nfield. Example (for message [google.protobuf.Duration][]):\n\n {\n \"@type\": \"type.googleapis.com/google.protobuf.Duration\",\n \"value\": \"1.212s\"\n }"
|
||||
},
|
||||
"runtimeStreamError": {
|
||||
"rpcStatus": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"grpc_code": {
|
||||
"code": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"http_code": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
"format": "int32",
|
||||
"description": "The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code]."
|
||||
},
|
||||
"message": {
|
||||
"type": "string"
|
||||
},
|
||||
"http_status": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"description": "A developer-facing error message, which should be in English. Any\nuser-facing error message should be localized and sent in the\n[google.rpc.Status.details][google.rpc.Status.details] field, or localized by the client."
|
||||
},
|
||||
"details": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/protobufAny"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-stream-definitions": {
|
||||
"openmatchEvaluateResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"result": {
|
||||
"$ref": "#/definitions/openmatchEvaluateResponse"
|
||||
},
|
||||
"error": {
|
||||
"$ref": "#/definitions/runtimeStreamError"
|
||||
},
|
||||
"description": "A list of messages that carry the error details. There is a common set of\nmessage types for APIs to use."
|
||||
}
|
||||
},
|
||||
"title": "Stream result of openmatchEvaluateResponse"
|
||||
"description": "The `Status` type defines a logical error model that is suitable for\ndifferent programming environments, including REST APIs and RPC APIs. It is\nused by [gRPC](https://github.com/grpc). Each `Status` message contains\nthree pieces of data: error code, error message, and error details.\n\nYou can find out more about this error model and how to work with it in the\n[API Design Guide](https://cloud.google.com/apis/design/errors)."
|
||||
}
|
||||
},
|
||||
"externalDocs": {
|
||||
|
@ -19,9 +19,10 @@ option csharp_namespace = "OpenMatch";
|
||||
|
||||
import "api/messages.proto";
|
||||
import "google/api/annotations.proto";
|
||||
import "protoc-gen-swagger/options/annotations.proto";
|
||||
import "protoc-gen-openapiv2/options/annotations.proto";
|
||||
import "google/protobuf/empty.proto";
|
||||
|
||||
option (grpc.gateway.protoc_gen_swagger.options.openapiv2_swagger) = {
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
|
||||
info: {
|
||||
title: "Frontend"
|
||||
version: "1.0"
|
||||
@ -52,7 +53,7 @@ option (grpc.gateway.protoc_gen_swagger.options.openapiv2_swagger) = {
|
||||
}
|
||||
// TODO Add annotations for security_defintiions.
|
||||
// See
|
||||
// https://github.com/grpc-ecosystem/grpc-gateway/blob/master/examples/proto/examplepb/a_bit_of_everything.proto
|
||||
// https://github.com/grpc-ecosystem/grpc-gateway/blob/master/examples/internal/proto/examplepb/a_bit_of_everything.proto
|
||||
};
|
||||
|
||||
message CreateTicketRequest {
|
||||
@ -60,40 +61,84 @@ message CreateTicketRequest {
|
||||
Ticket ticket = 1;
|
||||
}
|
||||
|
||||
message CreateTicketResponse {
|
||||
// A Ticket object with TicketId generated.
|
||||
Ticket ticket = 1;
|
||||
}
|
||||
|
||||
message DeleteTicketRequest {
|
||||
// A TicketId of a generated Ticket to be deleted.
|
||||
string ticket_id = 1;
|
||||
}
|
||||
|
||||
message DeleteTicketResponse {}
|
||||
|
||||
message GetTicketRequest {
|
||||
// A TicketId of a generated Ticket.
|
||||
string ticket_id = 1;
|
||||
}
|
||||
|
||||
message GetAssignmentsRequest {
|
||||
message WatchAssignmentsRequest {
|
||||
// A TicketId of a generated Ticket to get updates on.
|
||||
string ticket_id = 1;
|
||||
}
|
||||
|
||||
message GetAssignmentsResponse {
|
||||
message WatchAssignmentsResponse {
|
||||
// An updated Assignment of the requested Ticket.
|
||||
Assignment assignment = 1;
|
||||
}
|
||||
|
||||
// BETA FEATURE WARNING: This Request message is not finalized and still subject
|
||||
// to possible change or removal.
|
||||
message AcknowledgeBackfillRequest {
|
||||
// An existing ID of Backfill to acknowledge.
|
||||
string backfill_id = 1;
|
||||
|
||||
// An updated Assignment of the requested Backfill.
|
||||
Assignment assignment = 2;
|
||||
}
|
||||
|
||||
// BETA FEATURE WARNING: This Request message is not finalized and still subject
|
||||
// to possible change or removal.
|
||||
message AcknowledgeBackfillResponse {
|
||||
// The Backfill that was acknowledged.
|
||||
Backfill backfill = 1;
|
||||
|
||||
// All of the Tickets that were successfully assigned
|
||||
repeated Ticket tickets = 2;
|
||||
}
|
||||
|
||||
// BETA FEATURE WARNING: This Request message is not finalized and still subject
|
||||
// to possible change or removal.
|
||||
message CreateBackfillRequest {
|
||||
// An empty Backfill object.
|
||||
Backfill backfill = 1;
|
||||
}
|
||||
|
||||
// BETA FEATURE WARNING: This Request message is not finalized and still subject
|
||||
// to possible change or removal.
|
||||
message DeleteBackfillRequest {
|
||||
// An existing ID of Backfill to delete.
|
||||
string backfill_id = 1;
|
||||
}
|
||||
|
||||
// BETA FEATURE WARNING: This Request message is not finalized and still subject
|
||||
// to possible change or removal.
|
||||
message GetBackfillRequest {
|
||||
// An existing ID of Backfill to retrieve.
|
||||
string backfill_id = 1;
|
||||
}
|
||||
|
||||
// UpdateBackfillRequest - update searchFields, extensions and set assignment.
|
||||
//
|
||||
// BETA FEATURE WARNING: This Request message is not finalized and still subject
|
||||
// to possible change or removal.
|
||||
message UpdateBackfillRequest {
|
||||
// A Backfill object with ID set and fields to update.
|
||||
Backfill backfill = 1;
|
||||
}
|
||||
|
||||
|
||||
// The FrontendService implements APIs to manage and query status of a Tickets.
|
||||
service FrontendService {
|
||||
// CreateTicket assigns an unique TicketId to the input Ticket and record it in state storage.
|
||||
// A ticket is considered as ready for matchmaking once it is created.
|
||||
// - If a TicketId exists in a Ticket request, an auto-generated TicketId will override this field.
|
||||
// - If SearchFields exist in a Ticket, CreateTicket will also index these fields such that one can query the ticket with query.QueryTickets function.
|
||||
rpc CreateTicket(CreateTicketRequest) returns (CreateTicketResponse) {
|
||||
rpc CreateTicket(CreateTicketRequest) returns (Ticket) {
|
||||
option (google.api.http) = {
|
||||
post: "/v1/frontendservice/tickets"
|
||||
body: "*"
|
||||
@ -101,10 +146,8 @@ service FrontendService {
|
||||
}
|
||||
|
||||
// DeleteTicket immediately stops Open Match from using the Ticket for matchmaking and removes the Ticket from state storage.
|
||||
// The client must delete the Ticket when finished matchmaking with it.
|
||||
// - If SearchFields exist in a Ticket, DeleteTicket will deindex the fields lazily.
|
||||
// Users may still be able to assign/get a ticket after calling DeleteTicket on it.
|
||||
rpc DeleteTicket(DeleteTicketRequest) returns (DeleteTicketResponse) {
|
||||
// The client should delete the Ticket when finished matchmaking with it.
|
||||
rpc DeleteTicket(DeleteTicketRequest) returns (google.protobuf.Empty) {
|
||||
option (google.api.http) = {
|
||||
delete: "/v1/frontendservice/tickets/{ticket_id}"
|
||||
};
|
||||
@ -117,12 +160,63 @@ service FrontendService {
|
||||
};
|
||||
}
|
||||
|
||||
// GetAssignments stream back Assignment of the specified TicketId if it is updated.
|
||||
// WatchAssignments stream back Assignment of the specified TicketId if it is updated.
|
||||
// - If the Assignment is not updated, GetAssignment will retry using the configured backoff strategy.
|
||||
rpc GetAssignments(GetAssignmentsRequest)
|
||||
returns (stream GetAssignmentsResponse) {
|
||||
rpc WatchAssignments(WatchAssignmentsRequest)
|
||||
returns (stream WatchAssignmentsResponse) {
|
||||
option (google.api.http) = {
|
||||
get: "/v1/frontendservice/tickets/{ticket_id}/assignments"
|
||||
};
|
||||
}
|
||||
|
||||
// AcknowledgeBackfill is used to notify OpenMatch about GameServer connection info
|
||||
// This triggers an assignment process.
|
||||
// BETA FEATURE WARNING: This call and the associated Request and Response
|
||||
// messages are not finalized and still subject to possible change or removal.
|
||||
rpc AcknowledgeBackfill(AcknowledgeBackfillRequest) returns (AcknowledgeBackfillResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/v1/frontendservice/backfills/{backfill_id}/acknowledge"
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
|
||||
// CreateBackfill creates a new Backfill object.
|
||||
// BETA FEATURE WARNING: This call and the associated Request and Response
|
||||
// messages are not finalized and still subject to possible change or removal.
|
||||
rpc CreateBackfill(CreateBackfillRequest) returns (Backfill) {
|
||||
option (google.api.http) = {
|
||||
post: "/v1/frontendservice/backfills"
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
|
||||
// DeleteBackfill receives a backfill ID and deletes its resource.
|
||||
// Any tickets waiting for this backfill will be returned to the active pool, no longer pending.
|
||||
// BETA FEATURE WARNING: This call and the associated Request and Response
|
||||
// messages are not finalized and still subject to possible change or removal.
|
||||
rpc DeleteBackfill(DeleteBackfillRequest) returns (google.protobuf.Empty) {
|
||||
option (google.api.http) = {
|
||||
delete: "/v1/frontendservice/backfills/{backfill_id}"
|
||||
};
|
||||
}
|
||||
|
||||
// GetBackfill returns a backfill object by its ID.
|
||||
// BETA FEATURE WARNING: This call and the associated Request and Response
|
||||
// messages are not finalized and still subject to possible change or removal.
|
||||
rpc GetBackfill(GetBackfillRequest) returns (Backfill) {
|
||||
option (google.api.http) = {
|
||||
get: "/v1/frontendservice/backfills/{backfill_id}"
|
||||
};
|
||||
}
|
||||
|
||||
// UpdateBackfill updates search_fields and extensions for the backfill with the provided id.
|
||||
// Any tickets waiting for this backfill will be returned to the active pool, no longer pending.
|
||||
// BETA FEATURE WARNING: This call and the associated Request and Response
|
||||
// messages are not finalized and still subject to possible change or removal.
|
||||
rpc UpdateBackfill(UpdateBackfillRequest) returns (Backfill) {
|
||||
option (google.api.http) = {
|
||||
patch: "/v1/frontendservice/backfills"
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,11 @@
|
||||
"url": "https://github.com/googleforgames/open-match/blob/master/LICENSE"
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
{
|
||||
"name": "FrontendService"
|
||||
}
|
||||
],
|
||||
"schemes": [
|
||||
"http",
|
||||
"https"
|
||||
@ -24,15 +29,15 @@
|
||||
"application/json"
|
||||
],
|
||||
"paths": {
|
||||
"/v1/frontendservice/tickets": {
|
||||
"/v1/frontendservice/backfills": {
|
||||
"post": {
|
||||
"summary": "CreateTicket assigns an unique TicketId to the input Ticket and record it in state storage.\nA ticket is considered as ready for matchmaking once it is created.\n - If a TicketId exists in a Ticket request, an auto-generated TicketId will override this field.\n - If SearchFields exist in a Ticket, CreateTicket will also index these fields such that one can query the ticket with query.QueryTickets function.",
|
||||
"operationId": "CreateTicket",
|
||||
"summary": "CreateBackfill creates a new Backfill object.\nBETA FEATURE WARNING: This call and the associated Request and Response\nmessages are not finalized and still subject to possible change or removal.",
|
||||
"operationId": "FrontendService_CreateBackfill",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/openmatchCreateTicketResponse"
|
||||
"$ref": "#/definitions/openmatchBackfill"
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
@ -41,6 +46,213 @@
|
||||
"type": "string",
|
||||
"format": "string"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/openmatchCreateBackfillRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"FrontendService"
|
||||
]
|
||||
},
|
||||
"patch": {
|
||||
"summary": "UpdateBackfill updates search_fields and extensions for the backfill with the provided id.\nAny tickets waiting for this backfill will be returned to the active pool, no longer pending.\nBETA FEATURE WARNING: This call and the associated Request and Response\nmessages are not finalized and still subject to possible change or removal.",
|
||||
"operationId": "FrontendService_UpdateBackfill",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/openmatchBackfill"
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Returned when the resource does not exist.",
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"format": "string"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/openmatchUpdateBackfillRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"FrontendService"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/v1/frontendservice/backfills/{backfill_id}": {
|
||||
"get": {
|
||||
"summary": "GetBackfill returns a backfill object by its ID.\nBETA FEATURE WARNING: This call and the associated Request and Response\nmessages are not finalized and still subject to possible change or removal.",
|
||||
"operationId": "FrontendService_GetBackfill",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/openmatchBackfill"
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Returned when the resource does not exist.",
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"format": "string"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "backfill_id",
|
||||
"description": "An existing ID of Backfill to retrieve.",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"FrontendService"
|
||||
]
|
||||
},
|
||||
"delete": {
|
||||
"summary": "DeleteBackfill receives a backfill ID and deletes its resource.\nAny tickets waiting for this backfill will be returned to the active pool, no longer pending.\nBETA FEATURE WARNING: This call and the associated Request and Response\nmessages are not finalized and still subject to possible change or removal.",
|
||||
"operationId": "FrontendService_DeleteBackfill",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"properties": {}
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Returned when the resource does not exist.",
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"format": "string"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "backfill_id",
|
||||
"description": "An existing ID of Backfill to delete.",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"FrontendService"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/v1/frontendservice/backfills/{backfill_id}/acknowledge": {
|
||||
"post": {
|
||||
"summary": "AcknowledgeBackfill is used to notify OpenMatch about GameServer connection info\nThis triggers an assignment process.\nBETA FEATURE WARNING: This call and the associated Request and Response\nmessages are not finalized and still subject to possible change or removal.",
|
||||
"operationId": "FrontendService_AcknowledgeBackfill",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/openmatchAcknowledgeBackfillResponse"
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Returned when the resource does not exist.",
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"format": "string"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "backfill_id",
|
||||
"description": "An existing ID of Backfill to acknowledge.",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/openmatchAcknowledgeBackfillRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"FrontendService"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/v1/frontendservice/tickets": {
|
||||
"post": {
|
||||
"summary": "CreateTicket assigns an unique TicketId to the input Ticket and record it in state storage.\nA ticket is considered as ready for matchmaking once it is created.\n - If a TicketId exists in a Ticket request, an auto-generated TicketId will override this field.\n - If SearchFields exist in a Ticket, CreateTicket will also index these fields such that one can query the ticket with query.QueryTickets function.",
|
||||
"operationId": "FrontendService_CreateTicket",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/openmatchTicket"
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Returned when the resource does not exist.",
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"format": "string"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
@ -61,7 +273,7 @@
|
||||
"/v1/frontendservice/tickets/{ticket_id}": {
|
||||
"get": {
|
||||
"summary": "GetTicket get the Ticket associated with the specified TicketId.",
|
||||
"operationId": "GetTicket",
|
||||
"operationId": "FrontendService_GetTicket",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
@ -75,6 +287,12 @@
|
||||
"type": "string",
|
||||
"format": "string"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
@ -91,13 +309,13 @@
|
||||
]
|
||||
},
|
||||
"delete": {
|
||||
"summary": "DeleteTicket immediately stops Open Match from using the Ticket for matchmaking and removes the Ticket from state storage.\nThe client must delete the Ticket when finished matchmaking with it. \n - If SearchFields exist in a Ticket, DeleteTicket will deindex the fields lazily.\nUsers may still be able to assign/get a ticket after calling DeleteTicket on it.",
|
||||
"operationId": "DeleteTicket",
|
||||
"summary": "DeleteTicket immediately stops Open Match from using the Ticket for matchmaking and removes the Ticket from state storage.\nThe client should delete the Ticket when finished matchmaking with it.",
|
||||
"operationId": "FrontendService_DeleteTicket",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/openmatchDeleteTicketResponse"
|
||||
"properties": {}
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
@ -106,6 +324,12 @@
|
||||
"type": "string",
|
||||
"format": "string"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
@ -124,13 +348,22 @@
|
||||
},
|
||||
"/v1/frontendservice/tickets/{ticket_id}/assignments": {
|
||||
"get": {
|
||||
"summary": "GetAssignments stream back Assignment of the specified TicketId if it is updated.\n - If the Assignment is not updated, GetAssignment will retry using the configured backoff strategy.",
|
||||
"operationId": "GetAssignments",
|
||||
"summary": "WatchAssignments stream back Assignment of the specified TicketId if it is updated.\n - If the Assignment is not updated, GetAssignment will retry using the configured backoff strategy.",
|
||||
"operationId": "FrontendService_WatchAssignments",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.(streaming responses)",
|
||||
"schema": {
|
||||
"$ref": "#/x-stream-definitions/openmatchGetAssignmentsResponse"
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"result": {
|
||||
"$ref": "#/definitions/openmatchWatchAssignmentsResponse"
|
||||
},
|
||||
"error": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
},
|
||||
"title": "Stream result of openmatchWatchAssignmentsResponse"
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
@ -139,6 +372,12 @@
|
||||
"type": "string",
|
||||
"format": "string"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
@ -157,6 +396,37 @@
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"openmatchAcknowledgeBackfillRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"backfill_id": {
|
||||
"type": "string",
|
||||
"description": "An existing ID of Backfill to acknowledge."
|
||||
},
|
||||
"assignment": {
|
||||
"$ref": "#/definitions/openmatchAssignment",
|
||||
"description": "An updated Assignment of the requested Backfill."
|
||||
}
|
||||
},
|
||||
"description": "BETA FEATURE WARNING: This Request message is not finalized and still subject\nto possible change or removal."
|
||||
},
|
||||
"openmatchAcknowledgeBackfillResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"backfill": {
|
||||
"$ref": "#/definitions/openmatchBackfill",
|
||||
"description": "The Backfill that was acknowledged."
|
||||
},
|
||||
"tickets": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/openmatchTicket"
|
||||
},
|
||||
"title": "All of the Tickets that were successfully assigned"
|
||||
}
|
||||
},
|
||||
"description": "BETA FEATURE WARNING: This Request message is not finalized and still subject\nto possible change or removal."
|
||||
},
|
||||
"openmatchAssignment": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@ -172,7 +442,48 @@
|
||||
"description": "Customized information not inspected by Open Match, to be used by the match\nmaking function, evaluator, and components making calls to Open Match.\nOptional, depending on the requirements of the connected systems."
|
||||
}
|
||||
},
|
||||
"description": "An Assignment represents a game server assignment associated with a Ticket. Open\nmatch does not require or inspect any fields on assignment."
|
||||
"description": "An Assignment represents a game server assignment associated with a Ticket.\nOpen Match does not require or inspect any fields on assignment."
|
||||
},
|
||||
"openmatchBackfill": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "Id represents an auto-generated Id issued by Open Match."
|
||||
},
|
||||
"search_fields": {
|
||||
"$ref": "#/definitions/openmatchSearchFields",
|
||||
"description": "Search fields are the fields which Open Match is aware of, and can be used\nwhen specifying filters."
|
||||
},
|
||||
"extensions": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/protobufAny"
|
||||
},
|
||||
"description": "Customized information not inspected by Open Match, to be used by\nthe Match Function, evaluator, and components making calls to Open Match.\nOptional, depending on the requirements of the connected systems."
|
||||
},
|
||||
"create_time": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "Create time is the time the Ticket was created. It is populated by Open\nMatch at the time of Ticket creation."
|
||||
},
|
||||
"generation": {
|
||||
"type": "string",
|
||||
"format": "int64",
|
||||
"description": "Generation gets incremented on GameServers update operations.\nPrevents the MMF from overriding a newer version from the game server.\nDo NOT read or write to this field, it is for internal tracking, and changing the value will cause bugs."
|
||||
}
|
||||
},
|
||||
"description": "Represents a backfill entity which is used to fill partially full matches.\n\nBETA FEATURE WARNING: This call and the associated Request and Response\nmessages are not finalized and still subject to possible change or removal."
|
||||
},
|
||||
"openmatchCreateBackfillRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"backfill": {
|
||||
"$ref": "#/definitions/openmatchBackfill",
|
||||
"description": "An empty Backfill object."
|
||||
}
|
||||
},
|
||||
"description": "BETA FEATURE WARNING: This Request message is not finalized and still subject\nto possible change or removal."
|
||||
},
|
||||
"openmatchCreateTicketRequest": {
|
||||
"type": "object",
|
||||
@ -183,27 +494,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"openmatchCreateTicketResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"ticket": {
|
||||
"$ref": "#/definitions/openmatchTicket",
|
||||
"description": "A Ticket object with TicketId generated."
|
||||
}
|
||||
}
|
||||
},
|
||||
"openmatchDeleteTicketResponse": {
|
||||
"type": "object"
|
||||
},
|
||||
"openmatchGetAssignmentsResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"assignment": {
|
||||
"$ref": "#/definitions/openmatchAssignment",
|
||||
"description": "An updated Assignment of the requested Ticket."
|
||||
}
|
||||
}
|
||||
},
|
||||
"openmatchSearchFields": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@ -241,7 +531,7 @@
|
||||
},
|
||||
"assignment": {
|
||||
"$ref": "#/definitions/openmatchAssignment",
|
||||
"description": "An Assignment represents a game server assignment associated with a Ticket.\nOpen Match does not require or inspect any fields on Assignment."
|
||||
"description": "An Assignment represents a game server assignment associated with a Ticket,\nor whatever finalized matched state means for your use case.\nOpen Match does not require or inspect any fields on Assignment."
|
||||
},
|
||||
"search_fields": {
|
||||
"$ref": "#/definitions/openmatchSearchFields",
|
||||
@ -253,9 +543,33 @@
|
||||
"$ref": "#/definitions/protobufAny"
|
||||
},
|
||||
"description": "Customized information not inspected by Open Match, to be used by the match\nmaking function, evaluator, and components making calls to Open Match.\nOptional, depending on the requirements of the connected systems."
|
||||
},
|
||||
"create_time": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "Create time is the time the Ticket was created. It is populated by Open\nMatch at the time of Ticket creation."
|
||||
}
|
||||
},
|
||||
"description": "A Ticket is a basic matchmaking entity in Open Match. A Ticket represents either an\nindividual 'Player' or a 'Group' of players. Open Match will not interpret\nwhat the Ticket represents but just treat it as a matchmaking unit with a set\nof SearchFields. Open Match stores the Ticket in state storage and enables an\nAssignment to be associated with this Ticket."
|
||||
"description": "A Ticket is a basic matchmaking entity in Open Match. A Ticket may represent\nan individual 'Player', a 'Group' of players, or any other concepts unique to\nyour use case. Open Match will not interpret what the Ticket represents but\njust treat it as a matchmaking unit with a set of SearchFields. Open Match\nstores the Ticket in state storage and enables an Assignment to be set on the\nTicket."
|
||||
},
|
||||
"openmatchUpdateBackfillRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"backfill": {
|
||||
"$ref": "#/definitions/openmatchBackfill",
|
||||
"description": "A Backfill object with ID set and fields to update."
|
||||
}
|
||||
},
|
||||
"description": "UpdateBackfillRequest - update searchFields, extensions and set assignment.\n\nBETA FEATURE WARNING: This Request message is not finalized and still subject\nto possible change or removal."
|
||||
},
|
||||
"openmatchWatchAssignmentsResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"assignment": {
|
||||
"$ref": "#/definitions/openmatchAssignment",
|
||||
"description": "An updated Assignment of the requested Ticket."
|
||||
}
|
||||
}
|
||||
},
|
||||
"protobufAny": {
|
||||
"type": "object",
|
||||
@ -272,44 +586,27 @@
|
||||
},
|
||||
"description": "`Any` contains an arbitrary serialized protocol buffer message along with a\nURL that describes the type of the serialized message.\n\nProtobuf library provides support to pack/unpack Any values in the form\nof utility functions or additional generated methods of the Any type.\n\nExample 1: Pack and unpack a message in C++.\n\n Foo foo = ...;\n Any any;\n any.PackFrom(foo);\n ...\n if (any.UnpackTo(\u0026foo)) {\n ...\n }\n\nExample 2: Pack and unpack a message in Java.\n\n Foo foo = ...;\n Any any = Any.pack(foo);\n ...\n if (any.is(Foo.class)) {\n foo = any.unpack(Foo.class);\n }\n\n Example 3: Pack and unpack a message in Python.\n\n foo = Foo(...)\n any = Any()\n any.Pack(foo)\n ...\n if any.Is(Foo.DESCRIPTOR):\n any.Unpack(foo)\n ...\n\n Example 4: Pack and unpack a message in Go\n\n foo := \u0026pb.Foo{...}\n any, err := ptypes.MarshalAny(foo)\n ...\n foo := \u0026pb.Foo{}\n if err := ptypes.UnmarshalAny(any, foo); err != nil {\n ...\n }\n\nThe pack methods provided by protobuf library will by default use\n'type.googleapis.com/full.type.name' as the type URL and the unpack\nmethods only use the fully qualified type name after the last '/'\nin the type URL, for example \"foo.bar.com/x/y.z\" will yield type\nname \"y.z\".\n\n\nJSON\n====\nThe JSON representation of an `Any` value uses the regular\nrepresentation of the deserialized, embedded message, with an\nadditional field `@type` which contains the type URL. Example:\n\n package google.profile;\n message Person {\n string first_name = 1;\n string last_name = 2;\n }\n\n {\n \"@type\": \"type.googleapis.com/google.profile.Person\",\n \"firstName\": \u003cstring\u003e,\n \"lastName\": \u003cstring\u003e\n }\n\nIf the embedded message type is well-known and has a custom JSON\nrepresentation, that representation will be embedded adding a field\n`value` which holds the custom JSON in addition to the `@type`\nfield. Example (for message [google.protobuf.Duration][]):\n\n {\n \"@type\": \"type.googleapis.com/google.protobuf.Duration\",\n \"value\": \"1.212s\"\n }"
|
||||
},
|
||||
"runtimeStreamError": {
|
||||
"rpcStatus": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"grpc_code": {
|
||||
"code": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"http_code": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
"format": "int32",
|
||||
"description": "The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code]."
|
||||
},
|
||||
"message": {
|
||||
"type": "string"
|
||||
},
|
||||
"http_status": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"description": "A developer-facing error message, which should be in English. Any\nuser-facing error message should be localized and sent in the\n[google.rpc.Status.details][google.rpc.Status.details] field, or localized by the client."
|
||||
},
|
||||
"details": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/protobufAny"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-stream-definitions": {
|
||||
"openmatchGetAssignmentsResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"result": {
|
||||
"$ref": "#/definitions/openmatchGetAssignmentsResponse"
|
||||
},
|
||||
"error": {
|
||||
"$ref": "#/definitions/runtimeStreamError"
|
||||
},
|
||||
"description": "A list of messages that carry the error details. There is a common set of\nmessage types for APIs to use."
|
||||
}
|
||||
},
|
||||
"title": "Stream result of openmatchGetAssignmentsResponse"
|
||||
"description": "The `Status` type defines a logical error model that is suitable for\ndifferent programming environments, including REST APIs and RPC APIs. It is\nused by [gRPC](https://github.com/grpc). Each `Status` message contains\nthree pieces of data: error code, error message, and error details.\n\nYou can find out more about this error model and how to work with it in the\n[API Design Guide](https://cloud.google.com/apis/design/errors)."
|
||||
}
|
||||
},
|
||||
"externalDocs": {
|
||||
|
@ -19,9 +19,9 @@ option csharp_namespace = "OpenMatch";
|
||||
|
||||
import "api/messages.proto";
|
||||
import "google/api/annotations.proto";
|
||||
import "protoc-gen-swagger/options/annotations.proto";
|
||||
import "protoc-gen-openapiv2/options/annotations.proto";
|
||||
|
||||
option (grpc.gateway.protoc_gen_swagger.options.openapiv2_swagger) = {
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
|
||||
info: {
|
||||
title: "Match Function"
|
||||
version: "1.0"
|
||||
@ -69,8 +69,9 @@ message RunResponse {
|
||||
// The MatchFunction service implements APIs to run user-defined matchmaking logics.
|
||||
service MatchFunction {
|
||||
// DO NOT CALL THIS FUNCTION MANUALLY. USE backend.FetchMatches INSTEAD.
|
||||
// Run pulls Tickets that satisify Profile constraints from QueryService, runs matchmaking logics against them, then
|
||||
// constructs and streams back match candidates to the Backend service.
|
||||
// Run pulls Tickets that satisfy Profile constraints from QueryService,
|
||||
// runs matchmaking logic against them, then constructs and streams back
|
||||
// match candidates to the Backend service.
|
||||
rpc Run(RunRequest) returns (stream RunResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/v1/matchfunction:run"
|
||||
|
@ -13,6 +13,11 @@
|
||||
"url": "https://github.com/googleforgames/open-match/blob/master/LICENSE"
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
{
|
||||
"name": "MatchFunction"
|
||||
}
|
||||
],
|
||||
"schemes": [
|
||||
"http",
|
||||
"https"
|
||||
@ -26,13 +31,22 @@
|
||||
"paths": {
|
||||
"/v1/matchfunction:run": {
|
||||
"post": {
|
||||
"summary": "DO NOT CALL THIS FUNCTION MANUALLY. USE backend.FetchMatches INSTEAD.\nRun pulls Tickets that satisify Profile constraints from QueryService, runs matchmaking logics against them, then\nconstructs and streams back match candidates to the Backend service.",
|
||||
"operationId": "Run",
|
||||
"summary": "DO NOT CALL THIS FUNCTION MANUALLY. USE backend.FetchMatches INSTEAD.\nRun pulls Tickets that satisfy Profile constraints from QueryService,\nruns matchmaking logic against them, then constructs and streams back\nmatch candidates to the Backend service.",
|
||||
"operationId": "MatchFunction_Run",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.(streaming responses)",
|
||||
"schema": {
|
||||
"$ref": "#/x-stream-definitions/openmatchRunResponse"
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"result": {
|
||||
"$ref": "#/definitions/openmatchRunResponse"
|
||||
},
|
||||
"error": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
},
|
||||
"title": "Stream result of openmatchRunResponse"
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
@ -41,6 +55,12 @@
|
||||
"type": "string",
|
||||
"format": "string"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
@ -60,6 +80,17 @@
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"DoubleRangeFilterExclude": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"NONE",
|
||||
"MIN",
|
||||
"MAX",
|
||||
"BOTH"
|
||||
],
|
||||
"default": "NONE",
|
||||
"title": "- NONE: No bounds should be excluded when evaluating the filter, i.e.: MIN \u003c= x \u003c= MAX\n - MIN: Only the minimum bound should be excluded when evaluating the filter, i.e.: MIN \u003c x \u003c= MAX\n - MAX: Only the maximum bound should be excluded when evaluating the filter, i.e.: MIN \u003c= x \u003c MAX\n - BOTH: Both bounds should be excluded when evaluating the filter, i.e.: MIN \u003c x \u003c MAX"
|
||||
},
|
||||
"openmatchAssignment": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@ -75,7 +106,38 @@
|
||||
"description": "Customized information not inspected by Open Match, to be used by the match\nmaking function, evaluator, and components making calls to Open Match.\nOptional, depending on the requirements of the connected systems."
|
||||
}
|
||||
},
|
||||
"description": "An Assignment represents a game server assignment associated with a Ticket. Open\nmatch does not require or inspect any fields on assignment."
|
||||
"description": "An Assignment represents a game server assignment associated with a Ticket.\nOpen Match does not require or inspect any fields on assignment."
|
||||
},
|
||||
"openmatchBackfill": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "Id represents an auto-generated Id issued by Open Match."
|
||||
},
|
||||
"search_fields": {
|
||||
"$ref": "#/definitions/openmatchSearchFields",
|
||||
"description": "Search fields are the fields which Open Match is aware of, and can be used\nwhen specifying filters."
|
||||
},
|
||||
"extensions": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/protobufAny"
|
||||
},
|
||||
"description": "Customized information not inspected by Open Match, to be used by\nthe Match Function, evaluator, and components making calls to Open Match.\nOptional, depending on the requirements of the connected systems."
|
||||
},
|
||||
"create_time": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "Create time is the time the Ticket was created. It is populated by Open\nMatch at the time of Ticket creation."
|
||||
},
|
||||
"generation": {
|
||||
"type": "string",
|
||||
"format": "int64",
|
||||
"description": "Generation gets incremented on GameServers update operations.\nPrevents the MMF from overriding a newer version from the game server.\nDo NOT read or write to this field, it is for internal tracking, and changing the value will cause bugs."
|
||||
}
|
||||
},
|
||||
"description": "Represents a backfill entity which is used to fill partially full matches.\n\nBETA FEATURE WARNING: This call and the associated Request and Response\nmessages are not finalized and still subject to possible change or removal."
|
||||
},
|
||||
"openmatchDoubleRangeFilter": {
|
||||
"type": "object",
|
||||
@ -93,6 +155,10 @@
|
||||
"type": "number",
|
||||
"format": "double",
|
||||
"description": "Minimum value."
|
||||
},
|
||||
"exclude": {
|
||||
"$ref": "#/definitions/DoubleRangeFilterExclude",
|
||||
"description": "Defines the bounds to apply when filtering tickets by their search_fields.double_args value.\nBETA FEATURE WARNING: This field and the associated values are\nnot finalized and still subject to possible change or removal."
|
||||
}
|
||||
},
|
||||
"title": "Filters numerical values to only those within a range.\n double_arg: \"foo\"\n max: 10\n min: 5\nmatches:\n {\"foo\": 5}\n {\"foo\": 7.5}\n {\"foo\": 10}\ndoes not match:\n {\"foo\": 4}\n {\"foo\": 10.01}\n {\"foo\": \"7.5\"}\n {}"
|
||||
@ -125,6 +191,14 @@
|
||||
"$ref": "#/definitions/protobufAny"
|
||||
},
|
||||
"description": "Customized information not inspected by Open Match, to be used by the match\nmaking function, evaluator, and components making calls to Open Match.\nOptional, depending on the requirements of the connected systems."
|
||||
},
|
||||
"backfill": {
|
||||
"$ref": "#/definitions/openmatchBackfill",
|
||||
"description": "Backfill request which contains additional information to the match\nand contains an association to a GameServer.\nBETA FEATURE WARNING: This field is not finalized and still subject\nto possible change or removal."
|
||||
},
|
||||
"allocate_gameserver": {
|
||||
"type": "boolean",
|
||||
"description": "AllocateGameServer signalise Director that Backfill is new and it should \nallocate a GameServer, this Backfill would be assigned.\nBETA FEATURE WARNING: This field is not finalized and still subject\nto possible change or removal."
|
||||
}
|
||||
},
|
||||
"description": "A Match is used to represent a completed match object. It can be generated by\na MatchFunction as a proposal or can be returned by OpenMatch as a result in\nresponse to the FetchMatches call.\nWhen a match is returned by the FetchMatches call, it should contain at least\none ticket to be considered as valid."
|
||||
@ -165,7 +239,7 @@
|
||||
"items": {
|
||||
"$ref": "#/definitions/openmatchDoubleRangeFilter"
|
||||
},
|
||||
"description": "Set of Filters indicating the filtering criteria. Selected players must\nmatch every Filter."
|
||||
"description": "Set of Filters indicating the filtering criteria. Selected tickets must\nmatch every Filter."
|
||||
},
|
||||
"string_equals_filters": {
|
||||
"type": "array",
|
||||
@ -178,8 +252,19 @@
|
||||
"items": {
|
||||
"$ref": "#/definitions/openmatchTagPresentFilter"
|
||||
}
|
||||
},
|
||||
"created_before": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "If specified, only Tickets created before the specified time are selected."
|
||||
},
|
||||
"created_after": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "If specified, only Tickets created after the specified time are selected."
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Pool specfies a set of criteria that are used to select a subset of Tickets\nthat meet all the criteria."
|
||||
},
|
||||
"openmatchRunRequest": {
|
||||
"type": "object",
|
||||
@ -258,7 +343,7 @@
|
||||
},
|
||||
"assignment": {
|
||||
"$ref": "#/definitions/openmatchAssignment",
|
||||
"description": "An Assignment represents a game server assignment associated with a Ticket.\nOpen Match does not require or inspect any fields on Assignment."
|
||||
"description": "An Assignment represents a game server assignment associated with a Ticket,\nor whatever finalized matched state means for your use case.\nOpen Match does not require or inspect any fields on Assignment."
|
||||
},
|
||||
"search_fields": {
|
||||
"$ref": "#/definitions/openmatchSearchFields",
|
||||
@ -270,9 +355,14 @@
|
||||
"$ref": "#/definitions/protobufAny"
|
||||
},
|
||||
"description": "Customized information not inspected by Open Match, to be used by the match\nmaking function, evaluator, and components making calls to Open Match.\nOptional, depending on the requirements of the connected systems."
|
||||
},
|
||||
"create_time": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "Create time is the time the Ticket was created. It is populated by Open\nMatch at the time of Ticket creation."
|
||||
}
|
||||
},
|
||||
"description": "A Ticket is a basic matchmaking entity in Open Match. A Ticket represents either an\nindividual 'Player' or a 'Group' of players. Open Match will not interpret\nwhat the Ticket represents but just treat it as a matchmaking unit with a set\nof SearchFields. Open Match stores the Ticket in state storage and enables an\nAssignment to be associated with this Ticket."
|
||||
"description": "A Ticket is a basic matchmaking entity in Open Match. A Ticket may represent\nan individual 'Player', a 'Group' of players, or any other concepts unique to\nyour use case. Open Match will not interpret what the Ticket represents but\njust treat it as a matchmaking unit with a set of SearchFields. Open Match\nstores the Ticket in state storage and enables an Assignment to be set on the\nTicket."
|
||||
},
|
||||
"protobufAny": {
|
||||
"type": "object",
|
||||
@ -289,44 +379,27 @@
|
||||
},
|
||||
"description": "`Any` contains an arbitrary serialized protocol buffer message along with a\nURL that describes the type of the serialized message.\n\nProtobuf library provides support to pack/unpack Any values in the form\nof utility functions or additional generated methods of the Any type.\n\nExample 1: Pack and unpack a message in C++.\n\n Foo foo = ...;\n Any any;\n any.PackFrom(foo);\n ...\n if (any.UnpackTo(\u0026foo)) {\n ...\n }\n\nExample 2: Pack and unpack a message in Java.\n\n Foo foo = ...;\n Any any = Any.pack(foo);\n ...\n if (any.is(Foo.class)) {\n foo = any.unpack(Foo.class);\n }\n\n Example 3: Pack and unpack a message in Python.\n\n foo = Foo(...)\n any = Any()\n any.Pack(foo)\n ...\n if any.Is(Foo.DESCRIPTOR):\n any.Unpack(foo)\n ...\n\n Example 4: Pack and unpack a message in Go\n\n foo := \u0026pb.Foo{...}\n any, err := ptypes.MarshalAny(foo)\n ...\n foo := \u0026pb.Foo{}\n if err := ptypes.UnmarshalAny(any, foo); err != nil {\n ...\n }\n\nThe pack methods provided by protobuf library will by default use\n'type.googleapis.com/full.type.name' as the type URL and the unpack\nmethods only use the fully qualified type name after the last '/'\nin the type URL, for example \"foo.bar.com/x/y.z\" will yield type\nname \"y.z\".\n\n\nJSON\n====\nThe JSON representation of an `Any` value uses the regular\nrepresentation of the deserialized, embedded message, with an\nadditional field `@type` which contains the type URL. Example:\n\n package google.profile;\n message Person {\n string first_name = 1;\n string last_name = 2;\n }\n\n {\n \"@type\": \"type.googleapis.com/google.profile.Person\",\n \"firstName\": \u003cstring\u003e,\n \"lastName\": \u003cstring\u003e\n }\n\nIf the embedded message type is well-known and has a custom JSON\nrepresentation, that representation will be embedded adding a field\n`value` which holds the custom JSON in addition to the `@type`\nfield. Example (for message [google.protobuf.Duration][]):\n\n {\n \"@type\": \"type.googleapis.com/google.protobuf.Duration\",\n \"value\": \"1.212s\"\n }"
|
||||
},
|
||||
"runtimeStreamError": {
|
||||
"rpcStatus": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"grpc_code": {
|
||||
"code": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"http_code": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
"format": "int32",
|
||||
"description": "The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code]."
|
||||
},
|
||||
"message": {
|
||||
"type": "string"
|
||||
},
|
||||
"http_status": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"description": "A developer-facing error message, which should be in English. Any\nuser-facing error message should be localized and sent in the\n[google.rpc.Status.details][google.rpc.Status.details] field, or localized by the client."
|
||||
},
|
||||
"details": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/protobufAny"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-stream-definitions": {
|
||||
"openmatchRunResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"result": {
|
||||
"$ref": "#/definitions/openmatchRunResponse"
|
||||
},
|
||||
"error": {
|
||||
"$ref": "#/definitions/runtimeStreamError"
|
||||
},
|
||||
"description": "A list of messages that carry the error details. There is a common set of\nmessage types for APIs to use."
|
||||
}
|
||||
},
|
||||
"title": "Stream result of openmatchRunResponse"
|
||||
"description": "The `Status` type defines a logical error model that is suitable for\ndifferent programming environments, including REST APIs and RPC APIs. It is\nused by [gRPC](https://github.com/grpc). Each `Status` message contains\nthree pieces of data: error code, error message, and error details.\n\nYou can find out more about this error model and how to work with it in the\n[API Design Guide](https://cloud.google.com/apis/design/errors)."
|
||||
}
|
||||
},
|
||||
"externalDocs": {
|
||||
|
@ -19,17 +19,20 @@ option csharp_namespace = "OpenMatch";
|
||||
|
||||
import "google/rpc/status.proto";
|
||||
import "google/protobuf/any.proto";
|
||||
import "google/protobuf/timestamp.proto";
|
||||
|
||||
// A Ticket is a basic matchmaking entity in Open Match. A Ticket represents either an
|
||||
// individual 'Player' or a 'Group' of players. Open Match will not interpret
|
||||
// what the Ticket represents but just treat it as a matchmaking unit with a set
|
||||
// of SearchFields. Open Match stores the Ticket in state storage and enables an
|
||||
// Assignment to be associated with this Ticket.
|
||||
// A Ticket is a basic matchmaking entity in Open Match. A Ticket may represent
|
||||
// an individual 'Player', a 'Group' of players, or any other concepts unique to
|
||||
// your use case. Open Match will not interpret what the Ticket represents but
|
||||
// just treat it as a matchmaking unit with a set of SearchFields. Open Match
|
||||
// stores the Ticket in state storage and enables an Assignment to be set on the
|
||||
// Ticket.
|
||||
message Ticket {
|
||||
// Id represents an auto-generated Id issued by Open Match.
|
||||
string id = 1;
|
||||
|
||||
// An Assignment represents a game server assignment associated with a Ticket.
|
||||
// An Assignment represents a game server assignment associated with a Ticket,
|
||||
// or whatever finalized matched state means for your use case.
|
||||
// Open Match does not require or inspect any fields on Assignment.
|
||||
Assignment assignment = 3;
|
||||
|
||||
@ -42,6 +45,10 @@ message Ticket {
|
||||
// Optional, depending on the requirements of the connected systems.
|
||||
map<string, google.protobuf.Any> extensions = 5;
|
||||
|
||||
// Create time is the time the Ticket was created. It is populated by Open
|
||||
// Match at the time of Ticket creation.
|
||||
google.protobuf.Timestamp create_time = 6;
|
||||
|
||||
// Deprecated fields.
|
||||
reserved 2;
|
||||
}
|
||||
@ -59,8 +66,8 @@ message SearchFields {
|
||||
repeated string tags = 3;
|
||||
}
|
||||
|
||||
// An Assignment represents a game server assignment associated with a Ticket. Open
|
||||
// match does not require or inspect any fields on assignment.
|
||||
// An Assignment represents a game server assignment associated with a Ticket.
|
||||
// Open Match does not require or inspect any fields on assignment.
|
||||
message Assignment {
|
||||
// Connection information for this Assignment.
|
||||
string connection = 1;
|
||||
@ -96,6 +103,25 @@ message DoubleRangeFilter {
|
||||
|
||||
// Minimum value.
|
||||
double min = 3;
|
||||
|
||||
enum Exclude {
|
||||
// No bounds should be excluded when evaluating the filter, i.e.: MIN <= x <= MAX
|
||||
NONE = 0;
|
||||
|
||||
// Only the minimum bound should be excluded when evaluating the filter, i.e.: MIN < x <= MAX
|
||||
MIN = 1;
|
||||
|
||||
// Only the maximum bound should be excluded when evaluating the filter, i.e.: MIN <= x < MAX
|
||||
MAX = 2;
|
||||
|
||||
// Both bounds should be excluded when evaluating the filter, i.e.: MIN < x < MAX
|
||||
BOTH = 3;
|
||||
}
|
||||
|
||||
// Defines the bounds to apply when filtering tickets by their search_fields.double_args value.
|
||||
// BETA FEATURE WARNING: This field and the associated values are
|
||||
// not finalized and still subject to possible change or removal.
|
||||
Exclude exclude = 4;
|
||||
}
|
||||
|
||||
// Filters strings exactly equaling a value.
|
||||
@ -126,11 +152,13 @@ message TagPresentFilter {
|
||||
string tag = 1;
|
||||
}
|
||||
|
||||
// Pool specfies a set of criteria that are used to select a subset of Tickets
|
||||
// that meet all the criteria.
|
||||
message Pool {
|
||||
// A developer-chosen human-readable name for this Pool.
|
||||
string name = 1;
|
||||
|
||||
// Set of Filters indicating the filtering criteria. Selected players must
|
||||
// Set of Filters indicating the filtering criteria. Selected tickets must
|
||||
// match every Filter.
|
||||
repeated DoubleRangeFilter double_range_filters = 2;
|
||||
|
||||
@ -138,6 +166,12 @@ message Pool {
|
||||
|
||||
repeated TagPresentFilter tag_present_filters = 5;
|
||||
|
||||
// If specified, only Tickets created before the specified time are selected.
|
||||
google.protobuf.Timestamp created_before = 6;
|
||||
|
||||
// If specified, only Tickets created after the specified time are selected.
|
||||
google.protobuf.Timestamp created_after = 7;
|
||||
|
||||
// Deprecated fields.
|
||||
reserved 3;
|
||||
}
|
||||
@ -186,6 +220,45 @@ message Match {
|
||||
// Optional, depending on the requirements of the connected systems.
|
||||
map<string, google.protobuf.Any> extensions = 7;
|
||||
|
||||
// Backfill request which contains additional information to the match
|
||||
// and contains an association to a GameServer.
|
||||
// BETA FEATURE WARNING: This field is not finalized and still subject
|
||||
// to possible change or removal.
|
||||
Backfill backfill = 8;
|
||||
|
||||
// AllocateGameServer signalise Director that Backfill is new and it should
|
||||
// allocate a GameServer, this Backfill would be assigned.
|
||||
// BETA FEATURE WARNING: This field is not finalized and still subject
|
||||
// to possible change or removal.
|
||||
bool allocate_gameserver = 9;
|
||||
|
||||
// Deprecated fields.
|
||||
reserved 5, 6;
|
||||
}
|
||||
|
||||
// Represents a backfill entity which is used to fill partially full matches.
|
||||
//
|
||||
// BETA FEATURE WARNING: This call and the associated Request and Response
|
||||
// messages are not finalized and still subject to possible change or removal.
|
||||
message Backfill {
|
||||
// Id represents an auto-generated Id issued by Open Match.
|
||||
string id = 1;
|
||||
|
||||
// Search fields are the fields which Open Match is aware of, and can be used
|
||||
// when specifying filters.
|
||||
SearchFields search_fields = 2;
|
||||
|
||||
// Customized information not inspected by Open Match, to be used by
|
||||
// the Match Function, evaluator, and components making calls to Open Match.
|
||||
// Optional, depending on the requirements of the connected systems.
|
||||
map<string, google.protobuf.Any> extensions = 3;
|
||||
|
||||
// Create time is the time the Ticket was created. It is populated by Open
|
||||
// Match at the time of Ticket creation.
|
||||
google.protobuf.Timestamp create_time = 4;
|
||||
|
||||
// Generation gets incremented on GameServers update operations.
|
||||
// Prevents the MMF from overriding a newer version from the game server.
|
||||
// Do NOT read or write to this field, it is for internal tracking, and changing the value will cause bugs.
|
||||
int64 generation = 5;
|
||||
}
|
@ -19,9 +19,9 @@ option csharp_namespace = "OpenMatch";
|
||||
|
||||
import "api/messages.proto";
|
||||
import "google/api/annotations.proto";
|
||||
import "protoc-gen-swagger/options/annotations.proto";
|
||||
import "protoc-gen-openapiv2/options/annotations.proto";
|
||||
|
||||
option (grpc.gateway.protoc_gen_swagger.options.openapiv2_swagger) = {
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
|
||||
info: {
|
||||
title: "MM Logic (Data Layer)"
|
||||
version: "1.0"
|
||||
@ -52,29 +52,74 @@ option (grpc.gateway.protoc_gen_swagger.options.openapiv2_swagger) = {
|
||||
}
|
||||
// TODO Add annotations for security_defintiions.
|
||||
// See
|
||||
// https://github.com/grpc-ecosystem/grpc-gateway/blob/master/examples/proto/examplepb/a_bit_of_everything.proto
|
||||
// https://github.com/grpc-ecosystem/grpc-gateway/blob/master/examples/internal/proto/examplepb/a_bit_of_everything.proto
|
||||
};
|
||||
|
||||
message QueryTicketsRequest {
|
||||
// A Pool is consists of a set of Filters.
|
||||
// The Pool representing the set of Filters to be queried.
|
||||
Pool pool = 1;
|
||||
}
|
||||
|
||||
message QueryTicketsResponse {
|
||||
// Tickets that satisfy all the filtering criteria.
|
||||
// Tickets that meet all the filtering criteria requested by the pool.
|
||||
repeated Ticket tickets = 1;
|
||||
}
|
||||
|
||||
message QueryTicketIdsRequest {
|
||||
// The Pool representing the set of Filters to be queried.
|
||||
Pool pool = 1;
|
||||
}
|
||||
|
||||
message QueryTicketIdsResponse {
|
||||
// TicketIDs that meet all the filtering criteria requested by the pool.
|
||||
repeated string ids = 1;
|
||||
}
|
||||
|
||||
// BETA FEATURE WARNING: This Request messages are not finalized and
|
||||
// still subject to possible change or removal.
|
||||
message QueryBackfillsRequest {
|
||||
// The Pool representing the set of Filters to be queried.
|
||||
Pool pool = 1;
|
||||
}
|
||||
|
||||
// BETA FEATURE WARNING: This Request messages are not finalized and
|
||||
// still subject to possible change or removal.
|
||||
message QueryBackfillsResponse {
|
||||
// Backfills that meet all the filtering criteria requested by the pool.
|
||||
repeated Backfill backfills = 1;
|
||||
}
|
||||
|
||||
// The QueryService service implements helper APIs for Match Function to query Tickets from state storage.
|
||||
service QueryService {
|
||||
// QueryTickets gets a list of Tickets that match all Filters of the input Pool.
|
||||
// - If the Pool contains no Filters, QueryTickets will return all Tickets in the state storage.
|
||||
// QueryTickets pages the Tickets by `storage.pool.size` and stream back response.
|
||||
// - storage.pool.size is default to 1000 if not set, and has a mininum of 10 and maximum of 10000
|
||||
// QueryTickets pages the Tickets by `queryPageSize` and stream back responses.
|
||||
// - queryPageSize is default to 1000 if not set, and has a minimum of 10 and maximum of 10000.
|
||||
rpc QueryTickets(QueryTicketsRequest) returns (stream QueryTicketsResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/v1/queryservice/tickets:query"
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
|
||||
// QueryTicketIds gets the list of TicketIDs that meet all the filtering criteria requested by the pool.
|
||||
// - If the Pool contains no Filters, QueryTicketIds will return all TicketIDs in the state storage.
|
||||
// QueryTicketIds pages the TicketIDs by `queryPageSize` and stream back responses.
|
||||
// - queryPageSize is default to 1000 if not set, and has a minimum of 10 and maximum of 10000.
|
||||
rpc QueryTicketIds(QueryTicketIdsRequest) returns (stream QueryTicketIdsResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/v1/queryservice/ticketids:query"
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
|
||||
// QueryBackfills gets a list of Backfills.
|
||||
// BETA FEATURE WARNING: This call and the associated Request and Response
|
||||
// messages are not finalized and still subject to possible change or removal.
|
||||
rpc QueryBackfills(QueryBackfillsRequest) returns (stream QueryBackfillsResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/v1/queryservice/backfills:query"
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,11 @@
|
||||
"url": "https://github.com/googleforgames/open-match/blob/master/LICENSE"
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
{
|
||||
"name": "QueryService"
|
||||
}
|
||||
],
|
||||
"schemes": [
|
||||
"http",
|
||||
"https"
|
||||
@ -24,15 +29,24 @@
|
||||
"application/json"
|
||||
],
|
||||
"paths": {
|
||||
"/v1/queryservice/tickets:query": {
|
||||
"/v1/queryservice/backfills:query": {
|
||||
"post": {
|
||||
"summary": "QueryTickets gets a list of Tickets that match all Filters of the input Pool.\n - If the Pool contains no Filters, QueryTickets will return all Tickets in the state storage.\nQueryTickets pages the Tickets by `storage.pool.size` and stream back response.\n - storage.pool.size is default to 1000 if not set, and has a mininum of 10 and maximum of 10000",
|
||||
"operationId": "QueryTickets",
|
||||
"summary": "QueryBackfills gets a list of Backfills.\nBETA FEATURE WARNING: This call and the associated Request and Response\nmessages are not finalized and still subject to possible change or removal.",
|
||||
"operationId": "QueryService_QueryBackfills",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.(streaming responses)",
|
||||
"schema": {
|
||||
"$ref": "#/x-stream-definitions/openmatchQueryTicketsResponse"
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"result": {
|
||||
"$ref": "#/definitions/openmatchQueryBackfillsResponse"
|
||||
},
|
||||
"error": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
},
|
||||
"title": "Stream result of openmatchQueryBackfillsResponse"
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
@ -41,6 +55,110 @@
|
||||
"type": "string",
|
||||
"format": "string"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/openmatchQueryBackfillsRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"QueryService"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/v1/queryservice/ticketids:query": {
|
||||
"post": {
|
||||
"summary": "QueryTicketIds gets the list of TicketIDs that meet all the filtering criteria requested by the pool.\n - If the Pool contains no Filters, QueryTicketIds will return all TicketIDs in the state storage.\nQueryTicketIds pages the TicketIDs by `queryPageSize` and stream back responses.\n - queryPageSize is default to 1000 if not set, and has a minimum of 10 and maximum of 10000.",
|
||||
"operationId": "QueryService_QueryTicketIds",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.(streaming responses)",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"result": {
|
||||
"$ref": "#/definitions/openmatchQueryTicketIdsResponse"
|
||||
},
|
||||
"error": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
},
|
||||
"title": "Stream result of openmatchQueryTicketIdsResponse"
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Returned when the resource does not exist.",
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"format": "string"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/openmatchQueryTicketIdsRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"QueryService"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/v1/queryservice/tickets:query": {
|
||||
"post": {
|
||||
"summary": "QueryTickets gets a list of Tickets that match all Filters of the input Pool.\n - If the Pool contains no Filters, QueryTickets will return all Tickets in the state storage.\nQueryTickets pages the Tickets by `queryPageSize` and stream back responses.\n - queryPageSize is default to 1000 if not set, and has a minimum of 10 and maximum of 10000.",
|
||||
"operationId": "QueryService_QueryTickets",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.(streaming responses)",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"result": {
|
||||
"$ref": "#/definitions/openmatchQueryTicketsResponse"
|
||||
},
|
||||
"error": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
},
|
||||
"title": "Stream result of openmatchQueryTicketsResponse"
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Returned when the resource does not exist.",
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"format": "string"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
@ -60,6 +178,17 @@
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"DoubleRangeFilterExclude": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"NONE",
|
||||
"MIN",
|
||||
"MAX",
|
||||
"BOTH"
|
||||
],
|
||||
"default": "NONE",
|
||||
"title": "- NONE: No bounds should be excluded when evaluating the filter, i.e.: MIN \u003c= x \u003c= MAX\n - MIN: Only the minimum bound should be excluded when evaluating the filter, i.e.: MIN \u003c x \u003c= MAX\n - MAX: Only the maximum bound should be excluded when evaluating the filter, i.e.: MIN \u003c= x \u003c MAX\n - BOTH: Both bounds should be excluded when evaluating the filter, i.e.: MIN \u003c x \u003c MAX"
|
||||
},
|
||||
"openmatchAssignment": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@ -75,7 +204,38 @@
|
||||
"description": "Customized information not inspected by Open Match, to be used by the match\nmaking function, evaluator, and components making calls to Open Match.\nOptional, depending on the requirements of the connected systems."
|
||||
}
|
||||
},
|
||||
"description": "An Assignment represents a game server assignment associated with a Ticket. Open\nmatch does not require or inspect any fields on assignment."
|
||||
"description": "An Assignment represents a game server assignment associated with a Ticket.\nOpen Match does not require or inspect any fields on assignment."
|
||||
},
|
||||
"openmatchBackfill": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "Id represents an auto-generated Id issued by Open Match."
|
||||
},
|
||||
"search_fields": {
|
||||
"$ref": "#/definitions/openmatchSearchFields",
|
||||
"description": "Search fields are the fields which Open Match is aware of, and can be used\nwhen specifying filters."
|
||||
},
|
||||
"extensions": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/protobufAny"
|
||||
},
|
||||
"description": "Customized information not inspected by Open Match, to be used by\nthe Match Function, evaluator, and components making calls to Open Match.\nOptional, depending on the requirements of the connected systems."
|
||||
},
|
||||
"create_time": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "Create time is the time the Ticket was created. It is populated by Open\nMatch at the time of Ticket creation."
|
||||
},
|
||||
"generation": {
|
||||
"type": "string",
|
||||
"format": "int64",
|
||||
"description": "Generation gets incremented on GameServers update operations.\nPrevents the MMF from overriding a newer version from the game server.\nDo NOT read or write to this field, it is for internal tracking, and changing the value will cause bugs."
|
||||
}
|
||||
},
|
||||
"description": "Represents a backfill entity which is used to fill partially full matches.\n\nBETA FEATURE WARNING: This call and the associated Request and Response\nmessages are not finalized and still subject to possible change or removal."
|
||||
},
|
||||
"openmatchDoubleRangeFilter": {
|
||||
"type": "object",
|
||||
@ -93,6 +253,10 @@
|
||||
"type": "number",
|
||||
"format": "double",
|
||||
"description": "Minimum value."
|
||||
},
|
||||
"exclude": {
|
||||
"$ref": "#/definitions/DoubleRangeFilterExclude",
|
||||
"description": "Defines the bounds to apply when filtering tickets by their search_fields.double_args value.\nBETA FEATURE WARNING: This field and the associated values are\nnot finalized and still subject to possible change or removal."
|
||||
}
|
||||
},
|
||||
"title": "Filters numerical values to only those within a range.\n double_arg: \"foo\"\n max: 10\n min: 5\nmatches:\n {\"foo\": 5}\n {\"foo\": 7.5}\n {\"foo\": 10}\ndoes not match:\n {\"foo\": 4}\n {\"foo\": 10.01}\n {\"foo\": \"7.5\"}\n {}"
|
||||
@ -109,7 +273,7 @@
|
||||
"items": {
|
||||
"$ref": "#/definitions/openmatchDoubleRangeFilter"
|
||||
},
|
||||
"description": "Set of Filters indicating the filtering criteria. Selected players must\nmatch every Filter."
|
||||
"description": "Set of Filters indicating the filtering criteria. Selected tickets must\nmatch every Filter."
|
||||
},
|
||||
"string_equals_filters": {
|
||||
"type": "array",
|
||||
@ -122,6 +286,61 @@
|
||||
"items": {
|
||||
"$ref": "#/definitions/openmatchTagPresentFilter"
|
||||
}
|
||||
},
|
||||
"created_before": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "If specified, only Tickets created before the specified time are selected."
|
||||
},
|
||||
"created_after": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "If specified, only Tickets created after the specified time are selected."
|
||||
}
|
||||
},
|
||||
"description": "Pool specfies a set of criteria that are used to select a subset of Tickets\nthat meet all the criteria."
|
||||
},
|
||||
"openmatchQueryBackfillsRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"pool": {
|
||||
"$ref": "#/definitions/openmatchPool",
|
||||
"description": "The Pool representing the set of Filters to be queried."
|
||||
}
|
||||
},
|
||||
"description": "BETA FEATURE WARNING: This Request messages are not finalized and \nstill subject to possible change or removal."
|
||||
},
|
||||
"openmatchQueryBackfillsResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"backfills": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/openmatchBackfill"
|
||||
},
|
||||
"description": "Backfills that meet all the filtering criteria requested by the pool."
|
||||
}
|
||||
},
|
||||
"description": "BETA FEATURE WARNING: This Request messages are not finalized and \nstill subject to possible change or removal."
|
||||
},
|
||||
"openmatchQueryTicketIdsRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"pool": {
|
||||
"$ref": "#/definitions/openmatchPool",
|
||||
"description": "The Pool representing the set of Filters to be queried."
|
||||
}
|
||||
}
|
||||
},
|
||||
"openmatchQueryTicketIdsResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"ids": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "TicketIDs that meet all the filtering criteria requested by the pool."
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -130,7 +349,7 @@
|
||||
"properties": {
|
||||
"pool": {
|
||||
"$ref": "#/definitions/openmatchPool",
|
||||
"description": "A Pool is consists of a set of Filters."
|
||||
"description": "The Pool representing the set of Filters to be queried."
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -142,7 +361,7 @@
|
||||
"items": {
|
||||
"$ref": "#/definitions/openmatchTicket"
|
||||
},
|
||||
"description": "Tickets is a list of Ticket representing one or more Tickets which meet all Filter criterias."
|
||||
"description": "Tickets that meet all the filtering criteria requested by the pool."
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -205,7 +424,7 @@
|
||||
},
|
||||
"assignment": {
|
||||
"$ref": "#/definitions/openmatchAssignment",
|
||||
"description": "An Assignment represents a game server assignment associated with a Ticket.\nOpen Match does not require or inspect any fields on Assignment."
|
||||
"description": "An Assignment represents a game server assignment associated with a Ticket,\nor whatever finalized matched state means for your use case.\nOpen Match does not require or inspect any fields on Assignment."
|
||||
},
|
||||
"search_fields": {
|
||||
"$ref": "#/definitions/openmatchSearchFields",
|
||||
@ -217,9 +436,14 @@
|
||||
"$ref": "#/definitions/protobufAny"
|
||||
},
|
||||
"description": "Customized information not inspected by Open Match, to be used by the match\nmaking function, evaluator, and components making calls to Open Match.\nOptional, depending on the requirements of the connected systems."
|
||||
},
|
||||
"create_time": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "Create time is the time the Ticket was created. It is populated by Open\nMatch at the time of Ticket creation."
|
||||
}
|
||||
},
|
||||
"description": "A Ticket is a basic matchmaking entity in Open Match. A Ticket represents either an\nindividual 'Player' or a 'Group' of players. Open Match will not interpret\nwhat the Ticket represents but just treat it as a matchmaking unit with a set\nof SearchFields. Open Match stores the Ticket in state storage and enables an\nAssignment to be associated with this Ticket."
|
||||
"description": "A Ticket is a basic matchmaking entity in Open Match. A Ticket may represent\nan individual 'Player', a 'Group' of players, or any other concepts unique to\nyour use case. Open Match will not interpret what the Ticket represents but\njust treat it as a matchmaking unit with a set of SearchFields. Open Match\nstores the Ticket in state storage and enables an Assignment to be set on the\nTicket."
|
||||
},
|
||||
"protobufAny": {
|
||||
"type": "object",
|
||||
@ -236,44 +460,27 @@
|
||||
},
|
||||
"description": "`Any` contains an arbitrary serialized protocol buffer message along with a\nURL that describes the type of the serialized message.\n\nProtobuf library provides support to pack/unpack Any values in the form\nof utility functions or additional generated methods of the Any type.\n\nExample 1: Pack and unpack a message in C++.\n\n Foo foo = ...;\n Any any;\n any.PackFrom(foo);\n ...\n if (any.UnpackTo(\u0026foo)) {\n ...\n }\n\nExample 2: Pack and unpack a message in Java.\n\n Foo foo = ...;\n Any any = Any.pack(foo);\n ...\n if (any.is(Foo.class)) {\n foo = any.unpack(Foo.class);\n }\n\n Example 3: Pack and unpack a message in Python.\n\n foo = Foo(...)\n any = Any()\n any.Pack(foo)\n ...\n if any.Is(Foo.DESCRIPTOR):\n any.Unpack(foo)\n ...\n\n Example 4: Pack and unpack a message in Go\n\n foo := \u0026pb.Foo{...}\n any, err := ptypes.MarshalAny(foo)\n ...\n foo := \u0026pb.Foo{}\n if err := ptypes.UnmarshalAny(any, foo); err != nil {\n ...\n }\n\nThe pack methods provided by protobuf library will by default use\n'type.googleapis.com/full.type.name' as the type URL and the unpack\nmethods only use the fully qualified type name after the last '/'\nin the type URL, for example \"foo.bar.com/x/y.z\" will yield type\nname \"y.z\".\n\n\nJSON\n====\nThe JSON representation of an `Any` value uses the regular\nrepresentation of the deserialized, embedded message, with an\nadditional field `@type` which contains the type URL. Example:\n\n package google.profile;\n message Person {\n string first_name = 1;\n string last_name = 2;\n }\n\n {\n \"@type\": \"type.googleapis.com/google.profile.Person\",\n \"firstName\": \u003cstring\u003e,\n \"lastName\": \u003cstring\u003e\n }\n\nIf the embedded message type is well-known and has a custom JSON\nrepresentation, that representation will be embedded adding a field\n`value` which holds the custom JSON in addition to the `@type`\nfield. Example (for message [google.protobuf.Duration][]):\n\n {\n \"@type\": \"type.googleapis.com/google.protobuf.Duration\",\n \"value\": \"1.212s\"\n }"
|
||||
},
|
||||
"runtimeStreamError": {
|
||||
"rpcStatus": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"grpc_code": {
|
||||
"code": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"http_code": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
"format": "int32",
|
||||
"description": "The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code]."
|
||||
},
|
||||
"message": {
|
||||
"type": "string"
|
||||
},
|
||||
"http_status": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"description": "A developer-facing error message, which should be in English. Any\nuser-facing error message should be localized and sent in the\n[google.rpc.Status.details][google.rpc.Status.details] field, or localized by the client."
|
||||
},
|
||||
"details": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/protobufAny"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-stream-definitions": {
|
||||
"openmatchQueryTicketsResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"result": {
|
||||
"$ref": "#/definitions/openmatchQueryTicketsResponse"
|
||||
},
|
||||
"error": {
|
||||
"$ref": "#/definitions/runtimeStreamError"
|
||||
},
|
||||
"description": "A list of messages that carry the error details. There is a common set of\nmessage types for APIs to use."
|
||||
}
|
||||
},
|
||||
"title": "Stream result of openmatchQueryTicketsResponse"
|
||||
"description": "The `Status` type defines a logical error model that is suitable for\ndifferent programming environments, including REST APIs and RPC APIs. It is\nused by [gRPC](https://github.com/grpc). Each `Status` message contains\nthree pieces of data: error code, error message, and error details.\n\nYou can find out more about this error model and how to work with it in the\n[API Design Guide](https://cloud.google.com/apis/design/errors)."
|
||||
}
|
||||
},
|
||||
"externalDocs": {
|
||||
|
@ -48,8 +48,8 @@
|
||||
|
||||
steps:
|
||||
- id: 'Docker Image: open-match-build'
|
||||
name: gcr.io/kaniko-project/executor
|
||||
args: ['--destination=gcr.io/$PROJECT_ID/open-match-build', '--cache=true', '--cache-ttl=48h', '--dockerfile=Dockerfile.ci']
|
||||
name: gcr.io/cloud-builders/docker
|
||||
args: ['build', '-t', 'gcr.io/$PROJECT_ID/open-match-build', '-f', 'Dockerfile.ci', '.']
|
||||
waitFor: ['-']
|
||||
|
||||
- id: 'Build: Clean'
|
||||
@ -90,7 +90,7 @@ steps:
|
||||
|
||||
- id: 'Build: Assets'
|
||||
name: 'gcr.io/$PROJECT_ID/open-match-build'
|
||||
args: ['make', 'assets', '-j12']
|
||||
args: ['make', '_CHARTS_BUCKET=${_CHARTS_BUCKET}', 'assets', '-j12']
|
||||
volumes:
|
||||
- name: 'go-vol'
|
||||
path: '/go'
|
||||
@ -132,7 +132,7 @@ steps:
|
||||
|
||||
- id: 'Deploy: Deployment Configs'
|
||||
name: 'gcr.io/$PROJECT_ID/open-match-build'
|
||||
args: ['make', '_GCB_POST_SUBMIT=${_GCB_POST_SUBMIT}', '_GCB_LATEST_VERSION=${_GCB_LATEST_VERSION}', 'SHORT_SHA=${SHORT_SHA}', 'BRANCH_NAME=${BRANCH_NAME}', 'ci-deploy-artifacts']
|
||||
args: ['make', '_GCB_POST_SUBMIT=${_GCB_POST_SUBMIT}', '_GCB_LATEST_VERSION=${_GCB_LATEST_VERSION}', 'SHORT_SHA=${SHORT_SHA}', 'BRANCH_NAME=${BRANCH_NAME}', '_CHARTS_BUCKET=${_CHARTS_BUCKET}', 'ci-deploy-artifacts']
|
||||
waitFor: ['Lint: Format, Vet, Charts', 'Test: Deploy Open Match']
|
||||
volumes:
|
||||
- name: 'go-vol'
|
||||
@ -153,7 +153,7 @@ steps:
|
||||
|
||||
artifacts:
|
||||
objects:
|
||||
location: gs://open-match-build-artifacts/output/
|
||||
location: '${_ARTIFACTS_BUCKET}'
|
||||
paths:
|
||||
- install/yaml/install.yaml
|
||||
- install/yaml/01-open-match-core.yaml
|
||||
@ -164,10 +164,13 @@ artifacts:
|
||||
- install/yaml/06-open-match-override-configmap.yaml
|
||||
|
||||
substitutions:
|
||||
_OM_VERSION: "0.0.0-dev"
|
||||
_OM_VERSION: "1.4.0-rc.1"
|
||||
_GCB_POST_SUBMIT: "0"
|
||||
_GCB_LATEST_VERSION: "undefined"
|
||||
logsBucket: 'gs://open-match-build-logs/'
|
||||
_ARTIFACTS_BUCKET: "gs://open-match-build-artifacts/output/"
|
||||
_LOGS_BUCKET: "gs://open-match-build-logs/"
|
||||
_CHARTS_BUCKET: "gs://open-match-chart"
|
||||
logsBucket: '${_LOGS_BUCKET}'
|
||||
options:
|
||||
sourceProvenanceHash: ['SHA256']
|
||||
machineType: 'N1_HIGHCPU_32'
|
||||
|
@ -16,11 +16,10 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"open-match.dev/open-match/internal/app"
|
||||
"open-match.dev/open-match/internal/app/backend"
|
||||
"open-match.dev/open-match/internal/config"
|
||||
"open-match.dev/open-match/internal/appmain"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app.RunApplication("backend", config.Read, backend.BindService)
|
||||
appmain.RunApplication("backend", backend.BindService)
|
||||
}
|
||||
|
@ -12,13 +12,13 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package e2e
|
||||
package main
|
||||
|
||||
import (
|
||||
"open-match.dev/open-match/internal/testing/e2e"
|
||||
"testing"
|
||||
"open-match.dev/open-match/internal/app/evaluator/defaulteval"
|
||||
"open-match.dev/open-match/internal/appmain"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
e2e.RunMain(m)
|
||||
func main() {
|
||||
appmain.RunApplication("evaluator", defaulteval.BindService)
|
||||
}
|
@ -16,11 +16,10 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"open-match.dev/open-match/internal/app"
|
||||
"open-match.dev/open-match/internal/app/frontend"
|
||||
"open-match.dev/open-match/internal/config"
|
||||
"open-match.dev/open-match/internal/appmain"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app.RunApplication("frontend", config.Read, frontend.BindService)
|
||||
appmain.RunApplication("frontend", frontend.BindService)
|
||||
}
|
||||
|
@ -16,11 +16,10 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"open-match.dev/open-match/internal/app"
|
||||
"open-match.dev/open-match/internal/app/minimatch"
|
||||
"open-match.dev/open-match/internal/config"
|
||||
"open-match.dev/open-match/internal/appmain"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app.RunApplication("minimatch", config.Read, minimatch.BindService)
|
||||
appmain.RunApplication("minimatch", minimatch.BindService)
|
||||
}
|
||||
|
@ -16,11 +16,10 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"open-match.dev/open-match/internal/app"
|
||||
"open-match.dev/open-match/internal/app/query"
|
||||
"open-match.dev/open-match/internal/config"
|
||||
"open-match.dev/open-match/internal/appmain"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app.RunApplication("query", config.Read, query.BindService)
|
||||
appmain.RunApplication("query", query.BindService)
|
||||
}
|
||||
|
@ -16,10 +16,9 @@ package main
|
||||
|
||||
import (
|
||||
"open-match.dev/open-match/examples/scale/backend"
|
||||
"open-match.dev/open-match/internal/app"
|
||||
"open-match.dev/open-match/internal/config"
|
||||
"open-match.dev/open-match/internal/appmain"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app.RunApplication("scale", config.Read, backend.BindService)
|
||||
appmain.RunApplication("scale", backend.BindService)
|
||||
}
|
||||
|
@ -16,10 +16,9 @@ package main
|
||||
|
||||
import (
|
||||
"open-match.dev/open-match/examples/scale/frontend"
|
||||
"open-match.dev/open-match/internal/app"
|
||||
"open-match.dev/open-match/internal/config"
|
||||
"open-match.dev/open-match/internal/appmain"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app.RunApplication("scale", config.Read, frontend.BindService)
|
||||
appmain.RunApplication("scale", frontend.BindService)
|
||||
}
|
||||
|
@ -16,11 +16,10 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"open-match.dev/open-match/internal/app"
|
||||
"open-match.dev/open-match/internal/app/synchronizer"
|
||||
"open-match.dev/open-match/internal/config"
|
||||
"open-match.dev/open-match/internal/appmain"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app.RunApplication("synchronizer", config.Read, synchronizer.BindService)
|
||||
appmain.RunApplication("synchronizer", synchronizer.BindService)
|
||||
}
|
||||
|
@ -9,14 +9,12 @@ To build Open Match you'll need the following applications installed.
|
||||
|
||||
* [Git](https://git-scm.com/downloads)
|
||||
* [Go](https://golang.org/doc/install)
|
||||
* [Python3 with virtualenv](https://wiki.python.org/moin/BeginnersGuide/Download)
|
||||
* Make (Mac: install [XCode](https://itunes.apple.com/us/app/xcode/id497799835))
|
||||
* [Docker](https://docs.docker.com/install/) including the
|
||||
[post-install steps](https://docs.docker.com/install/linux/linux-postinstall/).
|
||||
|
||||
Optional Software
|
||||
|
||||
* [Google Cloud Platform](gcloud.md)
|
||||
* [Visual Studio Code](https://code.visualstudio.com/Download) for IDE.
|
||||
Vim and Emacs work to.
|
||||
* [VirtualBox](https://www.virtualbox.org/wiki/Downloads) recommended for
|
||||
@ -27,8 +25,7 @@ running:
|
||||
|
||||
```bash
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y -q python3 python3-virtualenv virtualenv make \
|
||||
google-cloud-sdk git unzip tar
|
||||
sudo apt-get install -y -q make google-cloud-sdk git unzip tar
|
||||
```
|
||||
|
||||
*It's recommended that you install Go using their instructions because package
|
||||
@ -49,15 +46,13 @@ make
|
||||
|
||||
*Typically for contributing you'll want to
|
||||
[create a fork](https://help.github.com/en/articles/fork-a-repo) and use that
|
||||
but for purpose of this guide we'll be using the upstream/master.*
|
||||
but for purpose of this guide we'll be using the upstream/main.*
|
||||
|
||||
## Building
|
||||
## Building code and images
|
||||
|
||||
```bash
|
||||
# Reset workspace
|
||||
make clean
|
||||
# Compile all the binaries
|
||||
make all -j$(nproc)
|
||||
# Run tests
|
||||
make test
|
||||
# Build all the images.
|
||||
@ -87,11 +82,9 @@ default context the Makefile will honor that._
|
||||
# GKE cluster: make create-gke-cluster/delete-gke-cluster
|
||||
# or create a local Minikube cluster
|
||||
make create-gke-cluster
|
||||
# Step 2: Download helm and install Tiller in the cluster
|
||||
make push-helm
|
||||
# Step 3: Build and Push Open Match Images to gcr.io
|
||||
# Step 2: Build and Push Open Match Images to gcr.io
|
||||
make push-images -j$(nproc)
|
||||
# Install Open Match in the cluster.
|
||||
# Step 3: Install Open Match in the cluster.
|
||||
make install-chart
|
||||
|
||||
# Create a proxy to Open Match pods so that you can access them locally.
|
||||
@ -105,12 +98,29 @@ make proxy
|
||||
make delete-chart
|
||||
```
|
||||
|
||||
## Interaction
|
||||
## Iterating
|
||||
While iterating on the project, you may need to:
|
||||
1. Install/Run everything
|
||||
2. Make some code changes
|
||||
3. Make sure the changes compile by running `make test`
|
||||
4. Build and push Docker images to your personal registry by running `make push-images -j$(nproc)`
|
||||
5. Deploy the code change by running `make install-chart`
|
||||
6. Verify it's working by [looking at the logs](#accessing-logs) or looking at the monitoring dashboard by running `make proxy-grafana`
|
||||
7. Tear down Open Match by running `make delete-chart`
|
||||
|
||||
Before integrating with Open Match you can manually interact with it to get a feel for how it works.
|
||||
## Accessing logs
|
||||
To look at Open Match core services' logs, run:
|
||||
```bash
|
||||
# Replace open-match-frontend with the service name that you would like to access
|
||||
kubectl logs -n open-match svc/open-match-frontend
|
||||
```
|
||||
|
||||
`make proxy-ui` exposes the Swagger UI for Open Match locally on your computer.
|
||||
You can then go to http://localhost:51500 and view the API as well as interactively call Open Match.
|
||||
## API References
|
||||
While integrating with Open Match you may want to understand its API surface concepts or interact with it and get a feel for how it works.
|
||||
|
||||
The APIs are defined in `proto` format under the `api/` folder, with references available at [open-match.dev](https://open-match.dev/site/docs/reference/api/).
|
||||
|
||||
You can also run `make proxy-ui` to exposes the Swagger UI for Open Match locally on your computer after [deploying it to Kubernetes](#deploying-to-kubernetes), then go to http://localhost:51500 and view the REST APIs as well as interactively call Open Match.
|
||||
|
||||
By default you will be talking to the frontend server but you can change the target API url to any of the following:
|
||||
|
||||
@ -144,55 +154,9 @@ export GOPATH=$HOME/workspace/
|
||||
|
||||
## Pull Requests
|
||||
|
||||
If you want to submit a Pull Request there's some tools to help prepare your
|
||||
change.
|
||||
|
||||
```bash
|
||||
# Runs code generators, tests, and linters.
|
||||
make presubmit
|
||||
```
|
||||
|
||||
`make presubmit` catches most of the issues your change can run into. If the
|
||||
submit checks fail you can run it locally via,
|
||||
|
||||
```bash
|
||||
make local-cloud-build
|
||||
```
|
||||
If you want to submit a Pull Request, `make presubmit` can catch most of the issues your change can run into.
|
||||
|
||||
Our [continuous integration](https://console.cloud.google.com/cloud-build/builds?project=open-match-build)
|
||||
runs against all PRs. In order to see your build results you'll need to
|
||||
become a member of
|
||||
[open-match-discuss@googlegroups.com](https://groups.google.com/forum/#!forum/open-match-discuss).
|
||||
|
||||
|
||||
## Makefile
|
||||
|
||||
The Makefile is the core of Open Match's build process. There's a lot of
|
||||
commands but here's a list of the important ones and patterns to remember them.
|
||||
|
||||
```bash
|
||||
# Help
|
||||
make
|
||||
|
||||
# Reset workspace (delete all build artifacts)
|
||||
make clean
|
||||
# Delete auto-generated protobuf code and swagger API docs.
|
||||
make clean-protos clean-swagger-docs
|
||||
# make clean-* deletes some part of the build outputs.
|
||||
|
||||
# Build all Docker images
|
||||
make build-images
|
||||
# Build frontend docker image.
|
||||
make build-frontend-image
|
||||
|
||||
# Formats, Vets, and tests the codebase.
|
||||
make fmt vet test
|
||||
# Same as above also regenerates autogen files.
|
||||
make presubmit
|
||||
|
||||
# Run website on http://localhost:8080
|
||||
make run-site
|
||||
|
||||
# Proxy all Open Match processes to view them.
|
||||
make proxy
|
||||
```
|
||||
|
@ -12,24 +12,13 @@ SOURCE_VERSION=$1
|
||||
DEST_VERSION=$2
|
||||
SOURCE_PROJECT_ID=open-match-build
|
||||
DEST_PROJECT_ID=open-match-public-images
|
||||
IMAGE_NAMES="openmatch-backend openmatch-frontend openmatch-query openmatch-synchronizer openmatch-minimatch openmatch-demo-first-match openmatch-mmf-go-soloduel openmatch-mmf-go-pool openmatch-evaluator-go-simple openmatch-swaggerui openmatch-reaper"
|
||||
IMAGE_NAMES=$(make list-images)
|
||||
|
||||
for name in $IMAGE_NAMES
|
||||
do
|
||||
source_image=gcr.io/$SOURCE_PROJECT_ID/$name:$SOURCE_VERSION
|
||||
dest_image=gcr.io/$DEST_PROJECT_ID/$name:$DEST_VERSION
|
||||
source_image=gcr.io/$SOURCE_PROJECT_ID/openmatch-$name:$SOURCE_VERSION
|
||||
dest_image=gcr.io/$DEST_PROJECT_ID/openmatch-$name:$DEST_VERSION
|
||||
docker pull $source_image
|
||||
docker tag $source_image $dest_image
|
||||
docker push $dest_image
|
||||
done
|
||||
|
||||
echo "=============================================================="
|
||||
echo "=============================================================="
|
||||
echo "=============================================================="
|
||||
echo "=============================================================="
|
||||
|
||||
echo "Add these lines to your release notes:"
|
||||
for name in $IMAGE_NAMES
|
||||
do
|
||||
echo "docker pull gcr.io/$DEST_PROJECT_ID/$name:$DEST_VERSION"
|
||||
done
|
||||
|
7
docs/hugo_apiheader.txt
Normal file
7
docs/hugo_apiheader.txt
Normal file
@ -0,0 +1,7 @@
|
||||
---
|
||||
title: "Open Match API References"
|
||||
linkTitle: "Open Match API References"
|
||||
weight: 2
|
||||
description:
|
||||
This document provides API references for Open Match services.
|
||||
---
|
@ -37,7 +37,7 @@ func New() *ByteSub {
|
||||
}
|
||||
}
|
||||
|
||||
// AnnounceLatest writes b to all of the subscribers, with caviets listed in Subscribe.
|
||||
// AnnounceLatest writes b to all of the subscribers, with caveats listed in Subscribe.
|
||||
func (s *ByteSub) AnnounceLatest(b []byte) {
|
||||
s.r.Lock()
|
||||
defer s.r.Unlock()
|
||||
|
@ -51,7 +51,7 @@ func TestFastAndSlow(t *testing.T) {
|
||||
for count := 0; true; count++ {
|
||||
if v := <-slow; v == "3" {
|
||||
if count > 1 {
|
||||
t.Error("Expected to recieve at most 1 other value on slow before recieving the latest value.")
|
||||
t.Error("Expected to receive at most 1 other value on slow before receiving the latest value.")
|
||||
}
|
||||
break
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ func runScenario(ctx context.Context, name string, update updater.SetFunc) {
|
||||
update(s)
|
||||
|
||||
// See https://open-match.dev/site/docs/guides/api/
|
||||
conn, err := grpc.Dial("om-frontend.open-match.svc.cluster.local:50504", grpc.WithInsecure())
|
||||
conn, err := grpc.Dial("open-match-frontend.open-match.svc.cluster.local:50504", grpc.WithInsecure())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -102,7 +102,7 @@ func runScenario(ctx context.Context, name string, update updater.SetFunc) {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
ticketId = resp.Ticket.Id
|
||||
ticketId = resp.Id
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
@ -111,11 +111,11 @@ func runScenario(ctx context.Context, name string, update updater.SetFunc) {
|
||||
|
||||
var assignment *pb.Assignment
|
||||
{
|
||||
req := &pb.GetAssignmentsRequest{
|
||||
req := &pb.WatchAssignmentsRequest{
|
||||
TicketId: ticketId,
|
||||
}
|
||||
|
||||
stream, err := fe.GetAssignments(ctx, req)
|
||||
stream, err := fe.WatchAssignments(ctx, req)
|
||||
for assignment.GetConnection() == "" {
|
||||
resp, err := stream.Recv()
|
||||
if err != nil {
|
||||
|
@ -68,7 +68,7 @@ func run(ds *components.DemoShared) {
|
||||
ds.Update(s)
|
||||
|
||||
// See https://open-match.dev/site/docs/guides/api/
|
||||
conn, err := grpc.Dial("om-backend.open-match.svc.cluster.local:50505", grpc.WithInsecure())
|
||||
conn, err := grpc.Dial("open-match-backend.open-match.svc.cluster.local:50505", grpc.WithInsecure())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -131,9 +131,13 @@ func run(ds *components.DemoShared) {
|
||||
}
|
||||
|
||||
req := &pb.AssignTicketsRequest{
|
||||
TicketIds: ids,
|
||||
Assignment: &pb.Assignment{
|
||||
Connection: fmt.Sprintf("%d.%d.%d.%d:2222", rand.Intn(256), rand.Intn(256), rand.Intn(256), rand.Intn(256)),
|
||||
Assignments: []*pb.AssignmentGroup{
|
||||
{
|
||||
TicketIds: ids,
|
||||
Assignment: &pb.Assignment{
|
||||
Connection: fmt.Sprintf("%d.%d.%d.%d:2222", rand.Intn(256), rand.Intn(256), rand.Intn(256), rand.Intn(256)),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ type Updater struct {
|
||||
type SetFunc func(v interface{})
|
||||
|
||||
// New creates an Updater. Set is called when fields update, using the json
|
||||
// sererialized value of Updater's tree. All updates after ctx is canceled are
|
||||
// serialized value of Updater's tree. All updates after ctx is canceled are
|
||||
// ignored.
|
||||
func New(ctx context.Context, set func([]byte)) *Updater {
|
||||
f := func(v interface{}) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2019 Google LLC
|
||||
# Copyright 2020 Google LLC
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@ -14,11 +14,11 @@
|
||||
|
||||
FROM open-match-base-build as builder
|
||||
|
||||
WORKDIR /go/src/open-match.dev/open-match/test/matchfunction
|
||||
WORKDIR /go/src/open-match.dev/open-match/examples/functions/golang/backfill
|
||||
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o matchfunction .
|
||||
|
||||
FROM gcr.io/distroless/static:nonroot
|
||||
WORKDIR /app/
|
||||
COPY --from=builder --chown=nonroot /go/src/open-match.dev/open-match/test/matchfunction/matchfunction /app/
|
||||
COPY --from=builder --chown=nonroot /go/src/open-match.dev/open-match/examples/functions/golang/backfill/matchfunction /app/
|
||||
|
||||
ENTRYPOINT ["/app/matchfunction"]
|
||||
ENTRYPOINT ["/app/matchfunction"]
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2019 Google LLC
|
||||
// Copyright 2020 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@ -12,7 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package main a sample match function that uses the GRPC harness to set up
|
||||
// Package main defines a sample match function that uses the GRPC harness to set up
|
||||
// the match making function as a service. This sample is a reference
|
||||
// to demonstrate the usage of the GRPC harness and should only be used as
|
||||
// a starting point for your match function. You will need to modify the
|
||||
@ -20,16 +20,14 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
internalMmf "open-match.dev/open-match/internal/testing/mmf"
|
||||
"open-match.dev/open-match/test/matchfunction/mmf"
|
||||
"open-match.dev/open-match/examples/functions/golang/backfill/mmf"
|
||||
)
|
||||
|
||||
const (
|
||||
queryServiceAddr = "open-match-query.open-match.svc.cluster.local:50503" // Address of the QueryService endpoint.
|
||||
serverPort = 50502 // The port for hosting the Match Function.
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Invoke the harness to setup a GRPC service that handles requests to run the
|
||||
// match function. The harness itself queries open match for player pools for
|
||||
// the specified request and passes the pools to the match function to generate
|
||||
// proposals.
|
||||
internalMmf.RunMatchFunction(&internalMmf.FunctionSettings{
|
||||
Func: mmf.MakeMatches,
|
||||
})
|
||||
mmf.Start(queryServiceAddr, serverPort)
|
||||
}
|
297
examples/functions/golang/backfill/mmf/matchfunction.go
Normal file
297
examples/functions/golang/backfill/mmf/matchfunction.go
Normal file
@ -0,0 +1,297 @@
|
||||
// Copyright 2020 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.
|
||||
|
||||
// Package mmf provides a sample match function that uses the GRPC harness to set up 1v1 matches.
|
||||
// This sample is a reference to demonstrate the usage of backfill and should only be used as
|
||||
// a starting point for your match function. You will need to modify the
|
||||
// matchmaking logic in this function based on your game's requirements.
|
||||
package mmf
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"log"
|
||||
|
||||
"github.com/golang/protobuf/ptypes"
|
||||
"github.com/golang/protobuf/ptypes/any"
|
||||
"github.com/golang/protobuf/ptypes/wrappers"
|
||||
"google.golang.org/grpc"
|
||||
"open-match.dev/open-match/pkg/matchfunction"
|
||||
"open-match.dev/open-match/pkg/pb"
|
||||
)
|
||||
|
||||
const (
|
||||
playersPerMatch = 2
|
||||
openSlotsKey = "open-slots"
|
||||
matchName = "backfill-matchfunction"
|
||||
)
|
||||
|
||||
// matchFunctionService implements pb.MatchFunctionServer, the server generated
|
||||
// by compiling the protobuf, by fulfilling the pb.MatchFunctionServer interface.
|
||||
type matchFunctionService struct {
|
||||
grpc *grpc.Server
|
||||
queryServiceClient pb.QueryServiceClient
|
||||
port int
|
||||
}
|
||||
|
||||
func (s *matchFunctionService) Run(req *pb.RunRequest, stream pb.MatchFunction_RunServer) error {
|
||||
log.Printf("Generating proposals for function %v", req.GetProfile().GetName())
|
||||
|
||||
var proposals []*pb.Match
|
||||
profile := req.GetProfile()
|
||||
pools := profile.GetPools()
|
||||
|
||||
for _, p := range pools {
|
||||
tickets, err := matchfunction.QueryPool(stream.Context(), s.queryServiceClient, p)
|
||||
if err != nil {
|
||||
log.Printf("Failed to query tickets for the given pool, got %s", err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
backfills, err := matchfunction.QueryBackfillPool(stream.Context(), s.queryServiceClient, p)
|
||||
if err != nil {
|
||||
log.Printf("Failed to query backfills for the given pool, got %s", err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
matches, err := makeMatches(profile, p, tickets, backfills)
|
||||
if err != nil {
|
||||
log.Printf("Failed to generate matches, got %s", err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
proposals = append(proposals, matches...)
|
||||
}
|
||||
|
||||
log.Printf("Streaming %v proposals to Open Match", len(proposals))
|
||||
// Stream the generated proposals back to Open Match.
|
||||
for _, proposal := range proposals {
|
||||
if err := stream.Send(&pb.RunResponse{Proposal: proposal}); err != nil {
|
||||
log.Printf("Failed to stream proposals to Open Match, got %s", err.Error())
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// makeMatches tries to handle backfills at first, then it makes full matches, at the end it makes a match with backfill
|
||||
// if tickets left
|
||||
func makeMatches(profile *pb.MatchProfile, pool *pb.Pool, tickets []*pb.Ticket, backfills []*pb.Backfill) ([]*pb.Match, error) {
|
||||
var matches []*pb.Match
|
||||
newMatches, remainingTickets, err := handleBackfills(profile, tickets, backfills, len(matches))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
matches = append(matches, newMatches...)
|
||||
newMatches, remainingTickets = makeFullMatches(profile, remainingTickets, len(matches))
|
||||
matches = append(matches, newMatches...)
|
||||
|
||||
if len(remainingTickets) > 0 {
|
||||
match, err := makeMatchWithBackfill(profile, pool, remainingTickets, len(matches))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
matches = append(matches, match)
|
||||
}
|
||||
|
||||
return matches, nil
|
||||
}
|
||||
|
||||
// handleBackfills looks at each backfill's openSlots which is a number of required tickets,
|
||||
// acquires that tickets, decreases openSlots in backfill and makes a match with updated backfill and associated tickets.
|
||||
func handleBackfills(profile *pb.MatchProfile, tickets []*pb.Ticket, backfills []*pb.Backfill, lastMatchId int) ([]*pb.Match, []*pb.Ticket, error) {
|
||||
matchId := lastMatchId
|
||||
var matches []*pb.Match
|
||||
|
||||
for _, b := range backfills {
|
||||
openSlots, err := getOpenSlots(b)
|
||||
if err != nil {
|
||||
return nil, tickets, err
|
||||
}
|
||||
|
||||
var matchTickets []*pb.Ticket
|
||||
for openSlots > 0 && len(tickets) > 0 {
|
||||
matchTickets = append(matchTickets, tickets[0])
|
||||
tickets = tickets[1:]
|
||||
openSlots--
|
||||
}
|
||||
|
||||
if len(matchTickets) > 0 {
|
||||
err := setOpenSlots(b, openSlots)
|
||||
if err != nil {
|
||||
return nil, tickets, err
|
||||
}
|
||||
|
||||
matchId++
|
||||
match := newMatch(matchId, profile.Name, matchTickets, b)
|
||||
matches = append(matches, &match)
|
||||
}
|
||||
}
|
||||
|
||||
return matches, tickets, nil
|
||||
}
|
||||
|
||||
// makeMatchWithBackfill makes not full match, creates backfill for it with openSlots = playersPerMatch-len(tickets).
|
||||
func makeMatchWithBackfill(profile *pb.MatchProfile, pool *pb.Pool, tickets []*pb.Ticket, lastMatchId int) (*pb.Match, error) {
|
||||
if len(tickets) == 0 {
|
||||
return nil, fmt.Errorf("tickets are required")
|
||||
}
|
||||
|
||||
if len(tickets) >= playersPerMatch {
|
||||
return nil, fmt.Errorf("too many tickets")
|
||||
}
|
||||
|
||||
matchId := lastMatchId
|
||||
searchFields := newSearchFields(pool)
|
||||
backfill, err := newBackfill(searchFields, playersPerMatch-len(tickets))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
matchId++
|
||||
match := newMatch(matchId, profile.Name, tickets, backfill)
|
||||
// indicates that it is a new match and new game server should be allocated for it
|
||||
match.AllocateGameserver = true
|
||||
|
||||
return &match, nil
|
||||
}
|
||||
|
||||
// makeFullMatches makes matches without backfill
|
||||
func makeFullMatches(profile *pb.MatchProfile, tickets []*pb.Ticket, lastMatchId int) ([]*pb.Match, []*pb.Ticket) {
|
||||
ticketNum := 0
|
||||
matchId := lastMatchId
|
||||
var matches []*pb.Match
|
||||
|
||||
for ticketNum < playersPerMatch && len(tickets) >= playersPerMatch {
|
||||
ticketNum++
|
||||
|
||||
if ticketNum == playersPerMatch {
|
||||
matchId++
|
||||
|
||||
match := newMatch(matchId, profile.Name, tickets[:playersPerMatch], nil)
|
||||
matches = append(matches, &match)
|
||||
|
||||
tickets = tickets[playersPerMatch:]
|
||||
ticketNum = 0
|
||||
}
|
||||
}
|
||||
|
||||
return matches, tickets
|
||||
}
|
||||
|
||||
// newSearchFields creates search fields based on pool's search criteria. This is just example of how it can be done.
|
||||
func newSearchFields(pool *pb.Pool) *pb.SearchFields {
|
||||
searchFields := pb.SearchFields{}
|
||||
rangeFilters := pool.GetDoubleRangeFilters()
|
||||
|
||||
if rangeFilters != nil {
|
||||
doubleArgs := make(map[string]float64)
|
||||
for _, f := range rangeFilters {
|
||||
doubleArgs[f.DoubleArg] = (f.Max - f.Min) / 2
|
||||
}
|
||||
|
||||
if len(doubleArgs) > 0 {
|
||||
searchFields.DoubleArgs = doubleArgs
|
||||
}
|
||||
}
|
||||
|
||||
stringFilters := pool.GetStringEqualsFilters()
|
||||
|
||||
if stringFilters != nil {
|
||||
stringArgs := make(map[string]string)
|
||||
for _, f := range stringFilters {
|
||||
stringArgs[f.StringArg] = f.Value
|
||||
}
|
||||
|
||||
if len(stringArgs) > 0 {
|
||||
searchFields.StringArgs = stringArgs
|
||||
}
|
||||
}
|
||||
|
||||
tagFilters := pool.GetTagPresentFilters()
|
||||
|
||||
if tagFilters != nil {
|
||||
tags := make([]string, len(tagFilters))
|
||||
for _, f := range tagFilters {
|
||||
tags = append(tags, f.Tag)
|
||||
}
|
||||
|
||||
if len(tags) > 0 {
|
||||
searchFields.Tags = tags
|
||||
}
|
||||
}
|
||||
|
||||
return &searchFields
|
||||
}
|
||||
|
||||
func newBackfill(searchFields *pb.SearchFields, openSlots int) (*pb.Backfill, error) {
|
||||
b := pb.Backfill{
|
||||
SearchFields: searchFields,
|
||||
Generation: 0,
|
||||
CreateTime: ptypes.TimestampNow(),
|
||||
}
|
||||
|
||||
err := setOpenSlots(&b, int32(openSlots))
|
||||
return &b, err
|
||||
}
|
||||
|
||||
func newMatch(num int, profile string, tickets []*pb.Ticket, b *pb.Backfill) pb.Match {
|
||||
t := time.Now().Format("2006-01-02T15:04:05.00")
|
||||
|
||||
return pb.Match{
|
||||
MatchId: fmt.Sprintf("profile-%s-time-%s-num-%d", profile, t, num),
|
||||
MatchProfile: profile,
|
||||
MatchFunction: matchName,
|
||||
Tickets: tickets,
|
||||
Backfill: b,
|
||||
}
|
||||
}
|
||||
|
||||
func setOpenSlots(b *pb.Backfill, val int32) error {
|
||||
if b.Extensions == nil {
|
||||
b.Extensions = make(map[string]*any.Any)
|
||||
}
|
||||
|
||||
any, err := ptypes.MarshalAny(&wrappers.Int32Value{Value: val})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b.Extensions[openSlotsKey] = any
|
||||
return nil
|
||||
}
|
||||
|
||||
func getOpenSlots(b *pb.Backfill) (int32, error) {
|
||||
if b == nil {
|
||||
return 0, fmt.Errorf("expected backfill is not nil")
|
||||
}
|
||||
|
||||
if b.Extensions != nil {
|
||||
if any, ok := b.Extensions[openSlotsKey]; ok {
|
||||
var val wrappers.Int32Value
|
||||
err := ptypes.UnmarshalAny(any, &val)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return val.Value, nil
|
||||
}
|
||||
}
|
||||
|
||||
return playersPerMatch, nil
|
||||
}
|
142
examples/functions/golang/backfill/mmf/matchfunction_test.go
Normal file
142
examples/functions/golang/backfill/mmf/matchfunction_test.go
Normal file
@ -0,0 +1,142 @@
|
||||
// Copyright 2020 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.
|
||||
package mmf
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/golang/protobuf/ptypes"
|
||||
"github.com/golang/protobuf/ptypes/any"
|
||||
"github.com/golang/protobuf/ptypes/wrappers"
|
||||
"github.com/stretchr/testify/require"
|
||||
"open-match.dev/open-match/pkg/pb"
|
||||
)
|
||||
|
||||
func TestHandleBackfills(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
tickets []*pb.Ticket
|
||||
backfills []*pb.Backfill
|
||||
lastMatchId int
|
||||
expectedMatchLen int
|
||||
expectedTicketLen int
|
||||
expectedOpenSlots int32
|
||||
expectedErr bool
|
||||
}{
|
||||
{name: "returns no matches when no backfills specified", expectedMatchLen: 0, expectedTicketLen: 0},
|
||||
{name: "returns no matches when no tickets specified", expectedMatchLen: 0, expectedTicketLen: 0},
|
||||
{name: "returns a match with open slots decreased", tickets: []*pb.Ticket{{Id: "1"}}, backfills: []*pb.Backfill{withOpenSlots(1)}, expectedMatchLen: 1, expectedTicketLen: 0, expectedOpenSlots: playersPerMatch - 2},
|
||||
} {
|
||||
testCase := tc
|
||||
t.Run(testCase.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
profile := pb.MatchProfile{Name: "matchProfile"}
|
||||
matches, tickets, err := handleBackfills(&profile, testCase.tickets, testCase.backfills, testCase.lastMatchId)
|
||||
require.Equal(t, testCase.expectedErr, err != nil)
|
||||
require.Equal(t, testCase.expectedTicketLen, len(tickets))
|
||||
|
||||
if err != nil {
|
||||
require.Equal(t, 0, len(matches))
|
||||
} else {
|
||||
for _, m := range matches {
|
||||
require.NotNil(t, m.Backfill)
|
||||
|
||||
openSlots, err := getOpenSlots(m.Backfill)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, testCase.expectedOpenSlots, openSlots)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMakeMatchWithBackfill(t *testing.T) {
|
||||
for _, testCase := range []struct {
|
||||
name string
|
||||
tickets []*pb.Ticket
|
||||
lastMatchId int
|
||||
expectedOpenSlots int32
|
||||
expectedErr bool
|
||||
}{
|
||||
{name: "returns an error when length of tickets is greater then playerPerMatch", tickets: []*pb.Ticket{{Id: "1"}, {Id: "2"}, {Id: "3"}, {Id: "4"}, {Id: "5"}}, expectedErr: true},
|
||||
{name: "returns an error when length of tickets is equal to playerPerMatch", tickets: []*pb.Ticket{{Id: "1"}, {Id: "2"}, {Id: "3"}, {Id: "4"}}, expectedErr: true},
|
||||
{name: "returns an error when no tickets are provided", expectedErr: true},
|
||||
{name: "returns a match with backfill", tickets: []*pb.Ticket{{Id: "1"}}, expectedOpenSlots: playersPerMatch - 1},
|
||||
} {
|
||||
testCase := testCase
|
||||
t.Run(testCase.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
pool := pb.Pool{}
|
||||
profile := pb.MatchProfile{Name: "matchProfile"}
|
||||
match, err := makeMatchWithBackfill(&profile, &pool, testCase.tickets, testCase.lastMatchId)
|
||||
require.Equal(t, testCase.expectedErr, err != nil)
|
||||
|
||||
if err == nil {
|
||||
require.NotNil(t, match)
|
||||
require.NotNil(t, match.Backfill)
|
||||
require.True(t, match.AllocateGameserver)
|
||||
require.Equal(t, "", match.Backfill.Id)
|
||||
|
||||
openSlots, err := getOpenSlots(match.Backfill)
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, testCase.expectedOpenSlots, openSlots)
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func TestMakeFullMatches(t *testing.T) {
|
||||
for _, testCase := range []struct {
|
||||
name string
|
||||
tickets []*pb.Ticket
|
||||
lastMatchId int
|
||||
expectedMatchLen int
|
||||
expectedTicketLen int
|
||||
}{
|
||||
{name: "returns no matches when there are no tickets", tickets: []*pb.Ticket{}, expectedMatchLen: 0, expectedTicketLen: 0},
|
||||
{name: "returns no matches when length of tickets is less then playersPerMatch", tickets: []*pb.Ticket{{Id: "1"}}, expectedMatchLen: 0, expectedTicketLen: 1},
|
||||
{name: "returns a match when length of tickets is greater then playersPerMatch", tickets: []*pb.Ticket{{Id: "1"}, {Id: "2"}}, expectedMatchLen: 1, expectedTicketLen: 0},
|
||||
} {
|
||||
testCase := testCase
|
||||
t.Run(testCase.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
profile := pb.MatchProfile{Name: "matchProfile"}
|
||||
matches, tickets := makeFullMatches(&profile, testCase.tickets, testCase.lastMatchId)
|
||||
|
||||
require.Equal(t, testCase.expectedMatchLen, len(matches))
|
||||
require.Equal(t, testCase.expectedTicketLen, len(tickets))
|
||||
|
||||
for _, m := range matches {
|
||||
require.Nil(t, m.Backfill)
|
||||
require.Equal(t, playersPerMatch, len(m.Tickets))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func withOpenSlots(openSlots int) *pb.Backfill {
|
||||
val, err := ptypes.MarshalAny(&wrappers.Int32Value{Value: int32(openSlots)})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return &pb.Backfill{
|
||||
Extensions: map[string]*any.Any{
|
||||
openSlotsKey: val,
|
||||
},
|
||||
}
|
||||
}
|
59
examples/functions/golang/backfill/mmf/server.go
Normal file
59
examples/functions/golang/backfill/mmf/server.go
Normal file
@ -0,0 +1,59 @@
|
||||
// Copyright 2020 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.
|
||||
|
||||
// Package mmf provides a sample match function that uses the GRPC harness to set up 1v1 matches.
|
||||
// This sample is a reference to demonstrate the usage of backfill and should only be used as
|
||||
// a starting point for your match function. You will need to modify the
|
||||
// matchmaking logic in this function based on your game's requirements.
|
||||
package mmf
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"open-match.dev/open-match/pkg/pb"
|
||||
)
|
||||
|
||||
func Start(queryServiceAddr string, serverPort int) {
|
||||
// Connect to QueryService.
|
||||
conn, err := grpc.Dial(queryServiceAddr, grpc.WithInsecure())
|
||||
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to connect to Open Match, got %s", err.Error())
|
||||
}
|
||||
|
||||
defer conn.Close()
|
||||
|
||||
mmfService := matchFunctionService{
|
||||
queryServiceClient: pb.NewQueryServiceClient(conn),
|
||||
}
|
||||
|
||||
// Create and host a new gRPC service on the configured port.
|
||||
server := grpc.NewServer()
|
||||
pb.RegisterMatchFunctionServer(server, &mmfService)
|
||||
ln, err := net.Listen("tcp", fmt.Sprintf(":%d", serverPort))
|
||||
|
||||
if err != nil {
|
||||
log.Fatalf("TCP net listener initialization failed for port %v, got %s", serverPort, err.Error())
|
||||
}
|
||||
|
||||
log.Printf("TCP net listener initialized for port %v", serverPort)
|
||||
err = server.Serve(ln)
|
||||
|
||||
if err != nil {
|
||||
log.Fatalf("gRPC serve failed, got %s", err.Error())
|
||||
}
|
||||
}
|
@ -24,8 +24,8 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
queryServiceAddr = "om-query.open-match.svc.cluster.local:50503" // Address of the QueryService endpoint.
|
||||
serverPort = 50502 // The port for hosting the Match Function.
|
||||
queryServiceAddr = "open-match-query.open-match.svc.cluster.local:50503" // Address of the QueryService endpoint.
|
||||
serverPort = 50502 // The port for hosting the Match Function.
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
@ -19,11 +19,11 @@ import (
|
||||
|
||||
"open-match.dev/open-match/pkg/pb"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestMakeMatchesDeduplicate(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
require := require.New(t)
|
||||
|
||||
poolNameToTickets := map[string][]*pb.Ticket{
|
||||
"pool1": {{Id: "1"}},
|
||||
@ -31,12 +31,12 @@ func TestMakeMatchesDeduplicate(t *testing.T) {
|
||||
}
|
||||
|
||||
matches, err := makeMatches(poolNameToTickets)
|
||||
assert.Nil(err)
|
||||
assert.Equal(len(matches), 0)
|
||||
require.Nil(err)
|
||||
require.Equal(len(matches), 0)
|
||||
}
|
||||
|
||||
func TestMakeMatches(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
require := require.New(t)
|
||||
|
||||
poolNameToTickets := map[string][]*pb.Ticket{
|
||||
"pool1": {{Id: "1"}, {Id: "2"}, {Id: "3"}},
|
||||
@ -45,11 +45,11 @@ func TestMakeMatches(t *testing.T) {
|
||||
}
|
||||
|
||||
matches, err := makeMatches(poolNameToTickets)
|
||||
assert.Nil(err)
|
||||
assert.Equal(len(matches), 3)
|
||||
require.Nil(err)
|
||||
require.Equal(len(matches), 3)
|
||||
|
||||
for _, match := range matches {
|
||||
assert.Equal(2, len(match.Tickets))
|
||||
assert.Equal(matchName, match.MatchFunction)
|
||||
require.Equal(2, len(match.Tickets))
|
||||
require.Equal(matchName, match.MatchFunction)
|
||||
}
|
||||
}
|
||||
|
20
examples/scale/README.md
Normal file
20
examples/scale/README.md
Normal file
@ -0,0 +1,20 @@
|
||||
## How to use this framework
|
||||
|
||||
This is the framework that we use to benchmark Open Match against different matchmaking scenarios. For now (02/24/2020), this framework supports a Battle Royale, a Basic 1v1 matchmaking, and a Team Shooter scenario. You are welcome to write up your own `Scenario`, test it, and share the number that you are able to get to us.
|
||||
|
||||
1. The `Scenario` struct under the `scenarios/scenarios.go` file defines the parameters that this framework currently support/plan to support.
|
||||
2. Each subpackage `battleroyal`, `firstmatch`, and `teamshooter` implements to `GameScenario` interface defined under `scenarios/scenarios.go` file. Feel free to write your own benchmark scenario by implementing the interface.
|
||||
- Ticket `func() *pb.Ticket` - Tickets generator
|
||||
- Profiles `func() []*pb.MatchProfile` - Profiles generator
|
||||
- MMF `MatchFunction(p *pb.MatchProfile, poolTickets map[string][]*pb.Ticket) ([]*pb.Match, error)` - Custom matchmaking logic using a MatchProfile and a map struct that contains the mapping from pool name to the tickets of that pool.
|
||||
- Evaluate `Evaluate(stream pb.Evaluator_EvaluateServer) error` - Custom logic implementation of the evaluator.
|
||||
|
||||
Follow the instructions below if you want to use any of the existing benchmarking scenarios.
|
||||
|
||||
1. Open the `scenarios.go` file under the scenarios directory.
|
||||
2. Change the value of the `ActiveScenario` variable to the scenario that you would like Open Match to run against.
|
||||
3. Make sure you have `kubectl` connected to an existing Kubernetes cluster and run `make push-images` followed by `make install-scale-chart` to push the images and install Open Match core along with the scale components in the cluster.
|
||||
4. Run `make proxy`
|
||||
- Open `localhost:3000` to see the Grafana dashboards.
|
||||
- Open `localhost:9090` to see the Prometheus query server.
|
||||
- Open `localhost:[COMPONENT_HTTP_ENDPOINT]/help` to see how to access the zpages.
|
@ -25,6 +25,7 @@ import (
|
||||
"github.com/sirupsen/logrus"
|
||||
"go.opencensus.io/trace"
|
||||
"open-match.dev/open-match/examples/scale/scenarios"
|
||||
"open-match.dev/open-match/internal/appmain"
|
||||
"open-match.dev/open-match/internal/config"
|
||||
"open-match.dev/open-match/internal/rpc"
|
||||
"open-match.dev/open-match/internal/telemetry"
|
||||
@ -38,24 +39,23 @@ var (
|
||||
})
|
||||
|
||||
activeScenario = scenarios.ActiveScenario
|
||||
statProcessor = scenarios.NewStatProcessor()
|
||||
|
||||
mIterations = telemetry.Counter("scale_backend_iterations", "fetch match iterations")
|
||||
mFetchMatchCalls = telemetry.Counter("scale_backend_fetch_match_calls", "fetch match calls")
|
||||
mFetchMatchSuccesses = telemetry.Counter("scale_backend_fetch_match_successes", "fetch match successes")
|
||||
mFetchMatchErrors = telemetry.Counter("scale_backend_fetch_match_errors", "fetch match errors")
|
||||
mMatchesReturned = telemetry.Counter("scale_backend_matches_returned", "matches returned")
|
||||
mSumTicketsReturned = telemetry.Counter("scale_backend_sum_tickets_returned", "tickets in matches returned")
|
||||
mMatchesAssigned = telemetry.Counter("scale_backend_matches_assigned", "matches assigned")
|
||||
mMatchAssignsFailed = telemetry.Counter("scale_backend_match_assigns_failed", "match assigns failed")
|
||||
mTicketsDeleted = telemetry.Counter("scale_backend_tickets_deleted", "tickets deleted")
|
||||
mTicketDeletesFailed = telemetry.Counter("scale_backend_ticket_deletes_failed", "ticket deletes failed")
|
||||
mIterations = telemetry.Counter("scale_backend_iterations", "fetch match iterations")
|
||||
mFetchMatchCalls = telemetry.Counter("scale_backend_fetch_match_calls", "fetch match calls")
|
||||
mFetchMatchSuccesses = telemetry.Counter("scale_backend_fetch_match_successes", "fetch match successes")
|
||||
mFetchMatchErrors = telemetry.Counter("scale_backend_fetch_match_errors", "fetch match errors")
|
||||
mMatchesReturned = telemetry.Counter("scale_backend_matches_returned", "matches returned")
|
||||
mSumTicketsReturned = telemetry.Counter("scale_backend_sum_tickets_returned", "tickets in matches returned")
|
||||
mMatchesAssigned = telemetry.Counter("scale_backend_matches_assigned", "matches assigned")
|
||||
mMatchAssignsFailed = telemetry.Counter("scale_backend_match_assigns_failed", "match assigns failed")
|
||||
mBackfillsDeleted = telemetry.Counter("scale_backend_backfills_deleted", "backfills deleted")
|
||||
mBackfillDeletesFailed = telemetry.Counter("scale_backend_backfill_deletes_failed", "backfill deletes failed")
|
||||
)
|
||||
|
||||
// Run triggers execution of functions that continuously fetch, assign and
|
||||
// delete matches.
|
||||
func BindService(p *rpc.ServerParams, cfg config.View) error {
|
||||
go run(cfg)
|
||||
func BindService(p *appmain.Params, b *appmain.Bindings) error {
|
||||
go run(p.Config())
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -76,17 +76,31 @@ func run(cfg config.View) {
|
||||
defer feConn.Close()
|
||||
fe := pb.NewFrontendServiceClient(feConn)
|
||||
|
||||
startTime := time.Now()
|
||||
|
||||
w := logger.Writer()
|
||||
defer w.Close()
|
||||
|
||||
matchesForAssignment := make(chan *pb.Match, 30000)
|
||||
ticketsForDeletion := make(chan string, 30000)
|
||||
matchesToAssign := make(chan *pb.Match, 30000)
|
||||
|
||||
for i := 0; i < 50; i++ {
|
||||
go runAssignments(be, matchesForAssignment, ticketsForDeletion)
|
||||
go runDeletions(fe, ticketsForDeletion)
|
||||
if activeScenario.BackendAssignsTickets {
|
||||
for i := 0; i < 100; i++ {
|
||||
go runAssignments(be, matchesToAssign)
|
||||
}
|
||||
}
|
||||
|
||||
backfillsToDelete := make(chan *pb.Backfill, 30000)
|
||||
|
||||
if activeScenario.BackendDeletesBackfills {
|
||||
for i := 0; i < 100; i++ {
|
||||
go runDeleteBackfills(fe, backfillsToDelete)
|
||||
}
|
||||
}
|
||||
|
||||
matchesToAcknowledge := make(chan *pb.Match, 30000)
|
||||
|
||||
if activeScenario.BackendAcknowledgesBackfills {
|
||||
for i := 0; i < 100; i++ {
|
||||
go runAcknowledgeBackfills(fe, matchesToAcknowledge, backfillsToDelete)
|
||||
}
|
||||
}
|
||||
|
||||
// Don't go faster than this, as it likely means that FetchMatches is throwing
|
||||
@ -94,32 +108,29 @@ func run(cfg config.View) {
|
||||
for range time.Tick(time.Millisecond * 250) {
|
||||
// Keep pulling matches from Open Match backend
|
||||
profiles := activeScenario.Profiles()
|
||||
statProcessor.SetStat("TotalProfiles", len(profiles))
|
||||
var wg sync.WaitGroup
|
||||
|
||||
for _, p := range profiles {
|
||||
wg.Add(1)
|
||||
go func(wg *sync.WaitGroup, p *pb.MatchProfile) {
|
||||
defer wg.Done()
|
||||
runFetchMatches(be, p, matchesForAssignment)
|
||||
runFetchMatches(be, p, matchesToAssign, matchesToAcknowledge)
|
||||
}(&wg, p)
|
||||
}
|
||||
|
||||
// Wait for all profiles to complete before proceeding.
|
||||
wg.Wait()
|
||||
statProcessor.SetStat("TimeElapsed", time.Since(startTime).String())
|
||||
telemetry.RecordUnitMeasurement(context.Background(), mIterations)
|
||||
statProcessor.Log(w)
|
||||
}
|
||||
}
|
||||
|
||||
func runFetchMatches(be pb.BackendServiceClient, p *pb.MatchProfile, matchesForAssignment chan<- *pb.Match) {
|
||||
func runFetchMatches(be pb.BackendServiceClient, p *pb.MatchProfile, matchesToAssign chan<- *pb.Match, matchesToAcknowledge chan<- *pb.Match) {
|
||||
ctx, span := trace.StartSpan(context.Background(), "scale.backend/FetchMatches")
|
||||
defer span.End()
|
||||
|
||||
req := &pb.FetchMatchesRequest{
|
||||
Config: &pb.FunctionConfig{
|
||||
Host: "om-function",
|
||||
Host: "open-match-function",
|
||||
Port: 50502,
|
||||
Type: pb.FunctionConfig_GRPC,
|
||||
},
|
||||
@ -130,7 +141,7 @@ func runFetchMatches(be pb.BackendServiceClient, p *pb.MatchProfile, matchesForA
|
||||
stream, err := be.FetchMatches(ctx, req)
|
||||
if err != nil {
|
||||
telemetry.RecordUnitMeasurement(ctx, mFetchMatchErrors)
|
||||
statProcessor.RecordError("failed to get available stream client", err)
|
||||
logger.WithError(err).Error("failed to get available stream client")
|
||||
return
|
||||
}
|
||||
|
||||
@ -144,68 +155,97 @@ func runFetchMatches(be pb.BackendServiceClient, p *pb.MatchProfile, matchesForA
|
||||
|
||||
if err != nil {
|
||||
telemetry.RecordUnitMeasurement(ctx, mFetchMatchErrors)
|
||||
statProcessor.RecordError("failed to get matches from stream client", err)
|
||||
logger.WithError(err).Error("failed to get matches from stream client")
|
||||
return
|
||||
}
|
||||
|
||||
telemetry.RecordNUnitMeasurement(ctx, mSumTicketsReturned, int64(len(resp.GetMatch().Tickets)))
|
||||
telemetry.RecordUnitMeasurement(ctx, mMatchesReturned)
|
||||
statProcessor.IncrementStat("MatchCount", 1)
|
||||
|
||||
matchesForAssignment <- resp.GetMatch()
|
||||
if activeScenario.BackendAssignsTickets {
|
||||
matchesToAssign <- resp.GetMatch()
|
||||
}
|
||||
|
||||
if activeScenario.BackendAcknowledgesBackfills {
|
||||
matchesToAcknowledge <- resp.GetMatch()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func runAssignments(be pb.BackendServiceClient, matchesForAssignment <-chan *pb.Match, ticketsForDeletion chan<- string) {
|
||||
func runDeleteBackfills(fe pb.FrontendServiceClient, backfillsToDelete <-chan *pb.Backfill) {
|
||||
for b := range backfillsToDelete {
|
||||
if !activeScenario.BackfillDeleteCond(b) {
|
||||
continue
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
_, err := fe.DeleteBackfill(ctx, &pb.DeleteBackfillRequest{BackfillId: b.Id})
|
||||
if err != nil {
|
||||
logger.WithError(err).Errorf("failed to delete backfill: %s", b.Id)
|
||||
telemetry.RecordUnitMeasurement(ctx, mBackfillDeletesFailed)
|
||||
} else {
|
||||
telemetry.RecordUnitMeasurement(ctx, mBackfillsDeleted)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func runAcknowledgeBackfills(fe pb.FrontendServiceClient, matchesToAcknowledge <-chan *pb.Match, backfillsToDelete chan<- *pb.Backfill) {
|
||||
for m := range matchesToAcknowledge {
|
||||
backfillId := m.Backfill.GetId()
|
||||
if backfillId == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
err := acknowledgeBackfill(fe, backfillId)
|
||||
if err != nil {
|
||||
logger.WithError(err).Errorf("failed to acknowledge backfill: %s", backfillId)
|
||||
continue
|
||||
}
|
||||
|
||||
if activeScenario.BackendDeletesBackfills {
|
||||
backfillsToDelete <- m.Backfill
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func acknowledgeBackfill(fe pb.FrontendServiceClient, backfillId string) error {
|
||||
ctx, span := trace.StartSpan(context.Background(), "scale.frontend/AcknowledgeBackfill")
|
||||
defer span.End()
|
||||
|
||||
_, err := fe.AcknowledgeBackfill(ctx, &pb.AcknowledgeBackfillRequest{
|
||||
BackfillId: backfillId,
|
||||
Assignment: &pb.Assignment{
|
||||
Connection: fmt.Sprintf("%d.%d.%d.%d:2222", rand.Intn(256), rand.Intn(256), rand.Intn(256), rand.Intn(256)),
|
||||
},
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
func runAssignments(be pb.BackendServiceClient, matchesToAssign <-chan *pb.Match) {
|
||||
ctx := context.Background()
|
||||
|
||||
for m := range matchesForAssignment {
|
||||
for m := range matchesToAssign {
|
||||
ids := []string{}
|
||||
for _, t := range m.Tickets {
|
||||
ids = append(ids, t.GetId())
|
||||
}
|
||||
|
||||
if activeScenario.BackendAssignsTickets {
|
||||
_, err := be.AssignTickets(context.Background(), &pb.AssignTicketsRequest{
|
||||
TicketIds: ids,
|
||||
Assignment: &pb.Assignment{
|
||||
Connection: fmt.Sprintf("%d.%d.%d.%d:2222", rand.Intn(256), rand.Intn(256), rand.Intn(256), rand.Intn(256)),
|
||||
_, err := be.AssignTickets(context.Background(), &pb.AssignTicketsRequest{
|
||||
Assignments: []*pb.AssignmentGroup{
|
||||
{
|
||||
TicketIds: ids,
|
||||
Assignment: &pb.Assignment{
|
||||
Connection: fmt.Sprintf("%d.%d.%d.%d:2222", rand.Intn(256), rand.Intn(256), rand.Intn(256), rand.Intn(256)),
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
telemetry.RecordUnitMeasurement(ctx, mMatchAssignsFailed)
|
||||
statProcessor.RecordError("failed to assign tickets", err)
|
||||
continue
|
||||
}
|
||||
|
||||
telemetry.RecordUnitMeasurement(ctx, mMatchesAssigned)
|
||||
statProcessor.IncrementStat("Assigned", len(ids))
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
telemetry.RecordUnitMeasurement(ctx, mMatchAssignsFailed)
|
||||
logger.WithError(err).Error("failed to assign tickets")
|
||||
continue
|
||||
}
|
||||
|
||||
for _, id := range ids {
|
||||
ticketsForDeletion <- id
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func runDeletions(fe pb.FrontendServiceClient, ticketsForDeletion <-chan string) {
|
||||
ctx := context.Background()
|
||||
|
||||
for id := range ticketsForDeletion {
|
||||
if activeScenario.BackendDeletesTickets {
|
||||
req := &pb.DeleteTicketRequest{
|
||||
TicketId: id,
|
||||
}
|
||||
|
||||
_, err := fe.DeleteTicket(context.Background(), req)
|
||||
|
||||
if err == nil {
|
||||
telemetry.RecordUnitMeasurement(ctx, mTicketsDeleted)
|
||||
statProcessor.IncrementStat("Deleted", 1)
|
||||
} else {
|
||||
telemetry.RecordUnitMeasurement(ctx, mTicketDeletesFailed)
|
||||
statProcessor.RecordError("failed to delete tickets", err)
|
||||
}
|
||||
}
|
||||
telemetry.RecordUnitMeasurement(ctx, mMatchesAssigned)
|
||||
}
|
||||
}
|
||||
|
@ -16,13 +16,15 @@ package frontend
|
||||
|
||||
import (
|
||||
"context"
|
||||
"math/rand"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"go.opencensus.io/stats"
|
||||
"go.opencensus.io/trace"
|
||||
"open-match.dev/open-match/examples/scale/scenarios"
|
||||
"open-match.dev/open-match/internal/appmain"
|
||||
"open-match.dev/open-match/internal/config"
|
||||
"open-match.dev/open-match/internal/rpc"
|
||||
"open-match.dev/open-match/internal/telemetry"
|
||||
@ -34,20 +36,28 @@ var (
|
||||
"app": "openmatch",
|
||||
"component": "scale.frontend",
|
||||
})
|
||||
activeScenario = scenarios.ActiveScenario
|
||||
statProcessor = scenarios.NewStatProcessor()
|
||||
numOfRoutineCreate = 8
|
||||
activeScenario = scenarios.ActiveScenario
|
||||
|
||||
totalCreated uint32
|
||||
|
||||
mTicketsCreated = telemetry.Counter("scale_frontend_tickets_created", "tickets created")
|
||||
mTicketCreationsFailed = telemetry.Counter("scale_frontend_ticket_creations_failed", "tickets created")
|
||||
mTicketsCreated = telemetry.Counter("scale_frontend_tickets_created", "tickets created")
|
||||
mTicketCreationsFailed = telemetry.Counter("scale_frontend_ticket_creations_failed", "tickets created")
|
||||
mRunnersWaiting = concurrentGauge(telemetry.Gauge("scale_frontend_runners_waiting", "runners waiting"))
|
||||
mRunnersCreating = concurrentGauge(telemetry.Gauge("scale_frontend_runners_creating", "runners creating"))
|
||||
mTicketsDeleted = telemetry.Counter("scale_frontend_tickets_deleted", "tickets deleted")
|
||||
mTicketDeletesFailed = telemetry.Counter("scale_frontend_ticket_deletes_failed", "ticket deletes failed")
|
||||
mBackfillsCreated = telemetry.Counter("scale_frontend_backfills_created", "backfills_created")
|
||||
mBackfillCreationsFailed = telemetry.Counter("scale_frontend_backfill_creations_failed", "backfill creations failed")
|
||||
mTicketsTimeToAssignment = telemetry.HistogramWithBounds("scale_frontend_tickets_time_to_assignment", "tickets time to assignment", stats.UnitMilliseconds, []float64{0.01, 0.05, 0.1, 0.3, 0.6, 0.8, 1, 2, 3, 4, 5, 6, 8, 10, 13, 16, 20, 25, 30, 40, 50, 65, 80, 100, 130, 160, 200, 250, 300, 400, 500, 650, 800, 1000, 2000, 5000, 10000, 20000, 50000, 100000, 200000, 500000, 1000000})
|
||||
)
|
||||
|
||||
type ticketToWatch struct {
|
||||
id string
|
||||
createdAt time.Time
|
||||
}
|
||||
|
||||
// Run triggers execution of the scale frontend component that creates
|
||||
// tickets at scale in Open Match.
|
||||
func BindService(p *rpc.ServerParams, cfg config.View) error {
|
||||
go run(cfg)
|
||||
func BindService(p *appmain.Params, b *appmain.Bindings) error {
|
||||
go run(p.Config())
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -61,75 +71,171 @@ func run(cfg config.View) {
|
||||
}
|
||||
fe := pb.NewFrontendServiceClient(conn)
|
||||
|
||||
w := logger.Writer()
|
||||
defer w.Close()
|
||||
if activeScenario.FrontendCreatesBackfillsOnStart {
|
||||
createBackfills(fe, activeScenario.FrontendTotalBackfillsToCreate)
|
||||
}
|
||||
|
||||
ticketQPS := int(activeScenario.FrontendTicketCreatedQPS)
|
||||
ticketTotal := activeScenario.FrontendTotalTicketsToCreate
|
||||
totalCreated := 0
|
||||
|
||||
for {
|
||||
currentCreated := int(atomic.LoadUint32(&totalCreated))
|
||||
if ticketTotal != -1 && currentCreated >= ticketTotal {
|
||||
break
|
||||
}
|
||||
|
||||
// Each inner loop creates TicketCreatedQPS tickets
|
||||
var ticketPerRoutine, ticketModRoutine int
|
||||
start := time.Now()
|
||||
|
||||
if ticketTotal == -1 || currentCreated+ticketQPS <= ticketTotal {
|
||||
ticketPerRoutine = ticketQPS / numOfRoutineCreate
|
||||
ticketModRoutine = ticketQPS % numOfRoutineCreate
|
||||
} else {
|
||||
ticketPerRoutine = (ticketTotal - currentCreated) / numOfRoutineCreate
|
||||
ticketModRoutine = (ticketTotal - currentCreated) % numOfRoutineCreate
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
for i := 0; i < numOfRoutineCreate; i++ {
|
||||
wg.Add(1)
|
||||
if i < ticketModRoutine {
|
||||
go createPerCycle(&wg, fe, ticketPerRoutine+1, start)
|
||||
} else {
|
||||
go createPerCycle(&wg, fe, ticketPerRoutine, start)
|
||||
for range time.Tick(time.Second) {
|
||||
for i := 0; i < ticketQPS; i++ {
|
||||
if ticketTotal == -1 || totalCreated < ticketTotal {
|
||||
go runner(fe)
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for all concurrent creates to complete.
|
||||
wg.Wait()
|
||||
statProcessor.SetStat("TotalCreated", atomic.LoadUint32(&totalCreated))
|
||||
statProcessor.Log(w)
|
||||
}
|
||||
}
|
||||
|
||||
func createPerCycle(wg *sync.WaitGroup, fe pb.FrontendServiceClient, ticketPerRoutine int, start time.Time) {
|
||||
defer wg.Done()
|
||||
cycleCreated := 0
|
||||
func runner(fe pb.FrontendServiceClient) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
for j := 0; j < ticketPerRoutine; j++ {
|
||||
req := &pb.CreateTicketRequest{
|
||||
Ticket: activeScenario.Ticket(),
|
||||
g := stateGauge{}
|
||||
defer g.stop()
|
||||
|
||||
g.start(mRunnersWaiting)
|
||||
// A random sleep at the start of the worker evens calls out over the second
|
||||
// period, and makes timing between ticket creation calls a more realistic
|
||||
// poisson distribution.
|
||||
time.Sleep(time.Duration(rand.Int63n(int64(time.Second))))
|
||||
|
||||
g.start(mRunnersCreating)
|
||||
createdAt := time.Now()
|
||||
id, err := createTicket(ctx, fe)
|
||||
if err != nil {
|
||||
logger.WithError(err).Error("failed to create a ticket")
|
||||
return
|
||||
}
|
||||
|
||||
err = watchAssignments(ctx, fe, ticketToWatch{id: id, createdAt: createdAt})
|
||||
if err != nil {
|
||||
logger.WithError(err).Errorf("failed to get ticket assignment: %s", id)
|
||||
} else {
|
||||
ms := time.Since(createdAt).Nanoseconds() / 1e6
|
||||
stats.Record(ctx, mTicketsTimeToAssignment.M(ms))
|
||||
}
|
||||
|
||||
if activeScenario.FrontendDeletesTickets {
|
||||
err = deleteTicket(ctx, fe, id)
|
||||
if err != nil {
|
||||
logger.WithError(err).Errorf("failed to delete ticket: %s", id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func createTicket(ctx context.Context, fe pb.FrontendServiceClient) (string, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "scale.frontend/CreateTicket")
|
||||
defer span.End()
|
||||
|
||||
req := &pb.CreateTicketRequest{
|
||||
Ticket: activeScenario.Ticket(),
|
||||
}
|
||||
|
||||
resp, err := fe.CreateTicket(ctx, req)
|
||||
if err != nil {
|
||||
telemetry.RecordUnitMeasurement(ctx, mTicketCreationsFailed)
|
||||
return "", err
|
||||
}
|
||||
|
||||
telemetry.RecordUnitMeasurement(ctx, mTicketsCreated)
|
||||
return resp.Id, nil
|
||||
}
|
||||
|
||||
func watchAssignments(ctx context.Context, fe pb.FrontendServiceClient, ticket ticketToWatch) error {
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
defer cancel()
|
||||
stream, err := fe.WatchAssignments(ctx, &pb.WatchAssignmentsRequest{TicketId: ticket.id})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var a *pb.Assignment
|
||||
for a.GetConnection() == "" {
|
||||
resp, err := stream.Recv()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ctx, span := trace.StartSpan(context.Background(), "scale.frontend/CreateTicket")
|
||||
defer span.End()
|
||||
a = resp.Assignment
|
||||
}
|
||||
|
||||
timeLeft := start.Add(time.Second).Sub(time.Now())
|
||||
if timeLeft <= 0 {
|
||||
break
|
||||
}
|
||||
ticketsLeft := ticketPerRoutine - cycleCreated
|
||||
return nil
|
||||
}
|
||||
|
||||
time.Sleep(timeLeft / time.Duration(ticketsLeft))
|
||||
|
||||
if _, err := fe.CreateTicket(ctx, req); err == nil {
|
||||
cycleCreated++
|
||||
telemetry.RecordUnitMeasurement(ctx, mTicketsCreated)
|
||||
} else {
|
||||
statProcessor.RecordError("failed to create a ticket", err)
|
||||
telemetry.RecordUnitMeasurement(ctx, mTicketCreationsFailed)
|
||||
func createBackfills(fe pb.FrontendServiceClient, numBackfillsToCreate int) error {
|
||||
for i := 0; i < numBackfillsToCreate; i++ {
|
||||
err := createBackfill(fe)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
atomic.AddUint32(&totalCreated, uint32(cycleCreated))
|
||||
return nil
|
||||
}
|
||||
|
||||
func createBackfill(fe pb.FrontendServiceClient) error {
|
||||
ctx, span := trace.StartSpan(context.Background(), "scale.frontend/CreateBackfill")
|
||||
defer span.End()
|
||||
|
||||
req := pb.CreateBackfillRequest{
|
||||
Backfill: activeScenario.Backfill(),
|
||||
}
|
||||
|
||||
_, err := fe.CreateBackfill(ctx, &req)
|
||||
if err != nil {
|
||||
telemetry.RecordUnitMeasurement(ctx, mBackfillCreationsFailed)
|
||||
logger.WithError(err).Error("failed to create backfill")
|
||||
return err
|
||||
}
|
||||
|
||||
telemetry.RecordUnitMeasurement(ctx, mBackfillsCreated)
|
||||
return nil
|
||||
}
|
||||
|
||||
func deleteTicket(ctx context.Context, fe pb.FrontendServiceClient, ticketId string) error {
|
||||
_, err := fe.DeleteTicket(ctx, &pb.DeleteTicketRequest{TicketId: ticketId})
|
||||
if err != nil {
|
||||
telemetry.RecordUnitMeasurement(ctx, mTicketDeletesFailed)
|
||||
} else {
|
||||
telemetry.RecordUnitMeasurement(ctx, mTicketsDeleted)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// Allows concurrent moficiation of a gauge value by modifying the concurrent
|
||||
// value with a delta.
|
||||
func concurrentGauge(s *stats.Int64Measure) func(delta int64) {
|
||||
m := sync.Mutex{}
|
||||
v := int64(0)
|
||||
return func(delta int64) {
|
||||
m.Lock()
|
||||
defer m.Unlock()
|
||||
|
||||
v += delta
|
||||
telemetry.SetGauge(context.Background(), s, v)
|
||||
}
|
||||
}
|
||||
|
||||
// stateGauge will have a single value be applied to one gauge at a time.
|
||||
type stateGauge struct {
|
||||
f func(int64)
|
||||
}
|
||||
|
||||
// start begins a stage measured in a gauge, stopping any previously started
|
||||
// stage.
|
||||
func (g *stateGauge) start(f func(int64)) {
|
||||
g.stop()
|
||||
g.f = f
|
||||
f(1)
|
||||
}
|
||||
|
||||
// stop finishes the current stage by decrementing the gauge.
|
||||
func (g *stateGauge) stop() {
|
||||
if g.f != nil {
|
||||
g.f(-1)
|
||||
g.f = nil
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ var (
|
||||
func Run() {
|
||||
activeScenario := scenarios.ActiveScenario
|
||||
|
||||
conn, err := grpc.Dial("om-query.open-match.svc.cluster.local:50503", utilTesting.NewGRPCDialOptions(logger)...)
|
||||
conn, err := grpc.Dial("open-match-query.open-match.svc.cluster.local:50503", utilTesting.NewGRPCDialOptions(logger)...)
|
||||
if err != nil {
|
||||
logger.Fatalf("Failed to connect to Open Match, got %v", err)
|
||||
}
|
||||
|
271
examples/scale/scenarios/backfill/backfill.go
Normal file
271
examples/scale/scenarios/backfill/backfill.go
Normal file
@ -0,0 +1,271 @@
|
||||
// Copyright 2020 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.
|
||||
|
||||
package backfill
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"github.com/golang/protobuf/ptypes"
|
||||
"github.com/golang/protobuf/ptypes/any"
|
||||
"github.com/golang/protobuf/ptypes/wrappers"
|
||||
"open-match.dev/open-match/pkg/pb"
|
||||
)
|
||||
|
||||
const (
|
||||
poolName = "all"
|
||||
openSlotsKey = "open-slots"
|
||||
)
|
||||
|
||||
func Scenario() *BackfillScenario {
|
||||
ticketsPerMatch := 4
|
||||
return &BackfillScenario{
|
||||
TicketsPerMatch: ticketsPerMatch,
|
||||
MaxTicketsPerNotFullMatch: 3,
|
||||
BackfillDeleteCond: func(b *pb.Backfill) bool {
|
||||
openSlots := getOpenSlots(b, ticketsPerMatch)
|
||||
return openSlots <= 0
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type BackfillScenario struct {
|
||||
TicketsPerMatch int
|
||||
MaxTicketsPerNotFullMatch int
|
||||
BackfillDeleteCond func(*pb.Backfill) bool
|
||||
}
|
||||
|
||||
func (s *BackfillScenario) Profiles() []*pb.MatchProfile {
|
||||
return []*pb.MatchProfile{
|
||||
{
|
||||
Name: "entirePool",
|
||||
Pools: []*pb.Pool{
|
||||
{
|
||||
Name: poolName,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (s *BackfillScenario) Ticket() *pb.Ticket {
|
||||
return &pb.Ticket{}
|
||||
}
|
||||
|
||||
func (s *BackfillScenario) Backfill() *pb.Backfill {
|
||||
return &pb.Backfill{}
|
||||
}
|
||||
|
||||
func (s *BackfillScenario) MatchFunction(p *pb.MatchProfile, poolBackfills map[string][]*pb.Backfill, poolTickets map[string][]*pb.Ticket) ([]*pb.Match, error) {
|
||||
return statefullMMF(p, poolBackfills, poolTickets, s.TicketsPerMatch, s.MaxTicketsPerNotFullMatch)
|
||||
}
|
||||
|
||||
// statefullMMF is a MMF implementation which is used in scenario when we want MMF to create not full match and fill it later.
|
||||
// 1. The first FetchMatches is called
|
||||
// 2. MMF grabs maxTicketsPerNotFullMatch tickets and makes a match and new backfill for it
|
||||
// 3. MMF sets backfill's open slots to ticketsPerMatch - maxTicketsPerNotFullMatch
|
||||
// 4. MMF returns the match as a result
|
||||
// 5. The second FetchMatches is called
|
||||
// 6. MMF gets previously created backfill
|
||||
// 7. MMF gets backfill's open slots value
|
||||
// 8. MMF grabs openSlots tickets and makes a match with previously created backfill
|
||||
// 9. MMF sets backfill's open slots to 0
|
||||
// 10. MMF returns the match as a result
|
||||
func statefullMMF(p *pb.MatchProfile, poolBackfills map[string][]*pb.Backfill, poolTickets map[string][]*pb.Ticket, ticketsPerMatch int, maxTicketsPerNotFullMatch int) ([]*pb.Match, error) {
|
||||
var matches []*pb.Match
|
||||
|
||||
for pool, backfills := range poolBackfills {
|
||||
tickets, ok := poolTickets[pool]
|
||||
|
||||
if !ok || len(tickets) == 0 {
|
||||
// no tickets in pool
|
||||
continue
|
||||
}
|
||||
|
||||
// process backfills first
|
||||
for _, b := range backfills {
|
||||
l := len(tickets)
|
||||
if l == 0 {
|
||||
// no tickets left
|
||||
break
|
||||
}
|
||||
|
||||
openSlots := getOpenSlots(b, ticketsPerMatch)
|
||||
if openSlots <= 0 {
|
||||
// no free open slots
|
||||
continue
|
||||
}
|
||||
|
||||
if l > openSlots {
|
||||
l = openSlots
|
||||
}
|
||||
|
||||
setOpenSlots(b, openSlots-l)
|
||||
matches = append(matches, &pb.Match{
|
||||
MatchId: fmt.Sprintf("profile-%v-time-%v-%v", p.GetName(), time.Now().Format("2006-01-02T15:04:05.00"), len(matches)),
|
||||
Tickets: tickets[0:l],
|
||||
MatchProfile: p.GetName(),
|
||||
MatchFunction: "backfill",
|
||||
Backfill: b,
|
||||
})
|
||||
tickets = tickets[l:]
|
||||
}
|
||||
|
||||
// create not full matches with backfill
|
||||
for {
|
||||
l := len(tickets)
|
||||
if l == 0 {
|
||||
// no tickets left
|
||||
break
|
||||
}
|
||||
|
||||
if l > maxTicketsPerNotFullMatch {
|
||||
l = maxTicketsPerNotFullMatch
|
||||
}
|
||||
b := pb.Backfill{}
|
||||
setOpenSlots(&b, ticketsPerMatch-l)
|
||||
matches = append(matches, &pb.Match{
|
||||
MatchId: fmt.Sprintf("profile-%v-time-%v-%v", p.GetName(), time.Now().Format("2006-01-02T15:04:05.00"), len(matches)),
|
||||
Tickets: tickets[0:l],
|
||||
MatchProfile: p.GetName(),
|
||||
MatchFunction: "backfill",
|
||||
Backfill: &b,
|
||||
AllocateGameserver: true,
|
||||
})
|
||||
tickets = tickets[l:]
|
||||
}
|
||||
}
|
||||
|
||||
return matches, nil
|
||||
}
|
||||
|
||||
func getOpenSlots(b *pb.Backfill, defaultVal int) int {
|
||||
if b.Extensions == nil {
|
||||
return defaultVal
|
||||
}
|
||||
|
||||
any, ok := b.Extensions[openSlotsKey]
|
||||
if !ok {
|
||||
return defaultVal
|
||||
}
|
||||
|
||||
var val wrappers.Int32Value
|
||||
err := ptypes.UnmarshalAny(any, &val)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return int(val.Value)
|
||||
}
|
||||
|
||||
func setOpenSlots(b *pb.Backfill, val int) {
|
||||
if b.Extensions == nil {
|
||||
b.Extensions = make(map[string]*any.Any)
|
||||
}
|
||||
|
||||
any, err := ptypes.MarshalAny(&wrappers.Int32Value{Value: int32(val)})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
b.Extensions[openSlotsKey] = any
|
||||
}
|
||||
|
||||
// statelessMMF is a MMF implementation which is used in scenario when we want MMF to fill backfills created by a Gameserver. It doesn't create
|
||||
// or update any backfill.
|
||||
// 1. FetchMatches is called
|
||||
// 2. MMF gets a backfill
|
||||
// 3. MMF grabs ticketsPerMatch tickets and makes a match with the backfill
|
||||
// 4. MMF returns the match as a result
|
||||
func statelessMMF(p *pb.MatchProfile, poolBackfills map[string][]*pb.Backfill, poolTickets map[string][]*pb.Ticket, ticketsPerMatch int) ([]*pb.Match, error) {
|
||||
var matches []*pb.Match
|
||||
|
||||
for pool, backfills := range poolBackfills {
|
||||
tickets, ok := poolTickets[pool]
|
||||
|
||||
if !ok || len(tickets) == 0 {
|
||||
// no tickets in pool
|
||||
continue
|
||||
}
|
||||
|
||||
for _, b := range backfills {
|
||||
l := len(tickets)
|
||||
if l == 0 {
|
||||
// no tickets left
|
||||
break
|
||||
}
|
||||
|
||||
if l > ticketsPerMatch && ticketsPerMatch > 0 {
|
||||
l = ticketsPerMatch
|
||||
}
|
||||
|
||||
matches = append(matches, &pb.Match{
|
||||
MatchId: fmt.Sprintf("profile-%v-time-%v-%v", p.GetName(), time.Now().Format("2006-01-02T15:04:05.00"), len(matches)),
|
||||
Tickets: tickets[0:l],
|
||||
MatchProfile: p.GetName(),
|
||||
MatchFunction: "backfill",
|
||||
Backfill: b,
|
||||
})
|
||||
tickets = tickets[l:]
|
||||
}
|
||||
}
|
||||
|
||||
return matches, nil
|
||||
}
|
||||
|
||||
func (s *BackfillScenario) Evaluate(stream pb.Evaluator_EvaluateServer) error {
|
||||
tickets := map[string]struct{}{}
|
||||
backfills := map[string]struct{}{}
|
||||
matchIds := []string{}
|
||||
|
||||
outer:
|
||||
for {
|
||||
req, err := stream.Recv()
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to read evaluator input stream: %w", err)
|
||||
}
|
||||
|
||||
m := req.GetMatch()
|
||||
|
||||
if _, ok := backfills[m.Backfill.Id]; ok {
|
||||
continue outer
|
||||
}
|
||||
|
||||
for _, t := range m.Tickets {
|
||||
if _, ok := tickets[t.Id]; ok {
|
||||
continue outer
|
||||
}
|
||||
}
|
||||
|
||||
for _, t := range m.Tickets {
|
||||
tickets[t.Id] = struct{}{}
|
||||
}
|
||||
|
||||
matchIds = append(matchIds, m.GetMatchId())
|
||||
}
|
||||
|
||||
for _, id := range matchIds {
|
||||
err := stream.Send(&pb.EvaluateResponse{MatchId: id})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to sending evaluator output stream: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
package scenarios
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
"open-match.dev/open-match/pkg/pb"
|
||||
)
|
||||
|
||||
const (
|
||||
battleRoyalRegions = 20
|
||||
regionArg = "region"
|
||||
)
|
||||
|
||||
var (
|
||||
battleRoyalScenario = &Scenario{
|
||||
MMF: queryPoolsWrapper(battleRoyalMmf),
|
||||
Evaluator: fifoEvaluate,
|
||||
FrontendTotalTicketsToCreate: -1,
|
||||
FrontendTicketCreatedQPS: 100,
|
||||
BackendAssignsTickets: true,
|
||||
BackendDeletesTickets: true,
|
||||
Ticket: battleRoyalTicket,
|
||||
Profiles: battleRoyalProfile,
|
||||
}
|
||||
)
|
||||
|
||||
func battleRoyalProfile() []*pb.MatchProfile {
|
||||
p := []*pb.MatchProfile{}
|
||||
|
||||
for i := 0; i < battleRoyalRegions; i++ {
|
||||
p = append(p, &pb.MatchProfile{
|
||||
Name: battleRoyalRegionName(i),
|
||||
Pools: []*pb.Pool{
|
||||
{
|
||||
Name: poolName,
|
||||
StringEqualsFilters: []*pb.StringEqualsFilter{
|
||||
{
|
||||
StringArg: regionArg,
|
||||
Value: battleRoyalRegionName(i),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
func battleRoyalTicket() *pb.Ticket {
|
||||
// Simple way to give an uneven distribution of region population.
|
||||
a := rand.Intn(battleRoyalRegions) + 1
|
||||
r := rand.Intn(a)
|
||||
|
||||
return &pb.Ticket{
|
||||
SearchFields: &pb.SearchFields{
|
||||
StringArgs: map[string]string{
|
||||
regionArg: battleRoyalRegionName(r),
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func battleRoyalMmf(p *pb.MatchProfile, poolTickets map[string][]*pb.Ticket) ([]*pb.Match, error) {
|
||||
const playersInMatch = 100
|
||||
|
||||
tickets := poolTickets[poolName]
|
||||
var matches []*pb.Match
|
||||
|
||||
for i := 0; i+playersInMatch <= len(tickets); i += playersInMatch {
|
||||
matches = append(matches, &pb.Match{
|
||||
MatchId: fmt.Sprintf("profile-%v-time-%v-%v", p.GetName(), time.Now().Format("2006-01-02T15:04:05.00"), len(matches)),
|
||||
Tickets: tickets[i : i+playersInMatch],
|
||||
MatchProfile: p.GetName(),
|
||||
MatchFunction: "battleRoyal",
|
||||
})
|
||||
}
|
||||
|
||||
return matches, nil
|
||||
}
|
||||
|
||||
func battleRoyalRegionName(i int) string {
|
||||
return fmt.Sprintf("region_%d", i)
|
||||
}
|
145
examples/scale/scenarios/battleroyal/battleroyal.go
Normal file
145
examples/scale/scenarios/battleroyal/battleroyal.go
Normal file
@ -0,0 +1,145 @@
|
||||
// Copyright 2019 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.
|
||||
|
||||
package battleroyal
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
"open-match.dev/open-match/pkg/pb"
|
||||
)
|
||||
|
||||
const (
|
||||
poolName = "all"
|
||||
regionArg = "region"
|
||||
)
|
||||
|
||||
func battleRoyalRegionName(i int) string {
|
||||
return fmt.Sprintf("region_%d", i)
|
||||
}
|
||||
|
||||
func Scenario() *BattleRoyalScenario {
|
||||
return &BattleRoyalScenario{
|
||||
regions: 20,
|
||||
}
|
||||
}
|
||||
|
||||
type BattleRoyalScenario struct {
|
||||
regions int
|
||||
}
|
||||
|
||||
func (b *BattleRoyalScenario) Profiles() []*pb.MatchProfile {
|
||||
p := []*pb.MatchProfile{}
|
||||
|
||||
for i := 0; i < b.regions; i++ {
|
||||
p = append(p, &pb.MatchProfile{
|
||||
Name: battleRoyalRegionName(i),
|
||||
Pools: []*pb.Pool{
|
||||
{
|
||||
Name: poolName,
|
||||
StringEqualsFilters: []*pb.StringEqualsFilter{
|
||||
{
|
||||
StringArg: regionArg,
|
||||
Value: battleRoyalRegionName(i),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
func (b *BattleRoyalScenario) Ticket() *pb.Ticket {
|
||||
// Simple way to give an uneven distribution of region population.
|
||||
a := rand.Intn(b.regions) + 1
|
||||
r := rand.Intn(a)
|
||||
|
||||
return &pb.Ticket{
|
||||
SearchFields: &pb.SearchFields{
|
||||
StringArgs: map[string]string{
|
||||
regionArg: battleRoyalRegionName(r),
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (b *BattleRoyalScenario) Backfill() *pb.Backfill {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *BattleRoyalScenario) MatchFunction(p *pb.MatchProfile, poolBackfills map[string][]*pb.Backfill, poolTickets map[string][]*pb.Ticket) ([]*pb.Match, error) {
|
||||
const playersInMatch = 100
|
||||
|
||||
tickets := poolTickets[poolName]
|
||||
var matches []*pb.Match
|
||||
|
||||
for i := 0; i+playersInMatch <= len(tickets); i += playersInMatch {
|
||||
matches = append(matches, &pb.Match{
|
||||
MatchId: fmt.Sprintf("profile-%v-time-%v-%v", p.GetName(), time.Now().Format("2006-01-02T15:04:05.00"), len(matches)),
|
||||
Tickets: tickets[i : i+playersInMatch],
|
||||
MatchProfile: p.GetName(),
|
||||
MatchFunction: "battleRoyal",
|
||||
})
|
||||
}
|
||||
|
||||
return matches, nil
|
||||
}
|
||||
|
||||
// fifoEvaluate accepts all matches which don't contain the same ticket as in a
|
||||
// previously accepted match. Essentially first to claim the ticket wins.
|
||||
func (b *BattleRoyalScenario) Evaluate(stream pb.Evaluator_EvaluateServer) error {
|
||||
used := map[string]struct{}{}
|
||||
|
||||
// TODO: once the evaluator client supports sending and receiving at the
|
||||
// same time, don't buffer, just send results immediately.
|
||||
matchIDs := []string{}
|
||||
|
||||
outer:
|
||||
for {
|
||||
req, err := stream.Recv()
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error reading evaluator input stream: %w", err)
|
||||
}
|
||||
|
||||
m := req.GetMatch()
|
||||
|
||||
for _, t := range m.Tickets {
|
||||
if _, ok := used[t.Id]; ok {
|
||||
continue outer
|
||||
}
|
||||
}
|
||||
|
||||
for _, t := range m.Tickets {
|
||||
used[t.Id] = struct{}{}
|
||||
}
|
||||
|
||||
matchIDs = append(matchIDs, m.GetMatchId())
|
||||
}
|
||||
|
||||
for _, mID := range matchIDs {
|
||||
err := stream.Send(&pb.EvaluateResponse{MatchId: mID})
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error sending evaluator output stream: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
48
examples/scale/scenarios/first_match_scenario.go → examples/scale/scenarios/firstmatch/firstmatch.go
48
examples/scale/scenarios/first_match_scenario.go → examples/scale/scenarios/firstmatch/firstmatch.go
@ -1,4 +1,18 @@
|
||||
package scenarios
|
||||
// Copyright 2019 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.
|
||||
|
||||
package firstmatch
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@ -12,20 +26,14 @@ const (
|
||||
poolName = "all"
|
||||
)
|
||||
|
||||
var (
|
||||
firstMatchScenario = &Scenario{
|
||||
MMF: queryPoolsWrapper(firstMatchMmf),
|
||||
Evaluator: fifoEvaluate,
|
||||
FrontendTotalTicketsToCreate: -1,
|
||||
FrontendTicketCreatedQPS: 100,
|
||||
BackendAssignsTickets: true,
|
||||
BackendDeletesTickets: true,
|
||||
Ticket: firstMatchTicket,
|
||||
Profiles: firstMatchProfile,
|
||||
}
|
||||
)
|
||||
func Scenario() *FirstMatchScenario {
|
||||
return &FirstMatchScenario{}
|
||||
}
|
||||
|
||||
func firstMatchProfile() []*pb.MatchProfile {
|
||||
type FirstMatchScenario struct {
|
||||
}
|
||||
|
||||
func (*FirstMatchScenario) Profiles() []*pb.MatchProfile {
|
||||
return []*pb.MatchProfile{
|
||||
{
|
||||
Name: "entirePool",
|
||||
@ -38,11 +46,15 @@ func firstMatchProfile() []*pb.MatchProfile {
|
||||
}
|
||||
}
|
||||
|
||||
func firstMatchTicket() *pb.Ticket {
|
||||
func (*FirstMatchScenario) Ticket() *pb.Ticket {
|
||||
return &pb.Ticket{}
|
||||
}
|
||||
|
||||
func firstMatchMmf(p *pb.MatchProfile, poolTickets map[string][]*pb.Ticket) ([]*pb.Match, error) {
|
||||
func (*FirstMatchScenario) Backfill() *pb.Backfill {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (*FirstMatchScenario) MatchFunction(p *pb.MatchProfile, poolBackfills map[string][]*pb.Backfill, poolTickets map[string][]*pb.Ticket) ([]*pb.Match, error) {
|
||||
tickets := poolTickets[poolName]
|
||||
var matches []*pb.Match
|
||||
|
||||
@ -60,10 +72,10 @@ func firstMatchMmf(p *pb.MatchProfile, poolTickets map[string][]*pb.Ticket) ([]*
|
||||
|
||||
// fifoEvaluate accepts all matches which don't contain the same ticket as in a
|
||||
// previously accepted match. Essentially first to claim the ticket wins.
|
||||
func fifoEvaluate(stream pb.Evaluator_EvaluateServer) error {
|
||||
func (*FirstMatchScenario) Evaluate(stream pb.Evaluator_EvaluateServer) error {
|
||||
used := map[string]struct{}{}
|
||||
|
||||
// TODO: once the evaluator client supports sending and recieving at the
|
||||
// TODO: once the evaluator client supports sending and receiving at the
|
||||
// same time, don't buffer, just send results immediately.
|
||||
matchIDs := []string{}
|
||||
|
@ -14,10 +14,75 @@
|
||||
|
||||
package scenarios
|
||||
|
||||
import "open-match.dev/open-match/pkg/pb"
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"google.golang.org/grpc"
|
||||
"open-match.dev/open-match/examples/scale/scenarios/backfill"
|
||||
"open-match.dev/open-match/examples/scale/scenarios/firstmatch"
|
||||
"open-match.dev/open-match/internal/util/testing"
|
||||
"open-match.dev/open-match/pkg/matchfunction"
|
||||
"open-match.dev/open-match/pkg/pb"
|
||||
)
|
||||
|
||||
var (
|
||||
queryServiceAddress = "open-match-query.open-match.svc.cluster.local:50503" // Address of the QueryService Endpoint.
|
||||
|
||||
logger = logrus.WithFields(logrus.Fields{
|
||||
"app": "scale",
|
||||
})
|
||||
)
|
||||
|
||||
// GameScenario defines what tickets look like, and how they should be matched.
|
||||
type GameScenario interface {
|
||||
// Ticket creates a new ticket, with randomized parameters.
|
||||
Ticket() *pb.Ticket
|
||||
|
||||
// Backfill creates a new backfill, with randomized parameters.
|
||||
Backfill() *pb.Backfill
|
||||
|
||||
// Profiles lists all of the profiles that should run.
|
||||
Profiles() []*pb.MatchProfile
|
||||
|
||||
// MatchFunction is the custom logic implementation of the match function.
|
||||
MatchFunction(p *pb.MatchProfile, poolBackfills map[string][]*pb.Backfill, poolTickets map[string][]*pb.Ticket) ([]*pb.Match, error)
|
||||
|
||||
// Evaluate is the custom logic implementation of the evaluator.
|
||||
Evaluate(stream pb.Evaluator_EvaluateServer) error
|
||||
}
|
||||
|
||||
// ActiveScenario sets the scenario with preset parameters that we want to use for current Open Match benchmark run.
|
||||
var ActiveScenario = battleRoyalScenario
|
||||
var ActiveScenario = func() *Scenario {
|
||||
var gs GameScenario = firstmatch.Scenario()
|
||||
|
||||
// TODO: Select which scenario to use based on some configuration or choice,
|
||||
// so it's easier to run different scenarios without changing code.
|
||||
//gs = battleroyal.Scenario()
|
||||
//gs = teamshooter.Scenario()
|
||||
s := backfill.Scenario()
|
||||
gs = s
|
||||
|
||||
return &Scenario{
|
||||
FrontendTotalTicketsToCreate: -1,
|
||||
FrontendTicketCreatedQPS: 100,
|
||||
FrontendCreatesBackfillsOnStart: true,
|
||||
FrontendTotalBackfillsToCreate: 1000,
|
||||
FrontendDeletesTickets: true,
|
||||
|
||||
BackendAssignsTickets: false,
|
||||
BackendAcknowledgesBackfills: true,
|
||||
BackendDeletesBackfills: true,
|
||||
|
||||
Ticket: gs.Ticket,
|
||||
Backfill: gs.Backfill,
|
||||
BackfillDeleteCond: s.BackfillDeleteCond,
|
||||
Profiles: gs.Profiles,
|
||||
|
||||
MMF: queryPoolsWrapper(gs.MatchFunction),
|
||||
Evaluator: gs.Evaluate,
|
||||
}
|
||||
}()
|
||||
|
||||
// Scenario defines the controllable fields for Open Match benchmark scenarios
|
||||
type Scenario struct {
|
||||
@ -32,17 +97,23 @@ type Scenario struct {
|
||||
// TicketExtensionSize int
|
||||
// PendingTicketNumber int
|
||||
// MatchExtensionSize int
|
||||
FrontendTotalTicketsToCreate int // TotalTicketsToCreate = -1 let scale-frontend create tickets forever
|
||||
FrontendTicketCreatedQPS uint32
|
||||
FrontendTicketCreatedQPS uint32
|
||||
FrontendTotalTicketsToCreate int // TotalTicketsToCreate = -1 let scale-frontend create tickets forever
|
||||
FrontendTotalBackfillsToCreate int
|
||||
FrontendCreatesBackfillsOnStart bool
|
||||
FrontendDeletesTickets bool
|
||||
|
||||
// GameBackend Configs
|
||||
// ProfileNumber int
|
||||
// FilterNumber int
|
||||
BackendAssignsTickets bool
|
||||
BackendDeletesTickets bool
|
||||
BackendAssignsTickets bool
|
||||
BackendAcknowledgesBackfills bool
|
||||
BackendDeletesBackfills bool
|
||||
|
||||
Ticket func() *pb.Ticket
|
||||
Profiles func() []*pb.MatchProfile
|
||||
Ticket func() *pb.Ticket
|
||||
Backfill func() *pb.Backfill
|
||||
BackfillDeleteCond func(*pb.Backfill) bool
|
||||
Profiles func() []*pb.MatchProfile
|
||||
|
||||
MMF matchFunction
|
||||
Evaluator evaluatorFunction
|
||||
@ -58,3 +129,49 @@ func (mmf matchFunction) Run(req *pb.RunRequest, srv pb.MatchFunction_RunServer)
|
||||
func (eval evaluatorFunction) Evaluate(srv pb.Evaluator_EvaluateServer) error {
|
||||
return eval(srv)
|
||||
}
|
||||
|
||||
func getQueryServiceGRPCClient() pb.QueryServiceClient {
|
||||
conn, err := grpc.Dial(queryServiceAddress, testing.NewGRPCDialOptions(logger)...)
|
||||
if err != nil {
|
||||
logger.Fatalf("Failed to connect to Open Match, got %v", err)
|
||||
}
|
||||
return pb.NewQueryServiceClient(conn)
|
||||
}
|
||||
|
||||
func queryPoolsWrapper(mmf func(req *pb.MatchProfile, poolBackfills map[string][]*pb.Backfill, poolTickets map[string][]*pb.Ticket) ([]*pb.Match, error)) matchFunction {
|
||||
var q pb.QueryServiceClient
|
||||
var startQ sync.Once
|
||||
|
||||
return func(req *pb.RunRequest, stream pb.MatchFunction_RunServer) error {
|
||||
startQ.Do(func() {
|
||||
q = getQueryServiceGRPCClient()
|
||||
})
|
||||
|
||||
poolTickets, err := matchfunction.QueryPools(stream.Context(), q, req.GetProfile().GetPools())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
poolBackfills, err := matchfunction.QueryBackfillPools(stream.Context(), q, req.GetProfile().GetPools())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
proposals, err := mmf(req.GetProfile(), poolBackfills, poolTickets)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logger.WithFields(logrus.Fields{
|
||||
"proposals": proposals,
|
||||
}).Trace("proposals returned by match function")
|
||||
|
||||
for _, proposal := range proposals {
|
||||
if err := stream.Send(&pb.RunResponse{Proposal: proposal}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
334
examples/scale/scenarios/teamshooter/teamshooter.go
Normal file
334
examples/scale/scenarios/teamshooter/teamshooter.go
Normal file
@ -0,0 +1,334 @@
|
||||
// Copyright 2019 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.
|
||||
|
||||
// TeamShooterScenario is a scenario which is designed to emulate the
|
||||
// approximate behavior to open match that a skill based team game would have.
|
||||
// It doesn't try to provide good matchmaking for real players. There are three
|
||||
// arguments used:
|
||||
// mode: The game mode the players wants to play in. mode is a hard partition.
|
||||
// regions: Players may have good latency to one or more regions. A player will
|
||||
// search for matches in all eligible regions.
|
||||
// skill: Players have a random skill based on a normal distribution. Players
|
||||
// will only be matched with other players who have a close skill value. The
|
||||
// match functions have overlapping partitions of the skill brackets.
|
||||
package teamshooter
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
"math/rand"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"github.com/golang/protobuf/ptypes"
|
||||
"github.com/golang/protobuf/ptypes/any"
|
||||
"github.com/golang/protobuf/ptypes/wrappers"
|
||||
"open-match.dev/open-match/pkg/pb"
|
||||
)
|
||||
|
||||
const (
|
||||
poolName = "all"
|
||||
skillArg = "skill"
|
||||
modeArg = "mode"
|
||||
)
|
||||
|
||||
// TeamShooterScenario provides the required methods for running a scenario.
|
||||
type TeamShooterScenario struct {
|
||||
// Names of available region tags.
|
||||
regions []string
|
||||
// Maximum regions a player can search in.
|
||||
maxRegions int
|
||||
// Number of tickets which form a match.
|
||||
playersPerGame int
|
||||
// For each pair of consequitive values, the value to split profiles on by
|
||||
// skill.
|
||||
skillBoundaries []float64
|
||||
// Maximum difference between two tickets to consider a match valid.
|
||||
maxSkillDifference float64
|
||||
// List of mode names.
|
||||
modes []string
|
||||
// Returns a random mode, with some weight.
|
||||
randomMode func() string
|
||||
}
|
||||
|
||||
// Scenario creates a new TeamShooterScenario.
|
||||
func Scenario() *TeamShooterScenario {
|
||||
|
||||
modes, randomMode := weightedChoice(map[string]int{
|
||||
"pl": 100, // Payload, very popular.
|
||||
"cp": 25, // Capture point, 1/4 as popular.
|
||||
})
|
||||
|
||||
regions := []string{}
|
||||
for i := 0; i < 2; i++ {
|
||||
regions = append(regions, fmt.Sprintf("region_%d", i))
|
||||
}
|
||||
|
||||
return &TeamShooterScenario{
|
||||
regions: regions,
|
||||
maxRegions: 1,
|
||||
playersPerGame: 12,
|
||||
skillBoundaries: []float64{math.Inf(-1), 0, math.Inf(1)},
|
||||
maxSkillDifference: 0.01,
|
||||
modes: modes,
|
||||
randomMode: randomMode,
|
||||
}
|
||||
}
|
||||
|
||||
// Profiles shards the player base on mode, region, and skill.
|
||||
func (t *TeamShooterScenario) Profiles() []*pb.MatchProfile {
|
||||
p := []*pb.MatchProfile{}
|
||||
|
||||
for _, region := range t.regions {
|
||||
for _, mode := range t.modes {
|
||||
for i := 0; i+1 < len(t.skillBoundaries); i++ {
|
||||
skillMin := t.skillBoundaries[i] - t.maxSkillDifference/2
|
||||
skillMax := t.skillBoundaries[i+1] + t.maxSkillDifference/2
|
||||
p = append(p, &pb.MatchProfile{
|
||||
Name: fmt.Sprintf("%s_%s_%v-%v", region, mode, skillMin, skillMax),
|
||||
Pools: []*pb.Pool{
|
||||
{
|
||||
Name: poolName,
|
||||
DoubleRangeFilters: []*pb.DoubleRangeFilter{
|
||||
{
|
||||
DoubleArg: skillArg,
|
||||
Min: skillMin,
|
||||
Max: skillMax,
|
||||
},
|
||||
},
|
||||
TagPresentFilters: []*pb.TagPresentFilter{
|
||||
{
|
||||
Tag: region,
|
||||
},
|
||||
},
|
||||
StringEqualsFilters: []*pb.StringEqualsFilter{
|
||||
{
|
||||
StringArg: modeArg,
|
||||
Value: mode,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
// Ticket creates a randomized player.
|
||||
func (t *TeamShooterScenario) Ticket() *pb.Ticket {
|
||||
region := rand.Intn(len(t.regions))
|
||||
numRegions := rand.Intn(t.maxRegions) + 1
|
||||
|
||||
tags := []string{}
|
||||
for i := 0; i < numRegions; i++ {
|
||||
tags = append(tags, t.regions[region])
|
||||
// The Earth is actually a circle.
|
||||
region = (region + 1) % len(t.regions)
|
||||
}
|
||||
|
||||
return &pb.Ticket{
|
||||
SearchFields: &pb.SearchFields{
|
||||
DoubleArgs: map[string]float64{
|
||||
skillArg: clamp(rand.NormFloat64(), -3, 3),
|
||||
},
|
||||
StringArgs: map[string]string{
|
||||
modeArg: t.randomMode(),
|
||||
},
|
||||
Tags: tags,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (t *TeamShooterScenario) Backfill() *pb.Backfill {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MatchFunction puts tickets into matches based on their skill, finding the
|
||||
// required number of tickets for a game within the maximum skill difference.
|
||||
func (t *TeamShooterScenario) MatchFunction(p *pb.MatchProfile, poolBackfills map[string][]*pb.Backfill, poolTickets map[string][]*pb.Ticket) ([]*pb.Match, error) {
|
||||
skill := func(t *pb.Ticket) float64 {
|
||||
return t.SearchFields.DoubleArgs[skillArg]
|
||||
}
|
||||
|
||||
tickets := poolTickets[poolName]
|
||||
var matches []*pb.Match
|
||||
|
||||
sort.Slice(tickets, func(i, j int) bool {
|
||||
return skill(tickets[i]) < skill(tickets[j])
|
||||
})
|
||||
|
||||
for i := 0; i+t.playersPerGame <= len(tickets); i++ {
|
||||
mt := tickets[i : i+t.playersPerGame]
|
||||
if skill(mt[len(mt)-1])-skill(mt[0]) < t.maxSkillDifference {
|
||||
avg := float64(0)
|
||||
for _, t := range mt {
|
||||
avg += skill(t)
|
||||
}
|
||||
avg /= float64(len(mt))
|
||||
|
||||
q := float64(0)
|
||||
for _, t := range mt {
|
||||
diff := skill(t) - avg
|
||||
q -= diff * diff
|
||||
}
|
||||
|
||||
m, err := (&matchExt{
|
||||
id: fmt.Sprintf("profile-%v-time-%v-%v", p.GetName(), time.Now().Format("2006-01-02T15:04:05.00"), len(matches)),
|
||||
matchProfile: p.GetName(),
|
||||
matchFunction: "skillmatcher",
|
||||
tickets: mt,
|
||||
quality: q,
|
||||
}).pack()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
matches = append(matches, m)
|
||||
}
|
||||
}
|
||||
|
||||
return matches, nil
|
||||
}
|
||||
|
||||
// Evaluate returns matches in order of highest quality, skipping any matches
|
||||
// which contain tickets that are already used.
|
||||
func (t *TeamShooterScenario) Evaluate(stream pb.Evaluator_EvaluateServer) error {
|
||||
// Unpacked proposal matches.
|
||||
proposals := []*matchExt{}
|
||||
// Ticket ids which are used in a match.
|
||||
used := map[string]struct{}{}
|
||||
|
||||
for {
|
||||
req, err := stream.Recv()
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error reading evaluator input stream: %w", err)
|
||||
}
|
||||
|
||||
p, err := unpackMatch(req.GetMatch())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
proposals = append(proposals, p)
|
||||
}
|
||||
|
||||
// Higher quality is better.
|
||||
sort.Slice(proposals, func(i, j int) bool {
|
||||
return proposals[i].quality > proposals[j].quality
|
||||
})
|
||||
|
||||
outer:
|
||||
for _, p := range proposals {
|
||||
for _, t := range p.tickets {
|
||||
if _, ok := used[t.Id]; ok {
|
||||
continue outer
|
||||
}
|
||||
}
|
||||
|
||||
for _, t := range p.tickets {
|
||||
used[t.Id] = struct{}{}
|
||||
}
|
||||
|
||||
err := stream.Send(&pb.EvaluateResponse{MatchId: p.id})
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error sending evaluator output stream: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// matchExt presents the match and extension data in a native form, and allows
|
||||
// easy conversion to and from proto format.
|
||||
type matchExt struct {
|
||||
id string
|
||||
tickets []*pb.Ticket
|
||||
quality float64
|
||||
matchProfile string
|
||||
matchFunction string
|
||||
}
|
||||
|
||||
func unpackMatch(m *pb.Match) (*matchExt, error) {
|
||||
v := &wrappers.DoubleValue{}
|
||||
|
||||
err := ptypes.UnmarshalAny(m.Extensions["quality"], v)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error unpacking match quality: %w", err)
|
||||
}
|
||||
|
||||
return &matchExt{
|
||||
id: m.MatchId,
|
||||
tickets: m.Tickets,
|
||||
quality: v.Value,
|
||||
matchProfile: m.MatchProfile,
|
||||
matchFunction: m.MatchFunction,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (m *matchExt) pack() (*pb.Match, error) {
|
||||
v := &wrappers.DoubleValue{Value: m.quality}
|
||||
|
||||
a, err := ptypes.MarshalAny(v)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error packing match quality: %w", err)
|
||||
}
|
||||
|
||||
return &pb.Match{
|
||||
MatchId: m.id,
|
||||
Tickets: m.tickets,
|
||||
MatchProfile: m.matchProfile,
|
||||
MatchFunction: m.matchFunction,
|
||||
Extensions: map[string]*any.Any{
|
||||
"quality": a,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func clamp(v float64, min float64, max float64) float64 {
|
||||
if v < min {
|
||||
return min
|
||||
}
|
||||
if v > max {
|
||||
return max
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// weightedChoice takes a map of values, and their relative probability. It
|
||||
// returns a list of the values, along with a function which will return random
|
||||
// choices from the values with the weighted probability.
|
||||
func weightedChoice(m map[string]int) ([]string, func() string) {
|
||||
s := make([]string, 0, len(m))
|
||||
total := 0
|
||||
for k, v := range m {
|
||||
s = append(s, k)
|
||||
total += v
|
||||
}
|
||||
|
||||
return s, func() string {
|
||||
remainder := rand.Intn(total)
|
||||
for k, v := range m {
|
||||
remainder -= v
|
||||
if remainder < 0 {
|
||||
return k
|
||||
}
|
||||
}
|
||||
panic("weightedChoice is broken.")
|
||||
}
|
||||
}
|
@ -1,137 +0,0 @@
|
||||
// Copyright 2019 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.
|
||||
|
||||
package scenarios
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"sync"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"google.golang.org/grpc"
|
||||
"open-match.dev/open-match/internal/util/testing"
|
||||
"open-match.dev/open-match/pkg/matchfunction"
|
||||
"open-match.dev/open-match/pkg/pb"
|
||||
)
|
||||
|
||||
var (
|
||||
queryServiceAddress = "om-query.open-match.svc.cluster.local:50503" // Address of the QueryService Endpoint.
|
||||
|
||||
logger = logrus.WithFields(logrus.Fields{
|
||||
"app": "scale",
|
||||
})
|
||||
)
|
||||
|
||||
// StatProcessor uses syncMaps to store the stress test metrics and occurrence of errors.
|
||||
// It can write out the data to an input io.Writer.
|
||||
type StatProcessor struct {
|
||||
em *sync.Map
|
||||
sm *sync.Map
|
||||
}
|
||||
|
||||
// NewStatProcessor returns an initialized StatProcessor
|
||||
func NewStatProcessor() *StatProcessor {
|
||||
return &StatProcessor{
|
||||
em: &sync.Map{},
|
||||
sm: &sync.Map{},
|
||||
}
|
||||
}
|
||||
|
||||
// SetStat sets the value for a key
|
||||
func (e StatProcessor) SetStat(k string, v interface{}) {
|
||||
e.sm.Store(k, v)
|
||||
}
|
||||
|
||||
// IncrementStat atomically increments the value of a key by delta
|
||||
func (e StatProcessor) IncrementStat(k string, delta interface{}) {
|
||||
statRead, ok := e.sm.Load(k)
|
||||
if !ok {
|
||||
statRead = 0
|
||||
}
|
||||
|
||||
switch delta.(type) {
|
||||
case int:
|
||||
e.sm.Store(k, statRead.(int)+delta.(int))
|
||||
case float32:
|
||||
e.sm.Store(k, statRead.(float32)+delta.(float32))
|
||||
case float64:
|
||||
e.sm.Store(k, statRead.(float64)+delta.(float64))
|
||||
default:
|
||||
logger.Errorf("IncrementStat: type %T not supported", delta)
|
||||
}
|
||||
}
|
||||
|
||||
// RecordError atomically records the occurrence of input errors
|
||||
func (e StatProcessor) RecordError(desc string, err error) {
|
||||
errMsg := fmt.Sprintf("%s: %s", desc, err.Error())
|
||||
errRead, ok := e.em.Load(errMsg)
|
||||
if !ok {
|
||||
errRead = 0
|
||||
}
|
||||
e.em.Store(errMsg, errRead.(int)+1)
|
||||
}
|
||||
|
||||
// Log writes the formatted errors and metrics to the input writer
|
||||
func (e StatProcessor) Log(w io.Writer) {
|
||||
e.sm.Range(func(k interface{}, v interface{}) bool {
|
||||
w.Write([]byte(fmt.Sprintf("%s: %d \n", k, v)))
|
||||
return true
|
||||
})
|
||||
e.em.Range(func(k interface{}, v interface{}) bool {
|
||||
w.Write([]byte(fmt.Sprintf("%s: %d \n", k, v)))
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
func getQueryServiceGRPCClient() pb.QueryServiceClient {
|
||||
conn, err := grpc.Dial(queryServiceAddress, testing.NewGRPCDialOptions(logger)...)
|
||||
if err != nil {
|
||||
logger.Fatalf("Failed to connect to Open Match, got %v", err)
|
||||
}
|
||||
return pb.NewQueryServiceClient(conn)
|
||||
}
|
||||
|
||||
func queryPoolsWrapper(mmf func(req *pb.MatchProfile, pools map[string][]*pb.Ticket) ([]*pb.Match, error)) matchFunction {
|
||||
var q pb.QueryServiceClient
|
||||
var startQ sync.Once
|
||||
|
||||
return func(req *pb.RunRequest, stream pb.MatchFunction_RunServer) error {
|
||||
startQ.Do(func() {
|
||||
q = getQueryServiceGRPCClient()
|
||||
})
|
||||
|
||||
poolTickets, err := matchfunction.QueryPools(stream.Context(), q, req.GetProfile().GetPools())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
proposals, err := mmf(req.GetProfile(), poolTickets)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logger.WithFields(logrus.Fields{
|
||||
"proposals": proposals,
|
||||
}).Trace("proposals returned by match function")
|
||||
|
||||
for _, proposal := range proposals {
|
||||
if err := stream.Send(&pb.RunResponse{Proposal: proposal}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
80
go.mod
80
go.mod
@ -15,57 +15,51 @@ module open-match.dev/open-match
|
||||
// limitations under the License.
|
||||
|
||||
// When updating Go version, update Dockerfile.ci, Dockerfile.base-build, and go.mod
|
||||
go 1.13
|
||||
go 1.14
|
||||
|
||||
require (
|
||||
cloud.google.com/go v0.47.0 // indirect
|
||||
contrib.go.opencensus.io/exporter/jaeger v0.1.0
|
||||
contrib.go.opencensus.io/exporter/ocagent v0.6.0
|
||||
contrib.go.opencensus.io/exporter/prometheus v0.1.0
|
||||
contrib.go.opencensus.io/exporter/stackdriver v0.12.8
|
||||
contrib.go.opencensus.io/exporter/jaeger v0.2.1
|
||||
contrib.go.opencensus.io/exporter/ocagent v0.7.0
|
||||
contrib.go.opencensus.io/exporter/prometheus v0.2.0
|
||||
contrib.go.opencensus.io/exporter/stackdriver v0.13.4
|
||||
github.com/Bose/minisentinel v0.0.0-20200130220412-917c5a9223bb
|
||||
github.com/TV4/logrus-stackdriver-formatter v0.1.0
|
||||
github.com/alicebob/miniredis/v2 v2.10.1
|
||||
github.com/apache/thrift v0.13.0 // indirect
|
||||
github.com/aws/aws-sdk-go v1.25.27 // indirect
|
||||
github.com/alicebob/miniredis/v2 v2.14.1
|
||||
github.com/aws/aws-sdk-go v1.35.26 // indirect
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible
|
||||
github.com/fsnotify/fsnotify v1.4.7
|
||||
github.com/fsnotify/fsnotify v1.4.9
|
||||
github.com/go-redsync/redsync/v4 v4.3.0
|
||||
github.com/gogo/protobuf v1.3.1 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9 // indirect
|
||||
github.com/golang/protobuf v1.3.2
|
||||
github.com/gomodule/redigo v1.7.1-0.20190322064113-39e2c31b7ca3
|
||||
github.com/golang/protobuf v1.4.3
|
||||
github.com/gomodule/redigo v2.0.1-0.20191111085604-09d84710e01a+incompatible
|
||||
github.com/googleapis/gnostic v0.3.1 // indirect
|
||||
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.1.0
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.12.0
|
||||
github.com/imdario/mergo v0.3.8 // indirect
|
||||
github.com/json-iterator/go v1.1.8 // indirect
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect
|
||||
github.com/pelletier/go-toml v1.6.0 // indirect
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
|
||||
github.com/pkg/errors v0.8.1
|
||||
github.com/prometheus/client_golang v1.2.1
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.2.2
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.3.0
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/imdario/mergo v0.3.11 // indirect
|
||||
github.com/pelletier/go-toml v1.8.1 // indirect
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/prometheus/client_golang v1.8.0
|
||||
github.com/rs/xid v1.2.1
|
||||
github.com/sirupsen/logrus v1.4.2
|
||||
github.com/spf13/afero v1.2.1 // indirect
|
||||
github.com/sirupsen/logrus v1.7.0
|
||||
github.com/spf13/afero v1.4.1 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/spf13/viper v1.5.0
|
||||
github.com/stretchr/testify v1.4.0
|
||||
github.com/yuin/gopher-lua v0.0.0-20190514113301-1cd887cd7036 // indirect
|
||||
go.opencensus.io v0.22.1
|
||||
golang.org/x/crypto v0.0.0-20191105034135-c7e5f84aec59 // indirect
|
||||
golang.org/x/net v0.0.0-20191105084925-a882066a44e0
|
||||
golang.org/x/sys v0.0.0-20191105231009-c1f44814a5cd // indirect
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect
|
||||
google.golang.org/api v0.13.0 // indirect
|
||||
google.golang.org/appengine v1.6.5 // indirect
|
||||
google.golang.org/genproto v0.0.0-20191028173616-919d9bdd9fe6
|
||||
google.golang.org/grpc v1.25.0
|
||||
github.com/spf13/viper v1.7.1
|
||||
github.com/stretchr/testify v1.7.0
|
||||
go.opencensus.io v0.23.0
|
||||
golang.org/x/net v0.0.0-20210224082022-3d97a244fca7
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9
|
||||
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073 // indirect
|
||||
google.golang.org/api v0.35.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20210224155714-063164c882e6
|
||||
google.golang.org/grpc v1.36.0
|
||||
google.golang.org/protobuf v1.25.1-0.20201208041424-160c7477e0e8
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.2.5 // indirect
|
||||
k8s.io/api v0.0.0-20191004102255-dacd7df5a50b // kubernetes-1.13.12
|
||||
k8s.io/apimachinery v0.0.0-20191004074956-01f8b7d1121a // kubernetes-1.13.12
|
||||
k8s.io/client-go v0.0.0-20191004102537-eb5b9a8cfde7 // kubernetes-1.13.12
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
k8s.io/api v0.0.0-20191004102349-159aefb8556b // kubernetes-1.14.10
|
||||
k8s.io/apimachinery v0.0.0-20191004074956-c5d2f014d689 // kubernetes-1.14.10
|
||||
k8s.io/client-go v11.0.1-0.20191029005444-8e4128053008+incompatible // kubernetes-1.14.10
|
||||
k8s.io/klog v1.0.0 // indirect
|
||||
sigs.k8s.io/yaml v1.1.0 // indirect
|
||||
k8s.io/utils v0.0.0-20200729134348-d5654de09c73 // indirect
|
||||
sigs.k8s.io/yaml v1.2.0 // indirect
|
||||
)
|
||||
|
@ -20,28 +20,6 @@ metadata:
|
||||
app: open-match-demo
|
||||
release: open-match-demo
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: customize-configmap
|
||||
namespace: open-match-demo
|
||||
labels:
|
||||
app: open-match-customize
|
||||
component: config
|
||||
release: open-match-demo
|
||||
data:
|
||||
matchmaker_config_default.yaml: |-
|
||||
api:
|
||||
functions:
|
||||
hostname: "om-function"
|
||||
grpcport: 50502
|
||||
httpport: 51502
|
||||
matchmaker_config_override.yaml: |-
|
||||
api:
|
||||
query:
|
||||
hostname: "om-query.open-match.svc.cluster.local"
|
||||
grpcport: "50503"
|
||||
---
|
||||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
@ -108,20 +86,8 @@ spec:
|
||||
component: matchfunction
|
||||
release: open-match-demo
|
||||
spec:
|
||||
volumes:
|
||||
- name: customize-config-volume
|
||||
configMap:
|
||||
name: customize-configmap
|
||||
- name: om-config-volume-default
|
||||
configMap:
|
||||
name: customize-configmap
|
||||
containers:
|
||||
- name: om-function
|
||||
volumeMounts:
|
||||
- name: customize-config-volume
|
||||
mountPath: /app/config/override
|
||||
- name: om-config-volume-default
|
||||
mountPath: /app/config/default
|
||||
image: "gcr.io/open-match-public-images/openmatch-mmf-go-soloduel:0.0.0-dev"
|
||||
ports:
|
||||
- name: grpc
|
||||
|
@ -13,14 +13,14 @@
|
||||
# limitations under the License.
|
||||
|
||||
apiVersion: v2
|
||||
appVersion: "0.0.0-dev"
|
||||
version: 0.0.0-dev
|
||||
appVersion: "1.4.0-rc.1"
|
||||
version: 1.4.0-rc.1
|
||||
name: open-match
|
||||
dependencies:
|
||||
- name: redis
|
||||
version: 9.5.0
|
||||
repository: https://kubernetes-charts.storage.googleapis.com/
|
||||
condition: open-match-core.redis.install
|
||||
version: 16.3.1
|
||||
repository: https://charts.bitnami.com/bitnami
|
||||
condition: open-match-core.redis.enabled
|
||||
- name: open-match-telemetry
|
||||
version: 0.0.0-dev
|
||||
condition: open-match-telemetry.enabled
|
||||
|
@ -0,0 +1,20 @@
|
||||
{*
|
||||
Copyright 2019 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.
|
||||
*}
|
||||
|
||||
{{/* vim: set filetype=mustache: */}}
|
||||
{{- define "openmatchcustomize.function.hostName" -}}
|
||||
{{- .Values.function.hostName | default (printf "%s-function" (include "openmatch.fullname" . ) ) -}}
|
||||
{{- end -}}
|
@ -1,41 +0,0 @@
|
||||
# Copyright 2019 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.
|
||||
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: customize-configmap
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations: {{- include "openmatch.chartmeta" . | nindent 4 }}
|
||||
labels:
|
||||
app: {{ template "openmatch.name" . }}
|
||||
component: config
|
||||
release: {{ .Release.Name }}
|
||||
data:
|
||||
matchmaker_config_default.yaml: |-
|
||||
api:
|
||||
functions:
|
||||
hostname: "{{ .Values.function.hostName }}"
|
||||
grpcport: "{{ .Values.function.grpcPort }}"
|
||||
httpport: "{{ .Values.function.httpPort }}"
|
||||
|
||||
evaluator:
|
||||
hostname: "{{ .Values.evaluator.hostName }}"
|
||||
grpcport: "{{ .Values.evaluator.grpcPort }}"
|
||||
httpport: "{{ .Values.evaluator.httpPort }}"
|
||||
matchmaker_config_override.yaml: |-
|
||||
api:
|
||||
query:
|
||||
hostname: "{{ .Values.query.hostName }}.{{ .Release.Namespace }}.svc.cluster.local"
|
||||
grpcport: "{{ .Values.query.grpcPort }}"
|
@ -18,7 +18,7 @@
|
||||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: {{ .Values.evaluator.hostName }}
|
||||
name: {{ include "openmatch.evaluator.hostName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations: {{- include "openmatch.chartmeta" . | nindent 4 }}
|
||||
labels:
|
||||
@ -46,20 +46,20 @@ spec:
|
||||
apiVersion: autoscaling/v1
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: {{ .Values.evaluator.hostName }}
|
||||
name: {{ include "openmatch.evaluator.hostName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations: {{- include "openmatch.chartmeta" . | nindent 4 }}
|
||||
spec:
|
||||
scaleTargetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: {{ .Values.evaluator.hostName }}
|
||||
name: {{ include "openmatch.evaluator.hostName" . }}
|
||||
{{- include "openmatch.HorizontalPodAutoscaler.spec.common" . | nindent 2 }}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ .Values.evaluator.hostName }}
|
||||
name: {{ include "openmatch.evaluator.hostName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
app: {{ template "openmatch.name" . }}
|
||||
@ -82,12 +82,13 @@ spec:
|
||||
component: evaluator
|
||||
release: {{ .Release.Name }}
|
||||
spec:
|
||||
{{- include "openmatch.labels.nodegrouping" . | nindent 6 }}
|
||||
volumes:
|
||||
{{- include "openmatch.volumes.configs" (dict "configs" .Values.evaluatorConfigs) | nindent 8}}
|
||||
{{- include "openmatch.volumes.configs" (. | merge (dict "configs" .Values.evaluatorConfigs)) | nindent 8}}
|
||||
{{- include "openmatch.volumes.tls" . | nindent 8}}
|
||||
serviceAccountName: {{ .Values.global.kubernetes.serviceAccount }}
|
||||
serviceAccountName: {{ include "openmatch.serviceAccount.name" . }}
|
||||
containers:
|
||||
- name: {{ .Values.evaluator.hostName }}
|
||||
- name: {{ include "openmatch.evaluator.hostName" . }}
|
||||
volumeMounts:
|
||||
{{- include "openmatch.volumemounts.configs" (dict "configs" .Values.evaluatorConfigs) | nindent 10 }}
|
||||
{{- include "openmatch.volumemounts.tls" . | nindent 10 }}
|
||||
|
@ -18,7 +18,7 @@
|
||||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: {{ .Values.function.hostName }}
|
||||
name: {{ include "openmatchcustomize.function.hostName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations: {{- include "openmatch.chartmeta" . | nindent 4 }}
|
||||
labels:
|
||||
@ -46,20 +46,20 @@ spec:
|
||||
apiVersion: autoscaling/v1
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: {{ .Values.function.hostName }}
|
||||
name: {{ include "openmatchcustomize.function.hostName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations: {{- include "openmatch.chartmeta" . | nindent 4 }}
|
||||
spec:
|
||||
scaleTargetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: {{ .Values.function.hostName }}
|
||||
name: {{ include "openmatchcustomize.function.hostName" . }}
|
||||
{{- include "openmatch.HorizontalPodAutoscaler.spec.common" . | nindent 2 }}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ .Values.function.hostName }}
|
||||
name: {{ include "openmatchcustomize.function.hostName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations: {{- include "openmatch.chartmeta" . | nindent 4 }}
|
||||
labels:
|
||||
@ -83,12 +83,13 @@ spec:
|
||||
component: matchfunction
|
||||
release: {{ .Release.Name }}
|
||||
spec:
|
||||
{{- include "openmatch.labels.nodegrouping" . | nindent 6 }}
|
||||
volumes:
|
||||
{{- include "openmatch.volumes.configs" (dict "configs" .Values.mmfConfigs) | nindent 8}}
|
||||
{{- include "openmatch.volumes.configs" (. | merge (dict "configs" .Values.mmfConfigs)) | nindent 8}}
|
||||
{{- include "openmatch.volumes.tls" . | nindent 8}}
|
||||
serviceAccountName: {{ .Values.global.kubernetes.serviceAccount }}
|
||||
serviceAccountName: {{ include "openmatch.serviceAccount.name" . }}
|
||||
containers:
|
||||
- name: {{ .Values.function.hostName }}
|
||||
- name: {{ include "openmatchcustomize.function.hostName" . }}
|
||||
volumeMounts:
|
||||
{{- include "openmatch.volumemounts.configs" (dict "configs" .Values.mmfConfigs) | nindent 10 }}
|
||||
{{- include "openmatch.volumemounts.tls" . | nindent 10 }}
|
||||
|
@ -26,7 +26,7 @@ evaluator:
|
||||
enabled: false
|
||||
replicas: 3
|
||||
portType: ClusterIP
|
||||
image: openmatch-evaluator-go-simple
|
||||
image: openmatch-default-evaluator
|
||||
|
||||
evaluatorConfigs:
|
||||
# We use harness to implement the MMFs. MMF itself only requires one configmap but harness expects two,
|
||||
@ -35,11 +35,13 @@ evaluatorConfigs:
|
||||
default:
|
||||
volumeName: om-config-volume-default
|
||||
mountPath: /app/config/default
|
||||
configName: customize-configmap
|
||||
# This will be parsed through the `tpl` function.
|
||||
configName: '{{ include "openmatch.configmap.default" . }}'
|
||||
customize:
|
||||
volumeName: customize-config-volume
|
||||
volumeName: om-config-volume-override
|
||||
mountPath: /app/config/override
|
||||
configName: customize-configmap
|
||||
# This will be parsed through the `tpl` function.
|
||||
configName: '{{ include "openmatch.configmap.override" . }}'
|
||||
|
||||
mmfConfigs:
|
||||
# We use harness to implement the MMFs. MMF itself only requires one configmap but harness expects two,
|
||||
@ -48,8 +50,10 @@ mmfConfigs:
|
||||
default:
|
||||
volumeName: om-config-volume-default
|
||||
mountPath: /app/config/default
|
||||
configName: customize-configmap
|
||||
# This will be parsed through the `tpl` function.
|
||||
configName: '{{ include "openmatch.configmap.default" . }}'
|
||||
customize:
|
||||
volumeName: customize-config-volume
|
||||
volumeName: om-config-volume-override
|
||||
mountPath: /app/config/override
|
||||
configName: customize-configmap
|
||||
# This will be parsed through the `tpl` function.
|
||||
configName: '{{ include "openmatch.configmap.override" . }}'
|
||||
|
@ -18,13 +18,15 @@
|
||||
"links": [],
|
||||
"panels": [
|
||||
{
|
||||
"collapsed": false,
|
||||
"gridPos": {
|
||||
"h": 1,
|
||||
"w": 24,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"id": 16,
|
||||
"id": 28,
|
||||
"panels": [],
|
||||
"title": "Iterations",
|
||||
"type": "row"
|
||||
},
|
||||
@ -130,11 +132,317 @@
|
||||
"x": 0,
|
||||
"y": 9
|
||||
},
|
||||
"id": 16,
|
||||
"panels": [],
|
||||
"title": "Backfills",
|
||||
"type": "row"
|
||||
},
|
||||
{
|
||||
"aliasColors": {},
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"fill": 1,
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 10
|
||||
},
|
||||
"id": 30,
|
||||
"legend": {
|
||||
"avg": false,
|
||||
"current": false,
|
||||
"max": false,
|
||||
"min": false,
|
||||
"show": true,
|
||||
"total": false,
|
||||
"values": false
|
||||
},
|
||||
"lines": true,
|
||||
"linewidth": 1,
|
||||
"links": [],
|
||||
"nullPointMode": "null",
|
||||
"options": {},
|
||||
"percentage": false,
|
||||
"pointradius": 2,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
"seriesOverrides": [],
|
||||
"spaceLength": 10,
|
||||
"stack": false,
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "sum(rate(scale_backend_backfills_deleted[5m]))",
|
||||
"format": "time_series",
|
||||
"interval": "",
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "Backfilld Deleted per second",
|
||||
"refId": "B"
|
||||
},
|
||||
{
|
||||
"expr": "sum(rate(scale_backend_backfill_deletes_failed[5m]))",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "Backfill Deletions Failed per second",
|
||||
"refId": "C"
|
||||
}
|
||||
],
|
||||
"thresholds": [],
|
||||
"timeFrom": null,
|
||||
"timeRegions": [],
|
||||
"timeShift": null,
|
||||
"title": "Backfill Deletion",
|
||||
"tooltip": {
|
||||
"shared": true,
|
||||
"sort": 0,
|
||||
"value_type": "individual"
|
||||
},
|
||||
"type": "graph",
|
||||
"xaxis": {
|
||||
"buckets": null,
|
||||
"mode": "time",
|
||||
"name": null,
|
||||
"show": true,
|
||||
"values": []
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": "0",
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
}
|
||||
],
|
||||
"yaxis": {
|
||||
"align": false,
|
||||
"alignLevel": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"collapsed": false,
|
||||
"gridPos": {
|
||||
"h": 1,
|
||||
"w": 24,
|
||||
"x": 0,
|
||||
"y": 18
|
||||
},
|
||||
"id": 14,
|
||||
"panels": [],
|
||||
"title": "Tickets",
|
||||
"type": "row"
|
||||
},
|
||||
{
|
||||
"aliasColors": {},
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"fill": 0,
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 19
|
||||
},
|
||||
"id": 26,
|
||||
"legend": {
|
||||
"alignAsTable": true,
|
||||
"avg": false,
|
||||
"current": true,
|
||||
"max": false,
|
||||
"min": false,
|
||||
"rightSide": true,
|
||||
"show": true,
|
||||
"total": false,
|
||||
"values": true
|
||||
},
|
||||
"lines": true,
|
||||
"linewidth": 1,
|
||||
"links": [],
|
||||
"nullPointMode": "null",
|
||||
"options": {},
|
||||
"percentage": false,
|
||||
"pointradius": 2,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
"seriesOverrides": [],
|
||||
"spaceLength": 10,
|
||||
"stack": false,
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "histogram_quantile(0.99, sum(rate(scale_frontend_tickets_time_to_assignment_bucket[5m])) by (le))",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "99%-ile",
|
||||
"refId": "A"
|
||||
},
|
||||
{
|
||||
"expr": "histogram_quantile(0.95, sum(rate(scale_frontend_tickets_time_to_assignment_bucket[5m])) by (le))",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "95%-ile",
|
||||
"refId": "B"
|
||||
},
|
||||
{
|
||||
"expr": "histogram_quantile(0.90, sum(rate(scale_frontend_tickets_time_to_assignment_bucket[5m])) by (le))",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "90%-ile",
|
||||
"refId": "C"
|
||||
},
|
||||
{
|
||||
"expr": "histogram_quantile(0.50, sum(rate(scale_frontend_tickets_time_to_assignment_bucket[5m])) by (le))",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "50%-ile",
|
||||
"refId": "D"
|
||||
},
|
||||
{
|
||||
"expr": "histogram_quantile(0.10, sum(rate(scale_frontend_tickets_time_to_assignment_bucket[5m])) by (le))",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "10%-ile",
|
||||
"refId": "E"
|
||||
}
|
||||
],
|
||||
"thresholds": [],
|
||||
"timeFrom": null,
|
||||
"timeRegions": [],
|
||||
"timeShift": null,
|
||||
"title": "Ticket Time to Assignment",
|
||||
"tooltip": {
|
||||
"shared": true,
|
||||
"sort": 0,
|
||||
"value_type": "individual"
|
||||
},
|
||||
"type": "graph",
|
||||
"xaxis": {
|
||||
"buckets": null,
|
||||
"mode": "time",
|
||||
"name": null,
|
||||
"show": true,
|
||||
"values": []
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"format": "ms",
|
||||
"label": null,
|
||||
"logBase": 2,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
}
|
||||
],
|
||||
"yaxis": {
|
||||
"align": false,
|
||||
"alignLevel": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"aliasColors": {},
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"fill": 1,
|
||||
"gridPos": {
|
||||
"h": 9,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 19
|
||||
},
|
||||
"id": 12,
|
||||
"legend": {
|
||||
"avg": false,
|
||||
"current": false,
|
||||
"max": false,
|
||||
"min": false,
|
||||
"show": true,
|
||||
"total": false,
|
||||
"values": false
|
||||
},
|
||||
"lines": true,
|
||||
"linewidth": 1,
|
||||
"links": [],
|
||||
"nullPointMode": "null",
|
||||
"options": {},
|
||||
"percentage": false,
|
||||
"pointradius": 2,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
"seriesOverrides": [],
|
||||
"spaceLength": 10,
|
||||
"stack": false,
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "sum(rate(scale_backend_sum_tickets_returned[5m]))",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "Backend Tickets in Matches pers second",
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"thresholds": [],
|
||||
"timeFrom": null,
|
||||
"timeRegions": [],
|
||||
"timeShift": null,
|
||||
"title": "Tickets In Matches",
|
||||
"tooltip": {
|
||||
"shared": true,
|
||||
"sort": 0,
|
||||
"value_type": "individual"
|
||||
},
|
||||
"type": "graph",
|
||||
"xaxis": {
|
||||
"buckets": null,
|
||||
"mode": "time",
|
||||
"name": null,
|
||||
"show": true,
|
||||
"values": []
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": "0",
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
}
|
||||
],
|
||||
"yaxis": {
|
||||
"align": false,
|
||||
"alignLevel": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"aliasColors": {},
|
||||
"bars": false,
|
||||
@ -146,7 +454,7 @@
|
||||
"h": 9,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 10
|
||||
"y": 27
|
||||
},
|
||||
"id": 2,
|
||||
"legend": {
|
||||
@ -235,91 +543,6 @@
|
||||
"alignLevel": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"aliasColors": {},
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"fill": 1,
|
||||
"gridPos": {
|
||||
"h": 9,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 10
|
||||
},
|
||||
"id": 12,
|
||||
"legend": {
|
||||
"avg": false,
|
||||
"current": false,
|
||||
"max": false,
|
||||
"min": false,
|
||||
"show": true,
|
||||
"total": false,
|
||||
"values": false
|
||||
},
|
||||
"lines": true,
|
||||
"linewidth": 1,
|
||||
"links": [],
|
||||
"nullPointMode": "null",
|
||||
"options": {},
|
||||
"percentage": false,
|
||||
"pointradius": 2,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
"seriesOverrides": [],
|
||||
"spaceLength": 10,
|
||||
"stack": false,
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "sum(rate(scale_backend_sum_tickets_returned[5m]))",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "Backend Tickets in Matches pers second",
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"thresholds": [],
|
||||
"timeFrom": null,
|
||||
"timeRegions": [],
|
||||
"timeShift": null,
|
||||
"title": "Tickets In Matches",
|
||||
"tooltip": {
|
||||
"shared": true,
|
||||
"sort": 0,
|
||||
"value_type": "individual"
|
||||
},
|
||||
"type": "graph",
|
||||
"xaxis": {
|
||||
"buckets": null,
|
||||
"mode": "time",
|
||||
"name": null,
|
||||
"show": true,
|
||||
"values": []
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": "0",
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
}
|
||||
],
|
||||
"yaxis": {
|
||||
"align": false,
|
||||
"alignLevel": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"aliasColors": {},
|
||||
"bars": false,
|
||||
@ -330,7 +553,7 @@
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 19
|
||||
"y": 28
|
||||
},
|
||||
"id": 22,
|
||||
"legend": {
|
||||
@ -357,7 +580,7 @@
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "sum(rate(scale_backend_tickets_deleted[5m]))",
|
||||
"expr": "sum(rate(scale_frontend_tickets_deleted[5m]))",
|
||||
"format": "time_series",
|
||||
"interval": "",
|
||||
"intervalFactor": 1,
|
||||
@ -365,7 +588,7 @@
|
||||
"refId": "B"
|
||||
},
|
||||
{
|
||||
"expr": "sum(rate(scale_backend_ticket_deletes_failed[5m]))",
|
||||
"expr": "sum(rate(scale_frontend_ticket_deletes_failed[5m]))",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "Backend Ticket Deletions Failed per second",
|
||||
@ -413,13 +636,107 @@
|
||||
"alignLevel": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"aliasColors": {},
|
||||
"bars": false,
|
||||
"cacheTimeout": null,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"fill": 1,
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 36
|
||||
},
|
||||
"id": 24,
|
||||
"legend": {
|
||||
"avg": false,
|
||||
"current": false,
|
||||
"max": false,
|
||||
"min": false,
|
||||
"show": true,
|
||||
"total": false,
|
||||
"values": false
|
||||
},
|
||||
"lines": true,
|
||||
"linewidth": 1,
|
||||
"links": [],
|
||||
"nullPointMode": "null",
|
||||
"options": {},
|
||||
"percentage": false,
|
||||
"pointradius": 2,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
"seriesOverrides": [],
|
||||
"spaceLength": 10,
|
||||
"stack": false,
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "sum(scale_frontend_runners_waiting)",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "Runners Waiting To Start",
|
||||
"refId": "A"
|
||||
},
|
||||
{
|
||||
"expr": "sum(scale_frontend_runners_creating)",
|
||||
"format": "time_series",
|
||||
"instant": false,
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "Runners Creating Ticket",
|
||||
"refId": "B"
|
||||
}
|
||||
],
|
||||
"thresholds": [],
|
||||
"timeFrom": null,
|
||||
"timeRegions": [],
|
||||
"timeShift": null,
|
||||
"title": "Outstanding Frontend Runners",
|
||||
"tooltip": {
|
||||
"shared": true,
|
||||
"sort": 0,
|
||||
"value_type": "individual"
|
||||
},
|
||||
"type": "graph",
|
||||
"xaxis": {
|
||||
"buckets": null,
|
||||
"mode": "time",
|
||||
"name": null,
|
||||
"show": true,
|
||||
"values": []
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": "0",
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
}
|
||||
],
|
||||
"yaxis": {
|
||||
"align": false,
|
||||
"alignLevel": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"collapsed": false,
|
||||
"gridPos": {
|
||||
"h": 1,
|
||||
"w": 24,
|
||||
"x": 0,
|
||||
"y": 27
|
||||
"y": 44
|
||||
},
|
||||
"id": 18,
|
||||
"panels": [],
|
||||
@ -436,7 +753,7 @@
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 28
|
||||
"y": 45
|
||||
},
|
||||
"id": 6,
|
||||
"legend": {
|
||||
@ -522,7 +839,7 @@
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 28
|
||||
"y": 45
|
||||
},
|
||||
"id": 19,
|
||||
"legend": {
|
||||
@ -611,7 +928,7 @@
|
||||
"h": 1,
|
||||
"w": 24,
|
||||
"x": 0,
|
||||
"y": 36
|
||||
"y": 53
|
||||
},
|
||||
"id": 21,
|
||||
"panels": [],
|
||||
@ -628,7 +945,7 @@
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 37
|
||||
"y": 54
|
||||
},
|
||||
"id": 8,
|
||||
"legend": {
|
||||
@ -713,7 +1030,7 @@
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 37
|
||||
"y": 54
|
||||
},
|
||||
"id": 10,
|
||||
"legend": {
|
||||
@ -796,7 +1113,7 @@
|
||||
}
|
||||
}
|
||||
],
|
||||
"refresh": "",
|
||||
"refresh": "10s",
|
||||
"schemaVersion": 18,
|
||||
"style": "dark",
|
||||
"tags": [],
|
||||
|
@ -0,0 +1,42 @@
|
||||
{*
|
||||
Copyright 2019 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.
|
||||
*}
|
||||
|
||||
{{/* vim: set filetype=mustache: */}}
|
||||
{{/*
|
||||
Create a default fully qualified app name.
|
||||
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
|
||||
If release name contains chart name it will be used as a full name.
|
||||
*/}}
|
||||
{{- define "openmatchscale.fullname" -}}
|
||||
{{- if .Values.fullnameOverride }}
|
||||
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride }}
|
||||
{{- if contains $name .Release.Name }}
|
||||
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "openmatchscale.scaleBackend.hostName" -}}
|
||||
{{- .Values.scaleBackend.hostName | default (printf "%s-backend" (include "openmatchscale.fullname" . ) ) -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "openmatchscale.scaleFrontend.hostName" -}}
|
||||
{{- .Values.scaleFrontend.hostName | default (printf "%s-frontend" (include "openmatchscale.fullname" . ) ) -}}
|
||||
{{- end -}}
|
@ -15,7 +15,7 @@
|
||||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: {{ .Values.scaleBackend.hostName }}
|
||||
name: {{ include "openmatchscale.scaleBackend.hostName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations: {{- include "openmatch.chartmeta" . | nindent 4 }}
|
||||
labels:
|
||||
@ -34,7 +34,7 @@ spec:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ .Values.scaleBackend.hostName }}
|
||||
name: {{ include "openmatchscale.scaleBackend.hostName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations: {{- include "openmatch.chartmeta" . | nindent 4 }}
|
||||
labels:
|
||||
@ -59,11 +59,11 @@ spec:
|
||||
release: {{ .Release.Name }}
|
||||
spec:
|
||||
volumes:
|
||||
{{- include "openmatch.volumes.configs" (dict "configs" .Values.configs) | nindent 8}}
|
||||
{{- include "openmatch.volumes.configs" (. | merge (dict "configs" .Values.configs)) | nindent 8}}
|
||||
{{- include "openmatch.volumes.tls" . | nindent 8}}
|
||||
serviceAccountName: {{ .Values.global.kubernetes.serviceAccount }}
|
||||
serviceAccountName: {{ include "openmatch.serviceAccount.name" . }}
|
||||
containers:
|
||||
- name: {{ .Values.scaleBackend.hostName }}
|
||||
- name: {{ include "openmatchscale.scaleBackend.hostName" . }}
|
||||
volumeMounts:
|
||||
{{- include "openmatch.volumemounts.configs" (dict "configs" .Values.configs) | nindent 10 }}
|
||||
{{- include "openmatch.volumemounts.tls" . | nindent 10 }}
|
||||
|
@ -1,108 +0,0 @@
|
||||
# Copyright 2019 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.
|
||||
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: scale-configmap
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations: {{- include "openmatch.chartmeta" . | nindent 4 }}
|
||||
labels:
|
||||
app: {{ template "openmatch.name" . }}
|
||||
component: config
|
||||
release: {{ .Release.Name }}
|
||||
data:
|
||||
matchmaker_config_default.yaml: |-
|
||||
api:
|
||||
backend:
|
||||
hostname: "{{ .Values.backend.hostName }}"
|
||||
grpcport: "{{ .Values.backend.grpcPort }}"
|
||||
httpport: "{{ .Values.backend.httpPort }}"
|
||||
frontend:
|
||||
hostname: "{{ .Values.frontend.hostName }}"
|
||||
grpcport: "{{ .Values.frontend.grpcPort }}"
|
||||
httpport: "{{ .Values.frontend.httpPort }}"
|
||||
scale:
|
||||
httpport: "51509"
|
||||
{{- if .Values.global.tls.enabled }}
|
||||
tls:
|
||||
trustedCertificatePath: "{{.Values.global.tls.rootca.mountPath}}/public.cert"
|
||||
certificatefile: "{{.Values.global.tls.server.mountPath}}/public.cert"
|
||||
privatekey: "{{.Values.global.tls.server.mountPath}}/private.key"
|
||||
rootcertificatefile: "{{.Values.global.tls.rootca.mountPath}}/public.cert"
|
||||
{{- end }}
|
||||
|
||||
logging:
|
||||
level: debug
|
||||
{{- if .Values.global.telemetry.stackdriverMetrics.enabled }}
|
||||
format: stackdriver
|
||||
{{- else }}
|
||||
format: text
|
||||
{{- end }}
|
||||
rpc: {{ .Values.global.logging.rpc.enabled }}
|
||||
# Open Match applies the exponential backoff strategy for its retryable gRPC calls.
|
||||
# The settings below are the default backoff configuration used in Open Match.
|
||||
# See https://github.com/cenkalti/backoff/blob/v3/exponential.go for detailed explanations
|
||||
backoff:
|
||||
# The initial retry interval (in milliseconds)
|
||||
initialInterval: 100ms
|
||||
# maxInterval caps the maximum time elapsed for a retry interval
|
||||
maxInterval: 500ms
|
||||
# The next retry interval is multiplied by this multiplier
|
||||
multiplier: 1.5
|
||||
# Randomize the retry interval
|
||||
randFactor: 0.5
|
||||
# maxElapsedTime caps the retry time (in milliseconds)
|
||||
maxElapsedTime: 3000ms
|
||||
|
||||
telemetry:
|
||||
zpages:
|
||||
enable: "{{ .Values.global.telemetry.zpages.enabled }}"
|
||||
jaeger:
|
||||
enable: "{{ .Values.global.telemetry.jaeger.enabled }}"
|
||||
samplerFraction: {{ .Values.global.telemetry.jaeger.samplerFraction }}
|
||||
agentEndpoint: "{{ .Values.global.telemetry.jaeger.agentEndpoint }}"
|
||||
collectorEndpoint: "{{ .Values.global.telemetry.jaeger.collectorEndpoint }}"
|
||||
prometheus:
|
||||
enable: "{{ .Values.global.telemetry.prometheus.enabled }}"
|
||||
endpoint: "{{ .Values.global.telemetry.prometheus.endpoint }}"
|
||||
serviceDiscovery: "{{ .Values.global.telemetry.prometheus.serviceDiscovery }}"
|
||||
stackdriverMetrics:
|
||||
enable: "{{ .Values.global.telemetry.stackdriverMetrics.enabled }}"
|
||||
gcpProjectId: "{{ .Values.global.gcpProjectId }}"
|
||||
prefix: "{{ .Values.global.telemetry.stackdriverMetrics.prefix }}"
|
||||
reportingPeriod: "{{ .Values.global.telemetry.reportingPeriod }}"
|
||||
|
||||
matchmaker_config_override.yaml: |-
|
||||
testConfig:
|
||||
profile: "{{ .Values.testConfig.profile }}"
|
||||
regions:
|
||||
{{- range .Values.testConfig.regions }}
|
||||
- {{ . }}
|
||||
{{- end }}
|
||||
characters:
|
||||
{{- range .Values.testConfig.characters }}
|
||||
- {{ . }}
|
||||
{{- end }}
|
||||
minRating: "{{ .Values.testConfig.minRating }}"
|
||||
maxRating: "{{ .Values.testConfig.maxRating }}"
|
||||
ticketsPerMatch: "{{ .Values.testConfig.ticketsPerMatch }}"
|
||||
multifilter:
|
||||
rangeSize: "{{ .Values.testConfig.multifilter.rangeSize }}"
|
||||
rangeOverlap: "{{ .Values.testConfig.multifilter.rangeOverlap }}"
|
||||
multipool:
|
||||
rangeSize: "{{ .Values.testConfig.multipool.rangeSize }}"
|
||||
rangeOverlap: "{{ .Values.testConfig.multipool.rangeOverlap }}"
|
||||
characterCount: "{{ .Values.testConfig.multipool.characterCount }}"
|
||||
|
@ -15,7 +15,7 @@
|
||||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: {{ .Values.scaleFrontend.hostName }}
|
||||
name: {{ include "openmatchscale.scaleFrontend.hostName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations: {{- include "openmatch.chartmeta" . | nindent 4 }}
|
||||
labels:
|
||||
@ -31,10 +31,10 @@ spec:
|
||||
protocol: TCP
|
||||
port: {{ .Values.scaleFrontend.httpPort }}
|
||||
---
|
||||
apiVersion: extensions/v1beta1
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ .Values.scaleFrontend.hostName }}
|
||||
name: {{ include "openmatchscale.scaleFrontend.hostName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations: {{- include "openmatch.chartmeta" . | nindent 4 }}
|
||||
labels:
|
||||
@ -59,11 +59,11 @@ spec:
|
||||
release: {{ .Release.Name }}
|
||||
spec:
|
||||
volumes:
|
||||
{{- include "openmatch.volumes.configs" (dict "configs" .Values.configs) | nindent 8}}
|
||||
{{- include "openmatch.volumes.configs" (. | merge (dict "configs" .Values.configs)) | nindent 8}}
|
||||
{{- include "openmatch.volumes.tls" . | nindent 8}}
|
||||
serviceAccountName: {{ .Values.global.kubernetes.serviceAccount }}
|
||||
serviceAccountName: {{ include "openmatch.serviceAccount.name" . }}
|
||||
containers:
|
||||
- name: {{ .Values.scaleFrontend.hostName }}
|
||||
- name: {{ include "openmatchscale.scaleFrontend.hostName" . }}
|
||||
volumeMounts:
|
||||
{{- include "openmatch.volumemounts.configs" (dict "configs" .Values.configs) | nindent 10 }}
|
||||
{{- include "openmatch.volumemounts.tls" . | nindent 10 }}
|
||||
|
@ -16,7 +16,7 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: open-match-scale-dashboard
|
||||
name: {{ include "openmatchscale.fullname" . }}-dashboard
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
grafana_dashboard: "1"
|
||||
|
@ -13,13 +13,13 @@
|
||||
# limitations under the License.
|
||||
|
||||
scaleFrontend:
|
||||
hostName: om-scale-frontend
|
||||
hostName:
|
||||
httpPort: 51509
|
||||
replicas: 1
|
||||
image: openmatch-scale-frontend
|
||||
|
||||
scaleBackend:
|
||||
hostName: om-scale-backend
|
||||
hostName:
|
||||
httpPort: 51509
|
||||
replicas: 1
|
||||
image: openmatch-scale-backend
|
||||
@ -28,29 +28,10 @@ configs:
|
||||
default:
|
||||
volumeName: om-config-volume-default
|
||||
mountPath: /app/config/default
|
||||
configName: scale-configmap
|
||||
scale-configmap:
|
||||
volumeName: scale-config-volume
|
||||
# This will be parsed through the `tpl` function.
|
||||
configName: '{{ include "openmatch.configmap.default" . }}'
|
||||
override:
|
||||
volumeName: om-config-volume-override
|
||||
mountPath: /app/config/override
|
||||
configName: scale-configmap
|
||||
|
||||
testConfig:
|
||||
profile: scaleprofiles
|
||||
regions:
|
||||
- region.europe-west1
|
||||
- region.europe-west2
|
||||
- region.europe-west3
|
||||
- region.europe-west4
|
||||
characters:
|
||||
- cleric
|
||||
- knight
|
||||
minRating: 0
|
||||
maxRating: 100
|
||||
ticketsPerMatch: 8
|
||||
multifilter:
|
||||
rangeSize: 10
|
||||
rangeOverlap: 5
|
||||
multipool:
|
||||
rangeSize: 10
|
||||
rangeOverlap: 5
|
||||
characterCount: 4
|
||||
# This will be parsed through the `tpl` function.
|
||||
configName: '{{ include "openmatch.configmap.override" . }}'
|
||||
|
@ -20,14 +20,14 @@ version: 0.0.0-dev
|
||||
dependencies:
|
||||
- name: prometheus
|
||||
version: 9.2.0
|
||||
repository: https://kubernetes-charts.storage.googleapis.com/
|
||||
repository: https://charts.helm.sh/stable
|
||||
condition: global.telemetry.prometheus.enabled,prometheus.enabled
|
||||
- name: grafana
|
||||
version: 4.0.1
|
||||
repository: https://kubernetes-charts.storage.googleapis.com/
|
||||
repository: https://charts.helm.sh/stable
|
||||
condition: global.telemetry.grafana.enabled,grafana.enabled
|
||||
- name: jaeger
|
||||
version: 0.13.3
|
||||
repository: https://kubernetes-charts-incubator.storage.googleapis.com/
|
||||
repository: https://charts.helm.sh/stable
|
||||
condition: global.telemetry.jaeger.enabled,jaeger.enabled
|
||||
|
||||
|
@ -62,7 +62,7 @@
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "avg by (pod_name) (\n sum(\n rate(container_cpu_usage_seconds_total{pod_name=~\"om-.*\", container_name!=\"POD\"}[5m])\n ) by (pod_name, container_name) \n \n /\n \n sum(\n container_spec_cpu_quota{pod_name=~\"om-.*\", container_name!=\"POD\"} / container_spec_cpu_period{pod_name=~\"om-.*\", container_name!=\"POD\"}\n ) by (pod_name, container_name) \n \n * \n \n 100\n)",
|
||||
"expr": "avg by (pod_name) (\n\nsum(\n rate(container_cpu_usage_seconds_total{container_name!=\"POD\"}[5m]) * on (pod_name) group_left(label_app) max by (pod_name, label_app) (label_replace(kube_pod_labels{label_app=\"open-match\"}, \"pod_name\", \"$1\", \"pod\", \"(.*)\"))\n) by (pod_name, container_name)\n\n/\n\nsum(\n (container_spec_cpu_quota{container_name!=\"POD\"} * on (pod_name) group_left(label_app) max by (pod_name, label_app) (label_replace(kube_pod_labels{label_app=\"open-match\"}, \"pod_name\", \"$1\", \"pod\", \"(.*)\")))\n /\n (container_spec_cpu_period{container_name!=\"POD\"} * on (pod_name) group_left(label_app) max by (pod_name, label_app) (label_replace(kube_pod_labels{label_app=\"open-match\"}, \"pod_name\", \"$1\", \"pod\", \"(.*)\")))\n) by (pod_name, container_name)\n\n*\n\n100\n)\n",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "{{pod_name}}",
|
||||
@ -155,7 +155,7 @@
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "avg by (component) (go_goroutines{app=~\"open-match\", kubernetes_pod_name=~\"om-.*\"})",
|
||||
"expr": "avg by (component) (go_goroutines{app=~\"open-match\"})",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 2,
|
||||
"legendFormat": "{{component}}",
|
||||
@ -256,7 +256,7 @@
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "avg by (component,app) (process_resident_memory_bytes{app=~\"open-match\", kubernetes_pod_name=~\"om-.*\"})",
|
||||
"expr": "avg by (component,app) (process_resident_memory_bytes{app=~\"open-match\"})",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 2,
|
||||
"legendFormat": "{{component}} - resident",
|
||||
@ -265,7 +265,7 @@
|
||||
"step": 4
|
||||
},
|
||||
{
|
||||
"expr": "avg by (component,app) (process_virtual_memory_bytes{app=~\"open-match\", kubernetes_pod_name=~\"om-.*\"})",
|
||||
"expr": "avg by (component,app) (process_virtual_memory_bytes{app=~\"open-match\"})",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 2,
|
||||
"legendFormat": "{{component}} - virtual",
|
||||
@ -365,7 +365,7 @@
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "avg by (component) (deriv(process_resident_memory_bytes{app=~\"open-match\", kubernetes_pod_name=~\"om-.*\"}[$interval]))",
|
||||
"expr": "avg by (component) (deriv(process_resident_memory_bytes{app=~\"open-match\"}[$interval]))",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 2,
|
||||
"legendFormat": "{{component}} - resident",
|
||||
@ -374,7 +374,7 @@
|
||||
"step": 4
|
||||
},
|
||||
{
|
||||
"expr": "avg by (component) (deriv(process_virtual_memory_bytes{app=~\"open-match\", kubernetes_pod_name=~\"om-.*\"}[$interval]))",
|
||||
"expr": "avg by (component) (deriv(process_virtual_memory_bytes{app=~\"open-match\"}[$interval]))",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 2,
|
||||
"legendFormat": "{{component}} - virtual",
|
||||
@ -475,7 +475,7 @@
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "avg by (component) (go_memstats_alloc_bytes{app=~\"open-match\", kubernetes_pod_name=~\"om-.*\"})",
|
||||
"expr": "avg by (component) (go_memstats_alloc_bytes{app=~\"open-match\"})",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 2,
|
||||
"legendFormat": "{{component}} - bytes allocated",
|
||||
@ -484,7 +484,7 @@
|
||||
"step": 4
|
||||
},
|
||||
{
|
||||
"expr": "avg by (component) (rate(go_memstats_alloc_bytes_total{app=~\"open-match\", kubernetes_pod_name=~\"om-.*\"}[$interval]))",
|
||||
"expr": "avg by (component) (rate(go_memstats_alloc_bytes_total{app=~\"open-match\"}[$interval]))",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 2,
|
||||
"legendFormat": "{{component}} - alloc rate",
|
||||
@ -493,7 +493,7 @@
|
||||
"step": 4
|
||||
},
|
||||
{
|
||||
"expr": "avg by (component) (go_memstats_stack_inuse_bytes{app=~\"open-match\", kubernetes_pod_name=~\"om-.*\"})",
|
||||
"expr": "avg by (component) (go_memstats_stack_inuse_bytes{app=~\"open-match\"})",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 2,
|
||||
"legendFormat": "{{component}} - stack inuse",
|
||||
@ -502,7 +502,7 @@
|
||||
"step": 4
|
||||
},
|
||||
{
|
||||
"expr": "avg by (component) (go_memstats_heap_inuse_bytes{app=~\"open-match\", kubernetes_pod_name=~\"om-.*\"})",
|
||||
"expr": "avg by (component) (go_memstats_heap_inuse_bytes{app=~\"open-match\"})",
|
||||
"format": "time_series",
|
||||
"hide": false,
|
||||
"intervalFactor": 2,
|
||||
@ -604,7 +604,7 @@
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "avg by (component) (deriv(go_memstats_alloc_bytes{app=~\"open-match\", kubernetes_pod_name=~\"om-.*\"}[$interval]))",
|
||||
"expr": "avg by (component) (deriv(go_memstats_alloc_bytes{app=~\"open-match\"}[$interval]))",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 2,
|
||||
"legendFormat": "{{component}} - bytes allocated",
|
||||
@ -613,7 +613,7 @@
|
||||
"step": 4
|
||||
},
|
||||
{
|
||||
"expr": "avg by (component) (deriv(go_memstats_stack_inuse_bytes{app=~\"open-match\", kubernetes_pod_name=~\"om-.*\"}[$interval]))",
|
||||
"expr": "avg by (component) (deriv(go_memstats_stack_inuse_bytes{app=~\"open-match\"}[$interval]))",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 2,
|
||||
"legendFormat": "{{component}} - stack inuse",
|
||||
@ -622,7 +622,7 @@
|
||||
"step": 4
|
||||
},
|
||||
{
|
||||
"expr": "avg by (component) (deriv(go_memstats_heap_inuse_bytes{app=~\"open-match\", kubernetes_pod_name=~\"om-.*\"}[$interval]))",
|
||||
"expr": "avg by (component) (deriv(go_memstats_heap_inuse_bytes{app=~\"open-match\"}[$interval]))",
|
||||
"format": "time_series",
|
||||
"hide": false,
|
||||
"intervalFactor": 2,
|
||||
@ -719,7 +719,7 @@
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "avg by (component) (process_open_fds{app=~\"open-match\", kubernetes_pod_name=~\"om-.*\"})",
|
||||
"expr": "avg by (component) (process_open_fds{app=~\"open-match\"})",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 2,
|
||||
"legendFormat": "{{component}}",
|
||||
@ -815,7 +815,7 @@
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "avg by (component) (deriv(process_open_fds{app=~\"open-match\", kubernetes_pod_name=~\"om-.*\"}[$interval]))",
|
||||
"expr": "avg by (component) (deriv(process_open_fds{app=~\"open-match\"}[$interval]))",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 2,
|
||||
"legendFormat": "{{component}}",
|
||||
@ -911,7 +911,7 @@
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "avg by (component, quantile) (go_gc_duration_seconds{app=~\"open-match\", kubernetes_pod_name=~\"om-.*\"})",
|
||||
"expr": "avg by (component, quantile) (go_gc_duration_seconds{app=~\"open-match\"})",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 2,
|
||||
"legendFormat": "{{component}}: {{quantile}}",
|
||||
|
@ -15,8 +15,8 @@
|
||||
"editable": true,
|
||||
"gnetId": null,
|
||||
"graphTooltip": 0,
|
||||
"id": 3,
|
||||
"iteration": 1580245993833,
|
||||
"id": 2,
|
||||
"iteration": 1580944984710,
|
||||
"links": [],
|
||||
"panels": [
|
||||
{
|
||||
@ -415,7 +415,7 @@
|
||||
},
|
||||
"id": 57,
|
||||
"panels": [],
|
||||
"title": "openmatch.Mmlogic/QueryTickets",
|
||||
"title": "openmatch.QueryService/QueryTickets",
|
||||
"type": "row"
|
||||
},
|
||||
{
|
||||
@ -812,7 +812,7 @@
|
||||
},
|
||||
"id": 29,
|
||||
"panels": [],
|
||||
"title": "openmatch.Backend/AssignTickets",
|
||||
"title": "openmatch.BackendService/AssignTickets",
|
||||
"type": "row"
|
||||
},
|
||||
{
|
||||
@ -1210,7 +1210,7 @@
|
||||
"id": 31,
|
||||
"panels": [],
|
||||
"repeat": null,
|
||||
"title": "openmatch.Frontend/CreateTicket",
|
||||
"title": "openmatch.FrontendService/CreateTicket",
|
||||
"type": "row"
|
||||
},
|
||||
{
|
||||
@ -2399,7 +2399,7 @@
|
||||
},
|
||||
"id": 42,
|
||||
"panels": [],
|
||||
"title": "openmatch.Frontend/FetchMatches",
|
||||
"title": "openmatch.BackendService/FetchMatches",
|
||||
"type": "row"
|
||||
},
|
||||
{
|
||||
@ -3191,7 +3191,7 @@
|
||||
},
|
||||
"id": 23,
|
||||
"panels": [],
|
||||
"title": "openmatch.Frontend/DeleteTicket",
|
||||
"title": "openmatch.FrontendService/DeleteTicket",
|
||||
"type": "row"
|
||||
},
|
||||
{
|
||||
|
2131
install/helm/open-match/subcharts/open-match-telemetry/dashboards/match-making.json
Normal file
2131
install/helm/open-match/subcharts/open-match-telemetry/dashboards/match-making.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -16,8 +16,8 @@
|
||||
"editable": true,
|
||||
"gnetId": 763,
|
||||
"graphTooltip": 0,
|
||||
"id": 2,
|
||||
"iteration": 1579655194536,
|
||||
"id": 6,
|
||||
"iteration": 1580946687856,
|
||||
"links": [],
|
||||
"panels": [
|
||||
{
|
||||
@ -296,7 +296,7 @@
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"fill": 1,
|
||||
"fill": 0,
|
||||
"gridPos": {
|
||||
"h": 7,
|
||||
"w": 8,
|
||||
@ -312,6 +312,8 @@
|
||||
"min": false,
|
||||
"rightSide": true,
|
||||
"show": true,
|
||||
"sort": "current",
|
||||
"sortDesc": true,
|
||||
"total": false,
|
||||
"values": true
|
||||
},
|
||||
@ -325,24 +327,54 @@
|
||||
"pointradius": 2,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
"seriesOverrides": [],
|
||||
"seriesOverrides": [
|
||||
{
|
||||
"alias": "limit",
|
||||
"color": "#C4162A",
|
||||
"hideTooltip": true,
|
||||
"legend": false,
|
||||
"nullPointMode": "connected"
|
||||
},
|
||||
{
|
||||
"alias": "request",
|
||||
"color": "#73BF69",
|
||||
"hideTooltip": true,
|
||||
"legend": false,
|
||||
"nullPointMode": "connected"
|
||||
}
|
||||
],
|
||||
"spaceLength": 10,
|
||||
"stack": false,
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "sum(rate(container_cpu_usage_seconds_total{pod_name=~\"om-redis.*\", name!~\".*prometheus.*\", image!=\"\", container_name!=\"POD\"}[5m])) by (pod_name, container_name) /\nsum(container_spec_cpu_quota{name!~\".*prometheus.*\", image!=\"\", container_name!=\"POD\"}/container_spec_cpu_period{name!~\".*prometheus.*\", image!=\"\", container_name!=\"POD\"}) by (pod_name, container_name) * 100",
|
||||
"expr": "sum(rate(container_cpu_usage_seconds_total{name!~\".*prometheus.*\", image!=\"\", container_name!=\"POD\"}[5m]) * on (pod_name) group_left(label_app) max by (pod_name, label_app) (label_replace(kube_pod_labels{label_app=\"redis\"}, \"pod_name\", \"$1\", \"pod\", \"(.*)\"))) by (pod_name)",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "{{pod_name}}",
|
||||
"legendFormat": "{{pod_name}} usage",
|
||||
"refId": "A"
|
||||
},
|
||||
{
|
||||
"expr": "sum(kube_pod_container_resource_limits_cpu_cores * on (pod) group_left(label_app) max by (pod, label_app) (kube_pod_labels{label_app=\"redis\"})) by (pod)",
|
||||
"format": "time_series",
|
||||
"hide": false,
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "limit",
|
||||
"refId": "B"
|
||||
},
|
||||
{
|
||||
"expr": "sum(kube_pod_container_resource_requests_cpu_cores * on (pod) group_left(label_app) max by (pod, label_app) (kube_pod_labels{label_app=\"redis\"})) by (pod)",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "request",
|
||||
"refId": "C"
|
||||
}
|
||||
],
|
||||
"thresholds": [],
|
||||
"timeFrom": null,
|
||||
"timeRegions": [],
|
||||
"timeShift": null,
|
||||
"title": "CPU Usage Percentage of Limit",
|
||||
"title": "CPU Usage",
|
||||
"tooltip": {
|
||||
"shared": true,
|
||||
"sort": 0,
|
||||
@ -360,7 +392,7 @@
|
||||
"yaxes": [
|
||||
{
|
||||
"format": "short",
|
||||
"label": "%",
|
||||
"label": "core",
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
@ -628,6 +660,8 @@
|
||||
"min": false,
|
||||
"rightSide": true,
|
||||
"show": true,
|
||||
"sort": "current",
|
||||
"sortDesc": true,
|
||||
"total": false,
|
||||
"values": true
|
||||
},
|
||||
@ -655,6 +689,13 @@
|
||||
"refId": "A",
|
||||
"step": 240,
|
||||
"target": ""
|
||||
},
|
||||
{
|
||||
"expr": "sum by (kubernetes_pod_name) (rate(redis_commands_total[5m]))",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "total - {{kubernetes_pod_name}}",
|
||||
"refId": "B"
|
||||
}
|
||||
],
|
||||
"thresholds": [],
|
||||
@ -911,8 +952,8 @@
|
||||
{
|
||||
"allValue": null,
|
||||
"current": {
|
||||
"text": "10.28.0.27:9121",
|
||||
"value": "10.28.0.27:9121"
|
||||
"text": "10.28.0.12:9121",
|
||||
"value": "10.28.0.12:9121"
|
||||
},
|
||||
"datasource": "Prometheus",
|
||||
"definition": "label_values(redis_up, instance)",
|
||||
|
@ -1,290 +0,0 @@
|
||||
{
|
||||
"annotations": {
|
||||
"list": [
|
||||
{
|
||||
"builtIn": 1,
|
||||
"datasource": "-- Grafana --",
|
||||
"enable": true,
|
||||
"hide": true,
|
||||
"iconColor": "rgba(0, 211, 255, 1)",
|
||||
"name": "Annotations & Alerts",
|
||||
"type": "dashboard"
|
||||
}
|
||||
]
|
||||
},
|
||||
"editable": true,
|
||||
"gnetId": null,
|
||||
"graphTooltip": 0,
|
||||
"id": 3,
|
||||
"iteration": 1562886170229,
|
||||
"links": [],
|
||||
"panels": [
|
||||
{
|
||||
"aliasColors": {},
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"fill": 1,
|
||||
"gridPos": {
|
||||
"h": 9,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"id": 2,
|
||||
"legend": {
|
||||
"avg": false,
|
||||
"current": false,
|
||||
"max": false,
|
||||
"min": false,
|
||||
"show": true,
|
||||
"total": false,
|
||||
"values": false
|
||||
},
|
||||
"lines": true,
|
||||
"linewidth": 1,
|
||||
"links": [],
|
||||
"nullPointMode": "null",
|
||||
"options": {},
|
||||
"percentage": false,
|
||||
"pointradius": 2,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
"seriesOverrides": [],
|
||||
"spaceLength": 10,
|
||||
"stack": false,
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "sum(rate(frontend_tickets_created[$timewindow]))",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "Created",
|
||||
"refId": "A"
|
||||
},
|
||||
{
|
||||
"expr": "sum(rate(frontend_tickets_deleted[$timewindow]))",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "Deleted",
|
||||
"refId": "B"
|
||||
}
|
||||
],
|
||||
"thresholds": [],
|
||||
"timeFrom": null,
|
||||
"timeRegions": [],
|
||||
"timeShift": null,
|
||||
"title": "Ticket Flow",
|
||||
"tooltip": {
|
||||
"shared": true,
|
||||
"sort": 0,
|
||||
"value_type": "individual"
|
||||
},
|
||||
"type": "graph",
|
||||
"xaxis": {
|
||||
"buckets": null,
|
||||
"mode": "time",
|
||||
"name": null,
|
||||
"show": true,
|
||||
"values": []
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
}
|
||||
],
|
||||
"yaxis": {
|
||||
"align": false,
|
||||
"alignLevel": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"aliasColors": {},
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"description": "",
|
||||
"fill": 1,
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 0
|
||||
},
|
||||
"id": 4,
|
||||
"interval": "",
|
||||
"legend": {
|
||||
"avg": false,
|
||||
"current": false,
|
||||
"max": false,
|
||||
"min": false,
|
||||
"show": true,
|
||||
"total": false,
|
||||
"values": false
|
||||
},
|
||||
"lines": true,
|
||||
"linewidth": 1,
|
||||
"links": [],
|
||||
"nullPointMode": "null",
|
||||
"options": {},
|
||||
"percentage": false,
|
||||
"pointradius": 2,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
"seriesOverrides": [],
|
||||
"spaceLength": 10,
|
||||
"stack": false,
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "sum(rate(frontend_tickets_assignments_retrieved[$timewindow]))",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "Assignments Retrieved",
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"thresholds": [],
|
||||
"timeFrom": null,
|
||||
"timeRegions": [],
|
||||
"timeShift": null,
|
||||
"title": "Assignments",
|
||||
"tooltip": {
|
||||
"shared": true,
|
||||
"sort": 0,
|
||||
"value_type": "individual"
|
||||
},
|
||||
"type": "graph",
|
||||
"xaxis": {
|
||||
"buckets": null,
|
||||
"mode": "time",
|
||||
"name": null,
|
||||
"show": true,
|
||||
"values": []
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"decimals": null,
|
||||
"format": "reqps",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": "0",
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
}
|
||||
],
|
||||
"yaxis": {
|
||||
"align": false,
|
||||
"alignLevel": null
|
||||
}
|
||||
}
|
||||
],
|
||||
"schemaVersion": 18,
|
||||
"style": "dark",
|
||||
"tags": [],
|
||||
"templating": {
|
||||
"list": [
|
||||
{
|
||||
"allValue": null,
|
||||
"current": {
|
||||
"text": "5m",
|
||||
"value": "5m"
|
||||
},
|
||||
"hide": 0,
|
||||
"includeAll": false,
|
||||
"label": "Time Window",
|
||||
"multi": false,
|
||||
"name": "timewindow",
|
||||
"options": [
|
||||
{
|
||||
"selected": true,
|
||||
"text": "5m",
|
||||
"value": "5m"
|
||||
},
|
||||
{
|
||||
"selected": false,
|
||||
"text": "10m",
|
||||
"value": "10m"
|
||||
},
|
||||
{
|
||||
"selected": false,
|
||||
"text": "15m",
|
||||
"value": "15m"
|
||||
},
|
||||
{
|
||||
"selected": false,
|
||||
"text": "30m",
|
||||
"value": "30m"
|
||||
},
|
||||
{
|
||||
"selected": false,
|
||||
"text": "1h",
|
||||
"value": "1h"
|
||||
},
|
||||
{
|
||||
"selected": false,
|
||||
"text": "4h",
|
||||
"value": "4h"
|
||||
}
|
||||
],
|
||||
"query": "5m,10m,15m,30m,1h,4h",
|
||||
"skipUrlSync": false,
|
||||
"type": "custom"
|
||||
}
|
||||
]
|
||||
},
|
||||
"time": {
|
||||
"from": "now-6h",
|
||||
"to": "now"
|
||||
},
|
||||
"timepicker": {
|
||||
"refresh_intervals": [
|
||||
"5s",
|
||||
"10s",
|
||||
"30s",
|
||||
"1m",
|
||||
"5m",
|
||||
"15m",
|
||||
"30m",
|
||||
"1h",
|
||||
"2h",
|
||||
"1d"
|
||||
],
|
||||
"time_options": [
|
||||
"5m",
|
||||
"15m",
|
||||
"1h",
|
||||
"6h",
|
||||
"12h",
|
||||
"24h",
|
||||
"2d",
|
||||
"7d",
|
||||
"30d"
|
||||
]
|
||||
},
|
||||
"timezone": "",
|
||||
"title": "Tickets",
|
||||
"uid": "TlgyFfIWz",
|
||||
"version": 6
|
||||
}
|
@ -16,7 +16,7 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: open-match-dashboards
|
||||
name: {{ include "openmatch.fullname" . }}-dashboards
|
||||
labels:
|
||||
grafana_dashboard: "1"
|
||||
data:
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2019 Google LLC
|
||||
# Copyright 2020 Google LLC
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@ -12,13 +12,20 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
FROM open-match-base-build as builder
|
||||
|
||||
WORKDIR /go/src/open-match.dev/open-match/test/evaluator
|
||||
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o evaluator .
|
||||
|
||||
FROM gcr.io/distroless/static:nonroot
|
||||
WORKDIR /app/
|
||||
COPY --from=builder --chown=nonroot /go/src/open-match.dev/open-match/test/evaluator/evaluator /app/
|
||||
|
||||
ENTRYPOINT ["/app/evaluator"]
|
||||
{{- if .Values.global.telemetry.grafana.enabled }}
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ include "openmatch.fullname" . }}-datasource
|
||||
labels:
|
||||
grafana_datasource: "1"
|
||||
data:
|
||||
datasource.yaml: |-
|
||||
apiVersion: 1
|
||||
datasources:
|
||||
- name: Prometheus
|
||||
type: prometheus
|
||||
url: {{ tpl .Values.global.telemetry.grafana.prometheusServer . }}
|
||||
access: proxy
|
||||
isDefault: true
|
||||
{{- end }}
|
@ -142,17 +142,10 @@ grafana:
|
||||
notifiers: {}
|
||||
sidecar:
|
||||
dashboards:
|
||||
enabled: true
|
||||
enabled: true
|
||||
datasources:
|
||||
enabled: true
|
||||
plugins: grafana-piechart-panel
|
||||
datasources:
|
||||
datasources.yaml:
|
||||
apiVersion: 1
|
||||
datasources:
|
||||
- name: Prometheus
|
||||
type: prometheus
|
||||
url: http://open-match-prometheus-server.{{ .Release.Namespace }}.svc.cluster.local:80/
|
||||
access: proxy
|
||||
isDefault: true
|
||||
|
||||
jaeger:
|
||||
enabled: true
|
||||
|
@ -22,6 +22,26 @@ Expand the name of the chart.
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Create a default fully qualified app name.
|
||||
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
|
||||
If release name contains chart name it will be used as a full name.
|
||||
Instead of .Chart.Name, we hard-code "open-match" as we need to call this from subcharts, but get the
|
||||
same result as if called from this chart.
|
||||
*/}}
|
||||
{{- define "openmatch.fullname" -}}
|
||||
{{- if .Values.fullnameOverride }}
|
||||
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- $name := default "open-match" .Values.nameOverride }}
|
||||
{{- if contains $name .Release.Name }}
|
||||
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Render chart metadata labels: "chart", "heritage" unless "openmatch.noChartMeta" is set.
|
||||
*/}}
|
||||
@ -57,7 +77,7 @@ resources:
|
||||
{{- range $configIndex, $configValues := .configs }}
|
||||
- name: {{ $configValues.volumeName }}
|
||||
configMap:
|
||||
name: {{ $configValues.configName }}
|
||||
name: {{ tpl $configValues.configName $ }}
|
||||
{{- end }}
|
||||
{{- end -}}
|
||||
|
||||
@ -74,25 +94,25 @@ resources:
|
||||
{{- if .Values.global.tls.enabled }}
|
||||
- name: tls-server-volume
|
||||
secret:
|
||||
secretName: om-tls-server
|
||||
secretName: {{ include "openmatch.fullname" . }}-tls-server
|
||||
- name: root-ca-volume
|
||||
secret:
|
||||
secretName: om-tls-rootca
|
||||
secretName: {{ include "openmatch.fullname" . }}-tls-rootca
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "openmatch.volumemounts.withredis" -}}
|
||||
{{- if .Values.redis.usePassword }}
|
||||
{{- if .Values.redis.auth.enabled }}
|
||||
- name: redis-password
|
||||
mountPath: {{ .Values.redis.secretMountPath }}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "openmatch.volumes.withredis" -}}
|
||||
{{- if .Values.redis.usePassword }}
|
||||
{{- if .Values.redis.auth.enabled }}
|
||||
- name: redis-password
|
||||
secret:
|
||||
secretName: {{ .Values.redis.fullnameOverride }}
|
||||
secretName: {{ include "call-nested" (list . "redis" "redis.fullname") }}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
@ -135,3 +155,72 @@ minReplicas: {{ .Values.global.kubernetes.horizontalPodAutoScaler.minReplicas }}
|
||||
maxReplicas: {{ .Values.global.kubernetes.horizontalPodAutoScaler.maxReplicas }}
|
||||
targetCPUUtilizationPercentage: {{ .Values.global.kubernetes.horizontalPodAutoScaler.targetCPUUtilizationPercentage }}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "openmatch.serviceAccount.name" -}}
|
||||
{{- .Values.global.kubernetes.serviceAccount | default (printf "%s-unprivileged-service" (include "openmatch.fullname" . ) ) -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "openmatch.swaggerui.hostName" -}}
|
||||
{{- .Values.swaggerui.hostName | default (printf "%s-swaggerui" (include "openmatch.fullname" . ) ) -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "openmatch.query.hostName" -}}
|
||||
{{- .Values.query.hostName | default (printf "%s-query" (include "openmatch.fullname" . ) ) -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "openmatch.frontend.hostName" -}}
|
||||
{{- .Values.frontend.hostName | default (printf "%s-frontend" (include "openmatch.fullname" . ) ) -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "openmatch.backend.hostName" -}}
|
||||
{{- .Values.backend.hostName | default (printf "%s-backend" (include "openmatch.fullname" . ) ) -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "openmatch.synchronizer.hostName" -}}
|
||||
{{- .Values.synchronizer.hostName | default (printf "%s-synchronizer" (include "openmatch.fullname" . ) ) -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "openmatch.evaluator.hostName" -}}
|
||||
{{- .Values.evaluator.hostName | default (printf "%s-evaluator" (include "openmatch.fullname" . ) ) -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "openmatch.configmap.default" -}}
|
||||
{{- printf "%s-configmap-default" (include "openmatch.fullname" . ) -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "openmatch.configmap.override" -}}
|
||||
{{- printf "%s-configmap-override" (include "openmatch.fullname" . ) -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "openmatch.jaeger.agent" -}}
|
||||
{{- if index .Values "open-match-telemetry" "enabled" -}}
|
||||
{{- if index .Values "open-match-telemetry" "jaeger" "enabled" -}}
|
||||
{{ include "call-nested" (list . "open-match-telemetry.jaeger" "jaeger.agent.name") }}:6831
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "openmatch.jaeger.collector" -}}
|
||||
{{- if index .Values "open-match-telemetry" "enabled" -}}
|
||||
{{- if index .Values "open-match-telemetry" "jaeger" "enabled" -}}
|
||||
http://{{ include "call-nested" (list . "open-match-telemetry.jaeger" "jaeger.collector.name") }}:14268/api/traces
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Call templates from sub-charts in a synthesized context, workaround for https://github.com/helm/helm/issues/3920
|
||||
Mainly useful for things like `{{ include "call-nested" (list . "redis" "redis.fullname") }}`
|
||||
https://github.com/helm/helm/issues/4535#issuecomment-416022809
|
||||
https://github.com/helm/helm/issues/4535#issuecomment-477778391
|
||||
*/}}
|
||||
{{- define "call-nested" }}
|
||||
{{- $dot := index . 0 }}
|
||||
{{- $subchart := index . 1 | splitList "." }}
|
||||
{{- $template := index . 2 }}
|
||||
{{- $values := $dot.Values }}
|
||||
{{- range $subchart }}
|
||||
{{- $values = index $values . }}
|
||||
{{- end }}
|
||||
{{- include $template (dict "Chart" (dict "Name" (last $subchart)) "Values" $values "Release" $dot.Release "Capabilities" $dot.Capabilities) }}
|
||||
{{- end }}
|
@ -16,7 +16,7 @@
|
||||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: {{ .Values.backend.hostName }}
|
||||
name: {{ include "openmatch.backend.hostName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations: {{- include "openmatch.chartmeta" . | nindent 4 }}
|
||||
labels:
|
||||
@ -44,19 +44,19 @@ spec:
|
||||
apiVersion: autoscaling/v1
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: {{ .Values.backend.hostName }}
|
||||
name: {{ include "openmatch.backend.hostName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
spec:
|
||||
scaleTargetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: {{ .Values.backend.hostName }}
|
||||
name: {{ include "openmatch.backend.hostName" . }}
|
||||
{{- include "openmatch.HorizontalPodAutoscaler.spec.common" . | nindent 2 }}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ .Values.backend.hostName }}
|
||||
name: {{ include "openmatch.backend.hostName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations: {{- include "openmatch.chartmeta" . | nindent 4 }}
|
||||
labels:
|
||||
@ -82,12 +82,12 @@ spec:
|
||||
spec:
|
||||
{{- include "openmatch.labels.nodegrouping" . | nindent 6 }}
|
||||
volumes:
|
||||
{{- include "openmatch.volumes.configs" (dict "configs" .Values.configs) | nindent 8}}
|
||||
{{- include "openmatch.volumes.configs" (. | merge (dict "configs" .Values.configs)) | nindent 8}}
|
||||
{{- include "openmatch.volumes.tls" . | nindent 8}}
|
||||
{{- include "openmatch.volumes.withredis" . | nindent 8}}
|
||||
serviceAccountName: {{ .Values.global.kubernetes.serviceAccount }}
|
||||
serviceAccountName: {{ include "openmatch.serviceAccount.name" . }}
|
||||
containers:
|
||||
- name: {{ .Values.backend.hostName }}
|
||||
- name: {{ include "openmatch.backend.hostName" . }}
|
||||
volumeMounts:
|
||||
{{- include "openmatch.volumemounts.configs" (dict "configs" .Values.configs) | nindent 10 }}
|
||||
{{- include "openmatch.volumemounts.tls" . | nindent 10 }}
|
||||
|
@ -16,7 +16,7 @@
|
||||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: {{ .Values.frontend.hostName }}
|
||||
name: {{ include "openmatch.frontend.hostName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations: {{- include "openmatch.chartmeta" . | nindent 4 }}
|
||||
labels:
|
||||
@ -44,19 +44,19 @@ spec:
|
||||
apiVersion: autoscaling/v1
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: {{ .Values.frontend.hostName }}
|
||||
name: {{ include "openmatch.frontend.hostName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
spec:
|
||||
scaleTargetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: {{ .Values.frontend.hostName }}
|
||||
name: {{ include "openmatch.frontend.hostName" . }}
|
||||
{{- include "openmatch.HorizontalPodAutoscaler.spec.common" . | nindent 2 }}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ .Values.frontend.hostName }}
|
||||
name: {{ include "openmatch.frontend.hostName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations: {{- include "openmatch.chartmeta" . | nindent 4 }}
|
||||
labels:
|
||||
@ -82,12 +82,12 @@ spec:
|
||||
spec:
|
||||
{{- include "openmatch.labels.nodegrouping" . | nindent 6 }}
|
||||
volumes:
|
||||
{{- include "openmatch.volumes.configs" (dict "configs" .Values.configs) | nindent 8}}
|
||||
{{- include "openmatch.volumes.configs" (. | merge (dict "configs" .Values.configs)) | nindent 8}}
|
||||
{{- include "openmatch.volumes.tls" . | nindent 8}}
|
||||
{{- include "openmatch.volumes.withredis" . | nindent 8}}
|
||||
serviceAccountName: {{ .Values.global.kubernetes.serviceAccount }}
|
||||
serviceAccountName: {{ include "openmatch.serviceAccount.name" . }}
|
||||
containers:
|
||||
- name: {{ .Values.frontend.hostName }}
|
||||
- name: {{ include "openmatch.frontend.hostName" . }}
|
||||
volumeMounts:
|
||||
{{- include "openmatch.volumemounts.configs" (dict "configs" .Values.configs) | nindent 10 }}
|
||||
{{- include "openmatch.volumemounts.tls" . | nindent 10 }}
|
||||
|
@ -16,7 +16,7 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: om-configmap-default
|
||||
name: {{ include "openmatch.configmap.default" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations: {{- include "openmatch.chartmeta" . | nindent 4 }}
|
||||
labels:
|
||||
@ -50,28 +50,33 @@ data:
|
||||
|
||||
api:
|
||||
backend:
|
||||
hostname: "{{ .Values.backend.hostName }}"
|
||||
hostname: "{{ include "openmatch.backend.hostName" . }}"
|
||||
grpcport: "{{ .Values.backend.grpcPort }}"
|
||||
httpport: "{{ .Values.backend.httpPort }}"
|
||||
frontend:
|
||||
hostname: "{{ .Values.frontend.hostName }}"
|
||||
hostname: "{{ include "openmatch.frontend.hostName" . }}"
|
||||
grpcport: "{{ .Values.frontend.grpcPort }}"
|
||||
httpport: "{{ .Values.frontend.httpPort }}"
|
||||
query:
|
||||
hostname: "{{ .Values.query.hostName }}"
|
||||
hostname: "{{ include "openmatch.query.hostName" . }}"
|
||||
grpcport: "{{ .Values.query.grpcPort }}"
|
||||
httpport: "{{ .Values.query.httpPort }}"
|
||||
synchronizer:
|
||||
hostname: "{{ .Values.synchronizer.hostName }}"
|
||||
hostname: "{{ include "openmatch.synchronizer.hostName" . }}"
|
||||
grpcport: "{{ .Values.synchronizer.grpcPort }}"
|
||||
httpport: "{{ .Values.synchronizer.httpPort }}"
|
||||
swaggerui:
|
||||
hostname: "{{ .Values.swaggerui.hostName }}"
|
||||
hostname: "{{ include "openmatch.swaggerui.hostName" . }}"
|
||||
httpport: "{{ .Values.swaggerui.httpPort }}"
|
||||
scale-frontend:
|
||||
|
||||
# Configurations for api.test and api.scale are used for testing.
|
||||
test:
|
||||
hostname: "{{ include "openmatch.fullname" . }}-test"
|
||||
grpcport: "50509"
|
||||
httpport: "51509"
|
||||
scale-backend:
|
||||
httpport: "51510"
|
||||
scale:
|
||||
httpport: "51509"
|
||||
|
||||
{{- if .Values.global.tls.enabled }}
|
||||
tls:
|
||||
trustedCertificatePath: "{{.Values.global.tls.rootca.mountPath}}/public.cert"
|
||||
@ -80,39 +85,47 @@ data:
|
||||
rootcertificatefile: "{{.Values.global.tls.rootca.mountPath}}/public.cert"
|
||||
{{- end }}
|
||||
|
||||
storage:
|
||||
ignoreListTTL: {{ index .Values "open-match-core" "ignoreListTTL" }}
|
||||
page:
|
||||
size: 10000
|
||||
|
||||
redis:
|
||||
{{- if index .Values "open-match-core" "redis" "install" }}
|
||||
hostname: {{ .Values.redis.fullnameOverride }}-master.{{ .Release.Namespace }}.svc.cluster.local
|
||||
{{- if index .Values "open-match-core" "redis" "enabled" }}
|
||||
{{- if index .Values "redis" "sentinel" "enabled"}}
|
||||
sentinelPort: {{ .Values.redis.sentinel.port }}
|
||||
sentinelMaster: {{ .Values.redis.sentinel.masterSet }}
|
||||
sentinelHostname: {{ include "call-nested" (list . "redis" "common.names.fullname") }}
|
||||
sentinelUsePassword: {{ .Values.redis.auth.sentinel }}
|
||||
{{- else}}
|
||||
# Open Match's default Redis setups
|
||||
hostname: {{ include "call-nested" (list . "redis" "common.names.fullname") }}-master.{{ .Release.Namespace }}.svc.cluster.local
|
||||
port: {{ .Values.redis.redisPort }}
|
||||
user: {{ .Values.redis.user }}
|
||||
{{- end}}
|
||||
{{- else }}
|
||||
# BYO Redis setups
|
||||
hostname: {{ index .Values "open-match-core" "redis" "hostname" }}
|
||||
port: {{ index .Values "open-match-core" "redis" "port" }}
|
||||
user: {{ index .Values "open-match-core" "redis" "user" }}
|
||||
{{- end }}
|
||||
{{- if .Values.redis.usePassword }}
|
||||
usePassword: {{ .Values.redis.auth.enabled }}
|
||||
passwordPath: {{ .Values.redis.secretMountPath }}/redis-password
|
||||
{{- end }}
|
||||
pool:
|
||||
maxIdle: {{ index .Values "open-match-core" "redis" "pool" "maxIdle" }}
|
||||
maxActive: {{ index .Values "open-match-core" "redis" "pool" "maxActive" }}
|
||||
idleTimeout: {{ index .Values "open-match-core" "redis" "pool" "idleTimeout" }}
|
||||
healthCheckTimeout: {{ index .Values "open-match-core" "redis" "pool" "healthCheckTimeout" }}
|
||||
expiration: 43200
|
||||
|
||||
telemetry:
|
||||
reportingPeriod: "{{ .Values.global.telemetry.reportingPeriod }}"
|
||||
traceSamplingFraction: "{{ .Values.global.telemetry.traceSamplingFraction }}"
|
||||
zpages:
|
||||
enable: "{{ .Values.global.telemetry.zpages.enabled }}"
|
||||
jaeger:
|
||||
enable: "{{ .Values.global.telemetry.jaeger.enabled }}"
|
||||
samplerFraction: {{ .Values.global.telemetry.jaeger.samplerFraction }}
|
||||
agentEndpoint: "{{ .Values.global.telemetry.jaeger.agentEndpoint }}"
|
||||
collectorEndpoint: "{{ .Values.global.telemetry.jaeger.collectorEndpoint }}"
|
||||
{{- if .Values.global.telemetry.jaeger.enabled }}
|
||||
agentEndpoint: "{{ tpl .Values.global.telemetry.jaeger.agentEndpoint . }}"
|
||||
collectorEndpoint: "{{ tpl .Values.global.telemetry.jaeger.collectorEndpoint . }}"
|
||||
{{- else }}
|
||||
agentEndpoint: ""
|
||||
collectorEndpoint: ""
|
||||
{{- end }}
|
||||
prometheus:
|
||||
enable: "{{ .Values.global.telemetry.prometheus.enabled }}"
|
||||
endpoint: "{{ .Values.global.telemetry.prometheus.endpoint }}"
|
||||
|
@ -16,7 +16,7 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: om-configmap-override
|
||||
name: {{ include "openmatch.configmap.override" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations: {{- include "openmatch.chartmeta" . | nindent 4 }}
|
||||
labels:
|
||||
@ -25,12 +25,25 @@ metadata:
|
||||
release: {{ .Release.Name }}
|
||||
data:
|
||||
matchmaker_config_override.yaml: |-
|
||||
# Length of time between first fetch matches call, and when no further fetch
|
||||
# matches calls will join the current evaluation/synchronization cycle,
|
||||
# instead waiting for the next cycle.
|
||||
registrationInterval: {{ index .Values "open-match-core" "registrationInterval" }}
|
||||
# Length of time after match function as started before it will be canceled,
|
||||
# and evaluator call input is EOF.
|
||||
proposalCollectionInterval: {{ index .Values "open-match-core" "proposalCollectionInterval" }}
|
||||
# Time after a ticket has been returned from fetch matches (marked as pending)
|
||||
# before it automatically becomes active again and will be returned by query
|
||||
# calls.
|
||||
pendingReleaseTimeout: {{ index .Values "open-match-core" "pendingReleaseTimeout" }}
|
||||
# Time after a ticket has been assigned before it is automatically delted.
|
||||
assignedDeleteTimeout: {{ index .Values "open-match-core" "assignedDeleteTimeout" }}
|
||||
# Maximum number of tickets to return on a single QueryTicketsResponse.
|
||||
queryPageSize: {{ index .Values "open-match-core" "queryPageSize" }}
|
||||
backfillLockTimeout: {{ index .Values "open-match-core" "backfillLockTimeout" }}
|
||||
api:
|
||||
evaluator:
|
||||
hostname: "{{ .Values.evaluator.hostName }}"
|
||||
hostname: "{{ include "openmatch.evaluator.hostName" . }}"
|
||||
grpcport: "{{ .Values.evaluator.grpcPort }}"
|
||||
httpport: "{{ .Values.evaluator.httpPort }}"
|
||||
synchronizer:
|
||||
registrationIntervalMs: 250ms
|
||||
proposalCollectionIntervalMs: 20000ms
|
||||
{{- end }}
|
||||
|
@ -14,11 +14,11 @@
|
||||
|
||||
{{- if index .Values "open-match-core" "enabled" }}
|
||||
{{- if empty .Values.ci }}
|
||||
# om-redis-podsecuritypolicy is the least restricted PSP used to create privileged pods to disable THP in host kernel.
|
||||
# This is the least restricted PSP used to create privileged pods to disable THP in host kernel.
|
||||
apiVersion: policy/v1beta1
|
||||
kind: PodSecurityPolicy
|
||||
metadata:
|
||||
name: om-redis-podsecuritypolicy
|
||||
name: {{ include "openmatch.fullname" . }}-redis-podsecuritypolicy
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations:
|
||||
{{- include "openmatch.chartmeta" . | nindent 4 }}
|
||||
@ -51,11 +51,11 @@ spec:
|
||||
fsGroup:
|
||||
rule: 'RunAsAny'
|
||||
---
|
||||
# om-core-podsecuritypolicy does not allow creating privileged pods and restrict binded pods to use the specified port ranges.
|
||||
# This does not allow creating privileged pods and restrict binded pods to use the specified port ranges.
|
||||
apiVersion: policy/v1beta1
|
||||
kind: PodSecurityPolicy
|
||||
metadata:
|
||||
name: om-core-podsecuritypolicy
|
||||
name: {{ include "openmatch.fullname" . }}-core-podsecuritypolicy
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations: {{- include "openmatch.chartmeta" . | nindent 4 }}
|
||||
labels:
|
||||
|
@ -16,7 +16,7 @@
|
||||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: {{ .Values.query.hostName }}
|
||||
name: {{ include "openmatch.query.hostName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations: {{- include "openmatch.chartmeta" . | nindent 4 }}
|
||||
labels:
|
||||
@ -44,19 +44,19 @@ spec:
|
||||
apiVersion: autoscaling/v1
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: {{ .Values.query.hostName }}
|
||||
name: {{ include "openmatch.query.hostName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
spec:
|
||||
scaleTargetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: {{ .Values.query.hostName }}
|
||||
name: {{ include "openmatch.query.hostName" . }}
|
||||
{{- include "openmatch.HorizontalPodAutoscaler.spec.common" . | nindent 2 }}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ .Values.query.hostName }}
|
||||
name: {{ include "openmatch.query.hostName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations: {{- include "openmatch.chartmeta" . | nindent 4 }}
|
||||
labels:
|
||||
@ -82,12 +82,12 @@ spec:
|
||||
spec:
|
||||
{{- include "openmatch.labels.nodegrouping" . | nindent 6 }}
|
||||
volumes:
|
||||
{{- include "openmatch.volumes.configs" (dict "configs" .Values.configs) | nindent 8}}
|
||||
{{- include "openmatch.volumes.configs" (. | merge (dict "configs" .Values.configs)) | nindent 8}}
|
||||
{{- include "openmatch.volumes.tls" . | nindent 8}}
|
||||
{{- include "openmatch.volumes.withredis" . | nindent 8 }}
|
||||
serviceAccountName: {{ .Values.global.kubernetes.serviceAccount }}
|
||||
serviceAccountName: {{ include "openmatch.serviceAccount.name" . }}
|
||||
containers:
|
||||
- name: {{ .Values.query.hostName }}
|
||||
- name: {{ include "openmatch.query.hostName" . }}
|
||||
volumeMounts:
|
||||
{{- include "openmatch.volumemounts.configs" (dict "configs" .Values.configs) | nindent 10 }}
|
||||
{{- include "openmatch.volumemounts.tls" . | nindent 10 }}
|
||||
|
@ -29,7 +29,7 @@ metadata:
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ .Values.global.kubernetes.serviceAccount }}
|
||||
name: {{ include "openmatch.serviceAccount.name" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations: {{- include "openmatch.chartmeta" . | nindent 4 }}
|
||||
labels:
|
||||
@ -40,28 +40,26 @@ automountServiceAccountToken: true
|
||||
kind: Role
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
name: om-service-role
|
||||
name: {{ include "openmatch.fullname" . }}-service-role
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations: {{- include "openmatch.chartmeta" . | nindent 4 }}
|
||||
labels:
|
||||
app: {{ template "openmatch.name" . }}
|
||||
release: {{ .Release.Name }}
|
||||
rules:
|
||||
# Define om-service-role to use om-core-podsecuritypolicy
|
||||
- apiGroups:
|
||||
- extensions
|
||||
resources:
|
||||
- podsecuritypolicies
|
||||
resourceNames:
|
||||
- om-core-podsecuritypolicy
|
||||
- {{ include "openmatch.fullname" . }}-core-podsecuritypolicy
|
||||
verbs:
|
||||
- use
|
||||
---
|
||||
# This applies om-service-role to the open-match unprivileged service account under the release namespace.
|
||||
kind: RoleBinding
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
name: om-service-role-binding
|
||||
name: {{ include "openmatch.fullname" . }}-service-role-binding
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations: {{- include "openmatch.chartmeta" . | nindent 4 }}
|
||||
labels:
|
||||
@ -73,34 +71,33 @@ subjects:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
roleRef:
|
||||
kind: Role
|
||||
name: om-service-role
|
||||
name: {{ include "openmatch.fullname" . }}-service-role
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
---
|
||||
{{- if index .Values "open-match-core" "redis" "enabled" }}
|
||||
kind: Role
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
name: om-redis-role
|
||||
name: {{ include "openmatch.fullname" . }}-redis-role
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations: {{- include "openmatch.chartmeta" . | nindent 4 }}
|
||||
labels:
|
||||
app: {{ template "openmatch.name" . }}
|
||||
release: {{ .Release.Name }}
|
||||
rules:
|
||||
# Define om-redis-role to use om-redis-podsecuritypolicy
|
||||
- apiGroups:
|
||||
- extensions
|
||||
resources:
|
||||
- podsecuritypolicies
|
||||
resourceNames:
|
||||
- om-redis-podsecuritypolicy
|
||||
- {{ include "openmatch.fullname" . }}-redis-podsecuritypolicy
|
||||
verbs:
|
||||
- use
|
||||
---
|
||||
# This applies om-redis role to the om-redis privileged service account under the release namespace.
|
||||
kind: RoleBinding
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
name: om-redis-role-binding
|
||||
name: {{ include "openmatch.fullname" . }}-redis-role-binding
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations: {{- include "openmatch.chartmeta" . | nindent 4 }}
|
||||
labels:
|
||||
@ -108,10 +105,11 @@ metadata:
|
||||
release: {{ .Release.Name }}
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ .Values.redis.serviceAccount.name }} # Redis service account
|
||||
name: {{ include "call-nested" (list . "redis" "redis.serviceAccountName") }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
roleRef:
|
||||
kind: Role
|
||||
name: om-redis-role
|
||||
name: {{ include "openmatch.fullname" . }}-redis-role
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
@ -12,11 +12,11 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
{{- if index .Values "open-match-core" "enabled" }}
|
||||
{{- if index .Values "open-match-core" "swaggerui" "enabled" }}
|
||||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: {{ .Values.swaggerui.hostName }}
|
||||
name: {{ include "openmatch.swaggerui.hostName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations: {{- include "openmatch.chartmeta" . | nindent 4 }}
|
||||
labels:
|
||||
@ -36,7 +36,7 @@ spec:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ .Values.swaggerui.hostName }}
|
||||
name: {{ include "openmatch.swaggerui.hostName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations: {{- include "openmatch.chartmeta" . | nindent 4 }}
|
||||
labels:
|
||||
@ -61,11 +61,11 @@ spec:
|
||||
spec:
|
||||
{{- include "openmatch.labels.nodegrouping" . | nindent 6 }}
|
||||
volumes:
|
||||
{{- include "openmatch.volumes.configs" (dict "configs" .Values.configs) | nindent 8}}
|
||||
{{- include "openmatch.volumes.configs" (. | merge (dict "configs" .Values.configs)) | nindent 8}}
|
||||
{{- include "openmatch.volumes.tls" . | nindent 8}}
|
||||
serviceAccountName: {{ .Values.global.kubernetes.serviceAccount }}
|
||||
serviceAccountName: {{ include "openmatch.serviceAccount.name" . }}
|
||||
containers:
|
||||
- name: {{ .Values.swaggerui.hostName }}
|
||||
- name: {{ include "openmatch.swaggerui.hostName" . }}
|
||||
volumeMounts:
|
||||
{{- include "openmatch.volumemounts.configs" (dict "configs" .Values.configs) | nindent 10 }}
|
||||
{{- include "openmatch.volumemounts.tls" . | nindent 10 }}
|
||||
|
@ -16,7 +16,7 @@
|
||||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: {{ .Values.synchronizer.hostName }}
|
||||
name: {{ include "openmatch.synchronizer.hostName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations: {{- include "openmatch.chartmeta" . | nindent 4 }}
|
||||
labels:
|
||||
@ -40,7 +40,7 @@ spec:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ .Values.synchronizer.hostName }}
|
||||
name: {{ include "openmatch.synchronizer.hostName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations: {{- include "openmatch.chartmeta" . | nindent 4 }}
|
||||
labels:
|
||||
@ -66,12 +66,12 @@ spec:
|
||||
spec:
|
||||
{{- include "openmatch.labels.nodegrouping" . | nindent 6 }}
|
||||
volumes:
|
||||
{{- include "openmatch.volumes.configs" (dict "configs" .Values.configs) | nindent 8}}
|
||||
{{- include "openmatch.volumes.configs" (. | merge (dict "configs" .Values.configs)) | nindent 8}}
|
||||
{{- include "openmatch.volumes.tls" . | nindent 8}}
|
||||
{{- include "openmatch.volumes.withredis" . | nindent 8 }}
|
||||
serviceAccountName: {{ .Values.global.kubernetes.serviceAccount }}
|
||||
serviceAccountName: {{ include "openmatch.serviceAccount.name" . }}
|
||||
containers:
|
||||
- name: {{ .Values.synchronizer.hostName }}
|
||||
- name: {{ include "openmatch.synchronizer.hostName" . }}
|
||||
volumeMounts:
|
||||
{{- include "openmatch.volumemounts.configs" (dict "configs" .Values.configs) | nindent 10 }}
|
||||
{{- include "openmatch.volumemounts.tls" . | nindent 10 }}
|
||||
|
@ -1,8 +1,23 @@
|
||||
# This applies om-test-role to the open-match-test-service account under the release namespace.
|
||||
# Copyright 2019 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.
|
||||
|
||||
{{- if .Values.ci }}
|
||||
|
||||
kind: RoleBinding
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
name: om-test-role-binding
|
||||
name: {{ include "openmatch.fullname" . }}-test-role-binding
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations: {{- include "openmatch.chartmeta" . | nindent 4 }}
|
||||
labels:
|
||||
@ -10,9 +25,11 @@ metadata:
|
||||
release: {{ .Release.Name }}
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: open-match-test-service
|
||||
name: {{ include "openmatch.fullname" . }}-test-service
|
||||
namespace: {{ .Release.Namespace }}
|
||||
roleRef:
|
||||
kind: Role
|
||||
name: om-test-role
|
||||
name: {{ include "openmatch.fullname" . }}-test-role
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
|
||||
{{- end }}
|
||||
|
@ -1,23 +1,38 @@
|
||||
# Copyright 2019 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.
|
||||
|
||||
{{- if .Values.ci }}
|
||||
|
||||
kind: Role
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
name: om-test-role
|
||||
name: {{ include "openmatch.fullname" . }}-test-role
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations: {{- include "openmatch.chartmeta" . | nindent 4 }}
|
||||
labels:
|
||||
app: {{ template "openmatch.name" . }}
|
||||
release: {{ .Release.Name }}
|
||||
rules:
|
||||
# Define om-test-role to use om-core-podsecuritypolicy
|
||||
- apiGroups:
|
||||
- extensions
|
||||
resources:
|
||||
- podsecuritypolicies
|
||||
resourceNames:
|
||||
- om-core-podsecuritypolicy
|
||||
- {{ include "openmatch.fullname" . }}-core-podsecuritypolicy
|
||||
verbs:
|
||||
- use
|
||||
# Grant om-test-role get & list permission for k8s endpoints and pods resources
|
||||
# Grant this role get & list permission for k8s endpoints and pods resources
|
||||
# Required for e2e in-cluster testing.
|
||||
- apiGroups:
|
||||
- ""
|
||||
@ -27,3 +42,5 @@ rules:
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
|
||||
{{- end }}
|
||||
|
@ -1,11 +1,29 @@
|
||||
# Create a service account for open-match-test services.
|
||||
# Copyright 2019 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.
|
||||
|
||||
{{- if .Values.ci }}
|
||||
|
||||
# Create a service account for test services.
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: open-match-test-service
|
||||
name: {{ include "openmatch.fullname" . }}-test-service
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations: {{- include "openmatch.chartmeta" . | nindent 4 }}
|
||||
labels:
|
||||
app: {{ template "openmatch.name" . }}
|
||||
release: {{ .Release.Name }}
|
||||
automountServiceAccountToken: true
|
||||
|
||||
{{- end }}
|
||||
|
@ -1,24 +1,83 @@
|
||||
# Copyright 2019 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.
|
||||
|
||||
{{- if .Values.ci }}
|
||||
|
||||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: {{ include "openmatch.fullname" . }}-test
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations: {{- include "openmatch.chartmeta" . | nindent 4 }}
|
||||
labels:
|
||||
app: {{ template "openmatch.name" . }}
|
||||
component: test
|
||||
release: {{ .Release.Name }}
|
||||
spec:
|
||||
selector:
|
||||
app: {{ template "openmatch.name" . }}
|
||||
component: test
|
||||
release: {{ .Release.Name }}
|
||||
ports:
|
||||
- name: grpc
|
||||
protocol: TCP
|
||||
port: 50509
|
||||
- name: http
|
||||
protocol: TCP
|
||||
port: 51509
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: om-test
|
||||
name: {{ include "openmatch.fullname" . }}-test
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations:
|
||||
{{- include "openmatch.chartmeta" . | nindent 4 }}
|
||||
"helm.sh/hook": test-success
|
||||
labels:
|
||||
app: {{ template "openmatch.name" . }}
|
||||
component: om-test
|
||||
component: test
|
||||
release: {{ .Release.Name }}
|
||||
spec:
|
||||
# Specifies the duration in seconds relative to the startTime that the job may be active before the system tries to terminate it.
|
||||
activeDeadlineSeconds: 900
|
||||
serviceAccountName: open-match-test-service
|
||||
serviceAccountName: {{ include "openmatch.fullname" . }}-test-service
|
||||
automountServiceAccountToken: true
|
||||
volumes:
|
||||
- configMap:
|
||||
defaultMode: 420
|
||||
name: {{ include "openmatch.configmap.default" . }}
|
||||
name: om-config-volume-default
|
||||
- configMap:
|
||||
defaultMode: 420
|
||||
name: {{ include "openmatch.configmap.override" . }}
|
||||
name: om-config-volume-override
|
||||
containers:
|
||||
- image: "{{ .Values.global.image.registry }}/openmatch-base-build:{{ .Values.global.image.tag }}"
|
||||
- name: {{ include "openmatch.fullname" . }}-test
|
||||
volumeMounts:
|
||||
- mountPath: /app/config/default
|
||||
name: om-config-volume-default
|
||||
- mountPath: /app/config/override
|
||||
name: om-config-volume-override
|
||||
image: "{{ .Values.global.image.registry }}/openmatch-base-build:{{ .Values.global.image.tag }}"
|
||||
ports:
|
||||
- name: grpc
|
||||
containerPort: 50509
|
||||
- name: http
|
||||
containerPort: 51509
|
||||
imagePullPolicy: Always
|
||||
name: om-test
|
||||
name: test
|
||||
resources:
|
||||
limits:
|
||||
memory: 800Mi
|
||||
@ -32,7 +91,7 @@ spec:
|
||||
command: ["go"]
|
||||
args:
|
||||
- "test"
|
||||
- "./test/e2e"
|
||||
- "./internal/testing/e2e"
|
||||
- "-v"
|
||||
- "-timeout"
|
||||
- "150s"
|
||||
@ -40,3 +99,5 @@ spec:
|
||||
- "-tags"
|
||||
- "e2ecluster"
|
||||
restartPolicy: Never
|
||||
|
||||
{{- end }}
|
||||
|
@ -17,7 +17,7 @@
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: om-tls-rootca
|
||||
name: {{ include "openmatch.fullname" . }}-tls-rootca
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations: {{- include "openmatch.chartmeta" . | nindent 4 }}
|
||||
labels:
|
||||
@ -31,9 +31,9 @@ data:
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: om-tls-server
|
||||
name: {{ include "openmatch.fullname" . }}-tls-server
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations: {{- include "openmatch.chartmeta" . | nindent 2 }}
|
||||
annotations: {{- include "openmatch.chartmeta" . | nindent 4 }}
|
||||
labels:
|
||||
app: {{ template "openmatch.name" . }}
|
||||
component: tls
|
||||
|
@ -23,7 +23,7 @@
|
||||
# Begins the configuration section for `query` component in Open Match.
|
||||
# query:
|
||||
#
|
||||
# # Specifies om-query as the in-cluster domain name for the `query` service.
|
||||
# # Override the default in-cluster domain name for the `query` service to om-query.
|
||||
# hostName: om-query
|
||||
#
|
||||
# # Specifies the port for receiving RESTful HTTP requests in the `query` service.
|
||||
@ -44,74 +44,81 @@
|
||||
# # Specifies the image name to be used in a Kubernetes pod for `query` compoenent.
|
||||
# image: openmatch-query
|
||||
swaggerui: &swaggerui
|
||||
hostName: om-swaggerui
|
||||
hostName:
|
||||
httpPort: 51500
|
||||
portType: ClusterIP
|
||||
replicas: 1
|
||||
image: openmatch-swaggerui
|
||||
query: &query
|
||||
hostName: om-query
|
||||
hostName:
|
||||
grpcPort: 50503
|
||||
httpPort: 51503
|
||||
portType: ClusterIP
|
||||
replicas: 3
|
||||
image: openmatch-query
|
||||
frontend: &frontend
|
||||
hostName: om-frontend
|
||||
hostName:
|
||||
grpcPort: 50504
|
||||
httpPort: 51504
|
||||
portType: ClusterIP
|
||||
replicas: 3
|
||||
image: openmatch-frontend
|
||||
backend: &backend
|
||||
hostName: om-backend
|
||||
hostName:
|
||||
grpcPort: 50505
|
||||
httpPort: 51505
|
||||
portType: ClusterIP
|
||||
replicas: 3
|
||||
image: openmatch-backend
|
||||
synchronizer: &synchronizer
|
||||
hostName: om-synchronizer
|
||||
hostName:
|
||||
grpcPort: 50506
|
||||
httpPort: 51506
|
||||
portType: ClusterIP
|
||||
replicas: 1
|
||||
image: openmatch-synchronizer
|
||||
evaluator: &evaluator
|
||||
hostName: om-evaluator
|
||||
hostName:
|
||||
grpcPort: 50508
|
||||
httpPort: 51508
|
||||
replicas: 3
|
||||
function: &function
|
||||
hostName: om-function
|
||||
hostName:
|
||||
grpcPort: 50502
|
||||
httpPort: 51502
|
||||
replicas: 3
|
||||
|
||||
# Specifies the location and name of the Open Match application-level config volumes.
|
||||
# Used in template: `openmatch.volumemounts.configs` and `openmatch.volumes.configs` under `templates/_helpers.tpl` file.
|
||||
# Used in template: `openmatch.volumemounts.configs` and `openmatch.volumes.configs` under `templates/_helpers.tpl` file.
|
||||
configs:
|
||||
default:
|
||||
volumeName: om-config-volume-default
|
||||
mountPath: /app/config/default
|
||||
configName: om-configmap-default
|
||||
# This will be parsed through the `tpl` function.
|
||||
configName: '{{ include "openmatch.configmap.default" . }}'
|
||||
override:
|
||||
volumeName: om-config-volume-override
|
||||
mountPath: /app/config/override
|
||||
configName: om-configmap-override
|
||||
# This will be parsed through the `tpl` function.
|
||||
configName: '{{ include "openmatch.configmap.override" . }}'
|
||||
|
||||
# Override Redis settings
|
||||
# https://hub.helm.sh/charts/stable/redis
|
||||
# https://github.com/helm/charts/tree/master/stable/redis
|
||||
redis:
|
||||
fullnameOverride: om-redis
|
||||
redisPort: 6379
|
||||
usePassword: false
|
||||
usePasswordFile: false
|
||||
auth:
|
||||
enabled: false
|
||||
sentinel: false
|
||||
usePasswordFiles: false
|
||||
secretMountPath: /opt/bitnami/redis/secrets
|
||||
configmap: |
|
||||
maxclients 100000
|
||||
maxmemory 500000000
|
||||
sentinel:
|
||||
enabled: true
|
||||
masterSet: om-redis-master
|
||||
port: 26379
|
||||
master:
|
||||
disableCommands: [] # don't disable 'FLUSH-' commands
|
||||
resources:
|
||||
@ -125,12 +132,11 @@ redis:
|
||||
enabled: false
|
||||
metrics:
|
||||
enabled: true
|
||||
cluster:
|
||||
slaveCount: 3
|
||||
serviceAccount:
|
||||
create: true
|
||||
name: open-match-redis-service
|
||||
slave:
|
||||
replica:
|
||||
disableCommands: [] # don't disable 'FLUSH-' commands
|
||||
replicaCount: 3
|
||||
persistence:
|
||||
enabled: false
|
||||
resources:
|
||||
@ -168,26 +174,44 @@ redis:
|
||||
# Controls if users need to install backend, frontend, query, om-configmap, and swaggerui.
|
||||
open-match-core:
|
||||
enabled: true
|
||||
ignoreListTTL: 60000ms
|
||||
|
||||
# Length of time between first fetch matches call, and when no further fetch
|
||||
# matches calls will join the current evaluation/synchronization cycle,
|
||||
# instead waiting for the next cycle.
|
||||
registrationInterval: 250ms
|
||||
# Length of time after match function as started before it will be canceled,
|
||||
# and evaluator call input is EOF.
|
||||
proposalCollectionInterval: 20s
|
||||
# Time after a ticket has been returned from fetch matches (marked as pending)
|
||||
# before it automatically becomes active again and will be returned by query
|
||||
# calls.
|
||||
pendingReleaseTimeout: 1m
|
||||
# Time after a ticket has been assigned before it is automatically delted.
|
||||
assignedDeleteTimeout: 10m
|
||||
# Maximum number of tickets to return on a single QueryTicketsResponse.
|
||||
queryPageSize: 10000
|
||||
# Duration for redis locks to expire.
|
||||
backfillLockTimeout: 1m
|
||||
|
||||
redis:
|
||||
install: true
|
||||
# If open-match-core.redis.install is set to false, have Open Match components talk to this redis address instead.
|
||||
enabled: true
|
||||
# If open-match-core.redis.enabled is set to false, have Open Match components talk to this redis address instead.
|
||||
# Otherwise the default is set to the om-redis instance.
|
||||
hostname: # Your redis server address
|
||||
port: 6379
|
||||
user:
|
||||
user:
|
||||
pool:
|
||||
maxIdle: 500
|
||||
maxActive: 500
|
||||
idleTimeout: 0
|
||||
healthCheckTimeout: 300ms
|
||||
swaggerui:
|
||||
enabled: false
|
||||
|
||||
# Controls if users need to install scale testing setup for Open Match.
|
||||
open-match-scale:
|
||||
# Switch the value between true/false to turn on/off this subchart
|
||||
enabled: false
|
||||
frontend: *frontend
|
||||
backend: *backend
|
||||
|
||||
# Controls if users need to install the monitoring tools in Open Match.
|
||||
open-match-telemetry:
|
||||
@ -200,7 +224,6 @@ open-match-customize:
|
||||
enabled: false
|
||||
evaluator: *evaluator
|
||||
function: *function
|
||||
query: *query
|
||||
# You can override the evaluator/mmf image
|
||||
# evaluator:
|
||||
# image: [YOUR_EVALUATOR_IMAGE]
|
||||
@ -227,8 +250,8 @@ global:
|
||||
limits:
|
||||
memory: 3Gi
|
||||
cpu: 2
|
||||
# Defines a service account which provides an identity for processes that run in a Pod in Open Match.
|
||||
serviceAccount: open-match-unprivileged-service
|
||||
# Overrides the name of the service account which provides an identity for processes that run in a Pod in Open Match.
|
||||
serviceAccount:
|
||||
# Use this field if you need to override the port type for all services defined in this chart
|
||||
service:
|
||||
portType:
|
||||
@ -253,18 +276,18 @@ global:
|
||||
tag: 0.0.0-dev
|
||||
pullPolicy: Always
|
||||
|
||||
|
||||
# Expose the telemetry configurations to all subcharts because prometheus, for example,
|
||||
# requires pod-level annotation to customize its scrape path.
|
||||
# See definitions in templates/_helpers.tpl - "prometheus.annotations" section for details
|
||||
telemetry:
|
||||
reportingPeriod: "1m"
|
||||
traceSamplingFraction: 0.005 # What fraction of traces to sample.
|
||||
zpages:
|
||||
enabled: true
|
||||
jaeger:
|
||||
enabled: false
|
||||
samplerFraction: 0.005 # Configures a sampler that samples a given fraction of traces.
|
||||
agentEndpoint: "open-match-jaeger-agent:6831"
|
||||
collectorEndpoint: "http://open-match-jaeger-collector:14268/api/traces"
|
||||
agentEndpoint: '{{ include "openmatch.jaeger.agent" . }}'
|
||||
collectorEndpoint: '{{ include "openmatch.jaeger.collector" . }}'
|
||||
prometheus:
|
||||
enabled: false
|
||||
endpoint: "/metrics"
|
||||
@ -274,4 +297,3 @@ global:
|
||||
prefix: "open_match"
|
||||
grafana:
|
||||
enabled: false
|
||||
reportingPeriod: "1m"
|
||||
|
@ -23,7 +23,7 @@
|
||||
# Begins the configuration section for `query` component in Open Match.
|
||||
# query:
|
||||
#
|
||||
# # Specifies om-query as the in-cluster domain name for the `query` service.
|
||||
# # Override the default in-cluster domain name for the `query` service to om-query.
|
||||
# hostName: om-query
|
||||
#
|
||||
# # Specifies the port for receiving RESTful HTTP requests in the `query` service.
|
||||
@ -44,46 +44,46 @@
|
||||
# # Specifies the image name to be used in a Kubernetes pod for `query` compoenent.
|
||||
# image: openmatch-query
|
||||
swaggerui: &swaggerui
|
||||
hostName: om-swaggerui
|
||||
hostName:
|
||||
httpPort: 51500
|
||||
portType: ClusterIP
|
||||
replicas: 1
|
||||
image: openmatch-swaggerui
|
||||
query: &query
|
||||
hostName: om-query
|
||||
hostName:
|
||||
grpcPort: 50503
|
||||
httpPort: 51503
|
||||
portType: ClusterIP
|
||||
replicas: 3
|
||||
image: openmatch-query
|
||||
frontend: &frontend
|
||||
hostName: om-frontend
|
||||
hostName:
|
||||
grpcPort: 50504
|
||||
httpPort: 51504
|
||||
portType: ClusterIP
|
||||
replicas: 3
|
||||
image: openmatch-frontend
|
||||
backend: &backend
|
||||
hostName: om-backend
|
||||
hostName:
|
||||
grpcPort: 50505
|
||||
httpPort: 51505
|
||||
portType: ClusterIP
|
||||
replicas: 3
|
||||
image: openmatch-backend
|
||||
synchronizer: &synchronizer
|
||||
hostName: om-synchronizer
|
||||
hostName:
|
||||
grpcPort: 50506
|
||||
httpPort: 51506
|
||||
portType: ClusterIP
|
||||
replicas: 1
|
||||
image: openmatch-synchronizer
|
||||
evaluator: &evaluator
|
||||
hostName: om-evaluator
|
||||
hostName:
|
||||
grpcPort: 50508
|
||||
httpPort: 51508
|
||||
replicas: 3
|
||||
function: &function
|
||||
hostName: om-function
|
||||
hostName:
|
||||
grpcPort: 50502
|
||||
httpPort: 51502
|
||||
replicas: 3
|
||||
@ -94,37 +94,56 @@ configs:
|
||||
default:
|
||||
volumeName: om-config-volume-default
|
||||
mountPath: /app/config/default
|
||||
configName: om-configmap-default
|
||||
# This will be parsed through the `tpl` function.
|
||||
configName: '{{ include "openmatch.configmap.default" . }}'
|
||||
override:
|
||||
volumeName: om-config-volume-override
|
||||
mountPath: /app/config/override
|
||||
configName: om-configmap-override
|
||||
# This will be parsed through the `tpl` function.
|
||||
configName: '{{ include "openmatch.configmap.override" . }}'
|
||||
|
||||
# Override Redis settings
|
||||
# https://hub.helm.sh/charts/stable/redis
|
||||
# https://github.com/helm/charts/tree/master/stable/redis
|
||||
redis:
|
||||
fullnameOverride: om-redis
|
||||
redisPort: 6379
|
||||
usePassword: false
|
||||
usePasswordFile: false
|
||||
auth:
|
||||
enabled: false
|
||||
sentinel: false
|
||||
usePasswordFiles: false
|
||||
secretMountPath: /opt/bitnami/redis/secrets
|
||||
configmap: |
|
||||
maxclients 100000
|
||||
maxmemory 300000000
|
||||
sentinel:
|
||||
enabled: true
|
||||
masterSet: om-redis-master
|
||||
port: 26379
|
||||
resources:
|
||||
requests:
|
||||
memory: 300Mi
|
||||
cpu: 0.5
|
||||
master:
|
||||
disableCommands: [] # don't disable 'FLUSH-' commands
|
||||
resources:
|
||||
requests:
|
||||
memory: 300Mi
|
||||
cpu: 0.5
|
||||
replica:
|
||||
disableCommands: [] # don't disable 'FLUSH-' commands
|
||||
replicaCount: 3
|
||||
resources:
|
||||
requests:
|
||||
memory: 300Mi
|
||||
cpu: 0.5
|
||||
metrics:
|
||||
enabled: true
|
||||
cluster:
|
||||
slaveCount: 2
|
||||
resources:
|
||||
requests:
|
||||
memory: 300Mi
|
||||
cpu: 0.5
|
||||
serviceAccount:
|
||||
create: true
|
||||
name: open-match-redis-service
|
||||
sysctlImage:
|
||||
# Enable this setting in production if you are running Open Match under Linux environment
|
||||
enabled: false
|
||||
@ -153,26 +172,44 @@ redis:
|
||||
# Controls if users need to install backend, frontend, query, om-configmap, and swaggerui.
|
||||
open-match-core:
|
||||
enabled: true
|
||||
ignoreListTTL: 60000ms
|
||||
|
||||
# Length of time between first fetch matches call, and when no further fetch
|
||||
# matches calls will join the current evaluation/synchronization cycle,
|
||||
# instead waiting for the next cycle.
|
||||
registrationInterval: 250ms
|
||||
# Length of time after match function as started before it will be canceled,
|
||||
# and evaluator call input is EOF.
|
||||
proposalCollectionInterval: 20s
|
||||
# Time after a ticket has been returned from fetch matches (marked as pending)
|
||||
# before it automatically becomes active again and will be returned by query
|
||||
# calls.
|
||||
pendingReleaseTimeout: 1m
|
||||
# Time after a ticket has been assigned before it is automatically delted.
|
||||
assignedDeleteTimeout: 10m
|
||||
# Maximum number of tickets to return on a single QueryTicketsResponse.
|
||||
queryPageSize: 10000
|
||||
# Duration for redis locks to expire.
|
||||
backfillLockTimeout: 1m
|
||||
|
||||
redis:
|
||||
install: true
|
||||
# If open-match-core.redis.install is set to false, have Open Match components talk to this redis address instead.
|
||||
enabled: true
|
||||
# If open-match-core.redis.enabled is set to false, have Open Match components talk to this redis address instead.
|
||||
# Otherwise the default is set to the om-redis instance.
|
||||
hostname: # Your redis server address
|
||||
port: 6379
|
||||
user:
|
||||
user:
|
||||
pool:
|
||||
maxIdle: 200
|
||||
maxActive: 0
|
||||
idleTimeout: 0
|
||||
healthCheckTimeout: 300ms
|
||||
swaggerui:
|
||||
enabled: true
|
||||
|
||||
# Controls if users need to install scale testing setup for Open Match.
|
||||
open-match-scale:
|
||||
# Switch the value between true/false to turn on/off this subchart
|
||||
enabled: false
|
||||
frontend: *frontend
|
||||
backend: *backend
|
||||
|
||||
# Controls if users need to install the monitoring tools in Open Match.
|
||||
open-match-telemetry:
|
||||
@ -185,7 +222,6 @@ open-match-customize:
|
||||
enabled: false
|
||||
evaluator: *evaluator
|
||||
function: *function
|
||||
query: *query
|
||||
# You can override the evaluator/mmf image
|
||||
# evaluator:
|
||||
# image: [YOUR_EVALUATOR_IMAGE]
|
||||
@ -212,8 +248,8 @@ global:
|
||||
limits:
|
||||
memory: 100Mi
|
||||
cpu: 100m
|
||||
# Defines a service account which provides an identity for processes that run in a Pod in Open Match.
|
||||
serviceAccount: open-match-unprivileged-service
|
||||
# Overrides the name of the service account which provides an identity for processes that run in a Pod in Open Match.
|
||||
serviceAccount:
|
||||
# Use this field if you need to override the port type for all services defined in this chart
|
||||
service:
|
||||
portType:
|
||||
@ -235,21 +271,21 @@ global:
|
||||
# Use this field if you need to override the image registry and image tag for all services defined in this chart
|
||||
image:
|
||||
registry: gcr.io/open-match-public-images
|
||||
tag: 0.0.0-dev
|
||||
tag: 1.4.0-rc.1
|
||||
pullPolicy: Always
|
||||
|
||||
|
||||
# Expose the telemetry configurations to all subcharts because prometheus, for example,
|
||||
# requires pod-level annotation to customize its scrape path.
|
||||
# See definitions in templates/_helpers.tpl - "prometheus.annotations" section for details
|
||||
telemetry:
|
||||
reportingPeriod: "1m"
|
||||
traceSamplingFraction: 0.01 # What fraction of traces to sample.
|
||||
zpages:
|
||||
enabled: true
|
||||
jaeger:
|
||||
enabled: false
|
||||
samplerFraction: 0.01 # Configures a sampler that samples a given fraction of traces.
|
||||
agentEndpoint: "open-match-jaeger-agent:6831"
|
||||
collectorEndpoint: "http://open-match-jaeger-collector:14268/api/traces"
|
||||
agentEndpoint: '{{ include "openmatch.jaeger.agent" . }}'
|
||||
collectorEndpoint: '{{ include "openmatch.jaeger.collector" . }}'
|
||||
prometheus:
|
||||
enabled: false
|
||||
endpoint: "/metrics"
|
||||
@ -259,4 +295,5 @@ global:
|
||||
prefix: "open_match"
|
||||
grafana:
|
||||
enabled: false
|
||||
reportingPeriod: "1m"
|
||||
# This will be called with `tpl` in the open-match-telemetry subchart namespace.
|
||||
prometheusServer: 'http://{{ include "call-nested" (list . "prometheus" "prometheus.server.fullname") }}.{{ .Release.Namespace }}.svc.cluster.local:80/'
|
||||
|
@ -12,7 +12,7 @@ If you're making changes to these files you must check in the .tfstate file as
|
||||
well as comment the reason why you're enabling a feature or making a change.
|
||||
|
||||
## GCP Service Account Setup
|
||||
To use the terraform templates when developing Open Match, you need to have the [credential of your service account](https://www.terraform.io/docs/providers/google/provider_reference.html#credentials-1) associated with your Open Match project.
|
||||
To use the terraform templates when developing Open Match, you need to have the [credential of your service account](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/google_service_account) associated with your Open Match project.
|
||||
|
||||
```bash
|
||||
# Example: Generates the key file in GCP.
|
||||
|
@ -16,7 +16,7 @@ Lastly, these templates are meant for advanced users that are most likely
|
||||
already using Terraform.
|
||||
|
||||
## GCP Service Account Setup
|
||||
To use the terraform templates when developing Open Match, you need to have the [credential of your service account](https://www.terraform.io/docs/providers/google/provider_reference.html#credentials-1) associated with your Open Match project.
|
||||
To use the terraform templates when developing Open Match, you need to have the [credential of your service account](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/google_service_account) associated with your Open Match project.
|
||||
|
||||
```bash
|
||||
# Example: Generates the key file in GCP.
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2019 Google LLC
|
||||
// Copyright 2020 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@ -12,12 +12,15 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package e2e
|
||||
syntax = "proto3";
|
||||
package openmatch.internal;
|
||||
option go_package = "open-match.dev/open-match/internal/ipb";
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
import "api/messages.proto";
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
RunMain(m)
|
||||
}
|
||||
message BackfillInternal {
|
||||
// Represents a backfill entity which is used to fill partially full matches
|
||||
openmatch.Backfill backfill = 1;
|
||||
// List of ticket IDs associated with a current backfill
|
||||
repeated string ticket_ids = 2;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user