Hey!
I think I may have found a bug in the way lists of chainable objects are cached.
When accessing an element of the list, the function generating the list is not cached and evaluated again.
This causes a bunch of issues if the list is created from the state of another system (e.g. list of PRs or comments in GitHub).
It really hinders the performance as well if the function creating the list is slow and there are a lot of elements.
I've created a reproduction example. See this module that generates a list with a time stamp:
package main
import (
"time"
)
type Generator struct{}
type Element struct {
A string
}
func (m *Generator) Make() []Element {
time.Sleep(5 * time.Second)
t := time.Now().Format(time.DateTime)
return []Element{
{A: "[1] " + t},
{A: "[2] " + t},
{A: "[3] " + t},
{A: "[4] " + t},
}
}
And a module retrieving the values of each element:
package main
import (
"context"
)
type Consumer struct{}
func (m *Consumer) Do(ctx context.Context) (string, error) {
elems, err := dag.Generator().Make(ctx)
if err != nil {
return "", err
}
out := ""
for _, e := range elems {
s, err := e.A(ctx)
if err != nil {
return "", err
}
out += s + "\n"
}
return out, nil
}
I would expect that the list is only created once in elems, err := dag.Generator().Make(ctx).
However, each call to s, err := e.A(ctx) will call it again.
Since the Generator.Make function takes 5s then the whole things takes 25s when it should only take 5s.
Also I'm then getting different timestamps for each value (in a real scenario I'm not retrieving the correct github PR or comment)