Skip to content

Commit 6898178

Browse files
committed
design: add proposal doc for 33974
Updates golang/go#33974
1 parent 08b63ce commit 6898178

File tree

1 file changed

+139
-0
lines changed

1 file changed

+139
-0
lines changed
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
# Proposal: make the internal [lockedfile](https://godoc.org/github.com/golang/go/src/cmd/go/internal/lockedfile/) package public
2+
3+
Author(s): [Adrien Delorme]
4+
5+
Last updated: 2019-10-15
6+
7+
Discussion at https://golang.org/issue/33974.
8+
9+
## Abstract
10+
11+
Move already existing code residing golang/go/src/cmd/go/internal/lockedfile to
12+
`x/exp`. At `x/exp/lockedfile`.
13+
14+
## Background
15+
16+
A few Golang open source projects are implementing file locking mechanisms
17+
( https://github.com/gofrs/flock, https://github.com/MichaelS11/go-file-lock,
18+
https://github.com/juju/fslock ) but they do not seem to be maintained anymore,
19+
issues are ignored and they seem untrusted.
20+
As a result some major projects are doing their own version of it; ex:
21+
[terraform](https://github.com/hashicorp/terraform/blob/1ff9a540202b8c36e33db950374bbb4495737d8f/states/statemgr/filesystem_lock_unix.go),
22+
[boltdb](https://github.com/boltdb/bolt/search?q=flock&unscoped_q=flock).
23+
After some researches it seemed to us that the already existing and maintained
24+
[lockedfile](https://godoc.org/github.com/golang/go/src/cmd/go/internal/lockedfile/)
25+
package is the best 'open source' version.
26+
27+
File locking seems complicated and low level enough to be more closely
28+
maintained by the go community ( and/or team ? ).
29+
We think it would benefit the mass to make such a package public: since it's
30+
already being part of the go code and therefore being maintained; it should be
31+
made public.
32+
33+
## Proposal
34+
35+
We propose to copy the golang/go/src/cmd/go/internal/lockedfile to `x/exp`. To
36+
make it public. Not changing any of the named types for now.
37+
38+
Exported names:
39+
40+
```
41+
// Package lockedfile creates and manipulates files whose contents should only
42+
// change atomically.
43+
package lockedfile
44+
45+
//Read opens the named file with a read-lock and returns its contents.
46+
func Read(name string) ([]byte, error)
47+
48+
// Write opens the named file (creating it with the given permissions if
49+
// needed), then write-locks it and overwrites it with the given content.
50+
func Write(name string, content io.Reader, perm os.FileMode) (err error)
51+
52+
// A File is a locked *os.File.
53+
//
54+
// Closing the file releases the lock.
55+
//
56+
// If the program exits while a file is locked, the operating system releases
57+
// the lock but may not do so promptly: callers must ensure that all locked
58+
// files are closed before exiting.
59+
type File struct {
60+
// contains filtered or unexported fields
61+
}
62+
63+
// Create is like os.Create, but returns a write-locked file.
64+
* func Create(name string) (*File, error)
65+
66+
// Edit creates the named file with mode 0666 (before umask),
67+
// but does not truncate existing contents.
68+
//
69+
// If Edit succeeds, methods on the returned File can be used for I/O.
70+
// The associated file descriptor has mode O_RDWR and the file is write-locked.
71+
* func Edit(name string) (*File, error)
72+
73+
// Open is like os.Open, but returns a read-locked file.
74+
* func Open(name string) (*File, error)
75+
76+
// OpenFile is like os.OpenFile, but returns a locked file.
77+
// If flag includes os.O_WRONLY or os.O_RDWR, the file is write-locked;
78+
// otherwise, it is read-locked.
79+
* func OpenFile(name string, flag int, perm os.FileMode) (*File, error)
80+
81+
// Close unlocks and closes the underlying file.
82+
//
83+
// Close may be called multiple times; all calls after the first will return a
84+
// non-nil error.
85+
* func (f *File) Close() error
86+
87+
// A Mutex provides mutual exclusion within and across processes by locking a
88+
// well-known file. Such a file generally guards some other part of the
89+
// filesystem: for example, a Mutex file in a directory might guard access to
90+
// the entire tree rooted in that directory.
91+
//
92+
// Mutex does not implement sync.Locker: unlike a sync.Mutex, a lockedfile.Mutex
93+
// can fail to lock (e.g. if there is a permission error in the filesystem).
94+
//
95+
// Like a sync.Mutex, a Mutex may be included as a field of a larger struct but
96+
// must not be copied after first use. The Path field must be set before first
97+
// use and must not be change thereafter.
98+
type Mutex struct {
99+
Path string // The path to the well-known lock file. Must be non-empty.
100+
// contains filtered or unexported fields
101+
}
102+
103+
// MutexAt returns a new Mutex with Path set to the given non-empty path.
104+
* func MutexAt(path string) *Mutex
105+
106+
// Lock attempts to lock the Mutex.
107+
//
108+
// If successful, Lock returns a non-nil unlock function: it is provided as a
109+
// return-value instead of a separate method to remind the caller to check the
110+
// accompanying error. (See https://golang.org/issue/20803.)
111+
* func (mu *Mutex) Lock() (unlock func(), err error)
112+
113+
// String returns a string containing the path of the mutex.
114+
* func (mu *Mutex) String() string
115+
```
116+
117+
## Rationale
118+
119+
The golang/go/src/cmd/go/internal/lockedfile already exists but has untrusted &
120+
unmaintained alternatives.
121+
122+
* Making this package public will make it more used. A tiny surge of issues
123+
might come in the beginning; at the benefits of everyone. ( Unless it's
124+
bug free !! ).
125+
126+
* There exists a https://godoc.org/github.com/rogpeppe/go-internal package that
127+
exports a lot of internal packages from the go repo. But if go-internal
128+
became wildly popular; in order to have a bug fixed or a feature introduced
129+
in; a user would still need to open a PR on the go repo; then the author of
130+
go-internal would need to update the package.
131+
132+
## Compatibility
133+
134+
There are no compatibility issues. Since this will be a code addition.
135+
136+
## Implementation
137+
138+
Adrien Delorme plans to do copy the internal/lockedfile package from cmd/go to
139+
`x/exp`.

0 commit comments

Comments
 (0)