Skip to content

Commit

Permalink
из-за поздней сдачи возникают конфликты с веткой iter13
Browse files Browse the repository at this point in the history
Revert "Iter9 (#12)"

This reverts commit fa73032.
  • Loading branch information
StasMerzlyakov committed Mar 18, 2024
1 parent fa73032 commit 5a46c41
Show file tree
Hide file tree
Showing 52 changed files with 1,275 additions and 2,905 deletions.
1 change: 0 additions & 1 deletion .gitattributes

This file was deleted.

3 changes: 0 additions & 3 deletions Arch_Idea.png

This file was deleted.

17 changes: 0 additions & 17 deletions Questions.md

This file was deleted.

31 changes: 9 additions & 22 deletions cmd/agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,38 +8,25 @@ import (
"syscall"

"github.com/StasMerzlyakov/go-metrics/internal/agent"
"github.com/StasMerzlyakov/go-metrics/internal/config"
)

type Agent interface {
Start(ctx context.Context)
Wait()
}

func main() {
agentCfg, err := config.LoadAgentConfig()
agentCfg, err := agent.LoadConfig()
if err != nil {
log.Fatal(err)
}

metricStorage := agent.NewMemStatsStorage()
resultSender := agent.NewHTTPResultSender(agentCfg.ServerAddr)

var agnt Agent = agent.Create(agentCfg,
resultSender,
metricStorage,
)

// Взято отсюда: "Реализация Graceful Shutdown в Go"(https://habr.com/ru/articles/771626/)
// Сейчас выглядит избыточным - оставил как задел на будущее для сервера
ctx, cancelFn := context.WithCancel(context.Background())
ctx, cancel := context.WithCancel(context.Background())
exit := make(chan os.Signal, 1)
signal.Notify(exit, os.Interrupt, syscall.SIGTERM)

agnt.Start(ctx)
defer func() {
cancelFn()
agnt.Wait()
}()
<-exit
if agent, err := agent.CreateAgent(ctx, agentCfg); err != nil {
panic(err)
} else {
<-exit
cancel()
agent.Wait() // ожидаение завершения go-рутин в агенте
}
}
72 changes: 5 additions & 67 deletions cmd/server/server.go
Original file line number Diff line number Diff line change
@@ -1,81 +1,19 @@
package main

import (
"context"
"net/http"
"os"
"os/signal"
"syscall"
"log"

"github.com/StasMerzlyakov/go-metrics/internal/config"
"github.com/StasMerzlyakov/go-metrics/internal/server"
"github.com/StasMerzlyakov/go-metrics/internal/server/adapter/fs/formatter"
"github.com/StasMerzlyakov/go-metrics/internal/server/adapter/http/handler"
"github.com/StasMerzlyakov/go-metrics/internal/server/adapter/http/middleware/compress"
"github.com/StasMerzlyakov/go-metrics/internal/server/adapter/http/middleware/logging"
"github.com/StasMerzlyakov/go-metrics/internal/server/storage/memory"
"github.com/StasMerzlyakov/go-metrics/internal/server/usecase"
"go.uber.org/zap"
)

type Server interface {
Start(ctx context.Context)
WaitDone()
}

func createMiddleWareList(log *zap.SugaredLogger) []func(http.Handler) http.Handler {
return []func(http.Handler) http.Handler{
logging.NewLoggingResponseMW(log),
compress.NewCompressGZIPResponseMW(log), //compress.NewCompressGZIPBufferResponseMW(log),
compress.NewUncompressGZIPRequestMW(log),
logging.NewLoggingRequestMW(log),
}
}

func main() {

// Конфигурация
srvConf, err := config.LoadServerConfig()
srvConf, err := server.LoadConfig()
if err != nil {
panic(err)
log.Fatal(err)
}

// Создаем логгер
logger, err := zap.NewDevelopment()
if err != nil {
// вызываем панику, если ошибка
panic("cannot initialize zap")
if err := server.CreateServer(srvConf); err != nil {
panic(err)
}
defer logger.Sync()

sugarLog := logger.Sugar()

// Сборка сервера
storage := memory.NewStorage()

backupFomratter := formatter.NewJSON(sugarLog, srvConf.FileStoragePath)
backup := usecase.NewBackup(sugarLog, storage, backupFomratter)

metrics := usecase.NewMetrics(storage)

mwList := createMiddleWareList(sugarLog)
httpHandler := handler.NewHTTP(metrics, sugarLog, mwList...)

var server Server = server.NewMetricsServer(srvConf,
sugarLog,
httpHandler,
metrics,
backup)

// Запуск сервера
ctx, cancelFn := context.WithCancel(context.Background())
exit := make(chan os.Signal, 1)
signal.Notify(exit, os.Interrupt, syscall.SIGTERM)

server.Start(ctx)
defer func() {
cancelFn()
server.WaitDone()
}()
<-exit
}
17 changes: 4 additions & 13 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,12 @@ module github.com/StasMerzlyakov/go-metrics
go 1.19

require (
github.com/caarlos0/env v3.5.0+incompatible
github.com/go-chi/chi/v5 v5.0.11
github.com/go-resty/resty/v2 v2.11.0
github.com/pkg/errors v0.9.1
github.com/sirupsen/logrus v1.9.3
github.com/stretchr/testify v1.8.4
github.com/ungerik/go-pool v0.0.0-20140720100922-d102a2c7872a
go.uber.org/zap v1.27.0
)

require (
github.com/caarlos0/env v3.5.0+incompatible // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-chi/chi/v5 v5.0.11 // indirect
github.com/go-resty/resty/v2 v2.11.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
go.uber.org/multierr v1.10.0 // indirect
github.com/stretchr/testify v1.8.4 // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/sys v0.13.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
19 changes: 0 additions & 19 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,30 +1,16 @@
github.com/caarlos0/env v3.5.0+incompatible h1:Yy0UN8o9Wtr/jGHZDpCBLpNrzcFLLM2yixi/rBrKyJs=
github.com/caarlos0/env v3.5.0+incompatible/go.mod h1:tdCsowwCzMLdkqRYDlHpZCp2UooDD3MspDBjZ2AD02Y=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-chi/chi/v5 v5.0.11 h1:BnpYbFZ3T3S1WMpD79r7R5ThWX40TaFB7L31Y8xqSwA=
github.com/go-chi/chi/v5 v5.0.11/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
github.com/go-resty/resty/v2 v2.11.0 h1:i7jMfNOJYMp69lq7qozJP+bjgzfAzeOhuGlyDrqxT/8=
github.com/go-resty/resty/v2 v2.11.0/go.mod h1:iiP/OpA0CkcL3IGt1O0+/SIItFUbkkyw5BGXiVdTu+A=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/ungerik/go-pool v0.0.0-20140720100922-d102a2c7872a h1:Lfu+d2ZpWyfH6HyuQrGI3om39+yNuvk2OWT0UptrFAM=
github.com/ungerik/go-pool v0.0.0-20140720100922-d102a2c7872a/go.mod h1:DcjcKDwgMN/tbplnqJjxJNonhx4QvgPsv5W3N+h6sFU=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
Expand All @@ -44,11 +30,9 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
Expand All @@ -61,15 +45,12 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
101 changes: 50 additions & 51 deletions internal/agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,89 +2,88 @@ package agent

import (
"context"
"log"
"fmt"
"sync"
"time"

"github.com/StasMerzlyakov/go-metrics/internal/config"
"github.com/sirupsen/logrus"
"github.com/StasMerzlyakov/go-metrics/internal/storage"
)

type ResultSender interface {
SendMetrics(metrics []Metrics) error
type Agent interface {
Wait()
}

type MetricStorage interface {
Refresh() error
GetMetrics() []Metrics
}

func Create(config *config.AgentConfiguration,
resultSender ResultSender,
metricStorage MetricStorage,
) *agent {
func CreateAgent(ctx context.Context, config *Configuration) (Agent, error) {
agent := &agent{
metricStorage: metricStorage,
resultSender: resultSender,
pollIntervalSec: config.PollInterval,
reportIntervalSec: config.ReportInterval,
metricsSource: NewRuntimeMetricsSource(),
resultSender: NewHTTPResultSender(config.ServerAddr),
gaugeStorage: storage.NewMemoryFloat64Storage(),
poolCounter: 0,
}

return agent
go agent.PoolMetrics(ctx, config.PollInterval)
go agent.ReportMetrics(ctx, config.ReportInterval)
agent.wg.Add(2)
return agent, nil
}

type agent struct {
metricStorage MetricStorage
resultSender ResultSender
pollIntervalSec int
reportIntervalSec int
wg sync.WaitGroup
metricsSource MetricsSource
resultSender ResultSender
gaugeStorage storage.MetricsStorage[float64]
poolCounter int64
wg sync.WaitGroup
}

func (a *agent) Wait() {
a.wg.Wait()
}

func (a *agent) Start(ctx context.Context) {
go a.pollMetrics(ctx)
go a.reportMetrics(ctx)
a.wg.Add(2)
}

func (a *agent) pollMetrics(ctx context.Context) {
pollInterval := time.Duration(a.pollIntervalSec) * time.Second
defer a.wg.Done()
func (a *agent) PoolMetrics(ctx context.Context, pollIntervalSec int) {
counter := 0
for {
select {
case <-ctx.Done():
logrus.Info("PollMetrics DONE")
fmt.Printf("[%v] PoolMetrics DONE\n", time.Now())
a.wg.Done()
return

case <-time.After(pollInterval):
if err := a.metricStorage.Refresh(); err != nil {
logrus.Fatalf("PollMetrics metrics error: %v", err)
default:
time.Sleep(1 * time.Second) // Будем просыпаться каждую секунду для проверки ctx
counter++
if counter == pollIntervalSec {
counter = 0
for k, v := range a.metricsSource.PollMetrics() {
a.gaugeStorage.Set(k, v)
}
a.poolCounter = a.metricsSource.PollCount()
fmt.Printf("[%v] PoolMetrics [SUCCESS] (poolCounter %v)\n", time.Now(), a.poolCounter)
}
logrus.Info("PollMetrics SUCCESS")
}
}
}

func (a *agent) reportMetrics(ctx context.Context) {
reportInterval := time.Duration(a.reportIntervalSec) * time.Second

func (a *agent) ReportMetrics(ctx context.Context, reportIntervalSec int) {
counter := 0
MAIN:
for {
select {
case <-ctx.Done():
log.Println("ReportMetrics DONE")
fmt.Printf("[%v] ReportMetrics DONE\n", time.Now())
a.wg.Done()
return
case <-time.After(reportInterval):
metrics := a.metricStorage.GetMetrics()
err := a.resultSender.SendMetrics(metrics)
if err != nil {
log.Printf("ReportMetrics ERROR: %v\n", err)
} else {
logrus.Info("ReportMetrics SUCCESS")
default:
time.Sleep(1 * time.Second) // Будем просыпаться каждую секунду для проверки ctx
counter++
if counter == reportIntervalSec {
counter = 0
for _, key := range a.gaugeStorage.Keys() {
val, _ := a.gaugeStorage.Get(key)
if err := a.resultSender.SendGauge(key, val); err != nil {
fmt.Printf("[%v] ReportMetrics [ERROR] (poolCounter %v)\n", time.Now(), err)
continue MAIN
}
}
_ = a.resultSender.SendCounter("PoolCount", a.poolCounter)
fmt.Printf("[%v] ReportMetrics [SUCCESS] (poolCounter %v)\n", time.Now(), a.poolCounter)
}
}
}
Expand Down
15 changes: 15 additions & 0 deletions internal/agent/api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package agent

import "errors"

type MetricsSource interface {
PollMetrics() map[string]float64
PollCount() int64
}

var ErrServerInteraction = errors.New("server interaction error")

type ResultSender interface {
SendGauge(name string, value float64) error
SendCounter(name string, value int64) error
}
Loading

0 comments on commit 5a46c41

Please sign in to comment.