Commit 580c015
Add Asynchronous Token Refresh to
## Motivation
Synchronous token refresh introduces unnecessary blocking and latency,
which becomes especially problematic in high QPS (Queries Per Second)
workloads. In such scenarios, blocking token refresh operations can
create bottlenecks, impact throughput, and cause request queuing.
## Solution
This PR introduces asynchronous token refresh to improve responsiveness
and reliability, with particular benefits for high-throughput
applications.
## What changes are proposed in this pull request?
**Async Refresh Option**: Added `withAsyncRefresh(boolean enabled)`
method to enable/disable asynchronous token refresh. When enabled,
tokens are refreshed in the background when they become "stale" (close
to expiry).
### Token State Management
- **Three-State Token System**:
- `FRESH`: Token is valid and not close to expiry
- `STALE`: Token is valid but will expire soon (triggers async refresh
if enabled)
- `EXPIRED`: Token has expired (requires blocking refresh)
- `Token` class is now a pure data class, holding only token information
(access token, refresh token, expiry time).
- `TokenSource` implementations are responsible for token state
management and refresh logic.
### Performance Optimizations
- **Non-blocking for Stale Tokens**: When async is enabled and the token
is stale but not expired, API calls continue using the current token
while a background refresh is triggered, reducing latency and avoiding
thread blocking.
- **Blocking Only on Expiry**: If the token is expired, calls will still
block until a new token is fetched, ensuring correctness.
- **Default Stale Duration**: Tokens are considered stale 3 minutes
before expiry, allowing proactive refresh while maintaining validity.
### Thread Safety & Reliability
- **Synchronized Refresh Logic**: All async refresh operations are
synchronized to prevent race conditions and redundant refreshes.
- **Refresh State Tracking**: The implementation tracks:
- Whether a refresh is already in progress
- Whether the last refresh succeeded
- This prevents unnecessary or repeated background refreshes
- **Failure Handling**: If an async refresh fails, subsequent refreshes
will be forced to be synchronous until a successful refresh occurs.
### Configuration Options
**Experimental Features (may change in future releases)**:
- withClockSupplier() - Custom clock supplier for testing
- withAsyncRefresh() - Enable/disable asynchronous token refresh
- withExpiryBuffer() - Configure the expiry buffer duration
## Testing
- **Unit tests** cover async refresh triggering, correct token usage
during background refresh, and thread safety.
- **Time Control for Testing:**
The `RefreshableTokenSource` class can be configured with a custom clock
supplier via `withClockSupplier(ClockSupplier clockSupplier)`, allowing
tests to precisely control and simulate token expiry and refresh timing.
This enables deterministic testing of token state transitions and
refresh behavior without relying on real system time.
NO_CHANGELOG=true
---------
Co-authored-by: Parth Bansal <[email protected]>RefreshableTokenSource (#455)1 parent e51c2c6 commit 580c015
File tree
11 files changed
+436
-135
lines changed- databricks-sdk-java/src
- main/java/com/databricks/sdk/core
- oauth
- utils
- test/java/com/databricks/sdk/core
- oauth
- utils
11 files changed
+436
-135
lines changedLines changed: 221 additions & 12 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
8 | 11 | | |
9 | 12 | | |
10 | 13 | | |
| 14 | + | |
11 | 15 | | |
| 16 | + | |
| 17 | + | |
12 | 18 | | |
13 | 19 | | |
14 | 20 | | |
15 | 21 | | |
16 | | - | |
17 | | - | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
18 | 25 | | |
19 | 26 | | |
20 | | - | |
21 | 27 | | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
22 | 61 | | |
23 | 62 | | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
24 | 68 | | |
25 | 69 | | |
26 | 70 | | |
27 | 71 | | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
28 | 243 | | |
29 | 244 | | |
30 | 245 | | |
| 246 | + | |
31 | 247 | | |
32 | 248 | | |
33 | 249 | | |
34 | 250 | | |
35 | 251 | | |
36 | 252 | | |
37 | 253 | | |
| 254 | + | |
| 255 | + | |
38 | 256 | | |
39 | 257 | | |
40 | 258 | | |
| |||
75 | 293 | | |
76 | 294 | | |
77 | 295 | | |
78 | | - | |
79 | | - | |
80 | | - | |
81 | | - | |
82 | | - | |
83 | | - | |
84 | | - | |
85 | | - | |
86 | | - | |
87 | 296 | | |
Lines changed: 25 additions & 37 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | | - | |
4 | | - | |
5 | 3 | | |
6 | 4 | | |
7 | 5 | | |
| |||
23 | 21 | | |
24 | 22 | | |
25 | 23 | | |
26 | | - | |
27 | | - | |
28 | 24 | | |
29 | 25 | | |
30 | | - | |
31 | | - | |
32 | | - | |
33 | | - | |
34 | | - | |
35 | | - | |
| 26 | + | |
36 | 27 | | |
37 | 28 | | |
38 | 29 | | |
| |||
42 | 33 | | |
43 | 34 | | |
44 | 35 | | |
45 | | - | |
46 | | - | |
47 | | - | |
48 | | - | |
49 | | - | |
50 | | - | |
51 | | - | |
52 | | - | |
53 | | - | |
54 | | - | |
55 | 36 | | |
56 | 37 | | |
57 | 38 | | |
58 | | - | |
59 | 39 | | |
60 | 40 | | |
61 | 41 | | |
62 | 42 | | |
63 | | - | |
64 | | - | |
65 | | - | |
66 | | - | |
67 | | - | |
68 | | - | |
69 | | - | |
70 | | - | |
71 | | - | |
72 | | - | |
73 | | - | |
74 | | - | |
75 | | - | |
76 | | - | |
77 | | - | |
78 | | - | |
79 | 43 | | |
80 | 44 | | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
81 | 50 | | |
82 | 51 | | |
83 | 52 | | |
84 | 53 | | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
85 | 59 | | |
86 | 60 | | |
87 | 61 | | |
88 | 62 | | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
89 | 68 | | |
90 | 69 | | |
91 | 70 | | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
92 | 80 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
5 | | - | |
| 5 | + | |
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
| |||
Lines changed: 1 addition & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
154 | 154 | | |
155 | 155 | | |
156 | 156 | | |
157 | | - | |
| 157 | + | |
158 | 158 | | |
159 | 159 | | |
160 | 160 | | |
| |||
0 commit comments