From ecaf0da2281c355f5873fa674e2ad999f298293f Mon Sep 17 00:00:00 2001 From: John Date: Wed, 2 Dec 2020 21:33:07 +0800 Subject: [PATCH] improve package glog; add more unit testing case for package gmlock --- os/glog/glog_logger.go | 10 +++++-- os/glog/glog_logger_rotate.go | 10 ++++--- os/gmlock/gmlock_unit_lock_test.go | 48 ++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 7 deletions(-) diff --git a/os/glog/glog_logger.go b/os/glog/glog_logger.go index dee2827a6..1b3a8bea7 100644 --- a/os/glog/glog_logger.go +++ b/os/glog/glog_logger.go @@ -243,29 +243,33 @@ func (l *Logger) printToFile(now time.Time, buffer *bytes.Buffer) { defer gmlock.Unlock(memoryLockKey) file := l.getFilePointer(logFilePath) if file == nil { + intlog.Errorf(`got nil file pointer for: %s`, logFilePath) return } + // Please note that it differs from `file.Close()`, + // as the variable `file` would be changed in next logic. + defer func() { + file.Close() + }() // Rotation file size checks. if l.config.RotateSize > 0 { stat, err := file.Stat() if err != nil { - file.Close() // panic(err) intlog.Error(err) return } if stat.Size() > l.config.RotateSize { l.rotateFileBySize(now) + // Refresh file = l.getFilePointer(logFilePath) } } if _, err := file.Write(buffer.Bytes()); err != nil { - file.Close() // panic(err) intlog.Error(err) return } - file.Close() } // getFilePointer retrieves and returns a file pointer from file pool. diff --git a/os/glog/glog_logger_rotate.go b/os/glog/glog_logger_rotate.go index 877aae054..8c5a5b299 100644 --- a/os/glog/glog_logger_rotate.go +++ b/os/glog/glog_logger_rotate.go @@ -25,8 +25,6 @@ func (l *Logger) rotateFileBySize(now time.Time) { if l.config.RotateSize <= 0 { return } - l.rmu.Lock() - defer l.rmu.Unlock() if err := l.doRotateFile(l.getFilePath(now)); err != nil { // panic(err) intlog.Error(err) @@ -35,6 +33,8 @@ func (l *Logger) rotateFileBySize(now time.Time) { // doRotateFile rotates the given logging file. func (l *Logger) doRotateFile(filePath string) error { + l.rmu.Lock() + defer l.rmu.Unlock() // No backups, it then just removes the current logging file. if l.config.RotateBackupLimit == 0 { if err := gfile.Remove(filePath); err != nil { @@ -70,6 +70,8 @@ func (l *Logger) doRotateFile(filePath string) error { ) if !gfile.Exists(newFilePath) { break + } else { + intlog.Printf(`rotation file exists, continue: %s`, newFilePath) } } if err := gfile.Rename(filePath, newFilePath); err != nil { @@ -104,7 +106,7 @@ func (l *Logger) rotateChecksTimely() { ) intlog.Printf("logging rotation start checks: %+v", files) // ============================================================= - // Rotation expire file checks. + // Rotation of expired file checks. // ============================================================= if l.config.RotateExpire > 0 { var ( @@ -170,7 +172,7 @@ func (l *Logger) rotateChecksTimely() { } // ============================================================= - // Backups count limit and expiration checks. + // Backups count limitation and expiration checks. // ============================================================= var ( backupFilesMap = make(map[string]*garray.SortedArray) diff --git a/os/gmlock/gmlock_unit_lock_test.go b/os/gmlock/gmlock_unit_lock_test.go index afb60d91c..eba02d936 100644 --- a/os/gmlock/gmlock_unit_lock_test.go +++ b/os/gmlock/gmlock_unit_lock_test.go @@ -7,6 +7,7 @@ package gmlock_test import ( + "sync" "testing" "time" @@ -155,3 +156,50 @@ func Test_Locker_TryLockFunc(t *testing.T) { t.Assert(array.Len(), 2) }) } + +func Test_Multiple_Goroutine(t *testing.T) { + gtest.C(t, func(t *gtest.T) { + ch := make(chan struct{}, 0) + num := 1000 + wait := sync.WaitGroup{} + wait.Add(num) + for i := 0; i < num; i++ { + go func() { + defer wait.Done() + <-ch + gmlock.Lock("test") + defer gmlock.Unlock("test") + time.Sleep(time.Millisecond) + }() + } + close(ch) + wait.Wait() + }) + + gtest.C(t, func(t *gtest.T) { + ch := make(chan struct{}, 0) + num := 100 + wait := sync.WaitGroup{} + wait.Add(num * 2) + for i := 0; i < num; i++ { + go func() { + defer wait.Done() + <-ch + gmlock.Lock("test") + defer gmlock.Unlock("test") + time.Sleep(time.Millisecond) + }() + } + for i := 0; i < num; i++ { + go func() { + defer wait.Done() + <-ch + gmlock.RLock("test") + defer gmlock.RUnlock("test") + time.Sleep(time.Millisecond) + }() + } + close(ch) + wait.Wait() + }) +}