github.com/awesome-flow/flow@v0.0.3-0.20190918184116-508d75d68a2c/pkg/corev1alpha1/x/meta_parser.go (about) 1 package x 2 3 import ( 4 "bytes" 5 "net/url" 6 "strings" 7 "sync" 8 9 core "github.com/awesome-flow/flow/pkg/corev1alpha1" 10 ) 11 12 const ( 13 MetaDelimByte = ' ' 14 ) 15 16 type MetaParser struct { 17 name string 18 ctx *core.Context 19 queue chan *core.Message 20 wg sync.WaitGroup 21 } 22 23 var _ core.Actor = (*MetaParser)(nil) 24 25 func NewMetaParser(name string, ctx *core.Context, params core.Params) (core.Actor, error) { 26 return &MetaParser{ 27 name: name, 28 ctx: ctx, 29 queue: make(chan *core.Message), 30 }, nil 31 } 32 33 func (m *MetaParser) Name() string { 34 return m.name 35 } 36 37 func (m *MetaParser) Start() error { 38 return nil 39 } 40 41 func (m *MetaParser) Stop() error { 42 close(m.queue) 43 m.wg.Wait() 44 return nil 45 } 46 47 func (m *MetaParser) Connect(nthreads int, peer core.Receiver) error { 48 for i := 0; i < nthreads; i++ { 49 m.wg.Add(1) 50 go func() { 51 for msg := range m.queue { 52 if err := peer.Receive(msg); err != nil { 53 msg.Complete(core.MsgStatusFailed) 54 m.ctx.Logger().Error("meta parser %q failed to send message: %s", m.name, err) 55 } 56 } 57 m.wg.Done() 58 }() 59 } 60 return nil 61 } 62 63 func (m *MetaParser) Receive(msg *core.Message) error { 64 parsed, err := parseMsgMeta(msg) 65 if err != nil { 66 return err 67 } 68 m.queue <- parsed 69 return nil 70 } 71 72 func parseMsgMeta(msg *core.Message) (*core.Message, error) { 73 fullbody := msg.Body() 74 spix := bytes.IndexByte(fullbody, MetaDelimByte) 75 if spix == -1 { 76 return msg, nil 77 } 78 meta, body := fullbody[:spix], fullbody[spix+1:] 79 values, err := url.ParseQuery(string(meta)) 80 if err != nil { 81 return nil, err 82 } 83 for k, vs := range values { 84 msg.SetMeta(k, strings.Join(vs, ",")) 85 } 86 msg.SetBody(body) 87 return msg, nil 88 }