A request can wait to be served for longer than the access token it was
sent with lives, and comes back refused for a token that was valid when
it left. Uploads that take minutes make that wait ordinary.
- tell an expired token apart from any other refusal by the code the
API returns, and retry only that one, once
- prefer a token another process left behind over minting a second: it
saves a round trip, and a rotating provider would retire one that is
still in use. Assign it rather than read it, since the setter is what
rewrites the session header the retry will carry
- settle the token before the request so the one compared afterwards is
the one that was actually sent
- report an overloaded server when the second attempt is refused too,
and let API errors out of the upload path with their own type
The login cache is shared by every mdrs process, but the refresh was
guarded by a lock that only reaches inside one. Concurrent runs each
sent the same refresh token, and a provider that rotates them accepts
the first and refuses the rest.
- hold a lock that spans processes across the whole read-refresh-
write, checking cheaply first so ordinary requests never take it
- write the cache through a temporary file: opening it for writing
truncates it, and a reader landing in that window found it empty
and threw the session away
- take the lock for every write, not just the refresh, so a login
running beside one cannot be silently reverted
- wait for a busy lock on Windows rather than giving up after the ten
attempts msvcrt allows, and retry the rename it refuses while a
reader still holds the file open
- bound the refresh request on its own, so a provider that goes quiet
cannot hold the lock indefinitely
- accept bare hostnames such as localhost, store URLs without the
trailing slash, and join download paths through one helper