all repos — searchix @ 40d106a50be7fa87739e82c87c161db8e6a69b12

Search engine for NixOS, nix-darwin, home-manager and NUR users

feat: split storage import and indexing

Alan Pearce
commit

40d106a50be7fa87739e82c87c161db8e6a69b12

parent

517f219f3b249a26890f881569f9eac34ba7363d

1 file changed, 45 insertions(+), 48 deletions(-)

changed files
M internal/importer/importer.gointernal/importer/importer.go
@@ -7,70 +7,52 @@
"alin.ovh/searchix/internal/config" "alin.ovh/searchix/internal/index" "alin.ovh/searchix/internal/nix" + "alin.ovh/searchix/internal/storage" + "alin.ovh/x/log" ) type Processor interface { Process(context.Context) (<-chan nix.Importable, <-chan error) } -func (imp *Importer) process( +func Import[I nix.Importable]( ctx context.Context, - processor Processor, - source *config.Source, + log *log.Logger, + src func(context.Context) (<-chan I, <-chan error), + dst func(context.Context, <-chan I) <-chan error, ) (bool, error) { wg := sync.WaitGroup{} wg.Add(1) - objects, pErrs := processor.Process(ctx) - - d1, d2 := duplicate(objects) - - wg.Add(1) - iErrs := imp.options.WriteIndex.Import(ctx, d1) + objects, srcErrs := src(ctx) wg.Add(1) - wErrs := imp.options.Storage.Import(ctx, source, d2) + dstErrors := dst(ctx, objects) var hadObjectErrors bool var criticalError error go func() { for { select { - case err, running := <-iErrs: + case err, running := <-srcErrs: if !running { wg.Done() - iErrs = nil - imp.options.Logger.Debug("ingest completed") + srcErrs = nil + log.Debug("processing completed") continue } - be, isBatchError := err.(*index.BatchError) - if isBatchError { - criticalError = be - - break - } hadObjectErrors = true - imp.options.Logger.Warn("error ingesting object", "error", err) - case err, running := <-pErrs: + log.Warn("error processing object from source", "error", err) + case err, running := <-dstErrors: if !running { wg.Done() - pErrs = nil - imp.options.Logger.Debug("processing completed") + dstErrors = nil continue } hadObjectErrors = true - imp.options.Logger.Warn("error processing object", "error", err) - case err, running := <-wErrs: - if !running { - wg.Done() - wErrs = nil - - continue - } - hadObjectErrors = true - imp.options.Logger.Warn("error writing to storage", "error", err) + log.Warn("error writing object to target", "error", err) } } }()
@@ -80,22 +62,37 @@
return hadObjectErrors, criticalError } -func duplicate[T any](v <-chan T) (<-chan T, <-chan T) { - if v == nil { - return nil, nil +func ImportSource( + ctx context.Context, + logger *log.Logger, + store *storage.Store, + source *config.Source, + write *index.WriteIndex, +) (bool, error) { + var it func(context.Context, *log.Logger, *storage.Store, *config.Source, *index.WriteIndex) (bool, error) + switch source.Importer { + case config.Packages: + it = ImportWithType[nix.Package] + case config.Options: + it = ImportWithType[nix.Option] } - dup1 := make(chan T, 1) - dup2 := make(chan T, 1) - - go func() { - for v := range v { - dup1 <- v - dup2 <- v - } - close(dup1) - close(dup2) - }() + return it(ctx, logger, store, source, write) +} - return dup1, dup2 +func ImportWithType[I nix.Importable]( + ctx context.Context, + logger *log.Logger, + store *storage.Store, + source *config.Source, + write *index.WriteIndex, +) (bool, error) { + return Import( + ctx, + logger.Named("importer"), + storage.MakeSourceExporter[I](store, source), + func(ctx context.Context, objects <-chan I) <-chan error { + return write.Import(ctx, nix.ToGenericChannel(objects)) + }, + ) }