func getBaseConfig(cfg interface{}) (interface{}, error) { c, ok := cfg.(map[string]interface{}) if !ok { return nil, errors.New(fmt.Sprintf("getBaseConfig: Expected map[string]interface{}, got %v", cfg)) } if _, ok := c["remote"]; !ok { return cfg, nil } a, ok := c["arg"] if !ok { return nil, errors.New(fmt.Sprintf("getBaseConfig: Expected config to have field \"arg\", got %v", cfg)) } aa, ok := a.(map[string]interface{}) if !ok { return nil, errors.New(fmt.Sprintf("getBaseConfig: Expected config.arg to have field \"arg\" of map[string]interface{}, got %v", a)) } base, ok := aa["base"] if !ok { return nil, errors.New(fmt.Sprintf("getBaseConfig: Expected config.arg to have field \"base\", got %v", a)) } return base, nil }
func convRange(from int, to int, l int, fn string) (uint, uint, error) { if from < 0 { from = l + 1 + from } if from < 0 { from = 0 } if to < 0 { to = l + 1 + to } if to < 0 { return 0, 0, errors.New(fmt.Sprintf("%s: to:%v < 0", fn, to)) } if from > l { return 0, 0, errors.New(fmt.Sprintf("%s: from:%v > len:%v", fn, from, l)) } if to > l { return 0, 0, errors.New(fmt.Sprintf("%s: to:%v > len:%v", fn, to, l)) } if from > to { return 0, 0, errors.New(fmt.Sprintf("%s: from:%v > to:%v", fn, from, to)) } return uint(from), uint(to), nil }
func (self *serviceBackend) AddStream(bstream, name string, defs []string) (res backend.BackendStream, rerr error) { self.lock.Lock() defer self.lock.Unlock() if _, ok := self.streams[name]; ok { return nil, errors.New(fmt.Sprintf("serviceBackend.AddStream: backend with name \"%s\" already has stream \"%s\"", self.name, name)) } bs, ok := self.bstreams[bstream] if !ok { bstr, err := self.back.GetStream(bstream) if err != nil { return nil, err } bs = &backendStreamT{bstr, self.name, bstream, self.async, sync.Mutex{}, []backend.Stream{bstr}, 0} self.bstreams[bstream] = bs } st := &valueStream{nil, false, false, false} data, err := stream.Run(st, defs) if err != nil { return nil, err } s := &streamT{bs, defs, st, data} self.streams[name] = s bs.refcnt += 1 return s, nil }
func (self *remoteService) addSub(back, bname string, sid uint32, hFrom int, hTo int) (uint, uint, error) { cmd := addSubCmd{ Cmd: "subscribe", Data: addSubCmdData{ Id: self.getCmdId(), Back: back, Bname: bname, Sid: sid, From: hFrom, To: hTo, }, } v, err := self.getCmdRes(cmd.Data.Id, &cmd) if err != nil { return 0, 0, err } rr := rangeRes{} if err := json.NewDecoder(bytes.NewReader(v)).Decode(&rr); err != nil { return 0, 0, err } if rr.Err != "" { return 0, 0, errors.New(rr.Err) } return rr.From, rr.To, nil }
func (self *httpBackend) Config() (interface{}, error) { resp, err := self.p.Post(self.configUrl, nil) if err != nil { return nil, err } defer resp.Body.Close() res := configRes{} if err := json.NewDecoder(resp.Body).Decode(&res); err != nil { return nil, err } if res.Err != "" { return nil, errors.New(res.Err) } return map[string]interface{}{ "type": "http", "remote": true, "arg": map[string]interface{}{ "url": self.baseUrl, "base": res.Cfg, }, }, nil }
func (self *minByStream) Next() (Event, error) { if self.done { return nil, EOI } for { data, err1 := self.datas.Next() v, err2 := self.vals.Next() if err := getError(err1, err2); err != nil { if err == EOI { self.done = true return self.data, nil } return nil, err } val, ok := getIntOrFloat(v) if !ok { return nil, errors.New(fmt.Sprintf("MinBy: Expected number event, got %v", v)) } if val < self.val { self.data = data self.val = val } } }
func (self andStream) Next() (Event, error) { ok := true err := errors.List() for i, s := range self.streams { val, err1 := s.Next() if err1 == EOI { logPrintln(err) return nil, EOI } if err1 != nil { err.Add(err1) continue } bval, bok := val.(bool) if !bok { err.Add(errors.New(fmt.Sprintf("And: Expected bool event, got %v in stream #%d", val, i))) continue } ok = ok && bval } if err != nil { return nil, err } return ok, nil }
func (self *httpBackendStream) Read(from uint, to uint) (stream.Stream, error) { if from == to { return stream.Empty(), nil } resp, err := self.p.Post(fmt.Sprintf(self.readUrl, from, to), nil) if err != nil { return nil, err } defer resp.Body.Close() res := arrErrorObj{} if err := json.NewDecoder(resp.Body).Decode(&res); err != nil { return nil, err } if res.Err != "" { return nil, errors.New(res.Err) } r := make([]stream.Event, len(res.Events)) for i, v := range res.Events { r[i] = stream.Event([]byte(v)) } return stream.List(r), nil }
func (self *remoteService) rmSub(back, bname string, sid uint32) (bool, error) { cmd := rmSubCmd{ Cmd: "unsubscribe", Data: rmSubCmdData{ Id: self.getCmdId(), Back: back, Bname: bname, Sid: sid, }, } v, err := self.getCmdRes(cmd.Data.Id, &cmd) if err != nil { return false, err } rr := okRes{} if err := json.NewDecoder(bytes.NewReader(v)).Decode(&rr); err != nil { return false, err } if rr.Err != "" { return false, errors.New(rr.Err) } return rr.Ok, nil }
func (self *remoteServiceBackend) pushToSub(sid uint32, evt stream.Event) error { s, ok := self.getSub(sid) if !ok { return errors.New(fmt.Sprintf("remoteServiceBackend.pushToSub: Backend \"%s\" doesn't have subscriber %v", sid)) } return s.Add(evt) }
/* Creates a stream with events which are values of a field in events of the original stream as in JSON. Returns an error if the original field doesn't exist. The field might be deep inside, as in "object.value.data". */ func GetField(stream Stream, field string) Stream { return Map(stream, func(evt Event) (Event, error) { res, ok := getFieldImpl(evt, field) if !ok { return nil, errors.New(fmt.Sprintf("GetField: Expected event to have field %s, got %v", field, evt)) } return res, nil }) }
/* Creates a boolean stream with true events when the event of an original stream is less or equal to a given value and false events otherwise. Original stream must consist of numbers. */ func LessEqVal(stream Stream, val float64) Stream { return Map(stream, func(e Event) (Event, error) { v, ok := getIntOrFloat(e) if !ok { return nil, errors.New(fmt.Sprintf("LessEqVal: Expected event to be number, got %v", e)) } return v <= val, nil }) }
/* Takes a stream af strings and prepend a given string to all of them. */ func StringPrepend(stream Stream, pref string) Stream { return Map(stream, func(val Event) (Event, error) { v, ok := val.(string) if !ok { return nil, errors.New(fmt.Sprintf("StringPrepend: Expected event to be string, got %v", v)) } return pref + v, nil }) }
func (self *remoteService) handleEvent(back string, sid uint32, evt stream.Event) error { self.lock.Lock() b, ok := self.backends[back] self.lock.Unlock() if !ok { return errors.New(fmt.Sprintf("remoteService.handleEvent: No backend with name \"%v\"", back)) } return b.pushToSub(sid, evt) }
func (self *remoteService) handleCmdRes(id uint32, data json.RawMessage) error { ch := self.popCmd(id) if ch == nil { return errors.New(fmt.Sprintf("remoteService.handleCmdRes: No command with id %v!", id)) } ch <- data close(ch) return nil }
func (self *service) GetBackend(back string) (Backend, error) { self.lock.Lock() defer self.lock.Unlock() v, ok := self.backends[back] if !ok { return nil, errors.New(fmt.Sprintf("service.GetBackend: backend with name \"%s\" does not exist", back)) } return v, nil }
func (self *serviceBackend) GetStream(name string) (backend.BackendStream, string, error) { self.lock.Lock() defer self.lock.Unlock() s, ok := self.streams[name] if !ok { return nil, "", errors.New(fmt.Sprintf("serviceBackend.GetStream: backend with name \"%s\" does not have stream \"%s\"", self.name, name)) } return s, s.bs.bstream, nil }
func iter(ch chan []byte, msg []byte, s Service, subs map[uint32]*wsSub, slock *sync.Mutex) error { cmd := cmdName{} if err := json.NewDecoder(bytes.NewReader(msg)).Decode(&cmd); err != nil { return err } switch cmd.Cmd { case "add": if err := addCmdHandler(s, []byte(cmd.Data)); err != nil { return err } case "subscribe": data := addSubCmdData{} if err := json.NewDecoder(bytes.NewReader([]byte(cmd.Data))).Decode(&data); err != nil { return err } res, err := subCmdHandler(s, data, ch, subs, slock) if err != nil { res = subResult{Id: data.Id, Data: rangeRes{Err: err.Error()}} } buf := new(bytes.Buffer) if err := json.NewEncoder(buf).Encode(&res); err != nil { return err } go func() { ch <- buf.Bytes() }() case "unsubscribe": data := rmSubCmdData{} if err := json.NewDecoder(bytes.NewReader([]byte(cmd.Data))).Decode(&data); err != nil { return err } res, err := unsubCmdHandler(s, data, subs, slock) if err != nil { res = unsubResult{Id: data.Id, Data: okRes{Err: err.Error()}} } buf := new(bytes.Buffer) if err := json.NewEncoder(buf).Encode(&res); err != nil { return err } go func() { ch <- buf.Bytes() }() default: return errors.New(fmt.Sprintf("Unknown command \"%s\"!", cmd.Cmd)) } return nil }
func (self *service) AddBackend(back string, b backend.Backend) (Backend, error) { self.lock.Lock() defer self.lock.Unlock() if _, ok := self.backends[back]; ok { return nil, errors.New(fmt.Sprintf("service.AddBackend: backend with name \"%s\" already exists", back)) } res := &serviceBackend{b, back, self.async, sync.Mutex{}, map[string]*backendStreamT{}, map[string]*streamT{}} self.backends[back] = res return res, nil }
func (self *ledisStreamObj) Add(evt stream.Event) error { bs, ok := evt.([]byte) if !ok { return errors.New(fmt.Sprintf("ledisStreamObj.Add: Expected []byte, got %v", evt)) } self.delLock.RLock() defer self.delLock.RUnlock() _, err := self.db.RPush(self.key, bs) return err }
func (self decodeStream) Next() (Event, error) { evt, err := self.base.Next() if err != nil { return nil, err } bs, ok := evt.([]byte) if !ok { return nil, errors.New(fmt.Sprintf("Decode: Expected event to be []byte, got %v", evt)) } return self.d.Decode(bs) }
func (self *httpBackendStream) Add(evt stream.Event) error { bs, ok := evt.([]byte) if !ok { return errors.New(fmt.Sprintf("httpBackendStream.Add: Expected []byte, got %v", evt)) } resp, err := self.p.Post(self.addUrl, bytes.NewReader(bs)) if err != nil { return err } defer resp.Body.Close() res := errorObj{} if err := json.NewDecoder(resp.Body).Decode(&res); err != nil { return err } if res.Err != "" { return errors.New(res.Err) } return nil }
func (self *serviceBackend) rmSub(bstream string) (*backendStreamT, error) { self.lock.Lock() defer self.lock.Unlock() bs, ok := self.bstreams[bstream] if !ok { return nil, errors.New(fmt.Sprintf("serviceBackend.RmSub: backend with name \"%s\" does not have backend stream \"%s\"", self.name, bstream)) } bs.refcnt -= 1 if bs.refcnt == 0 { delete(self.bstreams, bstream) } return bs, nil }
func (self *wsSub) Add(evt stream.Event) error { bs, ok := evt.([]byte) if !ok { return errors.New(fmt.Sprintf("wsSub.Add: expected []byte event, got %v", evt)) } cmd := cmdResult{Back: self.back, Bname: self.bname, Sid: self.sid, Data: json.RawMessage(bs)} buf := new(bytes.Buffer) if err := json.NewEncoder(buf).Encode(&cmd); err != nil { return err } self.ch <- buf.Bytes() return nil }
func (self *httpBackend) Drop() error { resp, err := self.p.Post(self.dropUrl, nil) if err != nil { return err } defer resp.Body.Close() res := errorObj{} if err := json.NewDecoder(resp.Body).Decode(&res); err != nil { return err } if res.Err != "" { return errors.New(res.Err) } return nil }
func (self *serviceBackend) rmStream(name string) (*streamT, *backendStreamT, error) { self.lock.Lock() defer self.lock.Unlock() s, ok := self.streams[name] if !ok { return nil, nil, errors.New(fmt.Sprintf("serviceBackend.RmStream: backend with name \"%s\" does not have stream \"%s\"", self.name, name)) } delete(self.streams, name) s.bs.refcnt -= 1 if s.bs.refcnt == 0 { delete(self.bstreams, s.bs.bstream) return s, s.bs, nil } return s, nil, nil }
func (self *httpBackend) Streams() ([]string, error) { resp, err := self.p.Post(self.listUrl, nil) if err != nil { return nil, err } defer resp.Body.Close() res := sarrErrorObj{} if err := json.NewDecoder(resp.Body).Decode(&res); err != nil { return nil, err } if res.Err != "" { return nil, errors.New(res.Err) } return res.Streams, nil }
func (self *remoteService) Backends() ([]string, error) { resp, err := self.p.Post(fmt.Sprintf("%s/sbackends", self.baseUrl), nil) if err != nil { return nil, err } defer resp.Body.Close() rr := backendsRes{} if err := json.NewDecoder(resp.Body).Decode(&rr); err != nil { return nil, err } if rr.Err != "" { return nil, errors.New(rr.Err) } return rr.Backends, nil }
func callErr(p poster.Poster, url string, r io.Reader) error { resp, err := p.Post(url, r) if err != nil { return err } defer resp.Body.Close() rr := errorObj{} if err := json.NewDecoder(resp.Body).Decode(&rr); err != nil { return err } if rr.Err != "" { return errors.New(rr.Err) } return nil }
func unsubCmdHandler(s Service, data rmSubCmdData, subs map[uint32]*wsSub, slock *sync.Mutex) (res unsubResult, rerr error) { b, err := s.GetBackend(data.Back) if err != nil { return unsubResult{}, err } sub := getSub(data.Sid, subs, slock) if sub == nil { return unsubResult{}, errors.New(fmt.Sprintf("Unknown subscriber \"%v\"!", data.Id)) } r, err := b.RmSub(data.Bname, sub) if err != nil { return unsubResult{}, err } return unsubResult{Id: data.Id, Data: okRes{Ok: r}}, nil }