Skip to content

Commit

Permalink
Merge pull request #159 from yandex/arcadia
Browse files Browse the repository at this point in the history
Arcadia to master
  • Loading branch information
oke11o authored Jan 13, 2023
2 parents 691ecc4 + 0fefad9 commit 116cf1d
Show file tree
Hide file tree
Showing 140 changed files with 2,681 additions and 624 deletions.
2 changes: 1 addition & 1 deletion .goxc.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
],
"Arch": "amd64",
"Os": "linux darwin windows",
"PackageVersion": "0.1.3",
"PackageVersion": "0.3.1",
"TaskSettings": {
"publish-github": {
"owner": "yandex",
Expand Down
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
language: go

go:
- 1.11.x
- 1.15.x

env:
- GO111MODULE=on
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ fmt:

tools:
@echo "$(OK_COLOR)Install tools$(NO_COLOR)"
go install golang.org/x/tools/cmd/goimports
go install golang.org/x/tools/cmd/goimports@latest
go get golang.org/x/tools/cmd/cover
go get github.com/modocache/gover
go get github.com/mattn/goveralls
Expand Down
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
[![Join the chat at https://gitter.im/yandex/pandora](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/yandex/pandora?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Build Status](https://travis-ci.org/yandex/pandora.svg)](https://travis-ci.org/yandex/pandora)
[![Coverage Status](https://coveralls.io/repos/yandex/pandora/badge.svg?branch=develop&service=github)](https://coveralls.io/github/yandex/pandora?branch=develop)
[![Read the Docs](https://readthedocs.org/projects/yandexpandora/badge/)](https://readthedocs.org/projects/yandexpandora/)
[![Documentation Status](https://readthedocs.org/projects/yandexpandora/badge/?version=develop)](https://yandexpandora.readthedocs.io/en/develop/?badge=develop)

Pandora is a high-performance load generator in Go language. It has built-in HTTP(S) and HTTP/2 support and you can write your own load scenarios in Go, compiling them just before your test.
Pandora is a high-performance load generator in Go language. It has built-in HTTP(S) and HTTP/2 support and you can write your own load scenarios in Go, compiling them just before your test.

## How to start

Expand Down Expand Up @@ -42,5 +42,9 @@ Run the binary with your config (see config examples at [examples](https://githu
pandora myconfig.yaml
```

Or use Pandora with [Yandex.Tank](http://yandextank.readthedocs.org/en/latest/configuration.html#pandora) and
Or use Pandora with [Yandex.Tank](https://yandextank.readthedocs.io/en/latest/core_and_modules.html#pandora) and
[Overload](https://overload.yandex.net).

### Documentation
[ReadTheDocs](https://yandexpandora.readthedocs.io/en/develop/)

7 changes: 3 additions & 4 deletions acceptance_tests/acceptance_suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,9 @@ import (
. "github.com/onsi/gomega"
"github.com/onsi/gomega/gbytes"
"github.com/onsi/gomega/gexec"
"go.uber.org/zap"

"github.com/yandex/pandora/lib/ginkgoutil"
"github.com/yandex/pandora/lib/tag"
"go.uber.org/zap"
)

var pandoraBin string
Expand Down Expand Up @@ -112,7 +111,7 @@ func NewInstansePoolConfig() *InstancePoolConfig {
}

type InstancePoolConfig struct {
Id string
ID string
Provider map[string]interface{} `json:"ammo"`
Aggregator map[string]interface{} `json:"result"`
Gun map[string]interface{} `json:"gun"`
Expand Down Expand Up @@ -185,5 +184,5 @@ func (pt *PandoraTester) ExitCode() int {

func (pt *PandoraTester) Close() {
pt.Terminate()
os.RemoveAll(pt.TestDir)
_ = os.RemoveAll(pt.TestDir)
}
6 changes: 2 additions & 4 deletions acceptance_tests/http_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@ package acceptance

import (
"net/http"

"golang.org/x/net/http2"

"net/http/httptest"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"go.uber.org/atomic"
"golang.org/x/net/http2"
)

var _ = Describe("http", func() {
Expand Down Expand Up @@ -133,7 +131,7 @@ var _ = Describe("http", func() {
})

func startHTTP2(server *httptest.Server) {
http2.ConfigureServer(server.Config, nil)
_ = http2.ConfigureServer(server.Config, nil)
server.TLS = server.Config.TLSConfig
server.StartTLS()
}
82 changes: 58 additions & 24 deletions cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,17 @@ import (
"time"

"github.com/spf13/viper"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"

"github.com/yandex/pandora/core/config"
"github.com/yandex/pandora/core/engine"
"github.com/yandex/pandora/lib/zaputil"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)

const Version = "0.3.0"
const Version = "0.5.1"
const defaultConfigFile = "load"
const stdinConfigSelector = "-"

var useStdinConfig = false
var configSearchDirs = []string{"./", "./config", "/etc/pandora"}

type cliConfig struct {
Expand Down Expand Up @@ -90,15 +88,28 @@ func Run() {
}
var (
example bool
expvar bool
version bool
)
flag.BoolVar(&example, "example", false, "print example config to STDOUT and exit")
flag.BoolVar(&version, "version", false, "print pandora core version")
flag.BoolVar(&expvar, "expvar", false, "enable expvar service (DEPRECATED, use monitoring config section instead)")
flag.Parse()

if expvar {
fmt.Fprintf(os.Stderr, "-expvar flag is DEPRECATED. Use monitoring config section instead\n")
}

if example {
panic("Not implemented yet")
// TODO: print example config file content
}

if version {
fmt.Fprintf(os.Stderr, "Pandora core/%s\n", Version)
return
}

conf := readConfig()
log := newLogger(conf.Log)
zap.ReplaceGlobals(log)
Expand All @@ -117,46 +128,56 @@ func Run() {
errs := make(chan error)
go runEngine(ctx, pandora, errs)

// waiting for signal or error message from engine
awaitPandoraTermination(pandora, cancel, errs, log)
log.Info("Engine run successfully finished")
}

// helper function that awaits pandora run
func awaitPandoraTermination(pandora *engine.Engine, gracefulShutdown func(), errs chan error, log *zap.Logger) {
sigs := make(chan os.Signal, 2)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)

// waiting for signal or error message from engine
select {
case sig := <-sigs:
var interruptTimeout = 3 * time.Second
switch sig {
case syscall.SIGINT:
const interruptTimeout = 5 * time.Second
log.Info("SIGINT received. Trying to stop gracefully.", zap.Duration("timeout", interruptTimeout))
cancel()
select {
case <-time.After(interruptTimeout):
log.Fatal("Interrupt timeout exceeded")
case sig := <-sigs:
log.Fatal("Another signal received. Quiting.", zap.Stringer("signal", sig))
case err := <-errs:
log.Fatal("Engine interrupted", zap.Error(err))
}
// await gun timeout but no longer than 30 sec.
interruptTimeout = 30 * time.Second
log.Info("SIGINT received. Graceful shutdown.", zap.Duration("timeout", interruptTimeout))
gracefulShutdown()
case syscall.SIGTERM:
log.Fatal("SIGTERM received. Quiting.")
log.Info("SIGTERM received. Trying to stop gracefully.", zap.Duration("timeout", interruptTimeout))
gracefulShutdown()
default:
log.Fatal("Unexpected signal received. Quiting.", zap.Stringer("signal", sig))
}

select {
case <-time.After(interruptTimeout):
log.Fatal("Interrupt timeout exceeded")
case sig := <-sigs:
log.Fatal("Another signal received. Quiting.", zap.Stringer("signal", sig))
case err := <-errs:
log.Fatal("Engine interrupted", zap.Error(err))
}

case err := <-errs:
switch err {
case nil:
log.Info("Pandora engine successfully finished it's work")
case err:
const awaitTimeout = 3 * time.Second
log.Error("Engine run failed. Awaiting started tasks.", zap.Error(err), zap.Duration("timeout", awaitTimeout))
cancel()
gracefulShutdown()
time.AfterFunc(awaitTimeout, func() {
log.Fatal("Engine tasks timeout exceeded.")
})
pandora.Wait()
log.Fatal("Engine run failed. Pandora graceful shutdown successfully finished")
}
}
log.Info("Engine run successfully finished")
}

func runEngine(ctx context.Context, engine *engine.Engine, errs chan error) {
Expand All @@ -176,6 +197,7 @@ func readConfig() *cliConfig {

v := newViper()

var useStdinConfig = false
args := flag.Args()
if len(args) > 0 {
switch {
Expand Down Expand Up @@ -262,10 +284,16 @@ func startMonitoring(conf monitoringConfig) (stop func()) {
zap.L().Fatal("CPU profile file create fail", zap.Error(err))
}
zap.L().Info("Starting CPU profiling")
pprof.StartCPUProfile(f)
err = pprof.StartCPUProfile(f)
if err != nil {
zap.L().Info("CPU profiling is already enabled")
}
stops = append(stops, func() {
pprof.StopCPUProfile()
f.Close()
err := f.Close()
if err != nil {
zap.L().Info("Error closing CPUProfile file")
}
})
}
if conf.MemProfile.Enabled {
Expand All @@ -276,8 +304,14 @@ func startMonitoring(conf monitoringConfig) (stop func()) {
stops = append(stops, func() {
zap.L().Info("Writing memory profile")
runtime.GC()
pprof.WriteHeapProfile(f)
f.Close()
err := pprof.WriteHeapProfile(f)
if err != nil {
zap.L().Info("Error writing HeapProfile file")
}
err = f.Close()
if err != nil {
zap.L().Info("Error closing HeapProfile file")
}
})
}
stop = func() {
Expand Down
3 changes: 1 addition & 2 deletions cli/expvar.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@ package cli
import (
"time"

"go.uber.org/zap"

"github.com/yandex/pandora/core/engine"
"github.com/yandex/pandora/lib/monitoring"
"go.uber.org/zap"
)

func newEngineMetrics() engine.Metrics {
Expand Down
3 changes: 1 addition & 2 deletions components/example/example.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,9 @@ import (
"fmt"
"sync"

"go.uber.org/zap"

"github.com/yandex/pandora/core"
"github.com/yandex/pandora/core/aggregator/netsample"
"go.uber.org/zap"
)

type Ammo struct {
Expand Down
6 changes: 3 additions & 3 deletions components/example/import/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
package example

import (
. "github.com/yandex/pandora/components/example"
"github.com/yandex/pandora/components/example"
"github.com/yandex/pandora/core/register"
)

func Import() {
register.Provider("example", NewProvider, DefaultProviderConfig)
register.Gun("example", NewGun)
register.Provider("example", example.NewProvider, example.DefaultProviderConfig)
register.Gun("example", example.NewGun)
}
39 changes: 39 additions & 0 deletions components/grpc/ammo/ammo.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright (c) 2017 Yandex LLC. All rights reserved.
// Use of this source code is governed by a MPL 2.0
// license that can be found in the LICENSE file.
// Author: Vladimir Skipor <[email protected]>

package ammo

type Ammo struct {
Tag string `json:"tag"`
Call string `json:"call"`
Metadata map[string]string `json:"metadata"`
Payload map[string]interface{} `json:"payload"`
id int
isInvalid bool
}

func (a *Ammo) Reset(tag string, call string, metadata map[string]string, payload map[string]interface{}) {
*a = Ammo{tag, call, metadata, payload, -1, false}
}

func (a *Ammo) SetID(id int) {
a.id = id
}

func (a *Ammo) ID() int {
return a.id
}

func (a *Ammo) Invalidate() {
a.isInvalid = true
}

func (a *Ammo) IsInvalid() bool {
return a.isInvalid
}

func (a *Ammo) IsValid() bool {
return !a.isInvalid
}
Loading

0 comments on commit 116cf1d

Please sign in to comment.