红白配色, 头饰为校花紫荆花, 设计元素比较简约
还蛮受欢迎的, 做了梗图
附初稿纪念下
- 今年摸鱼了, 这悲惨的练习量…
红白配色, 头饰为校花紫荆花, 设计元素比较简约
还蛮受欢迎的, 做了梗图
附初稿纪念下
$
单行公式 $
$$
多行公式 $$
\\
公式内换行符\!
跟随\,
小空格\;
中空格\
大空格(约1字符)\quad
巨大空格(约2字符)\qquad
超巨大空格(约4字符)_
下标 ^
上标pSync
接收来自源Redis的数据再回放到目标Redisdatabase/sql
最主要还是实现了连接池逻辑Open会返回DB对象并开启一条connectionOpener线程
DB的核心方法: conn(ctx context.Context, strategy connReuseStrategy) (*driverConn, error)
DB的连接池: freeConn []*driverConn
DB的核心方法: putConnDBLocked(conn, err) bool
清理线程(connectionCleaner):
sql执行方法如Query,Exec,Ping等, 都会先去调conn获取连接, 再用其连接执行sql, 最后将putConnDBLocked(conn), (query是等rows全部scan完close再putConnDBLocked(conn))
关于resetSession最终的去处, 总的来说就是reset了个寂寞, 最终居然只是conn.SetReadDeadline(time.Time{})
?
http.Transport
这样的高频使用模块, 源码肯定得看看Transport是RoundTripper接口的实现: func RoundTrip(req *Request) (*Response, error)
Transport对外只提供方法: func RoundTrip(req *Request) (*Response, error)
Transport的内部对象idleLRU connLRU写得不错, 简单实现了LRU
http.Client就是在Tranport上简单封装一层
Transport就是一个连接池, 池子里面放着persistConn连接对象(idleConn map[connectMethodKey][]*persistConn)
queueForIdleConn: 根据请求的connectMethodKey从t.idleConn获取一个[]*persistConn切片, 并从切片中,根据算法获取一个有效的空闲连接。如果未获取到空闲连接,则将wantConn结构体放入t.idleConnWait[w.key]等待队列
连接释放逻辑在 (t *Transport) tryPutIdleConn(pconn *persistConn)
dialConnFor: 会调用t.dialConn获取一个真正的*persistConn。并将这个连接传递给w, 如果w已经获取到了连接,则会传递失败,此时调用t.putOrCloseIdleConn将连接放回空闲连接池。
dialConn:
dialConn里面这段代码是开启http2的核心