# workflow.NewFuture vs ExecuteActivity with selector.AddFuture

**URL:** <https://community.temporal.io/t/workflow-newfuture-vs-executeactivity-with-selector-addfuture/10162>\
**Category:** Community Support\
**Tags:** go-sdk\
**Created:** [November 21, 2023, 6:09pm UTC](https://community.temporal.io/t/workflow-newfuture-vs-executeactivity-with-selector-addfuture/10162 "2023-11-21T18:09:33Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![aakarim](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/aakarim/32/4375_2.png) [@aakarim](https://community.temporal.io/u/aakarim)\
**Post date:** [November 21, 2023, 6:09pm UTC](https://community.temporal.io/t/workflow-newfuture-vs-executeactivity-with-selector-addfuture/10162/1 "2023-11-21T18:09:34Z")

</div>

Hello,

I’m making a workflow where I want to run a batch in parallel, running around 15 activities at the same time and waiting for the result to complete before proceeding.

I have been using the following code to run these activities:

```auto
selector := workflow.NewSelector(ctx)
links := []string{...links} // insert links here
results := []string{}
childCtx, cancelHandler := workflow.WithCancel(ctx)
var batchErr error

for i, v := range links {
  v := v

  future := workflow.ExecuteActivity(childCtx, activities.ProcessLinks, v)
  selector.AddFuture(future, func(f workflow.Future) {
    var result string
    if err := f.Get(ctx, &result); err != nil {
        cancelHandler()
        batchErr = fmt.Errorf("ProcessLinks(%s): %w", v, err)
    }
    results = append(results, result)
  })
}
for i := 0; i < len(links); i++ {
        selector.Select(ctx)
	if batchErr != nil {
		return "", batchErr
	}
}
// continue from here with the results

```

But I also looked the ‘DSL’ example here: [https://github.com/temporalio/samples-go/blob/main/dsl/workflow.go](https://github.com/temporalio/samples-go/blob/main/dsl/workflow.go)

and I noticed it uses workflow.Go instead:

```auto
selector := workflow.NewSelector(ctx)
links := []string{...links} // insert links here
results := []string{}
childCtx, cancelHandler := workflow.WithCancel(ctx)
var batchErr error

for i, v := range links {
  v := v
  future, settable := workflow.NewFuture(childCtx)

  workflow.Go(childCtx, func(futCtx workflow.Context) {
    var result string
    err := workflow.ExecuteActivity(futCtx, activities.ProcessLinks, v).Get(futCtx, &result)
    settable.Set(result, err)
  })

  selector.AddFuture(future, func(f workflow.Future) {
    var result string
    if err := f.Get(ctx, &result); err != nil {
        cancelHandler()
        batchErr = fmt.Errorf("ProcessLinks(%s): %w", v, err)
    }
    results = append(results, result)
  })
}
for i := 0; i < len(links); i++ {
        selector.Select(ctx)
	if batchErr != nil {
		return "", batchErr
	}
}
// continue from here with the results

```

Which is the correct and canonical way to do this? Since AddFuture accepts a future and, I’m assuming, puts this event into the history anyway, what is the benefit of using a goroutine?

Also as a separate question, do I need to `defer` cancelHandler, like in Go?

---

<div class="post-metadata">

**Author:** ![maxim](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/maxim/32/8_2.png) [@maxim](https://community.temporal.io/u/maxim)\
**Post date:** [November 21, 2023, 8:00pm UTC](https://community.temporal.io/t/workflow-newfuture-vs-executeactivity-with-selector-addfuture/10162/2 "2023-11-21T20:00:21Z")

</div>

I don’t think you need a goroutine to run a single activity as it already returns a future. DSL example is overkill. Goroutine is easier when you need to run multiple sequences of activities. Each sequence per goroutine.

---

<div class="post-metadata">

**Author:** ![aakarim](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/aakarim/32/4375_2.png) [@aakarim](https://community.temporal.io/u/aakarim)\
**Post date:** [November 22, 2023, 10:32am UTC](https://community.temporal.io/t/workflow-newfuture-vs-executeactivity-with-selector-addfuture/10162/3 "2023-11-22T10:32:41Z")

</div>

Great. I was wondering!! I’m still not entirely sure why the DSL example is written using goroutines?

---

<div class="post-metadata">

**Author:** ![maxim](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/maxim/32/8_2.png) [@maxim](https://community.temporal.io/u/maxim)\
**Post date:** [November 22, 2023, 5:06pm UTC](https://community.temporal.io/t/workflow-newfuture-vs-executeactivity-with-selector-addfuture/10162/4 "2023-11-22T17:06:43Z")

</div>

The DSL example doesn’t execute a single activity in a goroutine. It [calls](https://github.com/temporalio/samples-go/blob/359c36a3c62516766735a7c6eb7d7f353599c166/dsl/workflow.go#L151C1-L158C2) an abstract function. The implementations of this function can contain arbitrary code.

```auto
func executeAsync(exe executable, ctx workflow.Context, bindings map[string]string) workflow.Future {
	future, settable := workflow.NewFuture(ctx)
	workflow.Go(ctx, func(ctx workflow.Context) {
		err := exe.execute(ctx, bindings)
		settable.Set(nil, err)
	})
	return future
}

```
