コード例 #1
0
ファイル: dir.go プロジェクト: Monnoroch/golfstream
func (self *dirStreamObj) Del(from uint, to uint) (res bool, rerr error) {
	if from == to {
		return true, nil
	}

	self.lock.Lock()
	defer self.lock.Unlock()

	l, err := self.slen()
	if err != nil {
		return false, err
	}

	if _, _, err := convRange(int(from), int(to), int(l), "dirStreamObj.Del"); err != nil {
		return false, err
	}

	file, err := os.Open(self.back.dir + "/" + self.name)
	if err != nil {
		return false, err
	}
	defer func() {
		rerr = errors.List().Add(rerr).Add(file.Close()).Err()
		res = rerr == nil
	}()

	tmp, err := ioutil.TempFile(self.back.dir, self.name)
	if err != nil {
		return false, err
	}
	defer func() {
		rerr = errors.List().Add(rerr).Add(tmp.Close()).Add(os.Remove(tmp.Name())).Err()
		res = rerr == nil
	}()

	scanner := bufio.NewScanner(file)
	lineNum := uint(0)
	for scanner.Scan() {
		if lineNum < from || lineNum >= to {
			if _, err := tmp.Write(scanner.Bytes()); err != nil {
				return false, err
			}
		}
		lineNum++
	}
	if err := scanner.Err(); err != nil {
		return false, err
	}

	return true, os.Rename(tmp.Name(), file.Name())
}
コード例 #2
0
ファイル: dir.go プロジェクト: Monnoroch/golfstream
func (self *dirStreamObj) slen() (_ uint, rerr error) {
	file, err := os.Open(self.back.dir + "/" + self.name)
	if err != nil {
		if os.IsNotExist(err) {
			return 0, nil
		}
		return 0, err
	}
	defer func() {
		rerr = errors.List().Add(rerr).Add(file.Close()).Err()
	}()

	buf := make([]byte, 8196)
	count := uint(0)
	lineSep := []byte{'\n'}
	for {
		c, err := file.Read(buf)
		if err != nil && err != io.EOF {
			return 0, err
		}

		count += uint(bytes.Count(buf[:c], lineSep))

		if err == io.EOF {
			break
		}
	}
	return count, nil

}
コード例 #3
0
ファイル: streams.go プロジェクト: Monnoroch/golfstream
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
}
コード例 #4
0
ファイル: streams.go プロジェクト: Monnoroch/golfstream
func (self zipStream) Next() (Event, error) {
	res := make([]Event, len(self.streams))
	for i, s := range self.streams {
		evt, err := s.Next()
		if err == EOI {
			if DebugLog {
				errs := errors.List()
				for _, data := range res {
					if err, ok := data.(error); ok {
						errs.Add(err)
					}
				}
				logPrintln(errs)
			}
			return nil, EOI
		}

		if err != nil {
			res[i] = err
		} else {
			res[i] = evt
		}
	}
	return res, nil
}
コード例 #5
0
ファイル: service.go プロジェクト: Monnoroch/golfstream
func (self *service) Close() error {
	self.lock.Lock()
	defer self.lock.Unlock()

	errs := errors.List()
	for _, v := range self.backends {
		errs.Add(v.close())
	}
	self.backends = nil
	return errs.Err()
}
コード例 #6
0
ファイル: service.go プロジェクト: Monnoroch/golfstream
func (self *serviceBackend) RmStream(name string) error {
	s, bs, err := self.rmStream(name)
	if err != nil {
		return err
	}

	errs := errors.List().Add(s.Close())
	if bs != nil {
		errs.Add(bs.Close())
	}
	return errs.Err()
}
コード例 #7
0
ファイル: service.go プロジェクト: Monnoroch/golfstream
func (self *serviceBackend) close() error {
	self.lock.Lock()
	defer self.lock.Unlock()

	errs := errors.List()
	for _, v := range self.streams {
		errs.Add(v.Close())
	}
	for _, v := range self.bstreams {
		errs.Add(v.Close())
	}
	return errs.Err()
}
コード例 #8
0
ファイル: service.go プロジェクト: Monnoroch/golfstream
func (self *backendStreamT) Add(evt stream.Event) error {
	self.lock.Lock()
	defer self.lock.Unlock()

	if self.async {
		errs := make([]error, len(self.subs))
		wg := sync.WaitGroup{}
		wg.Add(len(self.subs))
		for i, s := range self.subs {
			go func(n int, st backend.Stream) {
				defer wg.Done()
				errs[n] = st.Add(evt)
			}(i, s)
		}
		wg.Wait()
		return errors.List().AddAll(errs).Err()
	} else {
		errs := errors.List()
		for _, v := range self.subs {
			errs.Add(v.Add(evt))
		}
		return errs.Err()
	}
}
コード例 #9
0
ファイル: dir.go プロジェクト: Monnoroch/golfstream
func (self *dirStreamObj) Read(from uint, to uint) (sres stream.Stream, rerr error) {
	if from == to {
		return stream.Empty(), nil
	}

	self.lock.Lock()
	defer self.lock.Unlock()

	l, err := self.slen()
	if err != nil {
		return nil, err
	}

	if _, _, err := convRange(int(from), int(to), int(l), "dirStreamObj.Read"); err != nil {
		return nil, err
	}

	res := []stream.Event{}

	file, err := os.Open(self.back.dir + "/" + self.name)
	if err != nil {
		return nil, err
	}
	defer func() {
		rerr = errors.List().Add(rerr).Add(file.Close()).Err()
		if rerr != nil {
			sres = nil
		}
	}()

	scanner := bufio.NewScanner(file)
	lineNum := uint(0)
	for scanner.Scan() {
		if lineNum >= from && lineNum < to {
			res = append(res, scanner.Bytes())
		}
		lineNum++
	}
	if err := scanner.Err(); err != nil {
		return nil, err
	}

	return stream.List(res), nil
}
コード例 #10
0
ファイル: service.go プロジェクト: Monnoroch/golfstream
/*
This one is a bit tricky.
So the general idea is that we set a new value in the valueStream object
which then gets pulled by a function code in stream.Run()
which then gets pulled by self.data.Next() here.
The problem is that the function code does't return one event for each input: it can be 1:N or K:1.
So, the first problem is that we might need to call self.data.Next() multimple times, and
a second is that valueStream.Next() can be called several times for each self.data.Next().
So, what we do is make the value stream return the set event once, and the second time it's called we return a marker error,
and also set a flag, that this marker was issued. Then we call self.data.Next() in a loop until the marker was issued.
We can not directly check if the error is the marker because function code can change the error by, for example,
wrapping it in a errors list, so we need a flag.
So we loop until the  marker was issued and we pull 0 or more events and add them all to self.bs,
colecting the errors while doing it.
*/
func (self *streamT) Add(evt stream.Event) error {
	self.val.set(evt)

	errs := errors.List()
	for {
		res, err := self.data.Next()
		if err != nil {
			if self.val.markerIssued {
				if err != marker { // marker was transformed
					// TODO: log error? Not sure if we need it.
				}
				return errs.Err()
			}
			return errs.Add(err).Err()
		}
		if err := self.bs.Add(res); err != nil {
			errs.Add(err)
		}
	}
}
コード例 #11
0
ファイル: dir.go プロジェクト: Monnoroch/golfstream
func (self *dirStreamObj) Add(evt stream.Event) (rerr error) {
	bs, ok := evt.([]byte)
	if !ok {
		return errors.New(fmt.Sprintf("dirStreamObj.Add: Expected []byte, got %v", evt))
	}

	self.lock.Lock()
	defer self.lock.Unlock()

	file, err := os.OpenFile(self.back.dir+"/"+self.name, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0600)
	if err != nil {
		return err
	}
	defer func() {
		rerr = errors.List().Add(rerr).Add(file.Close()).Err()
	}()

	bs = append(bs, '\n')
	_, err = file.Write(bs)
	return err
}
コード例 #12
0
ファイル: streams.go プロジェクト: Monnoroch/golfstream
// Filtering nil and searching for EOI in errors
// If found EOI will return EOI and log non-EOI errors
// If all errors are nil will return nil
// otherwise will return ErrorList
func getError(errs ...error) error {
	end := false
	for _, err := range errs {
		if err == EOI {
			end = true
			break
		}
	}
	if end {
		if DebugLog {
			list := errors.List()
			for _, err := range errs {
				if err != EOI {
					list.Add(err)
				}
			}
			if err := list.Err(); err != nil {
				log.Println(err)
			}
		}
		return EOI
	}
	return errors.AsList(errs...).Err()
}
コード例 #13
0
ファイル: ledis.go プロジェクト: Monnoroch/golfstream
func (self *ledisBackend) Drop() error {
	return errors.List().
		Add(self.ledis.FlushAll()).
		Add(os.RemoveAll(self.dirname)).
		Err()
}