Skip to content

Commit fe319fc

Browse files
author
rain
committed
Merge remote-tracking branch 'origin/master' into bot/docs-audit
2 parents 2724c9a + 208ee4b commit fe319fc

38 files changed

Lines changed: 1956 additions & 296 deletions

File tree

.github/workflows/discord-posts.yml

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,40 @@ jobs:
2929
script: |
3030
const { owner, repo } = context.repo;
3131
const sha = context.sha;
32-
const prs = await github.paginate(github.rest.repos.listPullRequestsAssociatedWithCommit, {
33-
owner,
34-
repo,
35-
commit_sha: sha,
36-
});
32+
33+
async function findAssociatedPRs() {
34+
// It seems that when we do this too promptly after a PR merge then the data isn't there, so we have a retry loop.
35+
for (let attempt = 1; attempt <= 3; attempt++) {
36+
core.info('Looking for associated PRs..');
37+
const prs = await github.paginate(github.rest.repos.listPullRequestsAssociatedWithCommit, {
38+
owner,
39+
repo,
40+
commit_sha: sha,
41+
});
42+
43+
if (prs.length > 0) {
44+
return prs;
45+
}
46+
47+
core.info('No associated PRs found. Will check again.');
48+
await new Promise((resolve) => setTimeout(resolve, 30000));
49+
}
50+
51+
return [];
52+
}
53+
54+
const prs = await findAssociatedPRs();
55+
core.info(`Associated PR info found:`);
56+
core.info(JSON.stringify(prs, null, 2));
3757
3858
if (prs.length === 0) {
59+
core.info('No associated PRs found. Treating this push as a direct/non-PR push.');
3960
core.setOutput('is_pr_merge', 'false');
61+
core.info('Output is_pr_merge=false');
4062
return;
4163
}
4264
if (prs.length > 1) {
65+
core.info('Multiple associated PRs found. Failing because downstream notification expects exactly one PR.');
4366
core.setFailed(`Expected exactly one PR associated with ${sha}, found ${prs.length}.`);
4467
return;
4568
}

.github/workflows/llm-benchmark-periodic.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ jobs:
114114
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
115115
LLM_VENDOR: openrouter
116116
LLM_BENCHMARK_API_KEY: ${{ secrets.LLM_BENCHMARK_API_KEY }}
117-
LLM_BENCHMARK_UPLOAD_URL: ${{ secrets.LLM_BENCHMARK_UPLOAD_URL }}
117+
LLM_BENCHMARK_UPLOAD_URL: ${{ inputs.LLM_BENCHMARK_UPLOAD_URL }}
118118
DOTNET_MULTILEVEL_LOOKUP: "0"
119119
DOTNET_CLI_HOME: ${{ runner.temp }}/dotnet-home
120120
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: "1"

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/bindings-typescript/case-conversion-test-client/src/module_bindings/index.ts

Lines changed: 83 additions & 13 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/bindings-typescript/src/sdk/connection_manager.ts

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,72 @@ class ConnectionManagerImpl {
294294
return this.#buildManagedConnection(managed, builder);
295295
}
296296

297+
/**
298+
* Tears down the current connection and builds a fresh one from `builder`,
299+
* preserving the entry's ref count and listener set.
300+
*
301+
* `retain()` deliberately ignores the builder once a connection is live —
302+
* the right behaviour for ref-counting, but it blocks "reconnect with a
303+
* fresh token" flows (e.g. swapping an anonymous session for a signed-in one
304+
* after an auth change). `rebuild()` is the supported escape hatch: pass a
305+
* builder carrying the new token and the pool swaps the live connection
306+
* under the same subscribers, so framework hooks (`useTable`, `useReducer`,
307+
* …) re-bind to the new connection automatically.
308+
*
309+
* The old connection's callbacks are detached before it is closed, so its
310+
* disconnect event never leaks into pool state, and any pending auto-reconnect
311+
* is cancelled (the caller is driving the reconnect explicitly). Returns the
312+
* newly-built connection, or `null` if the key has no retained entry.
313+
*
314+
* @param key - Unique identifier for the connection (use getKey to generate)
315+
* @param builder - Fresh connection builder; its handlers are rewired into the pool
316+
*/
317+
rebuild<T extends DbConnectionImpl<any>>(
318+
key: string,
319+
builder: DbConnectionBuilder<T>
320+
): T | null {
321+
const managed = this.#connections.get(key);
322+
if (!managed || managed.refCount <= 0) {
323+
return null;
324+
}
325+
326+
// The caller is taking over the connection lifecycle explicitly; cancel a
327+
// deferred release or a pending auto-reconnect so neither races the fresh
328+
// connection, and reset the backoff so the next unexpected drop starts over.
329+
if (managed.pendingRelease) {
330+
clearTimeout(managed.pendingRelease);
331+
managed.pendingRelease = null;
332+
}
333+
if (managed.reconnectTimer) {
334+
clearTimeout(managed.reconnectTimer);
335+
managed.reconnectTimer = null;
336+
}
337+
managed.reconnectAttempt = 0;
338+
339+
const connection = managed.connection;
340+
if (connection) {
341+
this.#detachCallbacks(managed, connection);
342+
connection.disconnect();
343+
}
344+
managed.connection = undefined;
345+
346+
try {
347+
return this.#buildManagedConnection(managed, builder) as T;
348+
} catch (error) {
349+
// The old connection is already torn down, so a failed rebuild would
350+
// otherwise leave the pool reporting a stale "live" connection. Surface
351+
// the failure into pool state (matching the onConnectError shape) so
352+
// subscribers see a disconnected/errored connection, then re-throw so
353+
// the caller can handle it.
354+
this.#updateState(managed, {
355+
isActive: false,
356+
connectionError:
357+
error instanceof Error ? error : new Error(String(error)),
358+
});
359+
throw error;
360+
}
361+
}
362+
297363
release(key: string): void {
298364
const managed = this.#connections.get(key);
299365
if (!managed) {

0 commit comments

Comments
 (0)