samber / mo

🦄 Monads and popular FP abstractions, powered by Go 1.18+ Generics (Option, Result, Either...)

Home Page:https://pkg.go.dev/github.com/samber/mo

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Future[T] implementation discussion

yougahu opened this issue · comments

If we call (*Future[T]).Then after Future[T] has completed, the Than-callback will never been called. And if we try to Collect a completed Future[T], it could cause deadlock.

for example:

func Test_Future(t *testing.T) {
	completed := make(chan struct{})
	fut := mo.NewFuture(func(resolve func(int), reject func(error)) {
		resolve(1)
		close(completed)
	})

	<-completed
	fut.Then(func(in int) (int, error) {
            fmt.Println(in) // will never been print
	    return in, nil
	}).Collect() // deadlock
}

Futures call next future once they have finished, so if we chain a callback on a finished future, the call chain would be broken.

And here is my commit to fix this commit.

commit

+1
It also happens if we collect after resolve was called:

func Test_Future(t *testing.T) {
	completed := make(chan struct{})
	fut := mo.NewFuture(func(resolve func(int), reject func(error)) {
		resolve(1)
		close(completed)
	})

	<-completed
	fut.Collect() // deadlock
}

Hi there

Thanks for inspecting this. @yougahu I gonna merge your commit and create a new release of mo.