oasisprotocol / oasisprotocol/oasis-core
nit: runtime.SetFinalizer as defense in depth for missing Close
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 369
- Forks
- 151
- Avg merge
- 1d 3h
- Merged PRs (30d)
- 6
Description
Description of the bug
It is possible to create database references and forget to invoke Close before letting them become unreachable and we would not notice. Most of our code should be long running and probably never Close except in tests, etc, so this is probably an minor nit.
The NodeDB interface in go/storage/mkvs/urkel/db/api/api.go specifies that databases backing the Urkel tree use an interface that requires a call to Close before dropping the database reference. It is unclear whether the underlying databases already implement runtime.SetFinalizer based resource cleanup -- i.e., flush database buffers, closing file references if they don't use the standard File (which internally uses runtime.SetFinalizer to call (*file).close) -- so it may be a good idea to ensure that a missing Close can be detected reliably, e.g., have Close set a closed flag to enforce at-most-once semantics, and have the finalizer function check the flag to enforce at-least-once semantics, panicking (or some a severe log message) otherwise.
Using runtime.SetFinalizer can be a little tricky, since runtime.KeepAlive will likely also be needed, which may make this add too much complexity to be worth it. (May require wrapping like File and file.) If we decide so, there should be a comment that this was considered and to stress the usage contract re the use of Close.
Steps to reproduce
- Create a
leveldborbadgerbackedNodeDB. - Let it go out of scope without calling
Closeon the object and then explicitly callruntime.GC() - See that there is no error.
Expected behavior
Make it hard to write code that does not follow the Close contract.
Environment
- OS:
- Versions of relevant software and tools:
Additional information
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with go/storage/mkvs/urkel/db/api/api.go and the Close implementation around line 719 of go/storage/mkvs/urkel/db/badger/badger.go. Compare the leveldb and badger NodeDB implementations and investigate the runtime.SetFinalizer and runtime.KeepAlive requirements. Done means deciding whether finalizer-based detection is appropriate and, if so, enforcing the Close contract without unsafe resource handling.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- database
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100