Metros
The platform API is per metro, but the instances of one account live in more than one metro.
The SDK treats the metros in scope as one namespace.
A read asks every metro at the same time and merges the answers, and every result carries the metro it came from.
The scope
Set the scope for the client, for a group of calls, or for one call.
Code
An explicit scope skips metro discovery.
UKC_METRO works like metro, so it limits the client to that metro.
To see which metros the account can reach:
Code
The client discovers the metros once, and it caches the result.
It asks the control plane and trusts the endpoint that the control plane reports, so a new metro works without an SDK upgrade.
KNOWN_METROS lists the metros known at the release of this version:
| Code | Location |
|---|---|
fra | Frankfurt, DE |
dal | Dallas, TX, USA |
sin | Singapore |
was | Washington, DC, USA |
sfo | San Francisco, USA |
How operations behave in a scope
- A read covers the whole scope. Pages arrive in the order that the metros answer, so a slow metro doesn't delay a fast one.
createnever fans out. It needs one metro: the metro of the client, or the default target (metro,UKC_METRO, orfra) when the scope is wider.- A bulk operation acts on the whole scope.
The SDK locates the refs first, then sends one call to each metro that matched.
In a wide scope,
delete([{ name: "web" }])deletes everywebin scope. Make the scope narrower, or qualify the ref, to act on one resource. - The control plane is global. The scope doesn't affect it.
Names across metros
A name identifies a resource within one metro.
The same name can exist in more than one metro at once, often because you deployed the same thing everywhere.
As a result, a name with a wide scope can match more than one resource.
A { uuid } ref never has this problem, because a UUID identifies one resource wherever it lives.
You have three ways to say which resource you mean:
Code
One match: get()
get() requires exactly one match, because the next step is often a mutation.
If a name matches in more than one metro, get() throws an AmbiguousRefError.
The error carries the matches, so a recovery costs no further request:
Code
Every match: each()
each(ref) is the deliberate plural.
It resolves the matches once, then runs each operation in the metro that holds the match:
Code
An operation on a set returns an array.
each() exists on instances, volumes, services, and certificates.
Partial failure
One unreachable metro doesn't discard the rest of the answer.
The SDK drains the healthy metros first, then it throws a MetroFanoutError that names the failures:
Code
A bulk operation can't yield results as it goes, so the error carries the results that did succeed as err.results.
The same rule applies to a set from each().