Skip to content
This repository was archived by the owner on Sep 9, 2020. It is now read-only.

Commit 3fd5bb3

Browse files
ayang64sdboyer
authored andcommitted
Disable file locking when DEPNOLOCK set (#1206)
* Disable file locking when DEPNOLOCK set * Add DisableLocking bool members to Ctx and gps.SourceManagerConfig structs. This effectively communicates DEPNOLOCK from the shell, to Ctx, to SourceManager. The member is named DisableLocking to make its zero-value useful. * Add locker interface which implements TryLock(), Unlock(), and GetOwner() which lockfile.Lockfile alredy adheres to. This interface replaces the new type for the lf member of the SourceMgr struct. * Add a FalseLocker type which adheres to the Locker interface which does nothing. * Conditionally set the lf member of SourceMgr to either an instance of lockfile.Lockfile or FalseLocker depending on the value of SourceManagerConfig.DisableLocking. Signed-off-by: Ayan George <[email protected]> * Revert stray edit. Signed-off-by: Ayan George <[email protected]> * Improve comment for DisableLocking Signed-off-by: Ayan George <[email protected]> * Fix comment type-os * Fix comment type-os Signed-off-by: Ayan George <[email protected]> * Fix yet more type-os. Signed-off-by: Ayan George <[email protected]>
1 parent 82b3908 commit 3fd5bb3

File tree

3 files changed

+61
-15
lines changed

3 files changed

+61
-15
lines changed

cmd/dep/main.go

+4-3
Original file line numberDiff line numberDiff line change
@@ -147,9 +147,10 @@ func (c *Config) Run() (exitCode int) {
147147

148148
// Set up dep context.
149149
ctx := &dep.Ctx{
150-
Out: outLogger,
151-
Err: errLogger,
152-
Verbose: *verbose,
150+
Out: outLogger,
151+
Err: errLogger,
152+
Verbose: *verbose,
153+
DisableLocking: getEnv(c.Env, "DEPNOLOCK") != "",
153154
}
154155

155156
GOPATHS := filepath.SplitList(getEnv(c.Env, "GOPATH"))

context.go

+9-7
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,12 @@ import (
3434
// }
3535
//
3636
type Ctx struct {
37-
WorkingDir string // Where to execute.
38-
GOPATH string // Selected Go path, containing WorkingDir.
39-
GOPATHs []string // Other Go paths.
40-
Out, Err *log.Logger // Required loggers.
41-
Verbose bool // Enables more verbose logging.
37+
WorkingDir string // Where to execute.
38+
GOPATH string // Selected Go path, containing WorkingDir.
39+
GOPATHs []string // Other Go paths.
40+
Out, Err *log.Logger // Required loggers.
41+
Verbose bool // Enables more verbose logging.
42+
DisableLocking bool // When set, no lock file will be created to protect against simultaneous dep processes.
4243
}
4344

4445
// SetPaths sets the WorkingDir and GOPATHs fields. If GOPATHs is empty, then
@@ -87,8 +88,9 @@ func defaultGOPATH() string {
8788
// initialized to log to the receiver's logger.
8889
func (c *Ctx) SourceManager() (*gps.SourceMgr, error) {
8990
return gps.NewSourceManager(gps.SourceManagerConfig{
90-
Cachedir: filepath.Join(c.GOPATH, "pkg", "dep"),
91-
Logger: c.Out,
91+
Cachedir: filepath.Join(c.GOPATH, "pkg", "dep"),
92+
Logger: c.Out,
93+
DisableLocking: c.DisableLocking,
9294
})
9395
}
9496

internal/gps/source_manager.go

+48-5
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,41 @@ import (
2828
// Used to compute a friendly filepath from a URL-shaped input.
2929
var sanitizer = strings.NewReplacer("-", "--", ":", "-", "/", "-", "+", "-")
3030

31+
// A locker is responsible for preventing multiple instances of dep from
32+
// interfering with one-another.
33+
//
34+
// Currently, anything that can either TryLock(), Unlock(), or GetOwner()
35+
// satifies that need.
36+
type locker interface {
37+
TryLock() error
38+
Unlock() error
39+
GetOwner() (*os.Process, error)
40+
}
41+
42+
// A falselocker adheres to the locker interface and its purpose is to quietly
43+
// fail to lock when the DEPNOLOCK environment variable is set.
44+
//
45+
// This allows dep to run on systems where file locking doesn't work --
46+
// particularly those that use union mount type filesystems that don't
47+
// implement hard links or fnctl() style locking.
48+
type falseLocker struct{}
49+
50+
// Always returns an error to indicate there's no current ower PID for our
51+
// lock.
52+
func (fl falseLocker) GetOwner() (*os.Process, error) {
53+
return nil, fmt.Errorf("falseLocker always fails")
54+
}
55+
56+
// Does nothing and returns a nil error so caller beleives locking succeeded.
57+
func (fl falseLocker) TryLock() error {
58+
return nil
59+
}
60+
61+
// Does nothing and returns a nil error so caller beleives unlocking succeeded.
62+
func (fl falseLocker) Unlock() error {
63+
return nil
64+
}
65+
3166
// A SourceManager is responsible for retrieving, managing, and interrogating
3267
// source repositories. Its primary purpose is to serve the needs of a Solver,
3368
// but it is handy for other purposes, as well.
@@ -121,7 +156,7 @@ func (p ProjectAnalyzerInfo) String() string {
121156
// tools; control via dependency injection is intended to be sufficient.
122157
type SourceMgr struct {
123158
cachedir string // path to root of cache dir
124-
lf *lockfile.Lockfile // handle for the sm lock file on disk
159+
lf locker // handle for the sm lock file on disk
125160
suprvsr *supervisor // subsystem that supervises running calls/io
126161
cancelAll context.CancelFunc // cancel func to kill all running work
127162
deduceCoord *deductionCoordinator // subsystem that manages import path deduction
@@ -142,8 +177,9 @@ var _ SourceManager = &SourceMgr{}
142177

143178
// SourceManagerConfig holds configuration information for creating SourceMgrs.
144179
type SourceManagerConfig struct {
145-
Cachedir string // Where to store local instances of upstream sources.
146-
Logger *log.Logger // Optional info/warn logger. Discards if nil.
180+
Cachedir string // Where to store local instances of upstream sources.
181+
Logger *log.Logger // Optional info/warn logger. Discards if nil.
182+
DisableLocking bool // True if the SourceManager should NOT use a lock file to protect the Cachedir from multiple processes.
147183
}
148184

149185
// NewSourceManager produces an instance of gps's built-in SourceManager.
@@ -175,7 +211,14 @@ func NewSourceManager(c SourceManagerConfig) (*SourceMgr, error) {
175211
// we can spin on.
176212

177213
glpath := filepath.Join(c.Cachedir, "sm.lock")
178-
lockfile, err := lockfile.New(glpath)
214+
215+
lockfile, err := func() (locker, error) {
216+
if c.DisableLocking {
217+
return falseLocker{}, nil
218+
}
219+
return lockfile.New(glpath)
220+
}()
221+
179222
if err != nil {
180223
return nil, CouldNotCreateLockError{
181224
Path: glpath,
@@ -238,7 +281,7 @@ func NewSourceManager(c SourceManagerConfig) (*SourceMgr, error) {
238281

239282
sm := &SourceMgr{
240283
cachedir: c.Cachedir,
241-
lf: &lockfile,
284+
lf: lockfile,
242285
suprvsr: superv,
243286
cancelAll: cf,
244287
deduceCoord: deducer,

0 commit comments

Comments
 (0)