Skip to content

reactivejson/cowboys

Repository files navigation

Distributed Cowboys game

Maintainer GitHub go.mod Go version of a Go module Go Reference Go Go Report Card

Go implementation of Distributed cowboys shootout game. Spec:

  • We have a set of cowboys.
  • Each cowboy has a unique name, health points and damage points.
  • Each cowboy runs in it’s own isolated process, workload or replica.
  • All communication between cowboys happen via your Redis MQ
  • Cowboys encounter starts at the same time in parallel. Each cowboys selects random target and shoots.
  • Subtract shooter damage points from target health points.
  • If target cowboy health points are 0 or lower, then target is dead.
  • Cowboys don’t shoot themselves and don’t shoot dead cowboys.
  • After the shot shooter sleeps for 1 second.
  • Last standing cowboy is the winner. Kubernetes, Helm, and Docker-compose are used for container orchestration solution.

You can run the game in two ways:

  • You can run this game using docker compose where we have a master to orchestrate the game and each player will run in it's own container.
  • You can run this game using Kubernetes platform with helm

Project layout

This layout is following pattern:

cowboys
└───
    ├── .github
    │   └── workflows
    │     └── go.yml
    ├── cmd
    │   └── master
        │   └── main.go
        │   └── app
        │     └── setup.go
        │     └── app.go
        │     └── context.go
    │   └── player
        │   └── main.go
        │   └── app
        │     └── setup.go
        │     └── app.go
        │     └── context.go
    ├── internal
    │   └── app
    │     └── master.go
    │     └── player.go
    │   └── domain
    │     └── master.go
    │     └── player.go
    │   └── game
    │     └── event.go
    │     └── game-state.go
    ├── build
    │   └── Dockerfile
    ├── helm
    │   └── <helm chart files>
    ├── docker-compose.yml.j2
    ├── Makefile
    ├── README.md
    └── <source packages>

Setup

Getting started

cowboys game is available in github cowboys

go get github.com/reactivejson/cowboys

Build

build the app and docker images To build the components of the project, use the following commands:

make docker-build

This will build this application docker images so-called master and player

Deploy it and run it with docker compose

We use Jinja2 to run the application dynamically.

Use the following command to run the game and provide your list of players (or use the default one)

make run-app players=players.json

Example input:

{
  "players": [
    {
      "name": "p1",
      "health": 10,
      "damage": 3
    },
    {
      "name": "p2",
      "health": 5,
      "damage": 4
    },
    {
      "name": "p3",
      "health": 10,
      "damage": 1
    },
    {
      "name": "p4",
      "health": 7,
      "damage": 2
    }
  ]
}

And check the logs to see who won:)

docker compose logs -f

Testing

make test

Deploy with Helm chart in a Kubernetes environment

In order to deploy it in a Kubernetes platform with helm. Create Helm package

make helm-create
helm upgrade --namespace neo --install master chart/master -f <your-custom-values>.yml
helm upgrade --namespace neo --install player chart/player -f <your-custom-values-with-players>.yml

Test coverage

Test coverage is checked as a part of test execution with the gotestsum tool.

Test coverage is checked for unit tests and integration tests.

Coverage report files are available and stored as *coverage.txt and are also imported in the SonarQube for easier browsing.

golangci-lint

In the effort of reducing errors and improving the overall quality of code, golangci-lint is run as a part of the pipeline. Linting is run for the services and packages that have changes since the previous green build (in master) or previous commit (in local or review).

Any issues found by golangci-lint for the changed code will lead to a failed build.

golangci-lint rules are configured in .golangci.yml.

Requirements

Variable names

Commonly used one letter variable names:

  • i for index
  • r for reader
  • w for writer
  • c for client

License

Apache 2.0, see LICENSE.