mirror of
https://github.com/metabarcoding/obitools4.git
synced 2025-06-29 16:20:46 +00:00
First functional version of a blackboard and a blackboard based obicount
This commit is contained in:
108
pkg/obiblackboard/subtask.go
Normal file
108
pkg/obiblackboard/subtask.go
Normal file
@ -0,0 +1,108 @@
|
||||
package obiblackboard
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// RepeatTask creates a new DoTask function that repeats the given task n times.
|
||||
//
|
||||
// It takes an integer n as input, which specifies the number of times the task should be repeated.
|
||||
// It returns a new DoTask function that can be used to execute the repeated task.
|
||||
//
|
||||
// The returned DoTask function maintains a map of tasks to their counts and tasks.
|
||||
// When a task is executed, it checks if the task has been executed before.
|
||||
// If it has, it increments the count and returns the previously executed task.
|
||||
// If it has not been executed before, it executes the task using the provided runner function.
|
||||
// If the runner function returns nil, the task is not added to the task memory and nil is returned.
|
||||
// If the runner function returns a non-nil task, it is added to the task memory with a count of 0.
|
||||
// After executing the task, the function checks if the count is less than (n-1).
|
||||
// If it is, the task is added back to the blackboard to be executed again.
|
||||
// If the count is equal to (n-1), the task is removed from the task memory.
|
||||
// Finally, the function returns the executed task.
|
||||
func (runner DoTask) RepeatTask(n int) DoTask {
|
||||
type memtask struct {
|
||||
count int
|
||||
task *Task
|
||||
}
|
||||
taskMemory := make(map[*Task]*memtask)
|
||||
taskMemoryLock := sync.Mutex{}
|
||||
|
||||
if n < 1 {
|
||||
log.Fatalf("Cannot repeat a task less than once (n=%d)", n)
|
||||
}
|
||||
|
||||
st := func(bb *Blackboard, task *Task) *Task {
|
||||
taskMemoryLock.Lock()
|
||||
|
||||
mem, ok := taskMemory[task]
|
||||
|
||||
if !ok {
|
||||
nt := runner(bb, task)
|
||||
|
||||
if nt == nil {
|
||||
taskMemoryLock.Unlock()
|
||||
return nt
|
||||
}
|
||||
|
||||
mem = &memtask{
|
||||
count: 0,
|
||||
task: nt,
|
||||
}
|
||||
|
||||
taskMemory[task] = mem
|
||||
} else {
|
||||
mem.count++
|
||||
}
|
||||
|
||||
taskMemoryLock.Unlock()
|
||||
|
||||
if mem.count < (n - 1) {
|
||||
bb.PushTask(task)
|
||||
}
|
||||
|
||||
if mem.count == (n - 1) {
|
||||
taskMemoryLock.Lock()
|
||||
delete(taskMemory, task)
|
||||
taskMemoryLock.Unlock()
|
||||
}
|
||||
|
||||
return mem.task
|
||||
}
|
||||
|
||||
return st
|
||||
}
|
||||
|
||||
// CombineWith returns a new DoTask function that combines the given DoTask
|
||||
// functions. The returned function applies the `other` function to the result
|
||||
// of the `runner` function. The `bb` parameter is the Blackboard instance,
|
||||
// and the `task` parameter is the Task instance.
|
||||
//
|
||||
// Parameters:
|
||||
// - bb: The Blackboard instance.
|
||||
// - task: The Task instance.
|
||||
//
|
||||
// Returns:
|
||||
// - *Task: The result of applying the `other` function to the result of the
|
||||
// `runner` function.
|
||||
func (runner DoTask) CombineWith(other DoTask) DoTask {
|
||||
return func(bb *Blackboard, task *Task) *Task {
|
||||
return other(bb, runner(bb, task))
|
||||
}
|
||||
}
|
||||
|
||||
// SetTarget sets the target role for the task.
|
||||
//
|
||||
// Parameters:
|
||||
// - target: The target role to set.
|
||||
//
|
||||
// Returns:
|
||||
// - DoTask: The modified DoTask function.
|
||||
func (runner DoTask) SetTarget(target string) DoTask {
|
||||
return func(bb *Blackboard, task *Task) *Task {
|
||||
nt := runner(bb, task)
|
||||
nt.Role = target
|
||||
return nt
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user