-
Notifications
You must be signed in to change notification settings - Fork 1
Enhance logging, error handling, and resource management #381
Changes from all commits
1cbf089
7ce913f
274e185
e633468
12a5968
9ee2ddf
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 |
|---|---|---|
|
|
@@ -3,7 +3,6 @@ package main | |
| import ( | ||
| "context" | ||
| "flag" | ||
| "log/slog" | ||
| "os" | ||
| "time" | ||
|
|
||
|
|
@@ -20,37 +19,42 @@ import ( | |
| ) | ||
|
|
||
| func main() { | ||
| start := time.Now() | ||
|
|
||
| var isDev bool | ||
| flag.BoolVar(&isDev, "dev", false, "--dev") | ||
|
|
||
| var debug bool | ||
| flag.BoolVar(&debug, "debug", false, "--debug") | ||
|
|
||
| flag.Parse() | ||
|
|
||
| logger, err := logging.New(&logging.Options{Name: "accounts", Dev: isDev}) | ||
| if err != nil { | ||
| panic(err) | ||
| if isDev { | ||
| debug = true | ||
| } | ||
|
|
||
| logger := logging.NewSlogLogger(logging.SlogOptions{ | ||
|
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. issue (complexity): Consider consolidating logger initialization to reduce code duplication and complexity. The changes introduce useful new functionality, but the logger initialization process has become overly complex. We suggest unifying the logger creation to reduce duplication while maintaining the new debugging options. Here's a proposed simplification: func main() {
start := time.Now()
var isDev, debug bool
flag.BoolVar(&isDev, "dev", false, "--dev")
flag.BoolVar(&debug, "debug", false, "--debug")
flag.Parse()
if isDev {
debug = true
}
logger, err := logging.New(&logging.Options{
Name: "accounts-api",
Dev: isDev,
ShowDebugLog: debug,
SlogOptions: logging.SlogOptions{
ShowCaller: true,
ShowDebugLogs: debug,
SetAsDefaultLogger: true,
},
})
if err != nil {
panic(err)
}
app := fx.New(
fx.NopLogger,
fx.Supply(logger),
// ... rest of the providers
)
// ... rest of the main function
}This approach:
These changes reduce complexity while preserving the new features, making the code more maintainable and easier to understand. |
||
| ShowCaller: true, | ||
| ShowDebugLogs: debug, | ||
| SetAsDefaultLogger: true, | ||
| }) | ||
|
|
||
| app := fx.New( | ||
| fx.NopLogger, | ||
|
|
||
| fx.Provide(func() logging.Logger { | ||
| return logger | ||
| fx.Provide(func() (logging.Logger, error) { | ||
| return logging.New(&logging.Options{Name: "accounts-api", Dev: isDev, ShowDebugLog: debug}) | ||
| }), | ||
|
|
||
| fx.Provide(func() *slog.Logger { | ||
| return logging.NewSlogLogger(logging.SlogOptions{ | ||
| ShowCaller: true, | ||
| ShowDebugLogs: isDev, | ||
| SetAsDefaultLogger: true, | ||
| }) | ||
| }), | ||
| fx.Supply(logger), | ||
|
|
||
| fx.Provide(func() (*env.Env, error) { | ||
| if e, err := env.LoadEnv(); err != nil { | ||
| e, err := env.LoadEnv() | ||
| if err != nil { | ||
| return nil, errors.NewE(err) | ||
| } else { | ||
| e.IsDev = isDev | ||
| return e, nil | ||
| } | ||
| e.IsDev = isDev | ||
| return e, nil | ||
| }), | ||
|
|
||
| fx.Provide(func(e *env.Env) (*rest.Config, error) { | ||
|
|
@@ -79,10 +83,10 @@ func main() { | |
| defer cancelFunc() | ||
|
|
||
| if err := app.Start(ctx); err != nil { | ||
| logger.Errorf(err, "error starting accounts app") | ||
| logger.Error("failed to start accounts api, got", "err", err) | ||
| os.Exit(1) | ||
| } | ||
|
|
||
| common.PrintReadyBanner() | ||
| common.PrintReadyBanner2(time.Since(start)) | ||
| <-app.Done() | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -666,13 +666,17 @@ func (d *domain) OnEnvironmentDeleteMessage(ctx ConsoleContext, env entities.Env | |
| return errors.NewE(err) | ||
| } | ||
|
|
||
| if err := d.environmentRepo.DeleteOne( | ||
| ctx, | ||
| repos.Filter{ | ||
| fields.AccountName: ctx.AccountName, | ||
| fields.MetadataName: env.Name, | ||
| }, | ||
| ); err != nil { | ||
| if err := d.environmentRepo.DeleteOne(ctx, repos.Filter{ | ||
| fields.AccountName: ctx.AccountName, | ||
| fields.MetadataName: env.Name, | ||
| }); err != nil { | ||
| return errors.NewE(err) | ||
| } | ||
|
|
||
| if err := d.resourceMappingRepo.DeleteMany(ctx, repos.Filter{ | ||
|
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. suggestion: Consider handling partial failure scenarios The addition of resource mapping deletion is good for data integrity. However, consider wrapping this operation along with the environment deletion in a transaction, or implement a rollback mechanism to handle scenarios where one operation succeeds and the other fails. |
||
| fc.ResourceMappingResourceHeirarchy: entities.ResourceHeirarchyEnvironment, | ||
| fc.EnvironmentName: env.Name, | ||
| }); err != nil { | ||
| return errors.NewE(err) | ||
| } | ||
|
|
||
|
|
@@ -701,16 +705,9 @@ func (d *domain) OnEnvironmentUpdateMessage(ctx ConsoleContext, env entities.Env | |
| return d.resyncK8sResource(ctx, xenv.Name, xenv.SyncStatus.Action, &xenv.Environment, xenv.RecordVersion) | ||
| } | ||
|
|
||
| uenv, err := d.environmentRepo.PatchById( | ||
| ctx, | ||
| xenv.Id, | ||
| common.PatchForSyncFromAgent( | ||
| &env, | ||
| recordVersion, | ||
| status, | ||
| common.PatchOpts{ | ||
| MessageTimestamp: opts.MessageTimestamp, | ||
| })) | ||
| uenv, err := d.environmentRepo.PatchById(ctx, xenv.Id, common.PatchForSyncFromAgent( | ||
| &env, recordVersion, status, common.PatchOpts{MessageTimestamp: opts.MessageTimestamp}), | ||
| ) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
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.
suggestion: Consider potential inconsistency in invitation acceptance process
The change to delete the invitation after acceptance is good for database cleanliness. However, consider the order of operations and potential failure scenarios. If the system crashes after adding the membership but before deleting the invitation, it could lead to an inconsistent state. Consider using a transactional approach if possible, or implement a mechanism to handle such edge cases.