From f19065261ea27e46cfd826a3623b080c4c9894aa Mon Sep 17 00:00:00 2001 From: Eric Coissac Date: Mon, 13 Apr 2026 16:27:14 +0200 Subject: [PATCH] We kept --- pkg/obilua/lua.go | 91 +++++++++++++++++++++++++++++++++++++-- pkg/obioptions/version.go | 2 +- version.txt | 2 +- 3 files changed, 89 insertions(+), 6 deletions(-) diff --git a/pkg/obilua/lua.go b/pkg/obilua/lua.go index 1bfa07f..9604bbe 100644 --- a/pkg/obilua/lua.go +++ b/pkg/obilua/lua.go @@ -141,6 +141,69 @@ func LuaWorker(proto *lua.FunctionProto) obiseq.SeqWorker { return nil } +// LuaSliceWorker creates a SeqSliceWorker that calls the Lua function +// named "slice_worker". Unlike LuaWorker, the entire batch (BioSequenceSlice) +// is passed to the Lua function at once, enabling batch-level processing +// (e.g. a single HTTP request per batch instead of one per sequence). +// +// The Lua function signature: +// +// function slice_worker(slice) -- receives a BioSequenceSlice +// -- process the batch +// return slice -- returns a BioSequenceSlice (or nil) +// end +func LuaSliceWorker(proto *lua.FunctionProto) obiseq.SeqSliceWorker { + interpreter := NewInterpreter() + lfunc := interpreter.NewFunctionFromProto(proto) + interpreter.Push(lfunc) + err := interpreter.PCall(0, lua.MultRet, nil) + + if err != nil { + log.Fatalf("Error in executing the lua script: %v", err) + } + + result := interpreter.GetGlobal("slice_worker") + + if lua_worker, ok := result.(*lua.LFunction); ok { + f := func(slice obiseq.BioSequenceSlice) (obiseq.BioSequenceSlice, error) { + if err := interpreter.CallByParam(lua.P{ + Fn: lua_worker, + NRet: 1, + Protect: true, + }, obiseqslice2Lua(interpreter, &slice)); err != nil { + log.Fatal(err) + } + + lreponse := interpreter.Get(-1) + defer interpreter.Pop(1) + + if reponse, ok := lreponse.(*lua.LUserData); ok { + s := reponse.Value + switch val := s.(type) { + case *obiseq.BioSequenceSlice: + return *val, nil + case *obiseq.BioSequence: + return obiseq.BioSequenceSlice{val}, nil + default: + r := reflect.TypeOf(val) + return nil, fmt.Errorf("slice_worker function doesn't return the correct type %s", r) + } + } + + if _, ok = lreponse.(*lua.LNilType); ok { + return nil, nil + } + + return nil, fmt.Errorf("slice_worker function doesn't return the correct type %T", lreponse) + } + + return f + } + + log.Fatalf("The slice_worker object is not a function") + return nil +} + // LuaProcessor processes a Lua script on a sequence iterator and returns a new iterator. // // Parameters: @@ -216,11 +279,27 @@ func LuaProcessor(iterator obiiter.IBioSequence, name, program string, breakOnEr }() - ff := func(iterator obiiter.IBioSequence) { - w := LuaWorker(proto) - sw := obiseq.SeqToSliceWorker(w, false) + // Detect whether the script defines slice_worker (batch-level) or worker (per-sequence). + hasSliceWorker := func() bool { + interpreter := NewInterpreter() + lfunc := interpreter.NewFunctionFromProto(proto) + interpreter.Push(lfunc) + if err := interpreter.PCall(0, lua.MultRet, nil); err != nil { + return false + } + result := interpreter.GetGlobal("slice_worker") + interpreter.Close() + _, ok := result.(*lua.LFunction) + return ok + }() - // iterator = iterator.SortBatches() + ff := func(iterator obiiter.IBioSequence) { + var sw obiseq.SeqSliceWorker + if hasSliceWorker { + sw = LuaSliceWorker(proto) + } else { + sw = obiseq.SeqToSliceWorker(LuaWorker(proto), false) + } for iterator.Next() { seqs := iterator.Get() @@ -235,6 +314,10 @@ func LuaProcessor(iterator obiiter.IBioSequence, name, program string, breakOnEr } } + if ns == nil { + ns = obiseq.BioSequenceSlice{} + } + newIter.Push(obiiter.MakeBioSequenceBatch(seqs.Source(), seqs.Order(), ns)) } diff --git a/pkg/obioptions/version.go b/pkg/obioptions/version.go index 31199eb..86e46da 100644 --- a/pkg/obioptions/version.go +++ b/pkg/obioptions/version.go @@ -3,7 +3,7 @@ package obioptions // Version is automatically updated by the Makefile from version.txt // The patch number (third digit) is incremented on each push to the repository -var _Version = "Release 4.4.33" +var _Version = "Release 4.4.34" // Version returns the version of the obitools package. // diff --git a/version.txt b/version.txt index 1cfc545..b3f8f6f 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -4.4.33 +4.4.34