diff --git a/go.mod b/go.mod index 0fa893698..84a1c2da4 100644 --- a/go.mod +++ b/go.mod @@ -10,6 +10,7 @@ require ( github.com/gogo/protobuf v1.3.1 github.com/golang/mock v1.3.1 github.com/google/uuid v1.1.1 + github.com/hashicorp/golang-lru v0.5.4 github.com/ipfs/go-log v0.0.1 github.com/lunny/html2md v0.0.0-20181018071239-7d234de44546 github.com/mauidude/go-readability v0.0.0-20141216012317-2f30b1a346f1 diff --git a/go.sum b/go.sum index af8a4f4c3..97ed2f4a3 100644 --- a/go.sum +++ b/go.sum @@ -175,6 +175,8 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk= github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= +github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= diff --git a/util/linkpreview/cache.go b/util/linkpreview/cache.go new file mode 100644 index 000000000..42deb570e --- /dev/null +++ b/util/linkpreview/cache.go @@ -0,0 +1,37 @@ +package linkpreview + +import ( + "context" + + "github.com/anytypeio/go-anytype-library/pb/model" + "github.com/hashicorp/golang-lru" +) + +const ( + maxCacheEntries = 100 +) + +func NewWithCache() LinkPreview { + lruCache, _ := lru.New(maxCacheEntries) + return &cache{ + lp: New(), + cache: lruCache, + } +} + +type cache struct { + lp LinkPreview + cache *lru.Cache +} + +func (c *cache) Fetch(ctx context.Context, url string) (lp model.ModelLinkPreview, err error) { + if res, ok := c.cache.Get(url); ok { + return res.(model.ModelLinkPreview), nil + } + lp, err = c.lp.Fetch(ctx, url) + if err != nil { + return + } + c.cache.Add(url, lp) + return +} diff --git a/util/linkpreview/cache_test.go b/util/linkpreview/cache_test.go new file mode 100644 index 000000000..1ded3940e --- /dev/null +++ b/util/linkpreview/cache_test.go @@ -0,0 +1,40 @@ +package linkpreview + +import ( + "strings" + "testing" + + "github.com/anytypeio/go-anytype-library/pb/model" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestCache_Fetch(t *testing.T) { + ts := newTestServer("text/html", strings.NewReader(tetsHtml)) + lp := NewWithCache() + + info, err := lp.Fetch(ctx, ts.URL) + require.NoError(t, err) + assert.Equal(t, model.ModelLinkPreview{ + Url: ts.URL, + FaviconUrl: ts.URL + "/favicon.ico", + Title: "Title", + Description: "Description", + ImageUrl: "http://site.com/images/example.jpg", + Type: model.ModelLinkPreview_Page, + }, info) + + ts.Close() + + info, err = lp.Fetch(ctx, ts.URL) + require.NoError(t, err) + assert.Equal(t, model.ModelLinkPreview{ + Url: ts.URL, + FaviconUrl: ts.URL + "/favicon.ico", + Title: "Title", + Description: "Description", + ImageUrl: "http://site.com/images/example.jpg", + Type: model.ModelLinkPreview_Page, + }, info) + +}