美文网首页
go-diodes源码阅读(3)-笔记状态

go-diodes源码阅读(3)-笔记状态

作者: guonaihong | 来源:发表于2020-02-19 16:14 被阅读0次

前言

这是一篇笔记,先记录,自己能看懂,记录下里面核心知识点,有时间再丰富下描述信息,向外界输出。

来个zerolog里面的代码

wr := diode.NewWriter(os.Stdout, 1000, 10*time.Millisecond, func(missed int) {
        fmt.Printf("Logger Dropped %d messages", missed)
    })
log := zerolog.New(w)
log.Print("test")

高效的原因

zerolog有一段是这么描述diodes API的

Thread-safe, lock-free, non-blocking writer
If your writer might be slow or not thread-safe and you need your log producers to never get slowed down by a slow writer, you can use a diode.Writer as follow:

先看写的地方

直接调用低层多写,单读无锁队列。Write接口里面是往队列里面塞数据。这里还不是真正写的地方

func (dw Writer) Write(p []byte) (n int, err error) {
    // p is pooled in zerolog so we can't hold it passed this call, hence the
    // copy.
    p = append(bufPool.Get().([]byte), p...)
    dw.d.Set(diodes.GenericDataType(&p))
    return len(p), nil
}

真正写数据的地方

这里从无锁队列里面读取数据,调用真正写的接口。but,只有一个go程。

func (dw Writer) poll() {
    defer close(dw.done)
    for {
        d := dw.d.Next()
        if d == nil {
            return
        }
        p := *(*[]byte)(d)
        dw.w.Write(p)

        // Proper usage of a sync.Pool requires each entry to have approximately
        // the same memory cost. To obtain this property when the stored type
        // contains a variably-sized buffer, we add a hard limit on the maximum buffer
        // to place back in the pool.
        //
        // See https://golang.org/issue/23199
        const maxSize = 1 << 16 // 64KiB
        if cap(p) <= maxSize {
            bufPool.Put(p[:0])
        }
    }
}

回答高效的原因

  • 使用了无锁队列,没有加锁解锁带来的开销
  • 大buffer可以减小go程。超过吞吐量的直接丢了

相关文章

网友评论

      本文标题:go-diodes源码阅读(3)-笔记状态

      本文链接:https://www.haomeiwen.com/subject/ahpafhtx.html