-
Notifications
You must be signed in to change notification settings - Fork 146
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
PMM-11603 pmm-agent reload. #2410
Changes from 35 commits
5ee3727
397dd78
d1ed579
a798f6e
fe419c7
dc5fcfb
ef83b4b
e236c23
7e6b2a8
00dbaad
0e75cc4
f7425fa
f83b2b4
33183b8
69afdca
2392944
42e000a
69bcdf3
3ce3530
d72cd84
5186562
7a28f9f
98a896b
a370bbf
62d417f
83b9ed9
7b030bd
2bade5b
c309281
f7e91bc
b0b57c4
ed7cd0d
769547c
3db8435
9af8a27
316e62e
4d40b0d
72e1ab3
014bfa8
28ec4cf
64aa322
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -40,14 +40,13 @@ import ( | |
|
||
// Run implements `pmm-agent run` default command. | ||
func Run() { | ||
var cfg *config.Config | ||
l := logrus.WithField("component", "main") | ||
ctx, cancel := context.WithCancel(context.Background()) | ||
defer l.Info("Done.") | ||
|
||
const initServerLogsMaxLength = 32 // store logs before load configuration | ||
logStore := tailog.NewStore(initServerLogsMaxLength) | ||
logrus.SetOutput(io.MultiWriter(os.Stderr, logStore)) | ||
l := logrus.WithField("component", "main") | ||
rootCtx, rootCancel := context.WithCancel(context.Background()) | ||
|
||
defer l.Info("Done.") | ||
|
||
// handle termination signals | ||
signals := make(chan os.Signal, 1) | ||
|
@@ -56,75 +55,89 @@ func Run() { | |
s := <-signals | ||
signal.Stop(signals) | ||
l.Warnf("Got %s, shutting down...", unix.SignalName(s.(unix.Signal))) //nolint:forcetypeassert | ||
if cfg != nil { | ||
cleanupTmp(cfg.Paths.TempDir, l) | ||
} | ||
cancel() | ||
rootCancel() | ||
}() | ||
|
||
configStorage := config.NewStorage(nil) | ||
configFilepath, err := configStorage.Reload(l) | ||
if err != nil { | ||
l.Fatalf("Failed to load configuration: %s.", err) | ||
} | ||
|
||
cfg = configStorage.Get() | ||
|
||
cleanupTmp(cfg.Paths.TempDir, l) | ||
connectionUptimeService := connectionuptime.NewService(cfg.WindowConnectedTime) | ||
connectionUptimeService.RunCleanupGoroutine(ctx) | ||
v := versioner.New(&versioner.RealExecFunctions{}) | ||
supervisor := supervisor.NewSupervisor(ctx, v, configStorage) | ||
connectionChecker := connectionchecker.New(configStorage) | ||
r := runner.New(cfg.RunnerCapacity) | ||
client := client.New(configStorage, supervisor, r, connectionChecker, v, connectionUptimeService, logStore) | ||
localServer := agentlocal.NewServer(configStorage, supervisor, client, configFilepath, logStore) | ||
|
||
var wg sync.WaitGroup | ||
wg.Add(3) | ||
go func() { | ||
defer wg.Done() | ||
supervisor.Run(ctx) | ||
cancel() | ||
}() | ||
go func() { | ||
defer wg.Done() | ||
r.Run(ctx) | ||
cancel() | ||
}() | ||
go func() { | ||
defer wg.Done() | ||
localServer.Run(ctx) | ||
cancel() | ||
}() | ||
configStorage, configFilepath := prepareConfig(l) | ||
|
||
for { | ||
_, err = configStorage.Reload(l) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We need to reload the configs There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Reload is called when you use pmm-admin config subcommand. So it should not be necessary do it here, or we want to cover also case that someone will modify config manually during its running? Or there another case how you could change config? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, we want to cover that as well. We have API endpoint for that reason. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. and actually the main reason to have /reload endpoint is to be able to reload configs without restarting pmm-agent There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Am I wrong or reload for reload endpoint should be done by https://github.com/percona/pmm/pull/2410/files#diff-9bb22a7f420e8dfd90097d05536858550d6f7c00dfedada00e0606305d667db1R190 anyway? Thank you. |
||
if err != nil { | ||
l.Fatalf("Failed to load configuration: %s.", err) | ||
} | ||
|
||
ctx, cancel := context.WithCancel(rootCtx) | ||
cfg := configStorage.Get() | ||
|
||
config.ConfigureLogger(cfg) | ||
logStore.Resize(cfg.LogLinesCount) | ||
l.Debugf("Loaded configuration: %+v", cfg) | ||
prepareLogger(cfg, logStore, l) | ||
|
||
supervisor := supervisor.NewSupervisor(ctx, v, configStorage) | ||
connectionChecker := connectionchecker.New(configStorage) | ||
r := runner.New(cfg.RunnerCapacity) | ||
client := client.New(configStorage, supervisor, r, connectionChecker, v, prepareConnectionService(ctx, cfg), logStore) | ||
localServer := agentlocal.NewServer(configStorage, supervisor, client, configFilepath, logStore) | ||
|
||
logrus.Infof("Window check connection time is %.2f hour(s)", cfg.WindowConnectedTime.Hours()) | ||
connectionUptimeService.SetWindowPeriod(cfg.WindowConnectedTime) | ||
|
||
var wg sync.WaitGroup | ||
wg.Add(3) | ||
reloadCh := make(chan bool, 1) | ||
go func() { | ||
defer wg.Done() | ||
supervisor.Run(ctx) | ||
cancel() | ||
}() | ||
go func() { | ||
defer wg.Done() | ||
r.Run(ctx) | ||
cancel() | ||
}() | ||
go func() { | ||
defer wg.Done() | ||
localServer.Run(ctx, reloadCh) | ||
cancel() | ||
}() | ||
|
||
processClientUntilCancel(ctx, client, reloadCh, l) | ||
|
||
cleanupTmp(cfg.Paths.TempDir, l) | ||
wg.Wait() | ||
select { | ||
case <-rootCtx.Done(): | ||
return | ||
default: | ||
} | ||
} | ||
} | ||
|
||
func processClientUntilCancel(ctx context.Context, client *client.Client, reloadCh chan bool, l *logrus.Entry) { | ||
JiriCtvrtka marked this conversation as resolved.
Show resolved
Hide resolved
JiriCtvrtka marked this conversation as resolved.
Show resolved
Hide resolved
|
||
for { | ||
clientCtx, cancelClientCtx := context.WithCancel(ctx) | ||
client.Run(clientCtx) | ||
|
||
_ = client.Run(clientCtx) | ||
cancelClientCtx() | ||
|
||
<-client.Done() | ||
|
||
if ctx.Err() != nil { | ||
break | ||
select { | ||
case <-reloadCh: | ||
return | ||
case <-ctx.Done(): | ||
return | ||
default: | ||
} | ||
} | ||
wg.Wait() | ||
} | ||
|
||
func prepareConfig(l *logrus.Entry) (*config.Storage, string) { | ||
configStorage := config.NewStorage(nil) | ||
configFilepath, err := configStorage.Reload(l) | ||
if err != nil { | ||
l.Fatalf("Failed to load configuration: %s.", err) | ||
} | ||
Comment on lines
+129
to
+132
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we really need to reload right after storage created? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Its inside last func before loop https://github.com/percona/pmm/pull/2410/files#diff-ae8858561a752ed8fb97d610805944a2f0123026d91e30fdbcf8c34b3ae80f5bR62 In loop config is already used so it seems its late as possible. If you have an idea feel free to suggest it. |
||
|
||
return configStorage, configFilepath | ||
} | ||
|
||
func prepareLogger(cfg *config.Config, logStore *tailog.Store, l *logrus.Entry) { | ||
config.ConfigureLogger(cfg) | ||
logStore.Resize(cfg.LogLinesCount) | ||
l.Debugf("Loaded configuration: %+v", cfg) | ||
} | ||
|
||
func cleanupTmp(tmpRoot string, log *logrus.Entry) { | ||
|
@@ -141,3 +154,10 @@ func cleanupTmp(tmpRoot string, log *logrus.Entry) { | |
} | ||
} | ||
} | ||
|
||
func prepareConnectionService(ctx context.Context, cfg *config.Config) *connectionuptime.Service { | ||
connectionUptimeService := connectionuptime.NewService(cfg.WindowConnectedTime) | ||
connectionUptimeService.RunCleanupGoroutine(ctx) | ||
|
||
return connectionUptimeService | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We still need to clean up Tmp directory
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When its cancelled it will hit cleanupTmp there: https://github.com/percona/pmm/pull/2410/files/a370bbfd23a0fa3a8a3103eaeeeaad882d32874b#diff-ae8858561a752ed8fb97d610805944a2f0123026d91e30fdbcf8c34b3ae80f5bR115