OLD | NEW |
1 // Copyright 2015 The LUCI Authors. All rights reserved. | 1 // Copyright 2015 The LUCI Authors. All rights reserved. |
2 // Use of this source code is governed under the Apache License, Version 2.0 | 2 // Use of this source code is governed under the Apache License, Version 2.0 |
3 // that can be found in the LICENSE file. | 3 // that can be found in the LICENSE file. |
4 | 4 |
5 // Package settings implements storage for infrequently changing global | 5 // Package settings implements storage for infrequently changing global |
6 // settings. | 6 // settings. |
7 // | 7 // |
8 // Settings are represented as (key, value) pairs, where value is JSON | 8 // Settings are represented as (key, value) pairs, where value is JSON |
9 // serializable struct. Settings are cached internally in the process memory to | 9 // serializable struct. Settings are cached internally in the process memory to |
10 // avoid hitting the storage all the time. | 10 // avoid hitting the storage all the time. |
11 package settings | 11 package settings |
12 | 12 |
13 import ( | 13 import ( |
14 "encoding/json" | 14 "encoding/json" |
15 "errors" | 15 "errors" |
16 "reflect" | 16 "reflect" |
17 "sync" | 17 "sync" |
18 "time" | 18 "time" |
19 | 19 |
20 "golang.org/x/net/context" | 20 "golang.org/x/net/context" |
21 | 21 |
22 "github.com/luci/luci-go/common/clock" | 22 "github.com/luci/luci-go/common/clock" |
23 "github.com/luci/luci-go/common/data/caching/lazyslot" | 23 "github.com/luci/luci-go/common/data/caching/lazyslot" |
24 "github.com/luci/luci-go/common/logging" | 24 "github.com/luci/luci-go/common/logging" |
25 "github.com/luci/luci-go/common/retry" | 25 "github.com/luci/luci-go/common/retry" |
| 26 "github.com/luci/luci-go/common/retry/transient" |
26 ) | 27 ) |
27 | 28 |
28 var ( | 29 var ( |
29 // ErrNoSettings can be returned by Get and Set on fatal errors. | 30 // ErrNoSettings can be returned by Get and Set on fatal errors. |
30 ErrNoSettings = errors.New("settings: settings are not available") | 31 ErrNoSettings = errors.New("settings: settings are not available") |
31 | 32 |
32 // ErrBadType is returned if Get(...) receives unexpected type. | 33 // ErrBadType is returned if Get(...) receives unexpected type. |
33 ErrBadType = errors.New("settings: bad type") | 34 ErrBadType = errors.New("settings: bad type") |
34 ) | 35 ) |
35 | 36 |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
124 } | 125 } |
125 | 126 |
126 // New creates new Settings object that uses given Storage to fetch and save | 127 // New creates new Settings object that uses given Storage to fetch and save |
127 // settings. | 128 // settings. |
128 func New(storage Storage) *Settings { | 129 func New(storage Storage) *Settings { |
129 return &Settings{ | 130 return &Settings{ |
130 storage: storage, | 131 storage: storage, |
131 values: lazyslot.Slot{ | 132 values: lazyslot.Slot{ |
132 Timeout: 15 * time.Second, // retry for 15 sec at most | 133 Timeout: 15 * time.Second, // retry for 15 sec at most |
133 Fetcher: func(c context.Context, _ lazyslot.Value) (resu
lt lazyslot.Value, err error) { | 134 Fetcher: func(c context.Context, _ lazyslot.Value) (resu
lt lazyslot.Value, err error) { |
134 » » » » err = retry.Retry(c, retry.TransientOnly(retry.D
efault), func() error { | 135 » » » » err = retry.Retry(c, transient.Only(retry.Defaul
t), func() error { |
135 ctx, _ := clock.WithTimeout(c, 2*time.Se
cond) // trigger a retry after 2 sec RPC timeout | 136 ctx, _ := clock.WithTimeout(c, 2*time.Se
cond) // trigger a retry after 2 sec RPC timeout |
136 result, err = attemptToFetchSettings(ctx
, storage) | 137 result, err = attemptToFetchSettings(ctx
, storage) |
137 return err | 138 return err |
138 }, nil) | 139 }, nil) |
139 if err != nil { | 140 if err != nil { |
140 result = lazyslot.Value{} | 141 result = lazyslot.Value{} |
141 } | 142 } |
142 return | 143 return |
143 }, | 144 }, |
144 }, | 145 }, |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
222 } | 223 } |
223 | 224 |
224 // Log the change. Ignore JSON marshaling errors, they are not essential | 225 // Log the change. Ignore JSON marshaling errors, they are not essential |
225 // (and must not happen anyway). | 226 // (and must not happen anyway). |
226 existingJSON, _ := json.Marshal(existing) | 227 existingJSON, _ := json.Marshal(existing) |
227 modifiedJSON, _ := json.Marshal(value) | 228 modifiedJSON, _ := json.Marshal(value) |
228 logging.Warningf(c, "Settings %q changed from %s to %s by %q", key, exis
tingJSON, modifiedJSON, who) | 229 logging.Warningf(c, "Settings %q changed from %s to %s by %q", key, exis
tingJSON, modifiedJSON, who) |
229 | 230 |
230 return s.Set(c, key, value, who, why) | 231 return s.Set(c, key, value, who, why) |
231 } | 232 } |
OLD | NEW |