Skip to content

Refactor Microsoft Auth endpoints and enhance token handling#32

Open
alfarahn wants to merge 4 commits into
mainfrom
feature/crawl-timing-hooks
Open

Refactor Microsoft Auth endpoints and enhance token handling#32
alfarahn wants to merge 4 commits into
mainfrom
feature/crawl-timing-hooks

Conversation

@alfarahn
Copy link
Copy Markdown
Collaborator

  • Updated MicrosoftAuthEndpoints to use a named HTTP client with a 30s timeout for token requests.
  • Changed SaveIdentity and UpdateGraphTier methods in PersistentIdentity to be asynchronous.
  • Enhanced SessionTokenStore to include retry logic for transient network errors when fetching tokens.
  • Introduced a new Ipv4HttpHandler to enforce IPv4-only connections and a 5s connect timeout for all HTTP clients.
  • Improved error handling and logging for token refresh operations.
  • Added ephemeral "cooling down" rows in the ChatView component to visually indicate 429/5xx throttling events.
  • Implemented timing hooks to capture and log performance metrics for tool calls and server interactions.
  • Updated dependencies in the project file for GitHub Copilot SDK.

Summary

Type of change

  • Bug fix
  • New feature / new tool
  • Refactor
  • Documentation
  • Build / CI
  • Security

Checklist

  • Builds locally (dotnet build)
  • Frontend builds (npm run build in src/Dashboard/frontend)
  • No new secrets committed
  • No DELETE methods enabled in HTTP helpers
  • Updated .github/copilot-instructions.md if behaviour or structure changed
  • Updated CHANGELOG.md under [Unreleased]

Related issues

Closes #

- Updated MicrosoftAuthEndpoints to use a named HTTP client with a 30s timeout for token requests.
- Changed SaveIdentity and UpdateGraphTier methods in PersistentIdentity to be asynchronous.
- Enhanced SessionTokenStore to include retry logic for transient network errors when fetching tokens.
- Introduced a new Ipv4HttpHandler to enforce IPv4-only connections and a 5s connect timeout for all HTTP clients.
- Improved error handling and logging for token refresh operations.
- Added ephemeral "cooling down" rows in the ChatView component to visually indicate 429/5xx throttling events.
- Implemented timing hooks to capture and log performance metrics for tool calls and server interactions.
- Updated dependencies in the project file for GitHub Copilot SDK.
Comment thread src/Dashboard/frontend/src/components/ChatView.vue Fixed
Comment thread src/Dashboard/frontend/src/components/ChatView.vue Fixed
var done = new TaskCompletionSource();
var cancelled = false;
var toolTracker = new ConcurrentDictionary<string, (string Name, DateTimeOffset StartTime, Activity? Activity)>();
var firstEventLogged = 0;
Comment thread src/Dashboard/Program.cs
id = record.UserId,
login = $"user-{record.UserId & 0xFFFF:X4}",
name = record.Name,
avatar = (string?)null,
// Pass null activity — Activity is not safe for concurrent SetTag
// writers, and these drilldowns run in parallel. Each call still
// gets its own ActivitySource span inside HttpHelper.
try { return (c, Breakdown: (object)await GetBreakdownForDay(token, subscriptionId, c.Date, groupBy, activity: null)); }
// writers, and these drilldowns run in parallel. Each call still
// gets its own ActivitySource span inside HttpHelper.
try { return (c, Breakdown: (object)await GetBreakdownForDay(token, subscriptionId, c.Date, groupBy, activity: null)); }
catch (Exception ex) { return (c, Breakdown: (object)new { error = ex.Message }); }
// writers across the 8 parallel queries. HttpHelper still emits
// its own per-call span.
try { return (p.Label, Result: await RunResourceGraphQuery(token, p.Kql, subs, activity: null)); }
catch (Exception ex) { return (p.Label, Result: (object)new { error = "query exception", detail = ex.Message }); }
await ctx.Response.WriteAsync($"data: {donePayload}\n\n");
await ctx.Response.Body.FlushAsync();
}
catch { }
Comment on lines +422 to +426
catch (Exception bgEx)
{
logger.LogWarning(bgEx, "Background title generation failed for session {Sid}", bgSessionId);
return null;
}
logger.LogInformation("timing phase=sdk.first_event ms={Ms:F0} user={User}", firstMs, userLogin);
await SafeEmit(JsonSerializer.Serialize(new { type = "timing", phase = "sdk.first_event", ms = Math.Round(firstMs, 1), extra = new { evt = evt.GetType().Name } }));
}
catch { }
logger.LogInformation("timing phase=sdk.first_event ms={Ms:F0} user={User}", firstMs, userLogin);
await SafeEmit(JsonSerializer.Serialize(new { type = "timing", phase = "sdk.first_event", ms = Math.Round(firstMs, 1), extra = new { evt = evt.GetType().Name } }));
}
catch { }
{
var sw = Stopwatch.StartNew();
try { var v = await fn(); sw.Stop(); return (name, v, sw.Elapsed.TotalMilliseconds, null); }
catch (Exception ex) { sw.Stop(); return (name, null, sw.Elapsed.TotalMilliseconds, ex.Message); }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants