From 3318fe97dcc3cb2385ba7e5cbc4942ec4a773975 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Tue, 8 Jul 2014 11:42:03 -0700 Subject: [PATCH] terraform: ContextOpts can set a max parallelism --- terraform/context.go | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/terraform/context.go b/terraform/context.go index 9727aadfe..4820c6dc3 100644 --- a/terraform/context.go +++ b/terraform/context.go @@ -29,8 +29,9 @@ type Context struct { providers map[string]ResourceProviderFactory variables map[string]string - l sync.Mutex // Lock acquired during any task - sl sync.RWMutex // Lock acquired to R/W internal data + l sync.Mutex // Lock acquired during any task + parCh chan struct{} // Semaphore used to limit parallelism + sl sync.RWMutex // Lock acquired to R/W internal data runCh <-chan struct{} sh *stopHook } @@ -38,12 +39,13 @@ type Context struct { // ContextOpts are the user-creatable configuration structure to create // a context with NewContext. type ContextOpts struct { - Config *config.Config - Diff *Diff - Hooks []Hook - State *State - Providers map[string]ResourceProviderFactory - Variables map[string]string + Config *config.Config + Diff *Diff + Hooks []Hook + Parallelism int + State *State + Providers map[string]ResourceProviderFactory + Variables map[string]string } // NewContext creates a new context. @@ -60,6 +62,13 @@ func NewContext(opts *ContextOpts) *Context { copy(hooks, opts.Hooks) hooks[len(opts.Hooks)] = sh + // Make the parallelism channel + par := opts.Parallelism + if par == 0 { + par = 10 + } + parCh := make(chan struct{}, par) + return &Context{ config: opts.Config, diff: opts.Diff, @@ -68,7 +77,8 @@ func NewContext(opts *ContextOpts) *Context { providers: opts.Providers, variables: opts.Variables, - sh: sh, + parCh: parCh, + sh: sh, } } @@ -682,6 +692,12 @@ func (c *Context) genericWalkFn(cb genericWalkFunc) depgraph.WalkFunc { return nil } + // Limit parallelism + c.parCh <- struct{}{} + defer func() { + <-c.parCh + }() + switch m := n.Meta.(type) { case *GraphNodeResource: // Continue, we care about this the most