douhang1913 2018-07-08 10:46
浏览 42
已采纳

监控golang中的频道充值

There are several channels to monitor, their type are different and irrelevant(since we only care about len and cap), but golang compiler does not accept following code, whatever T is:

func monitorChan(ch chan T) {
    for {
        if len(ch) == cap(ch) {
            log.Warn("log")
        }
        time.Sleep(chanMonitorInterval)
    }
}

it shows error:

cannot use ch (type chan []byte) as type chan interface {} in argument to monitorChan.

How can this function be modified to write once monitor every channel?


Here is my code:

package main

import (
    "fmt"
    "time"
)

func monitorChan(ch chan interface{}) {
    for {
        if len(ch) == cap(ch) {
            fmt.Println("log")
        }
        time.Sleep(1 * time.Second)
    }
}

func main() {
    ch := make(chan []byte, 100)
    go monitorChan(ch)
    // actual things below ...
}

Playground: https://play.golang.org/p/t7T28IpLNAs

  • 写回答

2条回答 默认 最新

  • dongliushui2001 2018-07-08 14:44
    关注

    Use reflection. For example,

    package main
    
    import (
        "log"
        "reflect"
        "time"
    )
    
    func monitorChan(ch interface{}, intvl time.Duration) {
        v := reflect.ValueOf(ch)
        if v.Kind() != reflect.Chan {
            return
        }
    
        c := v.Cap()
        if c == 0 {
            return
        }
        for {
            if l := v.Len(); l == c {
                log.Printf("log: len(%d) cap(%d)", l, c)
            }
            time.Sleep(intvl)
        }
    }
    
    func main() {
        log.Print("main")
        c := make(chan []byte, 10)
        var chanMonitorInterval = 1 * time.Second
        go monitorChan(c, chanMonitorInterval)
        log.Print("monitor")
    
        time.Sleep(5 * chanMonitorInterval)
        for len(c) != cap(c) {
            c <- []byte{}
        }
        log.Print("len(c) == cap(c)")
        time.Sleep(3 * chanMonitorInterval)
        <-c
        log.Print("len(c) < cap(c)")
        time.Sleep(5 * chanMonitorInterval)
        log.Print("main")
    }
    

    Playground: https://play.golang.org/p/c5VhIIO0pik

    Output:

    2009/11/10 23:00:00 main
    2009/11/10 23:00:00 monitor
    2009/11/10 23:00:05 len(c) == cap(c)
    2009/11/10 23:00:06 log: len(10) cap(10)
    2009/11/10 23:00:07 log: len(10) cap(10)
    2009/11/10 23:00:08 log: len(10) cap(10)
    2009/11/10 23:00:08 len(c) < cap(c)
    2009/11/10 23:00:13 main
    

    References:

    Package reflect

    The Go Blog: The Laws of Reflection

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 oracle集群安装出bug
  • ¥15 关于#python#的问题:自动化测试
  • ¥20 问题请教!vue项目关于Nginx配置nonce安全策略的问题
  • ¥15 教务系统账号被盗号如何追溯设备
  • ¥20 delta降尺度方法,未来数据怎么降尺度
  • ¥15 c# 使用NPOI快速将datatable数据导入excel中指定sheet,要求快速高效
  • ¥15 再不同版本的系统上,TCP传输速度不一致
  • ¥15 高德地图2.0 版本点聚合中Marker的位置无法实时更新,如何解决呢?
  • ¥15 DIFY API Endpoint 问题。
  • ¥20 sub地址DHCP问题