Skip to content

Instantly share code, notes, and snippets.

@ohmystack
Last active December 5, 2016 03:18
Show Gist options
  • Save ohmystack/75c4eacda55d1f4f4b0083d4ad279798 to your computer and use it in GitHub Desktop.
Save ohmystack/75c4eacda55d1f4f4b0083d4ad279798 to your computer and use it in GitHub Desktop.
Golang gists
func goID() int {
var buf [64]byte
n := runtime.Stack(buf[:], false)
idField := strings.Fields(strings.TrimPrefix(string(buf[:n]), "goroutine "))[0]
id, err := strconv.Atoi(idField)
if err != nil {
panic(fmt.Sprintf("cannot get goroutine id: %v", err))
}
return id
}
// https://github.com/grpc/grpc-go/issues/106
// client
grpc.Dial(target, grpc.WithPerRPCCredentials(&loginCreds{
Username: "admin",
Password: "admin123",
}))
type loginCreds struct {
Username, Password string
}
func (c *loginCreds) GetRequestMetadata(context.Context, ...string) (map[string]string, error) {
return map[string]string{
"username": c.Username,
"password": c.Password,
}, nil
}
func (c *loginCreds) RequireTransportSecurity() bool {
return true
}
// server
grpc.NewServer(
grpc.StreamInterceptor(streamInterceptor),
grpc.UnaryInterceptor(unaryInterceptor)
)
func streamInterceptor(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
if err := authorize(stream.Context()); err != nil {
return err
}
return handler(srv, stream)
}
func unaryInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
if err := authorize(ctx); err != nil {
return err
}
return handler(ctx, req)
}
func authorize(ctx context.Context) error {
if md, ok := metadata.FromContext(ctx); ok {
if len(md["username"]) > 0 && md["username"][0] == "admin" &&
len(md["password"]) > 0 && md["password"][0] == "admin123" {
return nil
}
return AccessDeniedErr
}
return EmptyMetadataErr
}
// List implements storage.Interface.List
func (s *etcd3Storage) List(ctx context.Context, key string, intoList interface{}) error {
// Make sure the key ended with "/" to match the exact directory
// e.g. key "/a" matches "/a" "/a/b" "/ab", key "/a/" can only matches "/a/b"
if !strings.HasSuffix(key, "/") {
key += "/"
}
key = keyWithPrefix(s.prefix, key)
getResp, err := s.client.KV.Get(ctx, key, clientv3.WithPrefix())
if err != nil {
return err
}
if len(getResp.Kvs) == 0 {
return nil
}
// Get *Slice
v := reflect.ValueOf(intoList)
if v.Kind() != reflect.Ptr || v.IsNil() || v.Elem().Kind() != reflect.Slice {
return fmt.Errorf("intoList expected a non-nil pointer of a Slice")
}
// *Slice -> Slice
list := v.Elem()
// Slice -> *Object (the element in Slice)
elemType := list.Type().Elem()
if elemType.Kind() != reflect.Ptr {
return fmt.Errorf("element Type in the intoList expected a pointer")
}
for _, kv := range getResp.Kvs {
// Get an Interface{} object of (*Object -> Object),
// then use type assertion to get the real Object
obj, ok := reflect.New(elemType.Elem()).Interface().(object.Object)
if !ok {
return fmt.Errorf("%v not implemented object.Object", elemType.Elem())
}
if err := object.Decode(s.codec, kv.Value, obj); err != nil {
return storagedriver.NewInvalidObjError(key, string(kv.Value))
}
list.Set(reflect.Append(list, reflect.ValueOf(obj)))
}
return nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment