Coder Social home page Coder Social logo

Comments (13)

axengine avatar axengine commented on July 21, 2024 2

@zxmrlc 我fork了cache项目,修复了这个问题,你可以直接
https://github.com/axengine/cache

from cache.

axengine avatar axengine commented on July 21, 2024

gin可能使用了内存池或者sync.Pool等技术来管理内存,可能对[]byte的复用,而InMemoryStore直接缓存了gin的[]byte,因此可能被覆盖。重写cache的Write方法可以解决该问题。

func (w *cachedWriter) Write(data []byte) (int, error) {
	ret, err := w.ResponseWriter.Write(data)
	if err == nil {
		store := w.store
		var cache responseCache
		if err := store.Get(w.key, &cache); err == nil {
			cache.Data = append(cache.Data, data...)
		} else {
			cache.Data = make([]byte, len(data))
			copy(cache.Data, data)
		}

		//cache responses with a status code < 300
		if w.Status() < 300 {
			val := responseCache{
				w.Status(),
				w.Header(),
				cache.Data,
			}
			err = store.Set(w.key, val, w.expire)
			if err != nil {
				// need logger
			}
		}
	}
	return ret, err
}

from cache.

zxmrlc avatar zxmrlc commented on July 21, 2024

@axengine 你好,这个方法已经在类中更新,但是仍然存在问题.
image
我现在的库已经包含了你发布的这个函数. 但是还是存在缓存返回错误.
缓存本来应该返回json格式的内容,却混入了日志等信息...

from cache.

axengine avatar axengine commented on July 21, 2024

@zxmrlc
对缓存数据要先分配内存,做一次强拷贝,你的代码还是直接缓存了上层传过来的[]byte。
使用CachePageAtomic替换CachePage方法,CachePage在并发时会引起缓存数据错误。

from cache.

zxmrlc avatar zxmrlc commented on July 21, 2024

@axengine
首先谢谢您的回复..
我使用的就是CachePageAtomic,
你说的这个重写Write方法.. 是指申请内存然后进行操作吗?直接在cache库更改代码不太好吧..

from cache.

zxmrlc avatar zxmrlc commented on July 21, 2024

https://github.com/axengine/cache

感谢您的回复

from cache.

chenjiandongx avatar chenjiandongx commented on July 21, 2024

@axengine @appleboy Hi,

I get a little confused about the effect of the following code. What case will trigger this logic?

func (w *cachedWriter) Write(data []byte) (int, error) {
	ret, err := w.ResponseWriter.Write(data)
	if err == nil {
		store := w.store
		var cache responseCache
                 // start  -------
		if err := store.Get(w.key, &cache); err == nil {
                         // why does it need a append operation?
			data = append(cache.Data, data...)
		}
                 // end  -------
		//cache responses with a status code < 300
		if w.Status() < 300 {
			val := responseCache{
				w.Status(),
				w.Header(),
				data,
			}
			err = store.Set(w.key, val, w.expire)
			if err != nil {
				// need logger
			}
		}
	}
	return ret, err
}

from cache.

appleboy avatar appleboy commented on July 21, 2024

@axengine Can you send the PR?

from cache.

axengine avatar axengine commented on July 21, 2024
                 // start  -------
		if err := store.Get(w.key, &cache); err == nil {
                         // why it needs a append operation?
			data = append(cache.Data, data...)
		}
                 // end  -------

对一个大buff可能需要多次Write才能写完。

from cache.

chenjiandongx avatar chenjiandongx commented on July 21, 2024

@axengine Write 不是只被调用了一次吗?

https://github.com/gin-contrib/cache/blob/master/cache.go#L177

from cache.

morefreeze avatar morefreeze commented on July 21, 2024

@zxmrlc 我fork了cache项目,修复了这个问题,你可以直接
https://github.com/axengine/cache

尝试了你的项目github.com/axengine/cache v1.2.0,写了一段测试代码类似

store := persistence.NewInMemoryStore(time.Second * 2)
apiR.GET("/xxx", cache.CachePage(store, time.Second*2, GetSth))

然后用for i in {1..20}; do echo $i; curl www.abc.com/xxx > $i & done 并发去打,很容易就复现各文件大小不一致,接口返回一个固定的大字典,大小约200k

from cache.

htaoji1988 avatar htaoji1988 commented on July 21, 2024

我也遇到了,希望早点解决内存做缓存的问题

from cache.

seriousm4x avatar seriousm4x commented on July 21, 2024

ran into the same issue today. i can verify it

from cache.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.