mirror of https://github.com/cloudreve/Cloudreve
feat(audit): flush audit logs into DB in a standalone goroutine
parent
5f18d277c8
commit
bb9b42eb10
|
@ -164,6 +164,14 @@ func (s *server) Start() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *server) Close() {
|
func (s *server) Close() {
|
||||||
|
// Close audit recorder first to ensure all logs are persisted
|
||||||
|
if s.auditRecorder != nil {
|
||||||
|
s.logger.Info("Closing audit recorder...")
|
||||||
|
if err := s.auditRecorder.Close(); err != nil {
|
||||||
|
s.logger.Error("Failed to close audit recorder: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if s.dbClient != nil {
|
if s.dbClient != nil {
|
||||||
s.logger.Info("Shutting down database connection...")
|
s.logger.Info("Shutting down database connection...")
|
||||||
if err := s.dbClient.Close(); err != nil {
|
if err := s.dbClient.Close(); err != nil {
|
||||||
|
|
2
assets
2
assets
|
@ -1 +1 @@
|
||||||
Subproject commit eb2cfac37d73e5bd3000eb66a3a0062509efe122
|
Subproject commit a15906f3fb29710993e2e83835f92e563113aa18
|
|
@ -220,8 +220,29 @@ func (c *userClient) Delete(ctx context.Context, uid int) error {
|
||||||
func (c *userClient) ApplyStorageDiff(ctx context.Context, diffs StorageDiff) error {
|
func (c *userClient) ApplyStorageDiff(ctx context.Context, diffs StorageDiff) error {
|
||||||
ae := serializer.NewAggregateError()
|
ae := serializer.NewAggregateError()
|
||||||
for uid, diff := range diffs {
|
for uid, diff := range diffs {
|
||||||
if err := c.client.User.Update().Where(user.ID(uid)).AddStorage(diff).Exec(ctx); err != nil {
|
// Retry logic for MySQL deadlock (Error 1213)
|
||||||
ae.Add(fmt.Sprintf("%d", uid), fmt.Errorf("failed to apply storage diff for user %d: %w", uid, err))
|
// This is a temporary workaround. TODO: optimize storage mutation
|
||||||
|
maxRetries := 3
|
||||||
|
var lastErr error
|
||||||
|
for attempt := 0; attempt < maxRetries; attempt++ {
|
||||||
|
if err := c.client.User.Update().Where(user.ID(uid)).AddStorage(diff).Exec(ctx); err != nil {
|
||||||
|
lastErr = err
|
||||||
|
// Check if it's a MySQL deadlock error (Error 1213)
|
||||||
|
if strings.Contains(err.Error(), "Error 1213") && attempt < maxRetries-1 {
|
||||||
|
// Wait a bit before retrying with exponential backoff
|
||||||
|
time.Sleep(time.Duration(attempt+1) * 10 * time.Millisecond)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
ae.Add(fmt.Sprintf("%d", uid), fmt.Errorf("failed to apply storage diff for user %d: %w", uid, err))
|
||||||
|
break
|
||||||
|
}
|
||||||
|
// Success, break out of retry loop
|
||||||
|
lastErr = nil
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if lastErr != nil {
|
||||||
|
ae.Add(fmt.Sprintf("%d", uid), fmt.Errorf("failed to apply storage diff for user %d: %w", uid, lastErr))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue