通道管理器

本文介绍了通道管理器的技术亮点,如热替换机制,用于解决项目中全局变量因频繁变动导致的操作不一致问题。同时阐述了管理器如何初始化自定义变量,并通过接口实现对通道信息的收集、监控和控制。文章展示了良好的编码规范和设计思路。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

技术亮点提要

  • 热替换:主要是项目中经常会引用其他结构的变量,但是对方的变量又是时刻在变,随时申请,这就会引起操作不一致。热替换就是解决这种情况的一种方法。其中这样有益于面向接口设计的带来的一个好处,就是getXXX()方法。

全局变量

首先针对全局变量和特定类型,我们需要进行自定义和初始化部分变量

// 被用来表示通道管理器的状态的类型。
type ChannelManagerStatus uint8
const (
    CHANNEL_MANAGER_STATUS_UNINITIALIZED ChannelManagerStatus = 0 // 未初始化状态。
    CHANNEL_MANAGER_STATUS_INITIALIZED   ChannelManagerStatus = 1 // 已初始化状态。
    CHANNEL_MANAGER_STATUS_CLOSED        ChannelManagerStatus = 2 // 已关闭状态。
)
// 表示状态代码与状态名称之间的映射关系的字典。
var statusNameMap = map[ChannelManagerStatus]string{
    CHANNEL_MANAGER_STATUS_UNINITIALIZED: "uninitialized",
    CHANNEL_MANAGER_STATUS_INITIALIZED:   "initialized",
    CHANNEL_MANAGER_STATUS_CLOSED:        "closed",
}

接口实现

作为管理器,首先就要收集和监控通道的各项信息,同时对齐有一定的控制作用。

// 通道管理器的接口类型。
type ChannelManager interface {
    // 初始化通道管理器。
    // 参数channelArgs代表通道参数的容器。
    // 参数reset指明是否重新初始化通道管理器。
    Init(channelArgs base.ChannelArgs, reset bool) bool
    // 关闭通道管理器。
    Close() bool
    // 获取请求传输通道。
    ReqChan() (chan base.Request, error)
    // 获取响应传输通道。
    RespChan() (chan base.Response, error)
    // 获取条目传输通道。
    ItemChan() (chan base.Item, error)
    // 获取错误传输通道。
    ErrorChan() (chan error, error)
    // 获取通道管理器的状态。
    Status() ChannelManagerStatus
    // 获取摘要信息。
    Summary() string
}

具体实现

// 创建通道管理器。
func NewChannelManager(channelArgs base.ChannelArgs) ChannelManager {
    chanman := &myChannelManager{}
    chanman.Init(channelArgs, true)
    return chanman
}
// 通道管理器的实现类型。
type myChannelManager struct {
    channelArgs base.ChannelArgs     // 通道参数的容器。
    reqCh       chan base.Request    // 请求通道。
    respCh      chan base.Response   // 响应通道。
    itemCh      chan base.Item       // 条目通道。
    errorCh     chan error           // 错误通道。
    status      ChannelManagerStatus // 通道管理器的状态。
    rwmutex     sync.RWMutex         // 读写锁。
}
func (chanman *myChannelManager) Init(channelArgs base.ChannelArgs, reset bool) bool {
    if err := channelArgs.Check(); err != nil {
        panic(err)
    }
    chanman.rwmutex.Lock()
    defer chanman.rwmutex.Unlock()
    if chanman.status == CHANNEL_MANAGER_STATUS_INITIALIZED && !reset {
        return false
    }
    chanman.channelArgs = channelArgs
    chanman.reqCh = make(chan base.Request, channelArgs.ReqChanLen())
    chanman.respCh = make(chan base.Response, channelArgs.RespChanLen())
    chanman.itemCh = make(chan base.Item, channelArgs.ItemChanLen())
    chanman.errorCh = make(chan error, channelArgs.ErrorChanLen())
    chanman.status = CHANNEL_MANAGER_STATUS_INITIALIZED
    return true
}
func (chanman *myChannelManager) Close() bool {
    chanman.rwmutex.Lock()
    defer chanman.rwmutex.Unlock()
    if chanman.status != CHANNEL_MANAGER_STATUS_INITIALIZED {
        return false
    }
    close(chanman.reqCh)
    close(chanman.respCh)
    close(chanman.itemCh)
    close(chanman.errorCh)
    chanman.status = CHANNEL_MANAGER_STATUS_CLOSED
    return true
}
func (chanman *myChannelManager) ReqChan() (chan base.Request, error) {
    chanman.rwmutex.RLock()
    defer chanman.rwmutex.RUnlock()
    if err := chanman.checkStatus(); err != nil {
        return nil, err
    }
    return chanman.reqCh, nil
}
func (chanman *myChannelManager) RespChan() (chan base.Response, error) {
    chanman.rwmutex.RLock()
    defer chanman.rwmutex.RUnlock()
    if err := chanman.checkStatus(); err != nil {
        return nil, err
    }
    return chanman.respCh, nil
}
func (chanman *myChannelManager) ItemChan() (chan base.Item, error) {
    chanman.rwmutex.RLock()
    defer chanman.rwmutex.RUnlock()
    if err := chanman.checkStatus(); err != nil {
        return nil, err
    }
    return chanman.itemCh, nil
}
func (chanman *myChannelManager) ErrorChan() (chan error, error) {
    chanman.rwmutex.RLock()
    defer chanman.rwmutex.RUnlock()
    if err := chanman.checkStatus(); err != nil {
        return nil, err
    }
    return chanman.errorCh, nil
}
// 检查状态。在获取通道的时候,通道管理器应处于已初始化状态。
// 如果通道管理器未处于已初始化状态,那么本方法将会返回一个非nil的错误值。
func (chanman *myChannelManager) checkStatus() error {
    if chanman.status == CHANNEL_MANAGER_STATUS_INITIALIZED {
        return nil
    }
    statusName, ok := statusNameMap[chanman.status]
    if !ok {
        statusName = fmt.Sprintf("%d", chanman.status)
    }
    errMsg :=
        fmt.Sprintf("The undesirable status of channel manager: %s!\n",
            statusName)
    return errors.New(errMsg)

启发

这是一个完整的程序,里面编码格式比较规范。设计角度比较相信。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值