Beispiel #1
0
func New(wd string, ss Strategizer, gro ...GrabberOption) (*Grabber, error) {
	if wd == "" {
		return nil, MissingWorkDirError
	}
	mx := new(sync.RWMutex)
	g := &Grabber{
		wd:          wd,
		s:           ss,
		writeState:  mx,
		readState:   mx.RLocker(),
		qIn:         make(chan Segmenter, 100), // TODO(negz): Determine best buffer len.
		qOut:        make(chan Segmenter, 100),
		maxRetry:    3,
		doneMx:      new(sync.Mutex),
		pp:          make(chan bool),
		decoder:     yenc.NewDecoder, // TODO(negz): Detect encoding.
		fileCreator: createSegmentFile,
		grabT:       new(tomb.Tomb),
		enqueueT:    new(tomb.Tomb),
	}
	for _, o := range gro {
		if err := o(g); err != nil {
			return nil, err
		}
	}
	if g.name == "" {
		return nil, MissingNameError
	}
	g.hash = util.HashString(g.name)
	return g, nil
}
Beispiel #2
0
func NewSegment(ns *nzb.Segment, f Filer) Segmenter {
	mx := new(sync.RWMutex)
	return &Segment{
		ns:           ns,
		f:            f,
		writeState:   mx,
		readState:    mx.RLocker(),
		failedServer: make(map[Serverer]bool),
		failedGroup:  make(map[string]bool),
	}
}
Beispiel #3
0
func BenchmarkMtxBlock(b *testing.B) {
	var primer int64
	m := new(sync.RWMutex)
	c := sync.NewCond(m.RLocker())
	die := make(chan struct{})
	for i := 0; i < runtime.GOMAXPROCS(0); i++ {
		go func() {
			for {
				select {
				case <-die:
					return
				default:
					// Gosched doubles as our item of work, as above.
					runtime.Gosched()
				}
				m.Lock()
				atomic.AddInt64(&primer, 1)
				c.Broadcast()
				m.Unlock()
			}
		}()
	}
	b.RunParallel(func(pb *testing.PB) {
		for pb.Next() {
			myPrimer := atomic.LoadInt64(&primer)
			for {
				m.RLock()
				if myPrimer != primer {
					m.RUnlock()
					break
				}
				c.Wait()
				m.RUnlock()
			}
		}
	})
	close(die)
}
Beispiel #4
0
func NewFile(nf *nzb.File, g Grabberer, filter ...*regexp.Regexp) Filer {
	mx := new(sync.RWMutex)
	f := &File{
		nf:         nf,
		g:          g,
		hash:       util.HashString(nf.Subject),
		segments:   make([]Segmenter, 0, len(nf.Segments)),
		writeState: mx,
		readState:  mx.RLocker(),
		doneMx:     new(sync.Mutex),
		required:   true,
	}

	for _, ns := range nf.Segments {
		f.segments = append(f.segments, NewSegment(ns, f))
	}

	if par2RE.MatchString(nf.Subject) {
		f.par2 = true
		f.required = false
		f.Pause()
	}

	for _, r := range filter {
		if r.MatchString(nf.Subject) {
			f.filtered = true
			f.required = false
			f.Pause()
		}
	}

	if f.required {
		f.g.FileRequired()
	}

	return f
}