Added the ability to do Sequential Scans (#3378)

* Added the ability to do Seqential Scans
* Modify pkg/txn to run hooks with the outer context, instead of the context that was in a transaction
* update in application manual
This commit is contained in:
JoeSmithStarkers
2023-02-23 14:38:02 +11:00
committed by GitHub
parent 75a8d572cc
commit f767635080
6 changed files with 52 additions and 24 deletions

View File

@@ -69,6 +69,9 @@ const (
ParallelTasks = "parallel_tasks" ParallelTasks = "parallel_tasks"
parallelTasksDefault = 1 parallelTasksDefault = 1
SequentialScanning = "sequential_scanning"
SequentialScanningDefault = false
PreviewPreset = "preview_preset" PreviewPreset = "preview_preset"
PreviewAudio = "preview_audio" PreviewAudio = "preview_audio"
@@ -649,6 +652,10 @@ func (i *Instance) GetVideoFileNamingAlgorithm() models.HashAlgorithm {
return models.HashAlgorithm(ret) return models.HashAlgorithm(ret)
} }
func (i *Instance) GetSequentialScanning() bool {
return i.getBool(SequentialScanning)
}
func (i *Instance) GetGalleryCoverRegex() string { func (i *Instance) GetGalleryCoverRegex() string {
var regexString = i.getString(GalleryCoverRegex) var regexString = i.getString(GalleryCoverRegex)
@@ -1464,6 +1471,7 @@ func (i *Instance) setDefaultValues(write bool) error {
i.main.SetDefault(Port, portDefault) i.main.SetDefault(Port, portDefault)
i.main.SetDefault(ParallelTasks, parallelTasksDefault) i.main.SetDefault(ParallelTasks, parallelTasksDefault)
i.main.SetDefault(SequentialScanning, SequentialScanningDefault)
i.main.SetDefault(PreviewSegmentDuration, previewSegmentDurationDefault) i.main.SetDefault(PreviewSegmentDuration, previewSegmentDurationDefault)
i.main.SetDefault(PreviewSegments, previewSegmentsDefault) i.main.SetDefault(PreviewSegments, previewSegmentsDefault)
i.main.SetDefault(PreviewExcludeStart, previewExcludeStartDefault) i.main.SetDefault(PreviewExcludeStart, previewExcludeStartDefault)

View File

@@ -410,10 +410,11 @@ func (g *sceneGenerators) Generate(ctx context.Context, s *models.Scene, f *file
path := f.Path path := f.Path
config := instance.Config config := instance.Config
fileNamingAlgorithm := config.GetVideoFileNamingAlgorithm() fileNamingAlgorithm := config.GetVideoFileNamingAlgorithm()
sequentialScanning := config.GetSequentialScanning()
if t.ScanGenerateSprites { if t.ScanGenerateSprites {
progress.AddTotal(1) progress.AddTotal(1)
g.taskQueue.Add(fmt.Sprintf("Generating sprites for %s", path), func(ctx context.Context) { spriteFn := func(ctx context.Context) {
taskSprite := GenerateSpriteTask{ taskSprite := GenerateSpriteTask{
Scene: *s, Scene: *s,
Overwrite: overwrite, Overwrite: overwrite,
@@ -421,12 +422,18 @@ func (g *sceneGenerators) Generate(ctx context.Context, s *models.Scene, f *file
} }
taskSprite.Start(ctx) taskSprite.Start(ctx)
progress.Increment() progress.Increment()
}) }
if sequentialScanning {
spriteFn(ctx)
} else {
g.taskQueue.Add(fmt.Sprintf("Generating sprites for %s", path), spriteFn)
}
} }
if t.ScanGeneratePhashes { if t.ScanGeneratePhashes {
progress.AddTotal(1) progress.AddTotal(1)
g.taskQueue.Add(fmt.Sprintf("Generating phash for %s", path), func(ctx context.Context) { phashFn := func(ctx context.Context) {
taskPhash := GeneratePhashTask{ taskPhash := GeneratePhashTask{
File: f, File: f,
fileNamingAlgorithm: fileNamingAlgorithm, fileNamingAlgorithm: fileNamingAlgorithm,
@@ -436,12 +443,18 @@ func (g *sceneGenerators) Generate(ctx context.Context, s *models.Scene, f *file
} }
taskPhash.Start(ctx) taskPhash.Start(ctx)
progress.Increment() progress.Increment()
}) }
if sequentialScanning {
phashFn(ctx)
} else {
g.taskQueue.Add(fmt.Sprintf("Generating phash for %s", path), phashFn)
}
} }
if t.ScanGeneratePreviews { if t.ScanGeneratePreviews {
progress.AddTotal(1) progress.AddTotal(1)
g.taskQueue.Add(fmt.Sprintf("Generating preview for %s", path), func(ctx context.Context) { previewsFn := func(ctx context.Context) {
options := getGeneratePreviewOptions(GeneratePreviewOptionsInput{}) options := getGeneratePreviewOptions(GeneratePreviewOptionsInput{})
g := &generate.Generator{ g := &generate.Generator{
@@ -463,7 +476,13 @@ func (g *sceneGenerators) Generate(ctx context.Context, s *models.Scene, f *file
} }
taskPreview.Start(ctx) taskPreview.Start(ctx)
progress.Increment() progress.Increment()
}) }
if sequentialScanning {
previewsFn(ctx)
} else {
g.taskQueue.Add(fmt.Sprintf("Generating preview for %s", path), previewsFn)
}
} }
return nil return nil

View File

@@ -35,19 +35,19 @@ func executeHooks(ctx context.Context, hooks []TxnFunc) {
} }
} }
func executePostCommitHooks(ctx context.Context) { func executePostCommitHooks(ctx context.Context, outerCtx context.Context) {
m := hookManagerCtx(ctx) m := hookManagerCtx(ctx)
executeHooks(ctx, m.postCommitHooks) executeHooks(outerCtx, m.postCommitHooks)
} }
func executePostRollbackHooks(ctx context.Context) { func executePostRollbackHooks(ctx context.Context, outerCtx context.Context) {
m := hookManagerCtx(ctx) m := hookManagerCtx(ctx)
executeHooks(ctx, m.postRollbackHooks) executeHooks(outerCtx, m.postRollbackHooks)
} }
func executePostCompleteHooks(ctx context.Context) { func executePostCompleteHooks(ctx context.Context, outerCtx context.Context) {
m := hookManagerCtx(ctx) m := hookManagerCtx(ctx)
executeHooks(ctx, m.postCompleteHooks) executeHooks(outerCtx, m.postCompleteHooks)
} }
func AddPostCommitHook(ctx context.Context, hook TxnFunc) { func AddPostCommitHook(ctx context.Context, hook TxnFunc) {

View File

@@ -51,9 +51,8 @@ func WithReadTxn(ctx context.Context, m Manager, fn TxnFunc) error {
return withTxn(ctx, m, fn, exclusive, execComplete) return withTxn(ctx, m, fn, exclusive, execComplete)
} }
func withTxn(ctx context.Context, m Manager, fn TxnFunc, exclusive bool, execCompleteOnLocked bool) error { func withTxn(outerCtx context.Context, m Manager, fn TxnFunc, exclusive bool, execCompleteOnLocked bool) error {
var err error ctx, err := begin(outerCtx, m, exclusive)
ctx, err = begin(ctx, m, exclusive)
if err != nil { if err != nil {
return err return err
} }
@@ -61,21 +60,21 @@ func withTxn(ctx context.Context, m Manager, fn TxnFunc, exclusive bool, execCom
defer func() { defer func() {
if p := recover(); p != nil { if p := recover(); p != nil {
// a panic occurred, rollback and repanic // a panic occurred, rollback and repanic
rollback(ctx, m) rollback(ctx, outerCtx, m)
panic(p) panic(p)
} }
if err != nil { if err != nil {
// something went wrong, rollback // something went wrong, rollback
rollback(ctx, m) rollback(ctx, outerCtx, m)
if execCompleteOnLocked || !m.IsLocked(err) { if execCompleteOnLocked || !m.IsLocked(err) {
executePostCompleteHooks(ctx) executePostCompleteHooks(ctx, outerCtx)
} }
} else { } else {
// all good, commit // all good, commit
err = commit(ctx, m) err = commit(ctx, outerCtx, m)
executePostCompleteHooks(ctx) executePostCompleteHooks(ctx, outerCtx)
} }
}() }()
@@ -97,21 +96,21 @@ func begin(ctx context.Context, m Manager, exclusive bool) (context.Context, err
return ctx, nil return ctx, nil
} }
func commit(ctx context.Context, m Manager) error { func commit(ctx context.Context, outerCtx context.Context, m Manager) error {
if err := m.Commit(ctx); err != nil { if err := m.Commit(ctx); err != nil {
return err return err
} }
executePostCommitHooks(ctx) executePostCommitHooks(ctx, outerCtx)
return nil return nil
} }
func rollback(ctx context.Context, m Manager) { func rollback(ctx context.Context, outerCtx context.Context, m Manager) {
if err := m.Rollback(ctx); err != nil { if err := m.Rollback(ctx); err != nil {
return return
} }
executePostRollbackHooks(ctx) executePostRollbackHooks(ctx, outerCtx)
} }
// WithDatabase executes fn with the context provided by p.WithDatabase. // WithDatabase executes fn with the context provided by p.WithDatabase.

View File

@@ -1,4 +1,5 @@
### ✨ New Features ### ✨ New Features
* Add configuration option to perform generation operations sequentially after scanning a new video file. ([#3378](https://github.com/stashapp/stash/pull/3378))
* Optionally show range in generated funscript heatmaps. ([#3373](https://github.com/stashapp/stash/pull/3373)) * Optionally show range in generated funscript heatmaps. ([#3373](https://github.com/stashapp/stash/pull/3373))
* Show funscript heatmaps in scene player scrubber. ([#3374](https://github.com/stashapp/stash/pull/3374)) * Show funscript heatmaps in scene player scrubber. ([#3374](https://github.com/stashapp/stash/pull/3374))
* Support customising the filename regex used for determining the gallery cover image. ([#3391](https://github.com/stashapp/stash/pull/3391)) * Support customising the filename regex used for determining the gallery cover image. ([#3391](https://github.com/stashapp/stash/pull/3391))

View File

@@ -132,6 +132,7 @@ These options are typically not exposed in the UI and must be changed manually i
| `gallery_cover_regex` | The regex responsible for selecting images as gallery covers | | `gallery_cover_regex` | The regex responsible for selecting images as gallery covers |
| `proxy` | The url of a HTTP(S) proxy to be used when stash makes calls to online services Example: https://user:password@my.proxy:8080 | | `proxy` | The url of a HTTP(S) proxy to be used when stash makes calls to online services Example: https://user:password@my.proxy:8080 |
| `no_proxy` | A list of domains for which the proxy must not be used. Default is all local LAN: localhost,127.0.0.1,192.168.0.0/16,10.0.0.0/8,172.16.0.0/12 | | `no_proxy` | A list of domains for which the proxy must not be used. Default is all local LAN: localhost,127.0.0.1,192.168.0.0/16,10.0.0.0/8,172.16.0.0/12 |
| `sequential_scanning` | Modifies behaviour of the scanning functionality to generate support files (previews/sprites/phash) at the same time as fingerprinting/screenshotting. Useful when scanning cached remote files. |
### Custom served folders ### Custom served folders