helper/schema: expose stop information as a Context

This commit is contained in:
Mitchell Hashimoto 2016-10-25 11:29:24 -07:00
parent 045ddf3695
commit 5ee8042dff
No known key found for this signature in database
GPG Key ID: 744E147AA52F5B0A
5 changed files with 27 additions and 42 deletions

View File

@ -1,11 +1,11 @@
package azurerm package azurerm
import ( import (
"context"
"fmt" "fmt"
"log" "log"
"net/http" "net/http"
"net/http/httputil" "net/http/httputil"
"time"
"github.com/Azure/azure-sdk-for-go/arm/cdn" "github.com/Azure/azure-sdk-for-go/arm/cdn"
"github.com/Azure/azure-sdk-for-go/arm/compute" "github.com/Azure/azure-sdk-for-go/arm/compute"
@ -20,7 +20,6 @@ import (
mainStorage "github.com/Azure/azure-sdk-for-go/storage" mainStorage "github.com/Azure/azure-sdk-for-go/storage"
"github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest"
"github.com/Azure/go-autorest/autorest/azure" "github.com/Azure/go-autorest/autorest/azure"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform" "github.com/hashicorp/terraform/terraform"
riviera "github.com/jen20/riviera/azure" riviera "github.com/jen20/riviera/azure"
) )
@ -32,7 +31,7 @@ type ArmClient struct {
tenantId string tenantId string
subscriptionId string subscriptionId string
stopCh <-chan struct{} // From the provider StopContext context.Context
rivieraClient *riviera.Client rivieraClient *riviera.Client
@ -489,7 +488,3 @@ func (armClient *ArmClient) getQueueServiceClientForStorageAccount(resourceGroup
queueClient := storageClient.GetQueueService() queueClient := storageClient.GetQueueService()
return &queueClient, true, nil return &queueClient, true, nil
} }
func (armClient *ArmClient) CancelCh(max time.Duration) (<-chan struct{}, chan<- struct{}) {
return resource.StopCh(armClient.stopCh, max)
}

View File

@ -161,7 +161,7 @@ func providerConfigure(p *schema.Provider) schema.ConfigureFunc {
return nil, err return nil, err
} }
client.stopCh = p.StopCh() client.StopContext = p.StopContext()
err = registerAzureResourceProvidersWithSubscription(client.rivieraClient) err = registerAzureResourceProvidersWithSubscription(client.rivieraClient)
if err != nil { if err != nil {

View File

@ -1,6 +1,7 @@
package azurerm package azurerm
import ( import (
"context"
"fmt" "fmt"
"log" "log"
"net/http" "net/http"
@ -192,10 +193,9 @@ func resourceArmStorageAccountCreate(d *schema.ResourceData, meta interface{}) e
} }
// Create // Create
cancelCh, doneCh := client.CancelCh(1 * time.Hour) cancelCtx, _ := context.WithTimeout(client.StopContext, 1*time.Hour)
_, createErr := storageClient.Create( _, createErr := storageClient.Create(
resourceGroupName, storageAccountName, opts, cancelCh) resourceGroupName, storageAccountName, opts, cancelCtx.Done())
close(doneCh)
// The only way to get the ID back apparently is to read the resource again // The only way to get the ID back apparently is to read the resource again
read, err := storageClient.GetProperties(resourceGroupName, storageAccountName) read, err := storageClient.GetProperties(resourceGroupName, storageAccountName)

View File

@ -1,6 +1,7 @@
package schema package schema
import ( import (
"context"
"errors" "errors"
"fmt" "fmt"
"sort" "sort"
@ -51,9 +52,9 @@ type Provider struct {
meta interface{} meta interface{}
stopCh chan struct{} // stopCh is closed when Stop is called stopCtx context.Context
stopped bool // set to true once stopped to avoid double close of stopCh stopCtxCancel context.CancelFunc
stopLock sync.Mutex stopOnce sync.Once
} }
// ConfigureFunc is the function used to configure a Provider. // ConfigureFunc is the function used to configure a Provider.
@ -111,40 +112,29 @@ func (p *Provider) SetMeta(v interface{}) {
// Stopped reports whether the provider has been stopped or not. // Stopped reports whether the provider has been stopped or not.
func (p *Provider) Stopped() bool { func (p *Provider) Stopped() bool {
p.stopLock.Lock() ctx := p.StopContext()
defer p.stopLock.Unlock() select {
return p.stopped case <-ctx.Done():
return true
default:
return false
}
} }
// StopCh returns a channel that is closed once the provider is stopped. // StopCh returns a channel that is closed once the provider is stopped.
func (p *Provider) StopCh() <-chan struct{} { func (p *Provider) StopContext() context.Context {
p.stopLock.Lock() p.stopOnce.Do(p.stopInit)
defer p.stopLock.Unlock() return p.stopCtx
if p.stopCh == nil {
p.stopCh = make(chan struct{})
} }
return p.stopCh func (p *Provider) stopInit() {
p.stopCtx, p.stopCtxCancel = context.WithCancel(context.Background())
} }
// Stop implementation of terraform.ResourceProvider interface. // Stop implementation of terraform.ResourceProvider interface.
func (p *Provider) Stop() error { func (p *Provider) Stop() error {
p.stopLock.Lock() p.stopOnce.Do(p.stopInit)
defer p.stopLock.Unlock() p.stopCtxCancel()
// Close the stop channel and mark as stopped if we haven't
if !p.stopped {
// Initialize the stop channel so future calls to StopCh work
if p.stopCh == nil {
p.stopCh = make(chan struct{})
}
// Close and mark
close(p.stopCh)
p.stopped = true
}
return nil return nil
} }

View File

@ -338,7 +338,7 @@ func TestProviderStop(t *testing.T) {
} }
// Verify stopch blocks // Verify stopch blocks
ch := p.StopCh() ch := p.StopContext().Done()
select { select {
case <-ch: case <-ch:
t.Fatal("should not be stopped") t.Fatal("should not be stopped")
@ -376,7 +376,7 @@ func TestProviderStop_stopFirst(t *testing.T) {
} }
select { select {
case <-p.StopCh(): case <-p.StopContext().Done():
case <-time.After(10 * time.Millisecond): case <-time.After(10 * time.Millisecond):
t.Fatal("should be stopped") t.Fatal("should be stopped")
} }