forked from go-kratos/kratos
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
16 changed files
with
1,647 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
#### paladin | ||
|
||
##### 项目简介 | ||
|
||
paladin 是一个config SDK客户端,包括了file、mock几个抽象功能,方便使用本地文件或者sven配置中心,并且集成了对象自动reload功能。 | ||
|
||
|
||
local files: | ||
``` | ||
demo -conf=/data/conf/app/msm-servie.toml | ||
// or dir | ||
demo -conf=/data/conf/app/ | ||
``` | ||
example: | ||
``` | ||
type exampleConf struct { | ||
Bool bool | ||
Int int64 | ||
Float float64 | ||
String string | ||
} | ||
func (e *exampleConf) Set(text string) error { | ||
var ec exampleConf | ||
if err := toml.Unmarshal([]byte(text), &ec); err != nil { | ||
return err | ||
} | ||
*e = ec | ||
return nil | ||
} | ||
func ExampleClient() { | ||
if err := paladin.Init(); err != nil { | ||
panic(err) | ||
} | ||
var ( | ||
ec exampleConf | ||
eo exampleConf | ||
m paladin.TOML | ||
strs []string | ||
) | ||
// config unmarshal | ||
if err := paladin.Get("example.toml").UnmarshalTOML(&ec); err != nil { | ||
panic(err) | ||
} | ||
// config setter | ||
if err := paladin.Watch("example.toml", &ec); err != nil { | ||
panic(err) | ||
} | ||
// paladin map | ||
if err := paladin.Watch("example.toml", &m); err != nil { | ||
panic(err) | ||
} | ||
s, err := m.Value("key").String() | ||
b, err := m.Value("key").Bool() | ||
i, err := m.Value("key").Int64() | ||
f, err := m.Value("key").Float64() | ||
// value slice | ||
err = m.Value("strings").Slice(&strs) | ||
// watch key | ||
for event := range paladin.WatchEvent(context.TODO(), "key") { | ||
fmt.Println(event) | ||
} | ||
} | ||
``` | ||
|
||
##### 编译环境 | ||
|
||
- **请只用 Golang v1.12.x 以上版本编译执行** | ||
|
||
##### 依赖包 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package paladin | ||
|
||
import ( | ||
"context" | ||
) | ||
|
||
const ( | ||
// EventAdd config add event. | ||
EventAdd EventType = iota | ||
// EventUpdate config update event. | ||
EventUpdate | ||
// EventRemove config remove event. | ||
EventRemove | ||
) | ||
|
||
// EventType is config event. | ||
type EventType int | ||
|
||
// Event is watch event. | ||
type Event struct { | ||
Event EventType | ||
Key string | ||
Value string | ||
} | ||
|
||
// Watcher is config watcher. | ||
type Watcher interface { | ||
WatchEvent(context.Context, ...string) <-chan Event | ||
Close() error | ||
} | ||
|
||
// Setter is value setter. | ||
type Setter interface { | ||
Set(string) error | ||
} | ||
|
||
// Getter is value getter. | ||
type Getter interface { | ||
// Get a config value by a config key(may be a sven filename). | ||
Get(string) *Value | ||
// GetAll return all config key->value map. | ||
GetAll() *Map | ||
} | ||
|
||
// Client is config client. | ||
type Client interface { | ||
Watcher | ||
Getter | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
package paladin | ||
|
||
import ( | ||
"context" | ||
"flag" | ||
|
||
"github.com/bilibili/Kratos/pkg/log" | ||
) | ||
|
||
var ( | ||
// DefaultClient default client. | ||
DefaultClient Client | ||
confPath string | ||
vars = make(map[string][]Setter) // NOTE: no thread safe | ||
) | ||
|
||
func init() { | ||
flag.StringVar(&confPath, "conf", "", "default config path") | ||
} | ||
|
||
// Init init config client. | ||
func Init() (err error) { | ||
if confPath != "" { | ||
DefaultClient, err = NewFile(confPath) | ||
} else { | ||
// TODO: config service | ||
return | ||
} | ||
if err != nil { | ||
return | ||
} | ||
go func() { | ||
for event := range DefaultClient.WatchEvent(context.Background()) { | ||
if event.Event != EventUpdate && event.Event != EventAdd { | ||
continue | ||
} | ||
if sets, ok := vars[event.Key]; ok { | ||
for _, s := range sets { | ||
if err := s.Set(event.Value); err != nil { | ||
log.Error("paladin: vars:%v event:%v error(%v)", s, event, err) | ||
} | ||
} | ||
} | ||
} | ||
}() | ||
return | ||
} | ||
|
||
// Watch watch on a key. The configuration implements the setter interface, which is invoked when the configuration changes. | ||
func Watch(key string, s Setter) error { | ||
v := DefaultClient.Get(key) | ||
str, err := v.Raw() | ||
if err != nil { | ||
return err | ||
} | ||
if err := s.Set(str); err != nil { | ||
return err | ||
} | ||
vars[key] = append(vars[key], s) | ||
return nil | ||
} | ||
|
||
// WatchEvent watch on multi keys. Events are returned when the configuration changes. | ||
func WatchEvent(ctx context.Context, keys ...string) <-chan Event { | ||
return DefaultClient.WatchEvent(ctx, keys...) | ||
} | ||
|
||
// Get return value by key. | ||
func Get(key string) *Value { | ||
return DefaultClient.Get(key) | ||
} | ||
|
||
// GetAll return all config map. | ||
func GetAll() *Map { | ||
return DefaultClient.GetAll() | ||
} | ||
|
||
// Keys return values key. | ||
func Keys() []string { | ||
return DefaultClient.GetAll().Keys() | ||
} | ||
|
||
// Close close watcher. | ||
func Close() error { | ||
return DefaultClient.Close() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
package paladin_test | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
|
||
"github.com/bilibili/Kratos/pkg/conf/paladin" | ||
|
||
"github.com/BurntSushi/toml" | ||
) | ||
|
||
type exampleConf struct { | ||
Bool bool | ||
Int int64 | ||
Float float64 | ||
String string | ||
Strings []string | ||
} | ||
|
||
func (e *exampleConf) Set(text string) error { | ||
var ec exampleConf | ||
if err := toml.Unmarshal([]byte(text), &ec); err != nil { | ||
return err | ||
} | ||
*e = ec | ||
return nil | ||
} | ||
|
||
// ExampleClient is a example client usage. | ||
// exmaple.toml: | ||
/* | ||
bool = true | ||
int = 100 | ||
float = 100.1 | ||
string = "text" | ||
strings = ["a", "b", "c"] | ||
*/ | ||
func ExampleClient() { | ||
if err := paladin.Init(); err != nil { | ||
panic(err) | ||
} | ||
var ec exampleConf | ||
// var setter | ||
if err := paladin.Watch("example.toml", &ec); err != nil { | ||
panic(err) | ||
} | ||
if err := paladin.Get("example.toml").UnmarshalTOML(&ec); err != nil { | ||
panic(err) | ||
} | ||
// use exampleConf | ||
// watch event key | ||
go func() { | ||
for event := range paladin.WatchEvent(context.TODO(), "key") { | ||
fmt.Println(event) | ||
} | ||
}() | ||
} | ||
|
||
// ExampleMap is a example map usage. | ||
// exmaple.toml: | ||
/* | ||
bool = true | ||
int = 100 | ||
float = 100.1 | ||
string = "text" | ||
strings = ["a", "b", "c"] | ||
[object] | ||
string = "text" | ||
bool = true | ||
int = 100 | ||
float = 100.1 | ||
strings = ["a", "b", "c"] | ||
*/ | ||
func ExampleMap() { | ||
var ( | ||
m paladin.TOML | ||
strs []string | ||
) | ||
// paladin toml | ||
if err := paladin.Watch("example.toml", &m); err != nil { | ||
panic(err) | ||
} | ||
// value string | ||
s, err := m.Get("string").String() | ||
if err != nil { | ||
s = "default" | ||
} | ||
fmt.Println(s) | ||
// value bool | ||
b, err := m.Get("bool").Bool() | ||
if err != nil { | ||
b = false | ||
} | ||
fmt.Println(b) | ||
// value int | ||
i, err := m.Get("int").Int64() | ||
if err != nil { | ||
i = 100 | ||
} | ||
fmt.Println(i) | ||
// value float | ||
f, err := m.Get("float").Float64() | ||
if err != nil { | ||
f = 100.1 | ||
} | ||
fmt.Println(f) | ||
// value slice | ||
if err = m.Get("strings").Slice(&strs); err == nil { | ||
fmt.Println(strs) | ||
} | ||
} |
Oops, something went wrong.