···3838const MIN_NOT_FOUND_TTL: Duration = Duration::from_secs(60);
39394040#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
4141-enum IdentityKey {
4141+pub enum IdentityKey {
4242 Handle(Handle),
4343 Did(Did),
4444}
···186186 /// multi-producer *single consumer* queue
187187 refresh_queue: Arc<Mutex<RefreshQueue>>,
188188 /// just a lock to ensure only one refresher (queue consumer) is running (to be improved with a better refresher)
189189- refresher: Arc<Mutex<()>>,
189189+ refresher_task: Arc<Mutex<()>>,
190190}
191191192192impl Identity {
···225225 did_resolver: Arc::new(did_resolver),
226226 cache,
227227 refresh_queue: Default::default(),
228228- refresher: Default::default(),
228228+ refresher_task: Default::default(),
229229 })
230230 }
231231···293293 }
294294 IdentityData::NotFound => {
295295 if (now - *last_fetch) >= MIN_NOT_FOUND_TTL {
296296+ metrics::counter!("identity_handle_refresh_queued", "reason" => "ttl", "found" => "false").increment(1);
296297 self.queue_refresh(key).await;
297298 }
298299 Ok(None)
299300 }
300301 IdentityData::Did(did) => {
301302 if (now - *last_fetch) >= MIN_TTL {
303303+ metrics::counter!("identity_handle_refresh_queued", "reason" => "ttl", "found" => "true").increment(1);
302304 self.queue_refresh(key).await;
303305 }
304306 Ok(Some(did.clone()))
···347349 }
348350 IdentityData::NotFound => {
349351 if (now - *last_fetch) >= MIN_NOT_FOUND_TTL {
352352+ metrics::counter!("identity_did_refresh_queued", "reason" => "ttl", "found" => "false").increment(1);
350353 self.queue_refresh(key).await;
351354 }
352355 Ok(None)
353356 }
354357 IdentityData::Doc(mini_did) => {
355358 if (now - *last_fetch) >= MIN_TTL {
359359+ metrics::counter!("identity_did_refresh_queued", "reason" => "ttl", "found" => "true").increment(1);
356360 self.queue_refresh(key).await;
357361 }
358362 Ok(Some(mini_did.clone()))
···363367 /// put a refresh task on the queue
364368 ///
365369 /// this can be safely called from multiple concurrent tasks
366366- async fn queue_refresh(&self, key: IdentityKey) {
370370+ pub async fn queue_refresh(&self, key: IdentityKey) {
367371 // todo: max queue size
368372 let mut q = self.refresh_queue.lock().await;
369373 if !q.items.contains(&key) {
···440444 /// run the refresh queue consumer
441445 pub async fn run_refresher(&self, shutdown: CancellationToken) -> Result<(), IdentityError> {
442446 let _guard = self
443443- .refresher
447447+ .refresher_task
444448 .try_lock()
445449 .expect("there to only be one refresher running");
446450 loop {
···462466 log::trace!("refreshing handle {handle:?}");
463467 match self.handle_resolver.resolve(handle).await {
464468 Ok(did) => {
469469+ metrics::counter!("identity_handle_refresh", "success" => "true")
470470+ .increment(1);
465471 self.cache.insert(
466472 task_key.clone(),
467473 IdentityVal(UtcDateTime::now(), IdentityData::Did(did)),
468474 );
469475 }
470476 Err(atrium_identity::Error::NotFound) => {
477477+ metrics::counter!("identity_handle_refresh", "success" => "false", "reason" => "not found").increment(1);
471478 self.cache.insert(
472479 task_key.clone(),
473480 IdentityVal(UtcDateTime::now(), IdentityData::NotFound),
474481 );
475482 }
476483 Err(err) => {
484484+ metrics::counter!("identity_handle_refresh", "success" => "false", "reason" => "other").increment(1);
477485 log::warn!(
478486 "failed to refresh handle: {err:?}. leaving stale (should we eventually do something?)"
479487 );
···488496 Ok(did_doc) => {
489497 // TODO: fix in atrium: should verify id is did
490498 if did_doc.id != did.to_string() {
499499+ metrics::counter!("identity_did_refresh", "success" => "false", "reason" => "wrong did").increment(1);
491500 log::warn!(
492501 "refreshed did doc failed: wrong did doc id. dropping refresh."
493502 );
···496505 let mini_doc = match did_doc.try_into() {
497506 Ok(md) => md,
498507 Err(e) => {
508508+ metrics::counter!("identity_did_refresh", "success" => "false", "reason" => "bad doc").increment(1);
499509 log::warn!(
500510 "converting mini doc failed: {e:?}. dropping refresh."
501511 );
502512 continue;
503513 }
504514 };
515515+ metrics::counter!("identity_did_refresh", "success" => "true")
516516+ .increment(1);
505517 self.cache.insert(
506518 task_key.clone(),
507519 IdentityVal(UtcDateTime::now(), IdentityData::Doc(mini_doc)),
508520 );
509521 }
510522 Err(atrium_identity::Error::NotFound) => {
523523+ metrics::counter!("identity_did_refresh", "success" => "false", "reason" => "not found").increment(1);
511524 self.cache.insert(
512525 task_key.clone(),
513526 IdentityVal(UtcDateTime::now(), IdentityData::NotFound),
514527 );
515528 }
516529 Err(err) => {
530530+ metrics::counter!("identity_did_refresh", "success" => "false", "reason" => "other").increment(1);
517531 log::warn!(
518532 "failed to refresh did doc: {err:?}. leaving stale (should we eventually do something?)"
519533 );
+1-1
slingshot/src/lib.rs
···99pub use consumer::consume;
1010pub use firehose_cache::firehose_cache;
1111pub use healthcheck::healthcheck;
1212-pub use identity::Identity;
1212+pub use identity::{Identity, IdentityKey};
1313pub use record::{CachedRecord, ErrorResponseObject, Repo};
1414pub use server::serve;
+4-1
slingshot/src/main.rs
···154154155155 let repo = Repo::new(identity.clone());
156156157157+ let identity_for_server = identity.clone();
157158 let server_shutdown = shutdown.clone();
158159 let server_cache_handle = cache.clone();
159160 let bind = args.bind;
160161 tasks.spawn(async move {
161162 serve(
162163 server_cache_handle,
163163- identity,
164164+ identity_for_server,
164165 repo,
165166 args.acme_domain,
166167 args.acme_contact,
···173174 Ok(())
174175 });
175176177177+ let identity_refreshable = identity.clone();
176178 let consumer_shutdown = shutdown.clone();
177179 let consumer_cache = cache.clone();
178180 tasks.spawn(async move {
···180182 args.jetstream,
181183 None,
182184 args.jetstream_no_zstd,
185185+ identity_refreshable,
183186 consumer_shutdown,
184187 consumer_cache,
185188 )