-
Notifications
You must be signed in to change notification settings - Fork 326
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
fix: merge error issue 在window下 Merge报错 #578 #584
base: master
Are you sure you want to change the base?
Conversation
@@ -127,3 +130,7 @@ func (bm *BucketManager) GetBucketID(ds Ds, name BucketName) (BucketId, error) { | |||
return bucket.Id, nil | |||
} | |||
} | |||
|
|||
func (bm *BucketManager) close() error { | |||
return bm.fd.Close() |
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.
bucket.Meta
can't be removed when we call os.RemoveAll
on windows because it not closed.
return db.View(func(tx *Tx) error { | ||
return filesystem.CopyDir(db.opt.Dir, dir) | ||
return db.View(func(tx *Tx) (err error) { | ||
err = tx.db.flock.Unlock() |
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.
If we do not do these lines, backup of nutsdb will be blocked on windows. The reason is the files are locked.
return db.View(func(tx *Tx) error { | ||
return tarGZCompress(w, db.opt.Dir) | ||
return db.View(func(tx *Tx) (err error) { | ||
err = tx.db.flock.Unlock() |
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.
Same with above
@@ -188,6 +211,11 @@ func (db *DB) release() error { | |||
return err | |||
} | |||
|
|||
err = db.ActiveFile.Close() |
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.
I think we should release and close ActiveFile
when we release a db.
@@ -392,7 +424,14 @@ func (db *DB) doWrites() { | |||
|
|||
// setActiveFile sets the ActiveFile (DataFile object). | |||
func (db *DB) setActiveFile() (err error) { | |||
activeFilePath := getDataPath(db.MaxFileID, db.opt.Dir) | |||
if db.ActiveFile != nil { |
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.
Same with above. I think we also need close the previous ActiveFile
for { | ||
entry, err := f.readEntry(off) | ||
if err != nil { | ||
// whatever which logic branch it will choose, we will release the fd. | ||
_ = f.release() | ||
// _ = f.release() |
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.
The old release only something wrong. But I think we also release it after iteration.
db.Index.list.delete(bucket) | ||
} | ||
} | ||
// FIXME: it's useful? |
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.
PINNED: It seems that it's not useful and it will prevent the ci
if err := db.ActiveFile.rwManager.Close(); err != nil { | ||
db.mu.Unlock() | ||
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.
Close the current ActiveFile
because we will use a new one.
// FIXME: it's useful? | ||
// func tarDecompress(dst string, src io.Reader) error { | ||
// tarReader := tar.NewReader(src) | ||
|
||
// for { | ||
// header, err := tarReader.Next() | ||
// if err == io.EOF { | ||
// break | ||
// } | ||
// if err != nil { | ||
// return err | ||
// } | ||
|
||
// path := filepath.Join(dst, header.Name) | ||
// info := header.FileInfo() | ||
// if info.IsDir() { | ||
// if err = os.MkdirAll(path, info.Mode()); err != nil { | ||
// return err | ||
// } | ||
// continue | ||
// } | ||
|
||
// file, err := os.OpenFile(filepath.Clean(path), os.O_CREATE|os.O_TRUNC|os.O_WRONLY, info.Mode()) | ||
// if err != nil { | ||
// return err | ||
// } | ||
// defer file.Close() | ||
// _, err = io.Copy(file, tarReader) | ||
// if err != nil { | ||
// return err | ||
// } | ||
// } | ||
|
||
// return nil | ||
// } |
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.
PINNED, same with above
@@ -658,6 +662,7 @@ func (tx *Tx) setStatusRunning() { | |||
tx.status.Store(status) | |||
} | |||
|
|||
// FIXME: it's useful? |
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.
PINNED
@@ -186,11 +186,12 @@ func TestTx_LPop(t *testing.T) { | |||
runNutsDBTest(t, nil, func(t *testing.T, db *DB) { | |||
txCreateBucket(t, db, DataStructureList, bucket, nil) | |||
txPop(t, db, bucket, GetTestBytes(0), nil, ErrListNotFound, true) | |||
|
|||
db.Close() |
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.
On windows, I can run the next case if we don't close db in here. The files will be occupated. Some other unit cases same with here.
This late PR is for fixing #578 .
The superficial reason of this issue is: some places we use
filepath.Clean
and some places not. If we usefilepath.Clean
when we callWithDir
, nutsdb will work good coincidentally.In facts, there're more deeper reasons cause this reason. In one word, we don't close/release each file handler after it's used up. Windows is sensitive for these handlers. Of course, perhaps my understanding is incorrect.
Now I add more
xxx.Close()
for file handlers.Another fact for approve my view above is many unit cases work bad on windows and some cases caused by the above
reason
. Them work good after my fix for file handlers.Something more, for avoid non-standard handling of paths, I add a package named
nutsdbpath
to solve paths.Something Confused Me
I saw that some methods call multiple
runNutsDBTest
and the operation of creating bucket. Now I think we will throw errors if we do it. But there're many unit cases do these things.Advices for
runNutsDBTest
There're some unit cases which call multiple
runNutsDBTest
, but the two calls are not associated. In this scene, it will work bad on windows. Thet.CleanUp
only run when all cases finished, so it may not useful enough.Others
Some important things are mentions by comments in code or PR page. This PR may need a carefully review