mirror of
https://github.com/TeaOSLab/EdgeNode.git
synced 2025-11-06 01:50:26 +08:00
实现缓存策略的部分功能
This commit is contained in:
1
build/www/.gitignore
vendored
Normal file
1
build/www/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
cache
|
||||||
77
internal/caches/file_writer.go
Normal file
77
internal/caches/file_writer.go
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
package caches
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
type FileWriter struct {
|
||||||
|
rawWriter *os.File
|
||||||
|
key string
|
||||||
|
size int64
|
||||||
|
expiredAt int64
|
||||||
|
locker *sync.RWMutex
|
||||||
|
isReleased bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewFileWriter(rawWriter *os.File, key string, expiredAt int64, locker *sync.RWMutex) *FileWriter {
|
||||||
|
return &FileWriter{
|
||||||
|
key: key,
|
||||||
|
rawWriter: rawWriter,
|
||||||
|
expiredAt: expiredAt,
|
||||||
|
locker: locker,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 写入数据
|
||||||
|
func (this *FileWriter) Write(data []byte) (n int, err error) {
|
||||||
|
n, err = this.rawWriter.Write(data)
|
||||||
|
this.size += int64(n)
|
||||||
|
if err != nil {
|
||||||
|
_ = this.rawWriter.Close()
|
||||||
|
_ = os.Remove(this.rawWriter.Name())
|
||||||
|
this.Release()
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭
|
||||||
|
func (this *FileWriter) Close() error {
|
||||||
|
// 写入结束符
|
||||||
|
_, err := this.rawWriter.WriteString("\n$$$")
|
||||||
|
if err != nil {
|
||||||
|
_ = os.Remove(this.rawWriter.Name())
|
||||||
|
}
|
||||||
|
|
||||||
|
this.Release()
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 丢弃
|
||||||
|
func (this *FileWriter) Discard() error {
|
||||||
|
err := os.Remove(this.rawWriter.Name())
|
||||||
|
this.Release()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *FileWriter) Size() int64 {
|
||||||
|
return this.size
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *FileWriter) ExpiredAt() int64 {
|
||||||
|
return this.expiredAt
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *FileWriter) Key() string {
|
||||||
|
return this.key
|
||||||
|
}
|
||||||
|
|
||||||
|
// 释放锁,一定要调用
|
||||||
|
func (this *FileWriter) Release() {
|
||||||
|
if this.isReleased {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.isReleased = true
|
||||||
|
this.locker.Unlock()
|
||||||
|
}
|
||||||
@@ -123,9 +123,9 @@ func (this *Manager) FindStorageWithPolicy(policyId int64) StorageInterface {
|
|||||||
// 根据策略获取存储对象
|
// 根据策略获取存储对象
|
||||||
func (this *Manager) NewStorageWithPolicy(policy *serverconfigs.HTTPCachePolicy) StorageInterface {
|
func (this *Manager) NewStorageWithPolicy(policy *serverconfigs.HTTPCachePolicy) StorageInterface {
|
||||||
switch policy.Type {
|
switch policy.Type {
|
||||||
case serverconfigs.CachePolicyTypeFile:
|
case serverconfigs.CachePolicyStorageFile:
|
||||||
return NewFileStorage(policy)
|
return NewFileStorage(policy)
|
||||||
case serverconfigs.CachePolicyTypeMemory:
|
case serverconfigs.CachePolicyStorageMemory:
|
||||||
return nil // TODO 暂时返回nil
|
return nil // TODO 暂时返回nil
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ var (
|
|||||||
|
|
||||||
type FileStorage struct {
|
type FileStorage struct {
|
||||||
policy *serverconfigs.HTTPCachePolicy
|
policy *serverconfigs.HTTPCachePolicy
|
||||||
cacheConfig *serverconfigs.HTTPFileCacheConfig
|
cacheConfig *serverconfigs.HTTPFileCacheStorage
|
||||||
|
|
||||||
list *List
|
list *List
|
||||||
locker sync.RWMutex
|
locker sync.RWMutex
|
||||||
@@ -76,7 +76,7 @@ func (this *FileStorage) Init() error {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
// 配置
|
// 配置
|
||||||
cacheConfig := &serverconfigs.HTTPFileCacheConfig{}
|
cacheConfig := &serverconfigs.HTTPFileCacheStorage{}
|
||||||
optionsJSON, err := json.Marshal(this.policy.Options)
|
optionsJSON, err := json.Marshal(this.policy.Options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -119,7 +119,7 @@ func (this *FileStorage) Init() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *FileStorage) Read(key string, readerBuf []byte, callback func(data []byte, expiredAt int64)) error {
|
func (this *FileStorage) Read(key string, readerBuf []byte, callback func(data []byte, size int64, expiredAt int64, isEOF bool)) error {
|
||||||
hash, path := this.keyPath(key)
|
hash, path := this.keyPath(key)
|
||||||
if !this.list.Exist(hash) {
|
if !this.list.Exist(hash) {
|
||||||
return ErrNotFound
|
return ErrNotFound
|
||||||
@@ -185,6 +185,7 @@ func (this *FileStorage) Read(key string, readerBuf []byte, callback func(data [
|
|||||||
}
|
}
|
||||||
startOffset := SizeExpiredAt + SizeKeyLength + keyLength + SizeNL
|
startOffset := SizeExpiredAt + SizeKeyLength + keyLength + SizeNL
|
||||||
size := int(offset) + SizeEnd - startOffset
|
size := int(offset) + SizeEnd - startOffset
|
||||||
|
valueSize := offset - int64(startOffset)
|
||||||
|
|
||||||
_, err = fp.Seek(int64(startOffset), io.SeekStart)
|
_, err = fp.Seek(int64(startOffset), io.SeekStart)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -199,10 +200,10 @@ func (this *FileStorage) Read(key string, readerBuf []byte, callback func(data [
|
|||||||
if n <= SizeEnd-size { // 已经到了末尾
|
if n <= SizeEnd-size { // 已经到了末尾
|
||||||
break
|
break
|
||||||
} else {
|
} else {
|
||||||
callback(readerBuf[:n-(SizeEnd-size)], expiredAt)
|
callback(readerBuf[:n-(SizeEnd-size)], valueSize, expiredAt, true)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
callback(readerBuf[:n], expiredAt)
|
callback(readerBuf[:n], valueSize, expiredAt, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -218,7 +219,7 @@ func (this *FileStorage) Read(key string, readerBuf []byte, callback func(data [
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 打开缓存文件等待写入
|
// 打开缓存文件等待写入
|
||||||
func (this *FileStorage) Open(key string, expiredAt int64) (*Writer, error) {
|
func (this *FileStorage) Open(key string, expiredAt int64) (Writer, error) {
|
||||||
hash := stringutil.Md5(key)
|
hash := stringutil.Md5(key)
|
||||||
dir := this.cacheConfig.Dir + "/p" + strconv.FormatInt(this.policy.Id, 10) + "/" + hash[:2] + "/" + hash[2:4]
|
dir := this.cacheConfig.Dir + "/p" + strconv.FormatInt(this.policy.Id, 10) + "/" + hash[:2] + "/" + hash[2:4]
|
||||||
_, err := os.Stat(dir)
|
_, err := os.Stat(dir)
|
||||||
@@ -277,7 +278,7 @@ func (this *FileStorage) Open(key string, expiredAt int64) (*Writer, error) {
|
|||||||
|
|
||||||
isOk = true
|
isOk = true
|
||||||
|
|
||||||
return NewWriter(writer, key, expiredAt, &this.locker), nil
|
return NewFileWriter(writer, key, expiredAt, &this.locker), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 写入缓存数据
|
// 写入缓存数据
|
||||||
@@ -289,6 +290,7 @@ func (this *FileStorage) Write(key string, expiredAt int64, valueReader io.Reade
|
|||||||
|
|
||||||
hash := stringutil.Md5(key)
|
hash := stringutil.Md5(key)
|
||||||
dir := this.cacheConfig.Dir + "/p" + strconv.FormatInt(this.policy.Id, 10) + "/" + hash[:2] + "/" + hash[2:4]
|
dir := this.cacheConfig.Dir + "/p" + strconv.FormatInt(this.policy.Id, 10) + "/" + hash[:2] + "/" + hash[2:4]
|
||||||
|
|
||||||
_, err := os.Stat(dir)
|
_, err := os.Stat(dir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !os.IsNotExist(err) {
|
if !os.IsNotExist(err) {
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package caches
|
package caches
|
||||||
|
|
||||||
import "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||||
|
)
|
||||||
|
|
||||||
// 缓存存储接口
|
// 缓存存储接口
|
||||||
type StorageInterface interface {
|
type StorageInterface interface {
|
||||||
@@ -8,10 +10,10 @@ type StorageInterface interface {
|
|||||||
Init() error
|
Init() error
|
||||||
|
|
||||||
// 读取缓存
|
// 读取缓存
|
||||||
Read(key string, readerBuf []byte, callback func(data []byte, expiredAt int64)) error
|
Read(key string, readerBuf []byte, callback func(data []byte, size int64, expiredAt int64, isEOF bool)) error
|
||||||
|
|
||||||
// 打开缓存写入器等待写入
|
// 打开缓存写入器等待写入
|
||||||
Open(key string, expiredAt int64) (*Writer, error)
|
Open(key string, expiredAt int64) (Writer, error)
|
||||||
|
|
||||||
// 删除某个键值对应的缓存
|
// 删除某个键值对应的缓存
|
||||||
Delete(key string) error
|
Delete(key string) error
|
||||||
@@ -30,4 +32,7 @@ type StorageInterface interface {
|
|||||||
|
|
||||||
// 获取当前存储的Policy
|
// 获取当前存储的Policy
|
||||||
Policy() *serverconfigs.HTTPCachePolicy
|
Policy() *serverconfigs.HTTPCachePolicy
|
||||||
|
|
||||||
|
// 将缓存添加到列表
|
||||||
|
AddToList(item *Item)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,71 +1,19 @@
|
|||||||
package caches
|
package caches
|
||||||
|
|
||||||
import (
|
// 缓存内容写入接口
|
||||||
"os"
|
type Writer interface {
|
||||||
"sync"
|
// 写入数据
|
||||||
)
|
Write(data []byte) (n int, err error)
|
||||||
|
|
||||||
type Writer struct {
|
// 关闭
|
||||||
rawWriter *os.File
|
Close() error
|
||||||
key string
|
|
||||||
size int64
|
// 丢弃
|
||||||
expiredAt int64
|
Discard() error
|
||||||
locker *sync.RWMutex
|
|
||||||
isReleased bool
|
// Key
|
||||||
}
|
Key() string
|
||||||
|
|
||||||
func NewWriter(rawWriter *os.File, key string, expiredAt int64, locker *sync.RWMutex) *Writer {
|
// 过期时间
|
||||||
return &Writer{
|
ExpiredAt() int64
|
||||||
key: key,
|
|
||||||
rawWriter: rawWriter,
|
|
||||||
expiredAt: expiredAt,
|
|
||||||
locker: locker,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 写入数据
|
|
||||||
func (this *Writer) Write(data []byte) error {
|
|
||||||
n, err := this.rawWriter.Write(data)
|
|
||||||
this.size += int64(n)
|
|
||||||
if err != nil {
|
|
||||||
_ = this.rawWriter.Close()
|
|
||||||
_ = os.Remove(this.rawWriter.Name())
|
|
||||||
this.Release()
|
|
||||||
}
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 关闭
|
|
||||||
func (this *Writer) Close() error {
|
|
||||||
// 写入结束符
|
|
||||||
_, err := this.rawWriter.WriteString("\n$$$")
|
|
||||||
if err != nil {
|
|
||||||
_ = os.Remove(this.rawWriter.Name())
|
|
||||||
}
|
|
||||||
|
|
||||||
this.Release()
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *Writer) Size() int64 {
|
|
||||||
return this.size
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *Writer) ExpiredAt() int64 {
|
|
||||||
return this.expiredAt
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *Writer) Key() string {
|
|
||||||
return this.key
|
|
||||||
}
|
|
||||||
|
|
||||||
// 释放锁,一定要调用
|
|
||||||
func (this *Writer) Release() {
|
|
||||||
if this.isReleased {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.isReleased = true
|
|
||||||
this.locker.Unlock()
|
|
||||||
}
|
}
|
||||||
|
|||||||
47
internal/caches/writer_gzip.go
Normal file
47
internal/caches/writer_gzip.go
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
package caches
|
||||||
|
|
||||||
|
import "compress/gzip"
|
||||||
|
|
||||||
|
type gzipWriter struct {
|
||||||
|
rawWriter Writer
|
||||||
|
writer *gzip.Writer
|
||||||
|
key string
|
||||||
|
expiredAt int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewGzipWriter(gw Writer, key string, expiredAt int64) Writer {
|
||||||
|
return &gzipWriter{
|
||||||
|
rawWriter: gw,
|
||||||
|
writer: gzip.NewWriter(gw),
|
||||||
|
key: key,
|
||||||
|
expiredAt: expiredAt,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *gzipWriter) Write(data []byte) (n int, err error) {
|
||||||
|
return this.writer.Write(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *gzipWriter) Close() error {
|
||||||
|
err := this.writer.Close()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return this.rawWriter.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *gzipWriter) Discard() error {
|
||||||
|
err := this.writer.Close()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return this.rawWriter.Discard()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *gzipWriter) Key() string {
|
||||||
|
return this.key
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *gzipWriter) ExpiredAt() int64 {
|
||||||
|
return this.expiredAt
|
||||||
|
}
|
||||||
@@ -123,23 +123,26 @@ func (this *APIStream) handleWriteCache(message *pb.NodeStreamMessage) error {
|
|||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
writer, err := storage.Open(msg.Key, time.Now().Unix()+msg.LifeSeconds)
|
expiredAt := time.Now().Unix() + msg.LifeSeconds
|
||||||
|
writer, err := storage.Open(msg.Key, expiredAt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
this.replyFail(message.RequestId, "prepare writing failed: "+err.Error())
|
this.replyFail(message.RequestId, "prepare writing failed: "+err.Error())
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
defer func() {
|
_, err = writer.Write(msg.Value)
|
||||||
// 不用担心重复
|
|
||||||
_ = writer.Close()
|
|
||||||
}()
|
|
||||||
|
|
||||||
err = writer.Write(msg.Value)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
_ = writer.Discard()
|
||||||
this.replyFail(message.RequestId, "write failed: "+err.Error())
|
this.replyFail(message.RequestId, "write failed: "+err.Error())
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_ = writer.Close()
|
err = writer.Close()
|
||||||
|
if err == nil {
|
||||||
|
storage.AddToList(&caches.Item{
|
||||||
|
Key: msg.Key,
|
||||||
|
ExpiredAt: expiredAt,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
this.replyOk(message.RequestId, "write ok")
|
this.replyOk(message.RequestId, "write ok")
|
||||||
|
|
||||||
@@ -167,7 +170,7 @@ func (this *APIStream) handleReadCache(message *pb.NodeStreamMessage) error {
|
|||||||
|
|
||||||
buf := make([]byte, 1024)
|
buf := make([]byte, 1024)
|
||||||
size := 0
|
size := 0
|
||||||
err = storage.Read(msg.Key, buf, func(data []byte, expiredAt int64) {
|
err = storage.Read(msg.Key, buf, func(data []byte, valueSize int64, expiredAt int64, isEOF bool) {
|
||||||
size += len(data)
|
size += len(data)
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -324,7 +327,7 @@ func (this *APIStream) handlePreheatCache(message *pb.NodeStreamMessage) error {
|
|||||||
locker.Unlock()
|
locker.Unlock()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// TODO 可以自定义Header
|
// TODO 可以在管理界面自定义Header
|
||||||
req.Header.Set("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36")
|
req.Header.Set("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36")
|
||||||
req.Header.Set("Accept-Encoding", "gzip, deflate, br") // TODO 这里需要记录下缓存是否为gzip的
|
req.Header.Set("Accept-Encoding", "gzip, deflate, br") // TODO 这里需要记录下缓存是否为gzip的
|
||||||
resp, err := client.Do(req)
|
resp, err := client.Do(req)
|
||||||
@@ -339,7 +342,8 @@ func (this *APIStream) handlePreheatCache(message *pb.NodeStreamMessage) error {
|
|||||||
_ = resp.Body.Close()
|
_ = resp.Body.Close()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
writer, err := storage.Open(key, time.Now().Unix()+8600) // TODO 可以设置缓存过期事件
|
expiredAt := time.Now().Unix() + 8600
|
||||||
|
writer, err := storage.Open(key, expiredAt) // TODO 可以设置缓存过期事件
|
||||||
if err != nil {
|
if err != nil {
|
||||||
locker.Lock()
|
locker.Lock()
|
||||||
errorMessages = append(errorMessages, "open cache writer failed: "+key+": "+err.Error())
|
errorMessages = append(errorMessages, "open cache writer failed: "+key+": "+err.Error())
|
||||||
@@ -352,7 +356,7 @@ func (this *APIStream) handlePreheatCache(message *pb.NodeStreamMessage) error {
|
|||||||
for {
|
for {
|
||||||
n, err := resp.Body.Read(buf)
|
n, err := resp.Body.Read(buf)
|
||||||
if n > 0 {
|
if n > 0 {
|
||||||
writerErr := writer.Write(buf[:n])
|
_, writerErr := writer.Write(buf[:n])
|
||||||
if writerErr != nil {
|
if writerErr != nil {
|
||||||
locker.Lock()
|
locker.Lock()
|
||||||
errorMessages = append(errorMessages, "write failed: "+key+": "+writerErr.Error())
|
errorMessages = append(errorMessages, "write failed: "+key+": "+writerErr.Error())
|
||||||
@@ -362,7 +366,13 @@ func (this *APIStream) handlePreheatCache(message *pb.NodeStreamMessage) error {
|
|||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == io.EOF {
|
if err == io.EOF {
|
||||||
_ = writer.Close()
|
err = writer.Close()
|
||||||
|
if err == nil {
|
||||||
|
storage.AddToList(&caches.Item{
|
||||||
|
Key: key,
|
||||||
|
ExpiredAt: expiredAt,
|
||||||
|
})
|
||||||
|
}
|
||||||
isClosed = true
|
isClosed = true
|
||||||
} else {
|
} else {
|
||||||
locker.Lock()
|
locker.Lock()
|
||||||
|
|||||||
@@ -56,17 +56,23 @@ type HTTPRequest struct {
|
|||||||
rewriteRule *serverconfigs.HTTPRewriteRule // 匹配到的重写规则
|
rewriteRule *serverconfigs.HTTPRewriteRule // 匹配到的重写规则
|
||||||
rewriteReplace string // 重写规则的目标
|
rewriteReplace string // 重写规则的目标
|
||||||
rewriteIsExternalURL bool // 重写目标是否为外部URL
|
rewriteIsExternalURL bool // 重写目标是否为外部URL
|
||||||
cachePolicy *serverconfigs.HTTPCachePolicy // 缓存策略
|
cacheRef *serverconfigs.HTTPCacheRef // 缓存设置
|
||||||
cacheCond *serverconfigs.HTTPCacheCond // 缓存条件
|
cacheKey string // 缓存使用的Key
|
||||||
}
|
}
|
||||||
|
|
||||||
// 初始化
|
// 初始化
|
||||||
func (this *HTTPRequest) init() {
|
func (this *HTTPRequest) init() {
|
||||||
this.writer = NewHTTPWriter(this, this.RawWriter)
|
this.writer = NewHTTPWriter(this, this.RawWriter)
|
||||||
this.web = &serverconfigs.HTTPWebConfig{}
|
this.web = &serverconfigs.HTTPWebConfig{IsOn: true}
|
||||||
this.uri = this.RawReq.URL.RequestURI()
|
this.uri = this.RawReq.URL.RequestURI()
|
||||||
this.rawURI = this.uri
|
this.rawURI = this.uri
|
||||||
this.varMapping = map[string]string{}
|
this.varMapping = map[string]string{
|
||||||
|
// 缓存相关初始化
|
||||||
|
"cache.status": "BYPASS",
|
||||||
|
"cache.policy.name": "",
|
||||||
|
"cache.policy.id": "0",
|
||||||
|
"cache.policy.type": "",
|
||||||
|
}
|
||||||
this.requestFromTime = time.Now()
|
this.requestFromTime = time.Now()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,18 +109,15 @@ func (this *HTTPRequest) Do() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Gzip
|
// Gzip
|
||||||
shouldCloseWriter := false
|
if this.web.GzipRef != nil && this.web.GzipRef.IsOn && this.web.Gzip != nil && this.web.Gzip.IsOn && this.web.Gzip.Level > 0 {
|
||||||
if this.web.Gzip != nil && this.web.Gzip.IsOn && this.web.Gzip.Level > 0 {
|
|
||||||
shouldCloseWriter = true
|
|
||||||
this.writer.Gzip(this.web.Gzip)
|
this.writer.Gzip(this.web.Gzip)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 开始调用
|
// 开始调用
|
||||||
this.doBegin()
|
this.doBegin()
|
||||||
|
|
||||||
if shouldCloseWriter {
|
// 关闭写入
|
||||||
this.writer.Close()
|
this.writer.Close()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 开始调用
|
// 开始调用
|
||||||
@@ -125,6 +128,13 @@ func (this *HTTPRequest) doBegin() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 缓存
|
||||||
|
if this.web.Cache != nil && this.web.Cache.IsOn {
|
||||||
|
if this.doCacheRead() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 重写规则
|
// 重写规则
|
||||||
if this.rewriteRule != nil {
|
if this.rewriteRule != nil {
|
||||||
if this.doRewrite() {
|
if this.doRewrite() {
|
||||||
@@ -132,9 +142,6 @@ func (this *HTTPRequest) doBegin() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 缓存
|
|
||||||
// TODO
|
|
||||||
|
|
||||||
// root
|
// root
|
||||||
if this.web.Root != nil && this.web.Root.IsOn {
|
if this.web.Root != nil && this.web.Root.IsOn {
|
||||||
// 如果处理成功,则终止请求的处理
|
// 如果处理成功,则终止请求的处理
|
||||||
@@ -237,9 +244,15 @@ func (this *HTTPRequest) configureWeb(web *serverconfigs.HTTPWebConfig, isTop bo
|
|||||||
|
|
||||||
// gzip
|
// gzip
|
||||||
if web.GzipRef != nil && (web.GzipRef.IsPrior || isTop) {
|
if web.GzipRef != nil && (web.GzipRef.IsPrior || isTop) {
|
||||||
|
this.web.GzipRef = web.GzipRef
|
||||||
this.web.Gzip = web.Gzip
|
this.web.Gzip = web.Gzip
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// cache
|
||||||
|
if web.Cache != nil && (web.Cache.IsPrior || isTop) {
|
||||||
|
this.web.Cache = web.Cache
|
||||||
|
}
|
||||||
|
|
||||||
// 重写规则
|
// 重写规则
|
||||||
if len(web.RewriteRefs) > 0 {
|
if len(web.RewriteRefs) > 0 {
|
||||||
for index, ref := range web.RewriteRefs {
|
for index, ref := range web.RewriteRefs {
|
||||||
|
|||||||
153
internal/nodes/http_request_cache.go
Normal file
153
internal/nodes/http_request_cache.go
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
package nodes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"github.com/TeaOSLab/EdgeNode/internal/caches"
|
||||||
|
"github.com/iwind/TeaGo/logs"
|
||||||
|
"github.com/iwind/TeaGo/types"
|
||||||
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 读取缓存
|
||||||
|
func (this *HTTPRequest) doCacheRead() (shouldStop bool) {
|
||||||
|
if this.web.Cache == nil || !this.web.Cache.IsOn || len(this.web.Cache.CacheRefs) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查条件
|
||||||
|
for _, cacheRef := range this.web.Cache.CacheRefs {
|
||||||
|
if !cacheRef.IsOn ||
|
||||||
|
cacheRef.CachePolicyId == 0 ||
|
||||||
|
cacheRef.CachePolicy == nil ||
|
||||||
|
!cacheRef.CachePolicy.IsOn ||
|
||||||
|
cacheRef.Conds == nil ||
|
||||||
|
!cacheRef.Conds.HasRequestConds() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if cacheRef.Conds.MatchRequest(this.Format) {
|
||||||
|
this.cacheRef = cacheRef
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if this.cacheRef == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 相关变量
|
||||||
|
this.varMapping["cache.policy.name"] = this.cacheRef.CachePolicy.Name
|
||||||
|
this.varMapping["cache.policy.id"] = strconv.FormatInt(this.cacheRef.CachePolicy.Id, 10)
|
||||||
|
this.varMapping["cache.policy.type"] = this.cacheRef.CachePolicy.Type
|
||||||
|
|
||||||
|
// Cache-Pragma
|
||||||
|
if this.cacheRef.EnableRequestCachePragma {
|
||||||
|
if this.RawReq.Header.Get("Cache-Control") == "no-cache" || this.RawReq.Header.Get("Pragma") == "no-cache" {
|
||||||
|
this.cacheRef = nil
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO 支持Vary Header
|
||||||
|
|
||||||
|
// 检查是否有缓存
|
||||||
|
key := this.Format(this.cacheRef.Key)
|
||||||
|
if len(key) == 0 {
|
||||||
|
this.cacheRef = nil
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.cacheKey = key
|
||||||
|
|
||||||
|
// 读取缓存
|
||||||
|
storage := caches.SharedManager.FindStorageWithPolicy(this.cacheRef.CachePolicyId)
|
||||||
|
if storage == nil {
|
||||||
|
this.cacheRef = nil
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
buf := bytePool32k.Get()
|
||||||
|
defer func() {
|
||||||
|
bytePool32k.Put(buf)
|
||||||
|
}()
|
||||||
|
|
||||||
|
isBroken := false
|
||||||
|
headerBuf := []byte{}
|
||||||
|
statusCode := http.StatusOK
|
||||||
|
statusFound := false
|
||||||
|
headerFound := false
|
||||||
|
|
||||||
|
err := storage.Read(key, buf, func(data []byte, valueSize int64, expiredAt int64, isEOF bool) {
|
||||||
|
if isBroken {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果Header已发送完毕
|
||||||
|
if headerFound {
|
||||||
|
_, _ = this.writer.Write(data)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
headerBuf = append(headerBuf, data...)
|
||||||
|
|
||||||
|
if !statusFound {
|
||||||
|
lineIndex := bytes.IndexByte(headerBuf, '\n')
|
||||||
|
if lineIndex < 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
pieces := bytes.Split(headerBuf[:lineIndex], []byte{' '})
|
||||||
|
if len(pieces) < 2 {
|
||||||
|
isBroken = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
statusCode = types.Int(string(pieces[1]))
|
||||||
|
statusFound = true
|
||||||
|
headerBuf = headerBuf[lineIndex+1:]
|
||||||
|
|
||||||
|
// cache相关变量
|
||||||
|
this.varMapping["cache.status"] = "HIT"
|
||||||
|
}
|
||||||
|
|
||||||
|
for {
|
||||||
|
lineIndex := bytes.IndexByte(headerBuf, '\n')
|
||||||
|
if lineIndex < 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if lineIndex == 0 || lineIndex == 1 {
|
||||||
|
headerFound = true
|
||||||
|
|
||||||
|
this.processResponseHeaders(statusCode)
|
||||||
|
this.writer.WriteHeader(statusCode)
|
||||||
|
|
||||||
|
_, _ = this.writer.Write(headerBuf[lineIndex+1:])
|
||||||
|
headerBuf = nil
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分解Header
|
||||||
|
line := headerBuf[:lineIndex]
|
||||||
|
colonIndex := bytes.IndexByte(line, ':')
|
||||||
|
if colonIndex <= 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
this.writer.Header().Set(string(line[:colonIndex]), string(bytes.TrimSpace(line[colonIndex+1:])))
|
||||||
|
headerBuf = headerBuf[lineIndex+1:]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
if err == caches.ErrNotFound {
|
||||||
|
// cache相关变量
|
||||||
|
this.varMapping["cache.status"] = "MISS"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
logs.Println("read from cache failed: " + err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if isBroken {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
@@ -5,6 +5,9 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"compress/gzip"
|
"compress/gzip"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||||
|
"github.com/TeaOSLab/EdgeNode/internal/caches"
|
||||||
|
"github.com/TeaOSLab/EdgeNode/internal/utils"
|
||||||
|
"github.com/iwind/TeaGo/lists"
|
||||||
"github.com/iwind/TeaGo/logs"
|
"github.com/iwind/TeaGo/logs"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
@@ -26,6 +29,9 @@ type HTTPWriter struct {
|
|||||||
body []byte
|
body []byte
|
||||||
gzipBodyBuffer *bytes.Buffer // 当使用gzip压缩时使用
|
gzipBodyBuffer *bytes.Buffer // 当使用gzip压缩时使用
|
||||||
gzipBodyWriter *gzip.Writer // 当使用gzip压缩时使用
|
gzipBodyWriter *gzip.Writer // 当使用gzip压缩时使用
|
||||||
|
|
||||||
|
cacheWriter caches.Writer // 缓存写入
|
||||||
|
cacheStorage caches.StorageInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
// 包装对象
|
// 包装对象
|
||||||
@@ -59,62 +65,8 @@ func (this *HTTPWriter) Gzip(config *serverconfigs.HTTPGzipConfig) {
|
|||||||
|
|
||||||
// 准备输出
|
// 准备输出
|
||||||
func (this *HTTPWriter) Prepare(size int64) {
|
func (this *HTTPWriter) Prepare(size int64) {
|
||||||
if this.gzipConfig == nil || this.gzipConfig.Level <= 0 {
|
this.prepareGzip(size)
|
||||||
return
|
this.prepareCache(size)
|
||||||
}
|
|
||||||
|
|
||||||
// 判断Accept是否支持gzip
|
|
||||||
if !strings.Contains(this.req.requestHeader("Accept-Encoding"), "gzip") {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 尺寸和类型
|
|
||||||
if size < this.gzipConfig.MinBytes() || (this.gzipConfig.MaxBytes() > 0 && size > this.gzipConfig.MaxBytes()) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 校验其他条件
|
|
||||||
if this.gzipConfig.Conds != nil {
|
|
||||||
if len(this.gzipConfig.Conds.Groups) > 0 {
|
|
||||||
if !this.gzipConfig.Conds.MatchRequest(this.req.Format) || !this.gzipConfig.Conds.MatchResponse(this.req.Format) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// 默认校验文档类型
|
|
||||||
contentType := this.writer.Header().Get("Content-Type")
|
|
||||||
if len(contentType) > 0 && (!strings.HasPrefix(contentType, "text/") && !strings.HasPrefix(contentType, "application/")) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 如果已经有编码则不处理
|
|
||||||
if len(this.writer.Header().Get("Content-Encoding")) > 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// gzip writer
|
|
||||||
var err error = nil
|
|
||||||
this.gzipWriter, err = gzip.NewWriterLevel(this.writer, int(this.gzipConfig.Level))
|
|
||||||
if err != nil {
|
|
||||||
logs.Error(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// body copy
|
|
||||||
if this.bodyCopying {
|
|
||||||
this.gzipBodyBuffer = bytes.NewBuffer([]byte{})
|
|
||||||
this.gzipBodyWriter, err = gzip.NewWriterLevel(this.gzipBodyBuffer, int(this.gzipConfig.Level))
|
|
||||||
if err != nil {
|
|
||||||
logs.Error(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
header := this.writer.Header()
|
|
||||||
header.Set("Content-Encoding", "gzip")
|
|
||||||
header.Set("Transfer-Encoding", "chunked")
|
|
||||||
header.Set("Vary", "Accept-Encoding")
|
|
||||||
header.Del("Content-Length")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 包装前的原始的Writer
|
// 包装前的原始的Writer
|
||||||
@@ -156,6 +108,15 @@ func (this *HTTPWriter) Write(data []byte) (n int, err error) {
|
|||||||
if n > 0 {
|
if n > 0 {
|
||||||
this.sentBodyBytes += int64(n)
|
this.sentBodyBytes += int64(n)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 写入缓存
|
||||||
|
if this.cacheWriter != nil {
|
||||||
|
_, err = this.cacheWriter.Write(data)
|
||||||
|
if err != nil {
|
||||||
|
_ = this.cacheWriter.Discard()
|
||||||
|
logs.Println("write cache failed: " + err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
n = len(data) // 防止出现short write错误
|
n = len(data) // 防止出现short write错误
|
||||||
@@ -239,6 +200,7 @@ func (this *HTTPWriter) HeaderData() []byte {
|
|||||||
|
|
||||||
// 关闭
|
// 关闭
|
||||||
func (this *HTTPWriter) Close() {
|
func (this *HTTPWriter) Close() {
|
||||||
|
// gzip writer
|
||||||
if this.gzipWriter != nil {
|
if this.gzipWriter != nil {
|
||||||
if this.bodyCopying && this.gzipBodyWriter != nil {
|
if this.bodyCopying && this.gzipBodyWriter != nil {
|
||||||
_ = this.gzipBodyWriter.Close()
|
_ = this.gzipBodyWriter.Close()
|
||||||
@@ -247,6 +209,17 @@ func (this *HTTPWriter) Close() {
|
|||||||
_ = this.gzipWriter.Close()
|
_ = this.gzipWriter.Close()
|
||||||
this.gzipWriter = nil
|
this.gzipWriter = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// cache writer
|
||||||
|
if this.cacheWriter != nil {
|
||||||
|
err := this.cacheWriter.Close()
|
||||||
|
if err == nil {
|
||||||
|
this.cacheStorage.AddToList(&caches.Item{
|
||||||
|
Key: this.cacheWriter.Key(),
|
||||||
|
ExpiredAt: this.cacheWriter.ExpiredAt(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hijack
|
// Hijack
|
||||||
@@ -265,3 +238,138 @@ func (this *HTTPWriter) Flush() {
|
|||||||
flusher.Flush()
|
flusher.Flush()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 准备Gzip
|
||||||
|
func (this *HTTPWriter) prepareGzip(size int64) {
|
||||||
|
if this.gzipConfig == nil || this.gzipConfig.Level <= 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断Accept是否支持gzip
|
||||||
|
if !strings.Contains(this.req.requestHeader("Accept-Encoding"), "gzip") {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 尺寸和类型
|
||||||
|
if size < this.gzipConfig.MinBytes() || (this.gzipConfig.MaxBytes() > 0 && size > this.gzipConfig.MaxBytes()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 校验其他条件
|
||||||
|
if this.gzipConfig.Conds != nil {
|
||||||
|
if len(this.gzipConfig.Conds.Groups) > 0 {
|
||||||
|
if !this.gzipConfig.Conds.MatchRequest(this.req.Format) || !this.gzipConfig.Conds.MatchResponse(this.req.Format) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 默认校验文档类型
|
||||||
|
contentType := this.writer.Header().Get("Content-Type")
|
||||||
|
if len(contentType) > 0 && (!strings.HasPrefix(contentType, "text/") && !strings.HasPrefix(contentType, "application/")) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果已经有编码则不处理
|
||||||
|
if len(this.writer.Header().Get("Content-Encoding")) > 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// gzip writer
|
||||||
|
var err error = nil
|
||||||
|
this.gzipWriter, err = gzip.NewWriterLevel(this.writer, int(this.gzipConfig.Level))
|
||||||
|
if err != nil {
|
||||||
|
logs.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// body copy
|
||||||
|
if this.bodyCopying {
|
||||||
|
this.gzipBodyBuffer = bytes.NewBuffer([]byte{})
|
||||||
|
this.gzipBodyWriter, err = gzip.NewWriterLevel(this.gzipBodyBuffer, int(this.gzipConfig.Level))
|
||||||
|
if err != nil {
|
||||||
|
logs.Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
header := this.writer.Header()
|
||||||
|
header.Set("Content-Encoding", "gzip")
|
||||||
|
header.Set("Transfer-Encoding", "chunked")
|
||||||
|
header.Set("Vary", "Accept-Encoding")
|
||||||
|
header.Del("Content-Length")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 准备缓存
|
||||||
|
func (this *HTTPWriter) prepareCache(size int64) {
|
||||||
|
if this.writer == nil || size <= 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
cacheRef := this.req.cacheRef
|
||||||
|
if cacheRef == nil ||
|
||||||
|
cacheRef.CachePolicy == nil ||
|
||||||
|
!cacheRef.IsOn ||
|
||||||
|
(cacheRef.MaxSizeBytes() > 0 && size > cacheRef.MaxSizeBytes()) ||
|
||||||
|
(cacheRef.CachePolicy.MaxSizeBytes() > 0 && size > cacheRef.CachePolicy.MaxSizeBytes()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查状态
|
||||||
|
if len(cacheRef.Status) > 0 && !lists.ContainsInt(cacheRef.Status, this.StatusCode()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cache-Control
|
||||||
|
if len(cacheRef.SkipResponseCacheControlValues) > 0 {
|
||||||
|
cacheControl := this.writer.Header().Get("Cache-Control")
|
||||||
|
if len(cacheControl) > 0 {
|
||||||
|
values := strings.Split(cacheControl, ",")
|
||||||
|
for _, value := range values {
|
||||||
|
if cacheRef.ContainsCacheControl(strings.TrimSpace(value)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set-Cookie
|
||||||
|
if cacheRef.SkipResponseSetCookie && len(this.writer.Header().Get("Set-Cookie")) > 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 校验其他条件
|
||||||
|
if cacheRef.Conds != nil && cacheRef.Conds.HasResponseConds() && !cacheRef.Conds.MatchResponse(this.req.Format) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 打开缓存写入
|
||||||
|
storage := caches.SharedManager.FindStorageWithPolicy(this.req.cacheRef.CachePolicyId)
|
||||||
|
if storage == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.cacheStorage = storage
|
||||||
|
life := cacheRef.LifeSeconds()
|
||||||
|
if life <= 60 { // 最小不能少于1分钟
|
||||||
|
life = 60
|
||||||
|
}
|
||||||
|
expiredAt := utils.UnixTime() + life
|
||||||
|
cacheWriter, err := storage.Open(this.req.cacheKey, expiredAt)
|
||||||
|
if err != nil {
|
||||||
|
logs.Println("write cache failed: " + err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.cacheWriter = cacheWriter
|
||||||
|
if this.gzipWriter != nil {
|
||||||
|
this.cacheWriter = caches.NewGzipWriter(this.cacheWriter, this.req.cacheKey, expiredAt)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 写入Header
|
||||||
|
headerData := this.HeaderData()
|
||||||
|
_, err = cacheWriter.Write(headerData)
|
||||||
|
if err != nil {
|
||||||
|
logs.Println("write cache failed: " + err.Error())
|
||||||
|
_ = this.cacheWriter.Discard()
|
||||||
|
this.cacheWriter = nil
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
|
"github.com/TeaOSLab/EdgeNode/internal/caches"
|
||||||
"github.com/TeaOSLab/EdgeNode/internal/rpc"
|
"github.com/TeaOSLab/EdgeNode/internal/rpc"
|
||||||
"github.com/TeaOSLab/EdgeNode/internal/utils"
|
"github.com/TeaOSLab/EdgeNode/internal/utils"
|
||||||
"github.com/iwind/TeaGo/logs"
|
"github.com/iwind/TeaGo/logs"
|
||||||
@@ -102,6 +103,7 @@ func (this *Node) syncConfig(isFirstTime bool) error {
|
|||||||
// 刷新配置
|
// 刷新配置
|
||||||
logs.Println("[NODE]reload config ...")
|
logs.Println("[NODE]reload config ...")
|
||||||
nodeconfigs.ResetNodeConfig(nodeConfig)
|
nodeconfigs.ResetNodeConfig(nodeConfig)
|
||||||
|
caches.SharedManager.UpdatePolicies(nodeConfig.AllCachePolicies())
|
||||||
sharedNodeConfig = nodeConfig
|
sharedNodeConfig = nodeConfig
|
||||||
|
|
||||||
if !isFirstTime {
|
if !isFirstTime {
|
||||||
|
|||||||
Reference in New Issue
Block a user