Skip to content

Commit 21941e1

Browse files
expand and cleanup
1 parent 08b7380 commit 21941e1

File tree

6 files changed

+251
-17
lines changed

6 files changed

+251
-17
lines changed

.gitignore

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
*.swp
2+
*.out
3+
*.coverprofile
4+
*.test
5+
*.orig
6+
*~

.travis.yml

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
sudo: false
2+
3+
4+
language: go
5+
go:
6+
- 'tip'
7+
8+
install:
9+
- go get github.com/whyrusleeping/gx
10+
- go get github.com/whyrusleeping/gx-go
11+
- gx install --global
12+
script:
13+
- gx test -v -race -coverprofile=coverage.txt -covermode=atomic .
14+
15+
after_success:
16+
- bash <(curl -s https://codecov.io/bash)
17+
18+
cache:
19+
directories:
20+
- $GOPATH/src/gx
21+
22+
notifications:
23+
email: false
24+

README.md

+70-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,71 @@
11
# go-fs-lock
2-
Filesystem based locking
2+
3+
[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io)
4+
[![](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](http://ipfs.io/)
5+
[![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23ipfs)
6+
[![](https://img.shields.io/badge/readme%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme)
7+
[![GoDoc](https://godoc.org/github.com/ipfs/go-fs-lock?status.svg)](https://godoc.org/github.com/ipfs/go-fs-lock)
8+
[![Coverage Status](https://coveralls.io/repos/github/ipfs/go-fs-lock/badge.svg?branch=master)](https://coveralls.io/github/ipfs/go-fs-lock?branch=master)
9+
[![Travis CI](https://travis-ci.org/ipfs/go-fs-lock.svg?branch=master)](https://travis-ci.org/ipfs/go-fs-lock)
10+
11+
> Filesystem based locking
12+
13+
This is an implementation in Go of the [CID spec](https://github.com/ipld/cid).
14+
It is used in `go-ipfs` and related packages to refer to a typed hunk of data.
15+
16+
17+
## Table of Contents
18+
19+
- [Install](#install)
20+
- [Usage](#usage)
21+
- [API](#api)
22+
- [Contribute](#contribute)
23+
- [License](#license)
24+
25+
## Install
26+
27+
`go-fs-lock` is a standard Go module which can be installed with:
28+
29+
```sh
30+
go get github.com/ipfs/go-fs-lock
31+
```
32+
33+
Note that `go-fs-lock` is packaged with Gx, so it is recommended to use Gx to install and use it (see Usage section).
34+
35+
## Usage
36+
37+
### Using Gx and Gx-go
38+
39+
This module is packaged with [Gx](https://github.com/whyrusleeping/gx). In order to use it in your own project it is recommended that you:
40+
41+
```sh
42+
go get -u github.com/whyrusleeping/gx
43+
go get -u github.com/whyrusleeping/gx-go
44+
cd <your-project-repository>
45+
gx init
46+
gx import github.com/ipfs/go-fs-lock
47+
gx install --global
48+
gx-go --rewrite
49+
```
50+
51+
Please check [Gx](https://github.com/whyrusleeping/gx) and [Gx-go](https://github.com/whyrusleeping/gx-go) documentation for more information.
52+
53+
### Running tests
54+
55+
Before running tests, please run:
56+
57+
```sh
58+
make deps
59+
```
60+
61+
This will make sure that dependencies are rewritten to known working versions.
62+
63+
## Contribute
64+
65+
PRs are welcome!
66+
67+
Small note: If editing the Readme, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification.
68+
69+
## License
70+
71+
MIT © Protocol Labs, Inc.

main.go

+20-16
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package lock
1+
package fslock
22

33
import (
44
"fmt"
@@ -8,40 +8,44 @@ import (
88
"strings"
99
"syscall"
1010

11-
"gx/ipfs/QmNiJuT8Ja3hMVpBHXv3Q6dwmperaQ6JjLtpMQgMCD7xvx/go-ipfs-util"
12-
logging "gx/ipfs/QmSpJByNKFX1sCsHBEp3R73FL4NF6FnQTEGyNAXHm2GS52/go-log"
13-
lock "gx/ipfs/QmWi28zbQG6B1xfaaWx5cYoLn3kBFU6pQ6GWQNRV5P6dNe/lock"
11+
"github.com/ipfs/go-ipfs-util"
12+
logging "github.com/ipfs/go-log"
13+
lock "go4.org/lock"
1414
)
1515

16-
// LockFile is the filename of the repo lock, relative to config dir
17-
// TODO rename repo lock and hide name
18-
const LockFile = "repo.lock"
19-
2016
// log is the fsrepo logger
2117
var log = logging.Logger("lock")
2218

2319
func errPerm(path string) error {
2420
return fmt.Errorf("failed to take lock at %s: permission denied", path)
2521
}
2622

27-
func Lock(confdir string) (io.Closer, error) {
28-
return lock.Lock(path.Join(confdir, LockFile))
23+
// Lock creates the lock.
24+
func Lock(confdir, lockFile string) (io.Closer, error) {
25+
return lock.Lock(path.Join(confdir, lockFile))
2926
}
3027

31-
func Locked(confdir string) (bool, error) {
28+
// Locked checks if there is a lock already set.
29+
func Locked(confdir, lockFile string) (bool, error) {
3230
log.Debugf("Checking lock")
33-
if !util.FileExists(path.Join(confdir, LockFile)) {
34-
log.Debugf("File doesn't exist: %s", path.Join(confdir, LockFile))
31+
if !util.FileExists(path.Join(confdir, lockFile)) {
32+
log.Debugf("File doesn't exist: %s", path.Join(confdir, lockFile))
3533
return false, nil
3634
}
37-
if lk, err := Lock(confdir); err != nil {
35+
if lk, err := Lock(confdir, lockFile); err != nil {
3836
// EAGAIN == someone else has the lock
3937
if err == syscall.EAGAIN {
40-
log.Debugf("Someone else has the lock: %s", path.Join(confdir, LockFile))
38+
log.Debugf("Someone else has the lock: %s", path.Join(confdir, lockFile))
4139
return true, nil
4240
}
4341
if strings.Contains(err.Error(), "resource temporarily unavailable") {
44-
log.Debugf("Can't lock file: %s.\n reason: %s", path.Join(confdir, LockFile), err.Error())
42+
log.Debugf("Can't lock file: %s.\n reason: %s", path.Join(confdir, lockFile), err.Error())
43+
return true, nil
44+
}
45+
46+
// we hold the lock ourselves
47+
if strings.Contains(err.Error(), "already locked") {
48+
log.Debugf("Lock is already held by us: %s", path.Join(confdir, lockFile))
4549
return true, nil
4650
}
4751

main_test.go

+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package fslock_test
2+
3+
import (
4+
"os"
5+
"path"
6+
"testing"
7+
8+
lock "github.com/ipfs/go-fs-lock"
9+
)
10+
11+
func assertLock(t *testing.T, confdir, lockFile string, expected bool) {
12+
t.Helper()
13+
14+
isLocked, err := lock.Locked(confdir, lockFile)
15+
if err != nil {
16+
t.Fatal(err)
17+
}
18+
19+
if isLocked != expected {
20+
t.Fatalf("expected %t to be %t", isLocked, expected)
21+
}
22+
}
23+
24+
func TestLock_Simple(t *testing.T) {
25+
lockFile := "my-test.lock"
26+
confdir := os.TempDir()
27+
28+
// make sure we start clean
29+
_ = os.Remove(path.Join(confdir, lockFile))
30+
31+
assertLock(t, confdir, lockFile, false)
32+
33+
lockfile, err := lock.Lock(confdir, lockFile)
34+
if err != nil {
35+
t.Fatal(err)
36+
}
37+
38+
assertLock(t, confdir, lockFile, true)
39+
40+
if err := lockfile.Close(); err != nil {
41+
t.Fatal(err)
42+
}
43+
44+
assertLock(t, confdir, lockFile, false)
45+
46+
// second round of locking
47+
48+
lockfile, err = lock.Lock(confdir, lockFile)
49+
if err != nil {
50+
t.Fatal(err)
51+
}
52+
53+
assertLock(t, confdir, lockFile, true)
54+
55+
if err := lockfile.Close(); err != nil {
56+
t.Fatal(err)
57+
}
58+
59+
assertLock(t, confdir, lockFile, false)
60+
}
61+
62+
func TestLock_Multiple(t *testing.T) {
63+
lockFile1 := "test-1.lock"
64+
lockFile2 := "test-2.lock"
65+
confdir := os.TempDir()
66+
67+
// make sure we start clean
68+
_ = os.Remove(path.Join(confdir, lockFile1))
69+
_ = os.Remove(path.Join(confdir, lockFile2))
70+
71+
lock1, err := lock.Lock(confdir, lockFile1)
72+
if err != nil {
73+
t.Fatal(err)
74+
}
75+
lock2, err := lock.Lock(confdir, lockFile2)
76+
if err != nil {
77+
t.Fatal(err)
78+
}
79+
80+
assertLock(t, confdir, lockFile1, true)
81+
assertLock(t, confdir, lockFile2, true)
82+
83+
if err := lock1.Close(); err != nil {
84+
t.Fatal(err)
85+
}
86+
87+
assertLock(t, confdir, lockFile1, false)
88+
assertLock(t, confdir, lockFile2, true)
89+
90+
if err := lock2.Close(); err != nil {
91+
t.Fatal(err)
92+
}
93+
94+
assertLock(t, confdir, lockFile1, false)
95+
assertLock(t, confdir, lockFile2, false)
96+
}

package.json

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{
2+
"author": "dignifiedquire",
3+
"bugs": {
4+
"url": "https://github.com/ipfs/go-fs-lock/issues"
5+
},
6+
"gx": {
7+
"dvcsimport": "github.com/ipfs/go-fs-lock"
8+
},
9+
"gxDependencies": [
10+
{
11+
"author": "whyrusleeping",
12+
"hash": "QmNiJuT8Ja3hMVpBHXv3Q6dwmperaQ6JjLtpMQgMCD7xvx",
13+
"name": "go-ipfs-util",
14+
"version": "1.2.7"
15+
},
16+
{
17+
"hash": "QmSpJByNKFX1sCsHBEp3R73FL4NF6FnQTEGyNAXHm2GS52",
18+
"name": "go-log",
19+
"version": "1.2.0"
20+
},
21+
{
22+
"author": "whyrusleeping",
23+
"hash": "QmWi28zbQG6B1xfaaWx5cYoLn3kBFU6pQ6GWQNRV5P6dNe",
24+
"name": "lock",
25+
"version": "0.0.0"
26+
}
27+
],
28+
"gxVersion": "0.12.1",
29+
"language": "go",
30+
"license": "MIT",
31+
"name": "go-fs-lock",
32+
"releaseCmd": "git commit -a -m \"gx publish $VERSION\"",
33+
"version": "0.0.0"
34+
}
35+

0 commit comments

Comments
 (0)