Skip to content

Commit d00ff97

Browse files
committed
Fix review comments
Signed-off-by: Ganesh Vernekar <[email protected]>
1 parent 4b8a4c1 commit d00ff97

File tree

2 files changed

+90
-82
lines changed

2 files changed

+90
-82
lines changed

pkg/ring/lifecycler.go

Lines changed: 7 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,9 @@ package ring
22

33
import (
44
"context"
5-
"encoding/json"
6-
"errors"
75
"flag"
86
"fmt"
9-
"io/ioutil"
107
"os"
11-
"path"
128
"sort"
139
"sync"
1410
"time"
@@ -42,10 +38,6 @@ var (
4238
}, []string{"op", "status", "name"})
4339
)
4440

45-
const (
46-
tokensFileName = "tokens"
47-
)
48-
4941
// LifecyclerConfig is the config to build a Lifecycler.
5042
type LifecyclerConfig struct {
5143
RingConfig Config `yaml:"ring,omitempty"`
@@ -61,7 +53,7 @@ type LifecyclerConfig struct {
6153
NormaliseTokens bool `yaml:"normalise_tokens,omitempty"`
6254
InfNames []string `yaml:"interface_names"`
6355
FinalSleep time.Duration `yaml:"final_sleep"`
64-
TokensFileDir string `yaml:"token_file_dir,omitempty"`
56+
TokensFileDir string `yaml:"tokens_file_dir,omitempty"`
6557

6658
// For testing, you can override the address and ID of this ingester
6759
Addr string `yaml:"address"`
@@ -93,7 +85,7 @@ func (cfg *LifecyclerConfig) RegisterFlagsWithPrefix(prefix string, f *flag.Flag
9385
flagext.DeprecatedFlag(f, prefix+"claim-on-rollout", "DEPRECATED. This feature is no longer optional.")
9486
f.BoolVar(&cfg.NormaliseTokens, prefix+"normalise-tokens", false, "Store tokens in a normalised fashion to reduce allocations.")
9587
f.DurationVar(&cfg.FinalSleep, prefix+"final-sleep", 30*time.Second, "Duration to sleep for before exiting, to ensure metrics are scraped.")
96-
f.StringVar(&cfg.TokensFileDir, prefix+"token-file-dir", "", "Directory in which the token file is to be stored.")
88+
f.StringVar(&cfg.TokensFileDir, prefix+"tokens-file-dir", "", "Directory in which the tokens file is stored. If empty, tokens are not stored at shutdown and restored at startup.")
9789

9890
hostname, err := os.Hostname()
9991
if err != nil {
@@ -265,49 +257,16 @@ func (i *Lifecycler) getTokens() Tokens {
265257
return i.tokens
266258
}
267259

268-
func (i *Lifecycler) flushTokensToFile() {
269-
if i.cfg.TokensFileDir == "" || i.tokens == nil || len(i.tokens) == 0 {
270-
return
271-
}
272-
tokenFilePath := path.Join(i.cfg.TokensFileDir, tokensFileName)
273-
f, err := os.OpenFile(tokenFilePath, os.O_WRONLY|os.O_CREATE, 0666)
274-
if err != nil {
275-
level.Error(util.Logger).Log("msg", "error in creating token file", "err", err)
276-
return
277-
}
278-
279-
b, err := MarshalTokens(i.tokens)
280-
if err != nil {
281-
level.Error(util.Logger).Log("msg", "error in marshalling tokens", "err", err)
282-
return
283-
}
284-
if _, err = f.Write(b); err != nil {
285-
level.Error(util.Logger).Log("msg", "error in writing token file", "err", err)
286-
return
287-
}
288-
}
289-
290-
func (i *Lifecycler) getTokensFromFile() (Tokens, error) {
291-
tokenFilePath := path.Join(i.cfg.TokensFileDir, tokensFileName)
292-
b, err := ioutil.ReadFile(tokenFilePath)
293-
if err != nil {
294-
if os.IsNotExist(err) {
295-
return nil, nil
296-
}
297-
return nil, err
298-
}
299-
300-
return UnmarshalTokens(b)
301-
}
302-
303260
func (i *Lifecycler) setTokens(tokens Tokens) {
304261
tokensOwned.WithLabelValues(i.RingName).Set(float64(len(tokens)))
305262

306263
i.stateMtx.Lock()
307264
i.tokens = tokens
308265
i.stateMtx.Unlock()
309266

310-
i.flushTokensToFile()
267+
if err := i.tokens.StoreToFile(i.cfg.TokensFileDir); err != nil {
268+
level.Error(util.Logger).Log("msg", "error storing tokens to disk", "err", err)
269+
}
311270
}
312271

313272
// ClaimTokensFor takes all the tokens for the supplied ingester and assigns them to this ingester.
@@ -506,8 +465,9 @@ func (i *Lifecycler) initRing(ctx context.Context) error {
506465

507466
ingesterDesc, ok := ringDesc.Ingesters[i.ID]
508467
if !ok {
468+
var tokens Tokens
509469
// We load the tokens from the file only if it does not exist in the ring yet.
510-
tokens, err := i.getTokensFromFile()
470+
err := tokens.LoadFromFile(i.cfg.TokensFileDir)
511471
if err != nil {
512472
level.Error(util.Logger).Log("msg", "error in getting tokens from file", "err", err)
513473
} else if tokens != nil && len(tokens) > 0 {
@@ -752,38 +712,3 @@ func (i *Lifecycler) unregister(ctx context.Context) error {
752712
return ringDesc, true, nil
753713
})
754714
}
755-
756-
// TokenVersion1 is the version is a simple list of tokens.
757-
const TokenVersion1 = 1
758-
759-
// Tokens is a simple list of tokens.
760-
type Tokens []uint32
761-
762-
// MarshalTokens encodes given tokens into JSON.
763-
func MarshalTokens(tokens Tokens) ([]byte, error) {
764-
data := tokensJSON{
765-
Version: TokenVersion1,
766-
Tokens: tokens,
767-
}
768-
return json.Marshal(data)
769-
}
770-
771-
// UnmarshalTokens converts the JSON byte stream into Tokens.
772-
func UnmarshalTokens(b []byte) (Tokens, error) {
773-
tj := tokensJSON{}
774-
if err := json.Unmarshal(b, &tj); err != nil {
775-
return nil, err
776-
}
777-
switch tj.Version {
778-
case TokenVersion1:
779-
tokens := Tokens(tj.Tokens)
780-
return tokens, nil
781-
default:
782-
return nil, errors.New("invalid token type")
783-
}
784-
}
785-
786-
type tokensJSON struct {
787-
Version int `json:"version"`
788-
Tokens []uint32 `json:"tokens"`
789-
}

pkg/ring/tokens.go

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package ring
2+
3+
import (
4+
"encoding/json"
5+
"errors"
6+
"io/ioutil"
7+
"os"
8+
"path"
9+
)
10+
11+
const (
12+
// TokenVersion1 is the version is a simple list of tokens.
13+
TokenVersion1 = 1
14+
15+
// Name of the file in which tokens is stored.
16+
tokensFileName = "tokens"
17+
)
18+
19+
// Tokens is a simple list of tokens.
20+
type Tokens []uint32
21+
22+
// StoreToFile stores the tokens in the given directory.
23+
func (t Tokens) StoreToFile(dir string) error {
24+
if dir == "" {
25+
return errors.New("directory is empty")
26+
}
27+
tokenFilePath := path.Join(dir, tokensFileName)
28+
f, err := os.OpenFile(tokenFilePath, os.O_WRONLY|os.O_CREATE, 0666)
29+
if err != nil {
30+
return err
31+
}
32+
33+
b, err := t.Marshal()
34+
if err != nil {
35+
return err
36+
}
37+
if _, err = f.Write(b); err != nil {
38+
return err
39+
}
40+
return nil
41+
}
42+
43+
// LoadFromFile loads tokens from given directory.
44+
func (t *Tokens) LoadFromFile(dir string) error {
45+
tokenFilePath := path.Join(dir, tokensFileName)
46+
b, err := ioutil.ReadFile(tokenFilePath)
47+
if err != nil {
48+
if os.IsNotExist(err) {
49+
return nil
50+
}
51+
return err
52+
}
53+
return t.Unmarshal(b)
54+
}
55+
56+
// Marshal encodes the tokens into JSON.
57+
func (t Tokens) Marshal() ([]byte, error) {
58+
data := tokensJSON{
59+
Version: TokenVersion1,
60+
Tokens: t,
61+
}
62+
return json.Marshal(data)
63+
}
64+
65+
// Unmarshal reads the tokens from JSON byte stream.
66+
func (t *Tokens) Unmarshal(b []byte) error {
67+
tj := tokensJSON{}
68+
if err := json.Unmarshal(b, &tj); err != nil {
69+
return err
70+
}
71+
switch tj.Version {
72+
case TokenVersion1:
73+
*t = Tokens(tj.Tokens)
74+
return nil
75+
default:
76+
return errors.New("invalid token type")
77+
}
78+
}
79+
80+
type tokensJSON struct {
81+
Version int `json:"version"`
82+
Tokens []uint32 `json:"tokens"`
83+
}

0 commit comments

Comments
 (0)