DNSIMPLE: DOCS: handle multiple provider instances (#3678)

This commit is contained in:
Phil Pennock 2025-07-22 12:51:21 -04:00 committed by GitHub
parent 570477f8d3
commit 3f4f9b8083
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 26 additions and 3 deletions

View file

@ -34,3 +34,22 @@ An account ID determined on the first query?
That probably needs to be protected, even if every fetch returns the same data.
The `-race` build is a helpful hint but is not a guarantee.
#### Multiple Providers
Most simple use-cases likely use just one copy of a given provider, managing
zones in an account. But there can be multiple _distinct_ copies, each for
different accounts. Someone might use this while migrating accounts, for
instance. You might have two fields in `creds.json` both with a `TYPE` of
your provider.
The uses of the provider objects should never create copies; each is created
by a constructor, but thereafter is a singleton per constructed provider.
Thus it is safe to have synchronization objects inside the provider struct.
See, for example, the `dnsimple` provider, where there is a `sync.Once` _per
object_, not at a global level, so that the `.accountID` can be fetched just
once per configured provider. Because `sync.Once` contains a reference to
`sync.noCopy`, the `go vet` command will catch attempts to copy that object,
and so will catch attempts to copy the containing `dnsimpleProvider` object.

View file

@ -70,13 +70,17 @@ var nameServerSuffixes = []string{
".dnsimple-edge.com.",
}
var onceFetchAccountId sync.Once
// dnsimpleProvider is the handle for this provider.
type dnsimpleProvider struct {
AccountToken string // The account access token
BaseURL string // An alternate base URI
// We can have multiple _distinct_ versions of this struct, authenticated to
// different accounts, so _each_ version needs to be initialized just once.
// Note that sync.Once contains a reference to sync.noCopy so this will cause
// `go vet` to catch attempts to copy this outer provider struct.
onceFetchAccountId sync.Once
// This is protected under onceFetchAccountId so that this is fully safe concurrently.
accountID string // Account id cache
}
@ -305,7 +309,7 @@ func (c *dnsimpleProvider) getClient() *dnsimpleapi.Client {
func (c *dnsimpleProvider) getAccountID() (string, error) {
var onceErr error
onceFetchAccountId.Do(func() {
c.onceFetchAccountId.Do(func() {
client := c.getClient()
whoamiResponse, err := client.Identity.Whoami(context.Background())
if err != nil {