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

Commit be5b31c

Browse files
committed
Merge branch 'master' of https://github.com/gluster/glusterd2 into user_guide
2 parents 0138559 + 05a2531 commit be5b31c

27 files changed

Lines changed: 348 additions & 181 deletions

File tree

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,4 @@ VERSION
2222
endpoints.json
2323
generate-doc
2424
# Ignore vi backup files
25-
*~
25+
*~

doc/coding.md

Lines changed: 65 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,15 @@
22

33
Please follow coding conventions and guidelines described in the following documents:
44

5+
* [Go proverbs](https://go-proverbs.github.io/) - highly recommended read
56
* [CodeReviewComments](https://github.com/golang/go/wiki/CodeReviewComments)
67
* [Effective Go](https://golang.org/doc/effective_go.html)
8+
* [How to Write a Git Commit Message](https://chris.beams.io/posts/git-commit/)
79

8-
### Some more conventions
10+
Here's a list of some more specific conventions that are often followed in
11+
the code and will be pointed out in the review process:
912

10-
**General:**
13+
### General
1114
* Keep variable names short for variables that are local to the function.
1215
* Do not export a function or variable name outside the package until you
1316
have an external consumer for it.
@@ -16,7 +19,7 @@ Please follow coding conventions and guidelines described in the following docum
1619
* Do not use named return values in function definitions. Use only the type.
1720
Exception: defer()'d functions.
1821

19-
**Imports:**
22+
### Imports
2023

2124
We use the following convention for specifying imports:
2225

@@ -48,22 +51,22 @@ import (
4851
)
4952
```
5053

51-
**Error Handling:**
54+
### Error Handling
5255

5356
* Use variable name `err` to denote error variable during a function call.
5457
* Reuse the previously declared `err` variable as long as it is in scope.
5558
For example, do not use `errWrite` or `errRead`.
56-
* Do not panic().
59+
* Do not panic() for errors that can be bubbled up back to user. Use panic()
60+
only for fatal errors which shouldn't occur.
5761
* Do not ignore errors using `_` variable unless you know what you're doing.
5862
* Error strings should not start with a capital letter.
5963
* If error requires passing of extra information, you can define a new type
60-
* Error types should end in `Error` and error variables should have `Err` as
61-
prefix.
64+
* Error types should end with `Error`.
6265

63-
**Logging:**
66+
### Logging
6467

6568
* If a function is only invoked as part of a transaction step, always use the
66-
transaction's logger.
69+
transaction's logger to ensure propagation of request ID and transaction ID.
6770
* The inner-most utility functions should never log. Logging must almost always
6871
be done by the caller on receiving an `error`.
6972
* Always use log level `DEBUG` to provide useful **diagnostic information** to
@@ -75,3 +78,56 @@ import (
7578
or retry for it and/or is fully recoverable.
7679
* Use log level `ERROR` when something occurs which is fatal to the operation,
7780
but not to the service or application.
81+
82+
### Use of goto
83+
84+
Use of `goto` is generally frowned up on in higher level languages. We use
85+
`goto` statements for the following specific uses:
86+
* Ensure RPCs always return a reply to caller
87+
* Getting out of nested loops
88+
* Auto-generated code
89+
90+
Please use `defer()` for ensuring that relevant resource cleanups happen when a
91+
function/method exits. Also use `defer()` to revert something on a later
92+
failure.
93+
94+
Developers with significant experience in C should be careful not to
95+
excessively use `goto` just to ensure single exit point to a function. Unlike
96+
C programs, there is no memory to be free()d here. Care must be taken when one
97+
ports code from glusterd1 (c) to glusterd2 (go).
98+
99+
### glusterd2 specific conventions
100+
101+
**Do not log at the caller of `txn.*` methods:**
102+
103+
Certain patterns repeat very often in codebase. For reducing clutter, we have
104+
moved some of the logging at the caller to inside the function. One such
105+
instance are the methods of `transaction.Context` interface, which are used at
106+
so many places. They log internally and caller shouldn't be logging. For
107+
example:
108+
109+
```go
110+
if err := txn.Ctx.Set("req", &req); err != nil {
111+
// do NOT log here
112+
restutils.SendHTTPError(ctx, w, http.StatusInternalServerError, err)
113+
return
114+
}
115+
```
116+
117+
**Use log.WithError() to log errors**
118+
119+
It is common pattern to log the error received as a field in the log entry.
120+
Please use `WithError` for the same:
121+
122+
Do this:
123+
```go
124+
log.WithError(err).WithField("path", path).Error("Failed to delete path")
125+
```
126+
127+
Do NOT do this:
128+
```go
129+
log.WithFields(log.Fields{
130+
"error": err,
131+
"path": path,
132+
}).Error("Failed to delete path")
133+
```

doc/endpoints.md

Lines changed: 38 additions & 38 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

glustercli/cmd/common.go

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,26 @@ func handleGlusterdConnectFailure(msg, endpoints string, err error, errcode int)
4949
}
5050

5151
func failure(msg string, err error, errcode int) {
52+
5253
handleGlusterdConnectFailure(msg, flagEndpoints[0], err, errcode)
5354

54-
// If different error
55-
os.Stderr.WriteString(msg + "\n")
55+
w := os.Stderr
56+
57+
w.WriteString(msg + "\n")
58+
5659
if err != nil {
57-
os.Stderr.WriteString("\nError: " + err.Error() + "\n")
60+
resp := client.LastErrorResponse()
61+
62+
w.WriteString("\nResponse headers:\n")
63+
for k, v := range resp.Header {
64+
if strings.HasSuffix(k, "-Id") {
65+
w.WriteString(fmt.Sprintf("%s: %s\n", k, v[0]))
66+
}
67+
}
68+
69+
w.WriteString("\nResponse body:\n")
70+
w.WriteString(fmt.Sprintf("%s\n", err.Error()))
5871
}
72+
5973
os.Exit(errcode)
6074
}

glusterd2/commands/volumes/volume-list.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ func volumeListHandler(w http.ResponseWriter, r *http.Request) {
2424
volumes, err := volume.GetVolumes(filterParams)
2525
if err != nil {
2626
restutils.SendHTTPError(ctx, w, http.StatusInternalServerError, err)
27+
return
2728
}
2829
resp := createVolumeListResp(volumes)
2930
restutils.SendHTTPResponse(ctx, w, http.StatusOK, resp)

glusterd2/commands/volumes/volume-start.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package volumecommands
22

33
import (
4+
"io"
45
"net/http"
56

67
"github.com/gluster/glusterd2/glusterd2/events"
@@ -76,7 +77,8 @@ func volumeStartHandler(w http.ResponseWriter, r *http.Request) {
7677
volname := mux.Vars(r)["volname"]
7778
var req api.VolumeStartReq
7879

79-
if err := restutils.UnmarshalRequest(r, &req); err != nil {
80+
// request body is optional
81+
if err := restutils.UnmarshalRequest(r, &req); err != nil && err != io.EOF {
8082
restutils.SendHTTPError(ctx, w, http.StatusBadRequest, err)
8183
return
8284
}

glusterd2/events/liveness.go

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package events
22

33
import (
4+
"errors"
45
"strings"
56
"sync"
67

@@ -26,7 +27,6 @@ var lWatcher *livenessWatcher
2627
// broadcasts this information locally.
2728
func (l *livenessWatcher) Watch() {
2829
defer l.wg.Done()
29-
3030
wch := store.Store.Watch(store.Store.Ctx(), store.LivenessKeyPrefix,
3131
clientv3.WithPrefix(), clientv3.WithKeysOnly())
3232
for {
@@ -65,15 +65,28 @@ func (l *livenessWatcher) Watch() {
6565
}
6666
}
6767

68+
//Stop will stop the livenessWatcher if it is running and waits for
69+
//it to exit.
70+
func (l *livenessWatcher) Stop() error {
71+
if l.stopCh == nil {
72+
return errors.New("livness watcher has not been started")
73+
}
74+
close(l.stopCh)
75+
l.stopCh = nil
76+
l.wg.Wait()
77+
return nil
78+
}
79+
6880
func startLivenessWatcher() {
6981
lWatcher = &livenessWatcher{
70-
stopCh: make(chan struct{}, 0),
82+
stopCh: make(chan struct{}),
7183
}
7284
lWatcher.wg.Add(1)
7385
go lWatcher.Watch()
7486
}
7587

7688
func stopLivenessWatcher() {
77-
close(lWatcher.stopCh)
78-
lWatcher.wg.Wait()
89+
if err := lWatcher.Stop(); err != nil {
90+
log.WithError(err).Errorf("got error in stopping liveness watcher")
91+
}
7992
}

glusterd2/volume/volume-utils.go

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ func GetBrickMountInfo(mountRoot string) (*Mntent, error) {
162162

163163
}
164164

165-
//CreateSubvolInfo parses subvol information for response
165+
//CreateSubvolInfo parses subvol information for response
166166
func CreateSubvolInfo(sv *[]Subvol) []api.Subvol {
167167
var subvols []api.Subvol
168168

@@ -173,20 +173,21 @@ func CreateSubvolInfo(sv *[]Subvol) []api.Subvol {
173173
}
174174

175175
subvols = append(subvols, api.Subvol{
176-
Name: subvol.Name,
177-
Type: api.SubvolType(subvol.Type),
178-
Bricks: blist,
179-
ReplicaCount: subvol.ReplicaCount,
180-
ArbiterCount: subvol.ArbiterCount,
176+
Name: subvol.Name,
177+
Type: api.SubvolType(subvol.Type),
178+
Bricks: blist,
179+
ReplicaCount: subvol.ReplicaCount,
180+
ArbiterCount: subvol.ArbiterCount,
181+
DisperseCount: subvol.DisperseCount,
181182
})
182183
}
183184
return subvols
184185
}
185186

186-
//CreateVolumeInfoResp parses volume information for response
187+
//CreateVolumeInfoResp parses volume information for response
187188
func CreateVolumeInfoResp(v *Volinfo) *api.VolumeInfo {
188189

189-
return &api.VolumeInfo{
190+
resp := &api.VolumeInfo{
190191
ID: v.ID,
191192
Name: v.Name,
192193
Type: api.VolType(v.Type),
@@ -198,4 +199,13 @@ func CreateVolumeInfoResp(v *Volinfo) *api.VolumeInfo {
198199
Metadata: v.Metadata,
199200
SnapList: v.SnapList,
200201
}
202+
203+
// for common use cases, replica count of the volume is usually the
204+
// replica count of any one of the subvols and we take replica count
205+
// from the first subvol
206+
resp.ReplicaCount = resp.Subvols[0].ReplicaCount
207+
resp.ArbiterCount = resp.Subvols[0].ArbiterCount
208+
resp.DisperseCount = resp.Subvols[0].DisperseCount
209+
210+
return resp
201211
}

pkg/api/volume_resp.go

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,13 @@ type BrickInfo struct {
1616

1717
// Subvol contains static information about sub volume
1818
type Subvol struct {
19-
Name string `json:"name"`
20-
Type SubvolType `json:"type"`
21-
Bricks []BrickInfo `json:"bricks"`
22-
Subvols []Subvol `json:"subvols,omitempty"`
23-
ReplicaCount int `json:"replica-count"`
24-
ArbiterCount int `json:"arbiter-count"`
19+
Name string `json:"name"`
20+
Type SubvolType `json:"type"`
21+
Bricks []BrickInfo `json:"bricks"`
22+
Subvols []Subvol `json:"subvols,omitempty"`
23+
ReplicaCount int `json:"replica-count"`
24+
ArbiterCount int `json:"arbiter-count"`
25+
DisperseCount int `json:"disperse-count"`
2526
}
2627

2728
// SizeInfo represents sizing information.
@@ -52,18 +53,19 @@ type BricksStatusResp []BrickStatus
5253
// VolumeInfo contains static information about the volume.
5354
// Clients should NOT use this struct directly.
5455
type VolumeInfo struct {
55-
ID uuid.UUID `json:"id"`
56-
Name string `json:"name"`
57-
Type VolType `json:"type"`
58-
Transport string `json:"transport"`
59-
DistCount int `json:"distribute-count"`
60-
ReplicaCount int `json:"replica-count"`
61-
ArbiterCount int `json:"arbiter-count"`
62-
Options map[string]string `json:"options"`
63-
State VolState `json:"state"`
64-
Subvols []Subvol `json:"subvols"`
65-
Metadata map[string]string `json:"metadata"`
66-
SnapList []string `json:"snap-list"`
56+
ID uuid.UUID `json:"id"`
57+
Name string `json:"name"`
58+
Type VolType `json:"type"`
59+
Transport string `json:"transport"`
60+
DistCount int `json:"distribute-count"`
61+
ReplicaCount int `json:"replica-count"`
62+
ArbiterCount int `json:"arbiter-count,omitempty"`
63+
DisperseCount int `json:"disperse-count,omitempty"`
64+
Options map[string]string `json:"options"`
65+
State VolState `json:"state"`
66+
Subvols []Subvol `json:"subvols"`
67+
Metadata map[string]string `json:"metadata"`
68+
SnapList []string `json:"snap-list"`
6769
}
6870

6971
// VolumeStatusResp response contains the statuses of all bricks of the volume.

0 commit comments

Comments
 (0)