聊聊storagetapper的cache

codecraft      2022-02-13     375

关键词:

本文主要研究一下storagetapper的cache

cache

storagetapper/pipe/cache.go

type cacheEntry struct {
    pipe Pipe
    cfg  config.PipeConfig
}

var cache map[string]cacheEntry
var lock sync.Mutex
cache是一个cacheEntry的map,cacheEntry定义了Pipe和config.PipeConfig

CacheGet

storagetapper/pipe/cache.go

// CacheGet returns an instance of pipe with specified config from cache or
// creates new one if it's not in the cache yet
func CacheGet(pipeType string, cfg *config.PipeConfig, db *sql.DB) (Pipe, error) {
    lock.Lock()
    defer lock.Unlock()

    if cache == nil {
        cache = make(map[string]cacheEntry)
    }

    b, err := json.Marshal(cfg)
    if err != nil {
        return nil, err
    }

    h := sha256.New()
    _, _ = h.Write([]byte(pipeType + "$$$" + fmt.Sprintf("%p", db) + "$$$"))
    _, _ = h.Write(b)
    hs := fmt.Sprintf("%0x", h.Sum(nil))

    p, ok := cache[hs]
    if ok && reflect.DeepEqual(cfg, &p.cfg) {
        return p.pipe, nil
    }

    //FIXME: Implement proper collisions handling

    np, err := Create(pipeType, cfg, db)
    if err != nil {
        return nil, err
    }

    cache[hs] = cacheEntry{np, *cfg}

    log.Debugf("Created and cached new '%v' pipe (hash %v) with config: %+v. Cache size %v", pipeType, hs, *cfg, len(cache))

    return np, nil
}
CacheGet方法加锁操作cache,首先通过sha256来对pipeType及db来作为cache的key,然后取出cacheEntry,若存在则判断cfg与cacheEntry的cfg是否一样,如果一样则返回cacheEntry的pipe;否则通过Create创建Pipe,然后放入cache中

CacheDestroy

storagetapper/pipe/cache.go

// CacheDestroy releases all resources associated with cached pipes
func CacheDestroy() {
    lock.Lock()
    defer lock.Unlock()

    for h, p := range cache {
        log.Debugf("Closing %v pipe (hash %v) with config %+v", p.pipe.Type(), h, p.cfg)
        log.E(p.pipe.Close())
    }

    cache = nil
}
CacheDestroy方法通过加锁遍历cache,挨个执行pipe.Close()

小结

storagetapper的cache是一个cacheEntry的map,cacheEntry定义了Pipe和config.PipeConfig;CacheGet方法会获取cache,获取不到则Create;CacheDestroy则会通过加锁遍历cache,挨个执行pipe.Close()。

doc

  • storagetapper

聊聊storagetapper的pool

序本文主要研究一下storagetapper的poolThreadstoragetapper/pool/pool.gotypeThreadinterface{Start(muint,ffunc())Adjust(muint)Terminate()boolNumProcs()uint}Thread接口定义了Start、Adjust、Terminate、NumProcs方法poolstoragetap 查看详情

聊聊mysql:总览

...但从未认真总结、分析过这个数据库软件。最近想仔细地聊聊它,并横向对比一下和它类似的几款数据库产品。那么,从何说起呢?我们首先看一下它的架构,然后分别解释一下各部分如何工作的。先上架构图... 查看详情

kvm虚拟机存储速度

...分场景的,不同的场景其优化方向也是不同的,下面具体聊聊这4个方面的优化细节。1.CPUcpu优化需要搞清楚node、socket、core、logicprocessor的关系,知道内存、l3-cache、l2-cache、l1-cache和cpu的关系。针对kvm的优化,一般情况,都是通... 查看详情

聊聊dbsync的schedulable

序本文主要研究一下dbsync的SchedulableSchedulable//SchedulablerepresentanabstractionthatcanbescheduletypeSchedulablestruct{URLstringIDstring*contract.SyncSchedule*contract.ScheduleStatusstringstatusuint32}//NewS 查看详情

聊聊gost的generictaskpool

序本文主要研究一下gost的GenericTaskPoolGenericTaskPoolgost/sync/task_pool.go//GenericTaskPoolrepresentsangenerictaskpool.typeGenericTaskPoolinterface{//AddTaskwaitidleworkeraddtaskAddTask(ttask)bool//AddTaskAlw 查看详情

聊聊vue中的数据代理

今天和大家聊聊Vue中的数据代理,什么是数据代理数据代理:通过一个对象代理对另外一个对象中属性的操作Object.defineProperty这个方法也是Vue数据双向绑定原理的常见面试题。今天和大家聊聊Vue中的数据代理,什么是数据代理数... 查看详情

聊聊hystrix的源码(代码片段)

聊聊Hystrix的源码今天我们说一下Hystrix的源码的内容@EnableCircuitBreaker注解需要使用Hystrix的时候,需要我们通过@EnableCircuitBreaker来开启断路器,那么我们看一下这个注解:@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Inheri... 查看详情

聊聊mybatis的事务模块(代码片段)

@[TOC]聊聊Mybatis的事务模块mybatis定义了自己的事务接口来实现事务,这里同样也使用了工厂模式工厂模式中的产品Transaction接口:publicinterfaceTransactionConnectiongetConnection()throwsSQLException;voidcommit()throwsSQLException;voidrollback()throwsSQ 查看详情

聊聊go.cqrs的dispatcher

序本文主要研究一下go.cqrs的DispatcherDispatchertypeDispatcherinterface{Dispatch(CommandMessage)errorRegisterHandler(CommandHandler,...interface{})error}Dispatcher接口定义了Dispatch、RegisterHandler方法InMemoryDispatche 查看详情

聊聊基于lucene的搜索引擎核心技术实践

最近公司用到了ES搜索引擎,由于ES是基于Lucene的企业搜索引擎,无意间在“聊聊架构”微信公众号里发现了这篇文章,分享给大家。请点击链接:聊聊基于Lucene的搜索引擎核心技术实践 查看详情

聊聊mybatis的basestatementhandler的三个子类(代码片段)

@[TOC]聊聊Mybatis的BaseStatementHandler的三个子类今天我们继续聊StatementHandler的实现类PreparedStatementHandlerPreparedStatementHandler处理的是包含?占位符的sql语句,所以它需要进行参数绑定:@Overridepublicvoidparameterize(Statementstatement)thro 查看详情

聊聊hystrix

聊聊HystrixHystrix也是SpringCloud框架中的重要组件,它的功能有跳闸机制,也就是当服务的错误率超过一定的阈值的时候,Hystrix在一段时间内停止请求这个服务,它还有资源隔离的功能,也就是每个方法都可以使用一个小型的线程... 查看详情

聊聊typescript中的类型保护(代码片段)

聊聊TypeScript中的类型保护在TypeScript中使用联合类型时,往往会碰到这种尴尬的情况:interfaceBird //独有方法fly(); //共有方法layEggs();interfaceFish //独有方法swim(); //共有方法layEggs();functiongetSmallPet():Fish|Bird//...letpet=getSmallPet() 查看详情

聊聊mybatis的总体流程(代码片段)

@[TOC]聊聊Mybatis的总体流程我们前几篇文章分析了各个模块,今天我们吧这几个模块串起来,看看这些模块是怎么被Mybatis使用的我们先看一下Mybatis是怎么使用的StringconfigName="mybatis_config.xml";Readerreader=Resources.getResourceAsReader(configNam... 查看详情

聊聊mybatis的数据源之工厂模式

@[TOC]聊聊Mybatis的数据源之工厂模式工厂模式是比较简单的设计模式,Mybatis的数据源的部分使用了工厂模式工厂模式的工厂DataSourceFactory是工厂角色的接口层publicinterfaceDataSourceFactoryvoidsetProperties(Propertiesprops);DataSourcegetDataSource();... 查看详情

“匿名聊聊”作者谈如何打造现象级爆款小程序

  前段时间小程序“匿名聊聊”刷爆了朋友圈,可惜后面被屏蔽了。作为第一款现象级呈现爆炸级传播的小程序它是如何做到的呢?我们就跟随“匿名聊聊”作者来聊聊如何打造现象级爆款小程序。  作为第一... 查看详情

个人经历|聊聊我的安全成长之路

...天,看到TSRC的小密圈里发起了一个“大神”活动,聊聊初入行时,你心目中/身边的大神,刚看到活动的时候我也去参与了。在这里,重新梳理一下,也借此机会聊聊零基础的我是如何踏入安全行业,总结一下自身的成长... 查看详情

聊聊ribbon源码解读(代码片段)

聊聊Ribbon源码解读要说当今最流行的组件当然是SpringCloud,要说框架中最流行的负载均衡组件,非Ribbon莫属了@LoadBalanced注解当我们使用Ribbon的时候,spring中注入RestTemplate,并在上边添加@LoadBalanced,这样使用RestTemplate发送请求的... 查看详情