+26
src/handle_resolver/memory.rs
+26
src/handle_resolver/memory.rs
···
175
175
176
176
result
177
177
}
178
+
179
+
async fn set(&self, handle: &str, did: &str) -> Result<(), HandleResolverError> {
180
+
// Normalize the handle to lowercase
181
+
let handle = handle.to_lowercase();
182
+
183
+
// Update the in-memory cache
184
+
{
185
+
let mut cache = self.cache.write().await;
186
+
let timestamp = Self::current_timestamp();
187
+
cache.insert(
188
+
handle.clone(),
189
+
ResolveHandleResult::Found(timestamp, did.to_string()),
190
+
);
191
+
self.metrics.incr("resolver.memory.set").await;
192
+
tracing::debug!("Set handle {} -> DID {} in memory cache", handle, did);
193
+
194
+
// Track cache size
195
+
let cache_size = cache.len() as u64;
196
+
self.metrics
197
+
.gauge("resolver.memory.cache_entries", cache_size)
198
+
.await;
199
+
}
200
+
201
+
// Chain to inner resolver
202
+
self.inner.set(&handle, did).await
203
+
}
178
204
}
179
205
180
206
/// Create a new in-memory caching handle resolver.
+5
src/handle_resolver/proactive_refresh.rs
+5
src/handle_resolver/proactive_refresh.rs
···
141
141
142
142
Ok((did, resolve_time))
143
143
}
144
+
145
+
async fn set(&self, handle: &str, did: &str) -> Result<(), HandleResolverError> {
146
+
// Simply chain to inner resolver - no proactive refresh needed for manual sets
147
+
self.inner.set(handle, did).await
148
+
}
144
149
}
145
150
146
151
/// Create a ProactiveRefreshResolver with custom threshold using trait objects
+6
src/handle_resolver/rate_limited.rs
+6
src/handle_resolver/rate_limited.rs
···
187
187
// With permit acquired, forward to inner resolver
188
188
self.inner.resolve(s).await
189
189
}
190
+
191
+
async fn set(&self, handle: &str, did: &str) -> Result<(), HandleResolverError> {
192
+
// Set operations don't need rate limiting since they're typically administrative
193
+
// and don't involve network calls to external services
194
+
self.inner.set(handle, did).await
195
+
}
190
196
}
191
197
192
198
/// Create a rate-limited handle resolver.
+64
src/handle_resolver/sqlite.rs
+64
src/handle_resolver/sqlite.rs
···
255
255
256
256
result
257
257
}
258
+
259
+
async fn set(&self, handle: &str, did: &str) -> Result<(), HandleResolverError> {
260
+
// Normalize the handle to lowercase
261
+
let handle = handle.to_lowercase();
262
+
263
+
// Update the SQLite cache
264
+
if let Ok(mut conn) = self.pool.acquire().await {
265
+
// Create a resolution result for the successful mapping
266
+
let resolution_result = match HandleResolutionResult::success(did) {
267
+
Ok(res) => res,
268
+
Err(e) => {
269
+
tracing::warn!("Failed to create resolution result for set operation: {}", e);
270
+
self.metrics.incr("resolver.sqlite.set_result_create_error").await;
271
+
// Still chain to inner resolver even if we can't cache
272
+
return self.inner.set(&handle, did).await;
273
+
}
274
+
};
275
+
276
+
// Serialize to bytes
277
+
match resolution_result.to_bytes() {
278
+
Ok(bytes) => {
279
+
// Insert or update the cache entry
280
+
let timestamp = std::time::SystemTime::now()
281
+
.duration_since(std::time::UNIX_EPOCH)
282
+
.unwrap_or_default()
283
+
.as_secs() as i64;
284
+
285
+
let expires_at = timestamp + self.ttl_seconds as i64;
286
+
287
+
match sqlx::query(
288
+
"INSERT OR REPLACE INTO handle_resolution_cache (handle, resolved_value, created_at, expires_at) VALUES (?, ?, ?, ?)"
289
+
)
290
+
.bind(&handle)
291
+
.bind(&bytes)
292
+
.bind(timestamp)
293
+
.bind(expires_at)
294
+
.execute(&mut *conn)
295
+
.await
296
+
{
297
+
Ok(_) => {
298
+
tracing::debug!("Set handle {} -> DID {} in SQLite cache", handle, did);
299
+
self.metrics.incr("resolver.sqlite.set_success").await;
300
+
}
301
+
Err(e) => {
302
+
tracing::warn!("Failed to set handle->DID mapping in SQLite: {}", e);
303
+
self.metrics.incr("resolver.sqlite.set_cache_error").await;
304
+
// Still chain to inner resolver even if cache update fails
305
+
}
306
+
}
307
+
}
308
+
Err(e) => {
309
+
tracing::warn!("Failed to serialize resolution result for set operation: {}", e);
310
+
self.metrics.incr("resolver.sqlite.set_serialize_error").await;
311
+
// Still chain to inner resolver even if serialization fails
312
+
}
313
+
}
314
+
} else {
315
+
tracing::warn!("Failed to get SQLite connection for set operation");
316
+
self.metrics.incr("resolver.sqlite.set_connection_error").await;
317
+
}
318
+
319
+
// Chain to inner resolver
320
+
self.inner.set(&handle, did).await
321
+
}
258
322
}
259
323
260
324
/// Create a new SQLite-backed handle resolver with default 90-day TTL.