Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into stable
Browse files Browse the repository at this point in the history
  • Loading branch information
9seconds committed Aug 9, 2022
2 parents c07e3d5 + bd8a7ed commit 269852a
Show file tree
Hide file tree
Showing 92 changed files with 688 additions and 655 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ jobs:
strategy:
matrix:
go_version:
- ^1.18
- ^1.19
steps:
- name: Checkout
uses: actions/checkout@v2
Expand Down Expand Up @@ -114,12 +114,12 @@ jobs:
- name: Setup Go
uses: actions/setup-go@v2
with:
go-version: ^1.18
go-version: ^1.19

- name: Run linter
uses: golangci/golangci-lint-action@v3
with:
version: v1.45.0
version: v1.48.0

docker:
name: Docker
Expand Down
12 changes: 11 additions & 1 deletion .golangci.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,14 @@ format = "colored-line-number"

[linters]
enable-all = true
disable = ["thelper", "ireturn", "varnamelen", "gochecknoglobals", "gas", "goerr113", "exhaustivestruct", "containedctx"]
disable = [
"containedctx",
"exhaustivestruct",
"exhaustruct",
"gas",
"gochecknoglobals",
"goerr113",
"ireturn",
"thelper",
"varnamelen",
]
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
###############################################################################
# BUILD STAGE

FROM golang:1.18-alpine AS build
FROM golang:1.19-alpine AS build

RUN set -x \
&& apk --no-cache --update add \
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ ROOT_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
IMAGE_NAME := mtg
APP_NAME := $(IMAGE_NAME)

GOLANGCI_LINT_VERSION := v1.45.0
GOLANGCI_LINT_VERSION := v1.48.0

VERSION := $(shell git describe --exact-match HEAD 2>/dev/null || git describe --tags --always)
COMMON_BUILD_FLAGS := -trimpath -mod=readonly -ldflags="-extldflags '-static' -s -w -X 'main.version=$(VERSION)'"
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ surprises. Always choose some version tag.
Also, if you have `go` installed, you can always download this tool with `go get`:

```console
go get github.com/9seconds/mtg/v2
go install github.com/9seconds/mtg/v2@latest
```

#### Build from sources
Expand Down Expand Up @@ -338,7 +338,7 @@ $ sudo systemctl start mtg
or you can run a docker image

```console
docker run -d -v /etc/mtg.toml:/config.toml -p 443:3128 --name mtg-proxy --restart=unless-stopped nineseconds/mtg:2
docker run -d -v $PWD/config.toml:config.toml -p 443:3128 --name mtg-proxy --restart=unless-stopped nineseconds/mtg:2
```

where _443_ is a host port (a port you want to connect to from a
Expand Down
16 changes: 8 additions & 8 deletions antireplay/init.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
// Antireplay package has cache implementations that are effective
// against replay attacks.
// Antireplay package has cache implementations that are effective against
// replay attacks.
//
// To understand more about replay attacks, please read documentation
// for mtglib.AntiReplayCache interface. This package has a list of some
// To understand more about replay attacks, please read documentation for
// [mtglib.AntiReplayCache] interface. This package has a list of some
// implementations of this interface.
package antireplay

const (
// DefaultStableBloomFilterMaxSize is a recommended byte size for a
// stable bloom filter.
// DefaultStableBloomFilterMaxSize is a recommended byte size for a stable
// bloom filter.
DefaultStableBloomFilterMaxSize = 1024 * 1024 // 1MiB

// DefaultStableBloomFilterErrorRate is a recommended default error
// rate for a stable bloom filter.
// DefaultStableBloomFilterErrorRate is a recommended default error rate for a
// stable bloom filter.
DefaultStableBloomFilterErrorRate = 0.001
)
5 changes: 2 additions & 3 deletions antireplay/noop.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@ type noop struct{}

func (n noop) SeenBefore(_ []byte) bool { return false }

// NewNoop returns an implementation that does nothing. A corresponding
// method always returns false, so this cache accepts everything you
// pass to it.
// NewNoop returns an implementation that does nothing. A corresponding method
// always returns false, so this cache accepts everything you pass to it.
func NewNoop() mtglib.AntiReplayCache {
return noop{}
}
18 changes: 9 additions & 9 deletions antireplay/stable_bloom_filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,19 @@ func (s *stableBloomFilter) SeenBefore(digest []byte) bool {
return s.filter.TestAndAdd(digest)
}

// NewStableBloomFilter returns an implementation of AntiReplayCache
// based on stable bloom filter.
// NewStableBloomFilter returns an implementation of AntiReplayCache based on
// stable bloom filter.
//
// http://webdocs.cs.ualberta.ca/~drafiei/papers/DupDet06Sigmod.pdf
//
// The basic idea of a stable bloom filter is quite simple: each time
// when you set a new element, you randomly reset P elements. There is a
// hardcore math which proves that if you choose this P correctly, you
// can maintain the same error rate for a stream of elements.
// The basic idea of a stable bloom filter is quite simple: each time when you
// set a new element, you randomly reset P elements. There is a hardcore math
// which proves that if you choose this P correctly, you can maintain the same
// error rate for a stream of elements.
//
// byteSize is the number of bytes you want to give to a bloom filter.
// errorRate is desired false-positive error rate. If you want to use
// default values, please pass 0 for byteSize and <0 for errorRate.
// errorRate is desired false-positive error rate. If you want to use default
// values, please pass 0 for byteSize and <0 for errorRate.
func NewStableBloomFilter(byteSize uint, errorRate float64) mtglib.AntiReplayCache {
if byteSize == 0 {
byteSize = DefaultStableBloomFilterMaxSize
Expand All @@ -42,7 +42,7 @@ func NewStableBloomFilter(byteSize uint, errorRate float64) mtglib.AntiReplayCac
errorRate = DefaultStableBloomFilterErrorRate
}

sf := boom.NewDefaultStableBloomFilter(byteSize*8, errorRate) // nolint: gomnd
sf := boom.NewDefaultStableBloomFilter(byteSize*8, errorRate) //nolint: gomnd
sf.SetHash(xxhash.New64())

return &stableBloomFilter{
Expand Down
84 changes: 84 additions & 0 deletions buildinfo.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package main

import (
"crypto/sha256"
"encoding/base64"
"encoding/binary"
"fmt"
"io"
"runtime/debug"
"sort"
"strconv"
"time"
)

var version = "dev" // has to be set by ldflags

const (
buildInfoModuleStart byte = iota
buildInfoModuleFinish
buildInfoModuleDelimeter
)

func getVersion() string {
buildInfo, ok := debug.ReadBuildInfo()
if !ok {
return version
}

date := time.Now()
commit := ""
goVersion := buildInfo.GoVersion
dirtySuffix := ""

for _, setting := range buildInfo.Settings {
switch setting.Key {
case "vcs.time":
date, _ = time.Parse(time.RFC3339, setting.Value)
case "vcs.revision":
commit = setting.Value
case "vcs.modified":
if dirty, _ := strconv.ParseBool(setting.Value); dirty {
dirtySuffix = " [dirty]"
}
}
}

hasher := sha256.New()

checksumModule := func(mod *debug.Module) {
hasher.Write([]byte{buildInfoModuleStart})

io.WriteString(hasher, mod.Path) //nolint: errcheck
hasher.Write([]byte{buildInfoModuleDelimeter})

io.WriteString(hasher, mod.Version) //nolint: errcheck
hasher.Write([]byte{buildInfoModuleDelimeter})

io.WriteString(hasher, mod.Sum) //nolint: errcheck

hasher.Write([]byte{buildInfoModuleFinish})
}

io.WriteString(hasher, buildInfo.Path) //nolint: errcheck

binary.Write(hasher, binary.LittleEndian, uint64(1+len(buildInfo.Deps))) //nolint: errcheck

sort.Slice(buildInfo.Deps, func(i, j int) bool {
return buildInfo.Deps[i].Path > buildInfo.Deps[j].Path
})

checksumModule(&buildInfo.Main)

for _, module := range buildInfo.Deps {
checksumModule(module)
}

return fmt.Sprintf("%s (%s: %s on %s%s, modules checksum %s)",
version,
goVersion,
date.Format(time.RFC3339),
commit,
dirtySuffix,
base64.StdEncoding.EncodeToString(hasher.Sum(nil)))
}
6 changes: 3 additions & 3 deletions essentials/conns.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,19 @@ import (
"net"
)

// CloseableReader is a reader interface that can close its reading end.
// CloseableReader is an [io.Reader] interface that can close its reading end.
type CloseableReader interface {
io.Reader
CloseRead() error
}

// CloseableWriter is a writer that can close its writing end.
// CloseableWriter is an [io.Writer] that can close its writing end.
type CloseableWriter interface {
io.Writer
CloseWrite() error
}

// Conn is an extension of net.Conn that can close its ends. This mostly
// Conn is an extension of [net.Conn] that can close its ends. This mostly
// implies TCP connections.
type Conn interface {
net.Conn
Expand Down
4 changes: 2 additions & 2 deletions events/event_stream.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"github.com/OneOfOne/xxhash"
)

// EventStream is a default implementation of the mtglib.EventStream
// EventStream is a default implementation of the [mtglib.EventStream]
// interface.
//
// EventStream manages a set of goroutines, observers. Main
Expand Down Expand Up @@ -77,7 +77,7 @@ func NewEventStream(observerFactories []ObserverFactory) EventStream {
return rv
}

func eventStreamProcessor(ctx context.Context, eventChan <-chan mtglib.Event, observer Observer) { // nolint: cyclop
func eventStreamProcessor(ctx context.Context, eventChan <-chan mtglib.Event, observer Observer) { //nolint: cyclop
defer observer.Shutdown()

for {
Expand Down
40 changes: 20 additions & 20 deletions events/init.go
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
// Events has a default implementations of EventStream for mtglib.
//
// Please see documentation for mtglib.EventStream interface to get an
// idea of such an abstraction. This package has implementations for the
// default event stream.
// Please see documentation for [mtglib.EventStream] interface to get an idea
// of such an abstraction. This package has implementations for the default
// event stream.
//
// Default event stream has a list of its own concepts. First, all it
// does is a routing of messages to known observers. It takes an event,
// defines its type and pass this message to a method of the observer.
// Default event stream has a list of its own concepts. First, all it does is a
// routing of messages to known observers. It takes an event, defines its type
// and pass this message to a method of the observer.
//
// There might be many observers, but default event stream has a
// guarantee though. It uses StreamID as a sharding key and guarantees
// that a message with the same StreamID will be devlivered to the same
// observer instance. So, each producer is guarateed to get all relevant
// messages related to the same session. It is not possible that it will
// get EventFinish if it has not seen EventStart for that session yet.
// There might be many observers, but default event stream has a guarantee
// though. It uses StreamID as a sharding key and guarantees that a message
// with the same StreamID will be devlivered to the same observer instance. So,
// each producer is guarateed to get all relevant messages related to the same
// session. It is not possible that it will get EventFinish if it has not seen
// EventStart for that session yet.
package events

import "github.com/9seconds/mtg/v2/mtglib"

// Observer is an instance that listens for the incoming events.
//
// As it is said in the package description, the default event stream
// guarantees that all events with the same StreamID are going to be
// routed to the same instance of the observer. So, there is no need
// to synchronize information about streams between many observers
// instances, they can have their local storage.
// guarantees that all events with the same StreamID are going to be routed to
// the same instance of the observer. So, there is no need to synchronize
// information about streams between many observers instances, they can have
// their local storage.
type Observer interface {
// EventStart reacts on incoming mtglib.EventStart event.
EventStart(mtglib.EventStart)
Expand Down Expand Up @@ -65,8 +65,8 @@ type Observer interface {

// ObserverFactory creates a new instance of the observer.
//
// Default event stream creates a small set of goroutines to manage
// incoming messages. Each message is routed to an appropriate observer
// based on a sharding key, stream id. So, it is possible that an
// instance of mtg will have many observer instances, not a single one.
// Default event stream creates a small set of goroutines to manage incoming
// messages. Each message is routed to an appropriate observer based on a
// sharding key, stream id. So, it is possible that an instance of mtg will
// have many observer instances, not a single one.
type ObserverFactory func() Observer

0 comments on commit 269852a

Please sign in to comment.