예제 #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
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
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
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
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
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
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
/*
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
// 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
func (self *ledisBackend) Drop() error {
	return errors.List().
		Add(self.ledis.FlushAll()).
		Add(os.RemoveAll(self.dirname)).
		Err()
}