Skip to content

Commit

Permalink
init thumbnail service with the rview.OpenFileFn, don't pass it for…
Browse files Browse the repository at this point in the history
… every task
  • Loading branch information
ShoshinNikita committed Apr 7, 2024
1 parent 11c9b6a commit 6f884cb
Show file tree
Hide file tree
Showing 8 changed files with 164 additions and 137 deletions.
21 changes: 14 additions & 7 deletions cmd/rview.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package cmd
import (
"context"
"fmt"
"io"
"path/filepath"
"reflect"
"strings"
Expand Down Expand Up @@ -44,6 +45,12 @@ func (r *Rview) Prepare() (err error) {
return fmt.Errorf("couldn't prepare disk cache for service needs: %w", err)
}

// Rclone Instance
r.rcloneInstance, err = rclone.NewRclone(r.cfg.RclonePort, r.cfg.RcloneTarget, r.cfg.RcloneDirCacheTime)
if err != nil {
return fmt.Errorf("couldn't prepare rclone: %w", err)
}

// Thumbnail Service
if r.cfg.Thumbnails {
err := thumbnails.CheckVips()
Expand All @@ -61,7 +68,13 @@ func (r *Rview) Prepare() (err error) {
maxTotalFileSize := int64(r.cfg.ThumbnailsMaxTotalSizeInMB * 1 << 20)

r.thumbnailCleaner = cache.NewCleaner(thumbnailsCacheDir, maxFileAge, maxTotalFileSize)
r.thumbnailService = thumbnails.NewThumbnailService(thumbnailsCache, r.cfg.ThumbnailsWorkersCount, false)
openFileFn := func(ctx context.Context, id rview.FileID) (io.ReadCloser, error) {
rc, _, err := r.rcloneInstance.GetFile(ctx, id)
return rc, err
}
r.thumbnailService = thumbnails.NewThumbnailService(
openFileFn, thumbnailsCache, r.cfg.ThumbnailsWorkersCount, false,
)

} else {
rlog.Info("thumbnail service is disabled")
Expand All @@ -70,12 +83,6 @@ func (r *Rview) Prepare() (err error) {
r.thumbnailCleaner = cache.NewNoopCleaner()
}

// Rclone Instance
r.rcloneInstance, err = rclone.NewRclone(r.cfg.RclonePort, r.cfg.RcloneTarget, r.cfg.RcloneDirCacheTime)
if err != nil {
return fmt.Errorf("couldn't prepare rclone: %w", err)
}

// Search Service
r.searchService = search.NewService(r.rcloneInstance, serviceCache)

Expand Down
80 changes: 37 additions & 43 deletions rview/rview.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,31 +68,29 @@ func IsRcloneNotFoundError(err error) bool {
return errors.As(err, &rcloneErr) && rcloneErr.StatusCode == http.StatusNotFound
}

type (
Rclone interface {
GetFile(ctx context.Context, id FileID) (io.ReadCloser, http.Header, error)
GetDirInfo(ctx context.Context, path string, sort, order string) (*RcloneDirInfo, error)
}
type Rclone interface {
GetFile(ctx context.Context, id FileID) (io.ReadCloser, http.Header, error)
GetDirInfo(ctx context.Context, path string, sort, order string) (*RcloneDirInfo, error)
}

RcloneDirInfo struct {
Sort string `json:"sort"`
Order string `json:"order"`
type RcloneDirInfo struct {
Sort string `json:"sort"`
Order string `json:"order"`

Breadcrumbs []RcloneDirBreadcrumb `json:"breadcrumbs"`
Entries []RcloneDirEntry `json:"entries"`
}
Breadcrumbs []RcloneDirBreadcrumb `json:"breadcrumbs"`
Entries []RcloneDirEntry `json:"entries"`
}

RcloneDirBreadcrumb struct {
Text string `json:"text"`
}
type RcloneDirBreadcrumb struct {
Text string `json:"text"`
}

RcloneDirEntry struct {
URL string `json:"url"`
IsDir bool `json:"is_dir"`
Size int64 `json:"size"`
ModTime int64 `json:"mod_time"`
}
)
type RcloneDirEntry struct {
URL string `json:"url"`
IsDir bool `json:"is_dir"`
Size int64 `json:"size"`
ModTime int64 `json:"mod_time"`
}

var (
ErrCacheMiss = errors.New("cache miss")
Expand All @@ -114,28 +112,24 @@ type ThumbnailID struct {
FileID
}

type (
ThumbnailService interface {
NewThumbnailID(FileID) ThumbnailID
CanGenerateThumbnail(FileID) bool
IsThumbnailReady(ThumbnailID) bool
OpenThumbnail(context.Context, ThumbnailID) (io.ReadCloser, error)
SendTask(id FileID, openFileFn OpenFileFn) error
Shutdown(context.Context) error
}
type ThumbnailService interface {
NewThumbnailID(FileID) ThumbnailID
CanGenerateThumbnail(FileID) bool
IsThumbnailReady(ThumbnailID) bool
OpenThumbnail(context.Context, ThumbnailID) (io.ReadCloser, error)
SendTask(id FileID) error
Shutdown(context.Context) error
}

OpenFileFn func(ctx context.Context, id FileID) (io.ReadCloser, error)
)
type OpenFileFn func(ctx context.Context, id FileID) (io.ReadCloser, error)

type (
SearchService interface {
GetMinSearchLength() int
Search(ctx context.Context, search string, dirLimit, fileLimit int) (dirs, files []SearchHit, err error)
RefreshIndexes(ctx context.Context) error
}
type SearchService interface {
GetMinSearchLength() int
Search(ctx context.Context, search string, dirLimit, fileLimit int) (dirs, files []SearchHit, err error)
RefreshIndexes(ctx context.Context) error
}

SearchHit struct {
Path string
Score float64
}
)
type SearchHit struct {
Path string
Score float64
}
15 changes: 8 additions & 7 deletions tests/thumbnails_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ func TestThumbnailGeneration(t *testing.T) {
cache, err := cache.NewDiskCache(t.TempDir())
require.NoError(t, err)

thumbnailService := thumbnails.NewThumbnailService(cache, 1, true)

for _, tt := range []struct {
imageType string
file string
Expand All @@ -38,15 +36,18 @@ func TestThumbnailGeneration(t *testing.T) {
t.Run(tt.imageType, func(t *testing.T) {
r := require.New(t)

fileID := rview.NewFileID(tt.file, 0)
thumbnailID := thumbnailService.NewThumbnailID(fileID)

originalImage, err := os.ReadFile(filepath.Join("testdata", tt.file))
r.NoError(err)

err = thumbnailService.SendTask(fileID, func(context.Context, rview.FileID) (io.ReadCloser, error) {
openFileFn := func(context.Context, rview.FileID) (io.ReadCloser, error) {
return io.NopCloser(bytes.NewReader(originalImage)), nil
})
}
thumbnailService := thumbnails.NewThumbnailService(openFileFn, cache, 1, true)

fileID := rview.NewFileID(tt.file, 0)
thumbnailID := thumbnailService.NewThumbnailID(fileID)

err = thumbnailService.SendTask(fileID)
r.NoError(err)

ctx, cancel := context.WithTimeout(context.Background(), time.Second)
Expand Down
2 changes: 1 addition & 1 deletion thumbnails/noop.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func (NoopThumbnailService) IsThumbnailReady(rview.ThumbnailID) bool {
return false
}

func (NoopThumbnailService) SendTask(rview.FileID, rview.OpenFileFn) error {
func (NoopThumbnailService) SendTask(rview.FileID) error {
return ErrNoopThumbnailService
}

Expand Down
15 changes: 7 additions & 8 deletions thumbnails/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,9 @@ var (
)

type ThumbnailService struct {
cache rview.Cache
resizeFn func(originalFile, cacheFile string, id rview.ThumbnailID) error
cache rview.Cache
openFileFn rview.OpenFileFn
resizeFn func(originalFile, cacheFile string, id rview.ThumbnailID) error
// useOriginalImageThresholdSize defines the maximum size of an original image that should be
// used without resizing. The main purpose of resizing is to reduce image size, and with small
// files it is not always possible - after resizing they become just larger.
Expand All @@ -55,8 +56,6 @@ type ThumbnailService struct {
type generateThumbnailTask struct {
fileID rview.FileID
thumbnailID rview.ThumbnailID

openFileFn rview.OpenFileFn
}

func CheckVips() error {
Expand All @@ -75,8 +74,9 @@ func CheckVips() error {
//
// For some images we can generate thumbnails of different formats. For example,
// for .heic images we generate .jpeg thumbnails.
func NewThumbnailService(cache rview.Cache, workersCount int, generateThumbnailsForSmallFiles bool) *ThumbnailService {
func NewThumbnailService(openFileFn rview.OpenFileFn, cache rview.Cache, workersCount int, generateThumbnailsForSmallFiles bool) *ThumbnailService {
r := &ThumbnailService{
openFileFn: openFileFn,
cache: cache,
resizeFn: resizeWithVips,
useOriginalImageThresholdSize: 200 << 10, // 200 KiB
Expand Down Expand Up @@ -167,7 +167,7 @@ type stats struct {
}

func (s *ThumbnailService) processTask(ctx context.Context, task generateThumbnailTask) (finalStats stats, err error) {
rc, err := task.openFileFn(ctx, task.fileID)
rc, err := s.openFileFn(ctx, task.fileID)
if err != nil {
return stats{}, fmt.Errorf("couldn't get image reader: %w", err)
}
Expand Down Expand Up @@ -400,7 +400,7 @@ func (s *ThumbnailService) OpenThumbnail(ctx context.Context, id rview.Thumbnail
// must be absolute.
//
// SendTask ignores duplicate tasks. However, it doesn't check files on disk.
func (s *ThumbnailService) SendTask(id rview.FileID, openFileFn rview.OpenFileFn) error {
func (s *ThumbnailService) SendTask(id rview.FileID) error {
if s.stopped.Load() {
return errors.New("can't send tasks after Shutdown call")
}
Expand Down Expand Up @@ -428,7 +428,6 @@ func (s *ThumbnailService) SendTask(id rview.FileID, openFileFn rview.OpenFileFn
s.tasksCh <- generateThumbnailTask{
fileID: id,
thumbnailID: thumbnailID,
openFileFn: openFileFn,
}
return nil
}
Expand Down
Loading

0 comments on commit 6f884cb

Please sign in to comment.