fix: stabilize convex pagination and ci fallback

This commit is contained in:
Esdras Renan 2025-11-17 14:23:46 -03:00
parent a08b0d6d27
commit dbee5c28c8
2 changed files with 80 additions and 34 deletions

View file

@ -155,6 +155,7 @@ jobs:
id: key id: key
run: | run: |
echo "Waiting for Convex container..." echo "Waiting for Convex container..."
CID=""
for attempt in $(seq 1 12); do for attempt in $(seq 1 12); do
CID=$(docker ps --format '{{.ID}} {{.Names}}' | awk '/sistema_convex_backend/{print $1; exit}') CID=$(docker ps --format '{{.ID}} {{.Names}}' | awk '/sistema_convex_backend/{print $1; exit}')
if [ -n "$CID" ]; then if [ -n "$CID" ]; then
@ -166,14 +167,28 @@ jobs:
docker service update --force sistema_convex_backend || true docker service update --force sistema_convex_backend || true
sleep 5 sleep 5
done done
if [ -z "$CID" ]; then CONVEX_IMAGE="ghcr.io/get-convex/convex-backend:latest"
echo "No convex container" if [ -n "$CID" ]; then
KEY=$(docker exec -i "$CID" /bin/sh -lc './generate_admin_key.sh' | tr -d '\r' | grep -o 'convex-self-hosted|[^ ]*' | tail -n1)
else
echo "No running convex container detected; attempting offline admin key extraction..."
VOLUME="sistema_convex_data"
if docker volume inspect "$VOLUME" >/dev/null 2>&1; then
KEY=$(docker run --rm -v "$VOLUME":/convex/data "$CONVEX_IMAGE" /bin/sh -lc './generate_admin_key.sh' | tr -d '\r' | grep -o 'convex-self-hosted|[^ ]*' | tail -n1)
else
echo "Volume $VOLUME não encontrado; não foi possível extrair a chave admin"
fi
fi
echo "ADMIN_KEY=$KEY" >> $GITHUB_OUTPUT
echo "Admin key acquired? $([ -n "$KEY" ] && echo yes || echo no)"
if [ -z "$KEY" ]; then
docker service ps sistema_convex_backend || true
exit 1
fi
if [ -z "$KEY" ]; then
docker service ps sistema_convex_backend || true docker service ps sistema_convex_backend || true
exit 1 exit 1
fi fi
KEY=$(docker exec -i "$CID" /bin/sh -lc './generate_admin_key.sh' | tr -d '\r' | grep -o 'convex-self-hosted|[^ ]*' | tail -n1)
echo "ADMIN_KEY=$KEY" >> $GITHUB_OUTPUT
echo "Admin key acquired? $([ -n "$KEY" ] && echo yes || echo no)"
- name: Copy production .env if present - name: Copy production .env if present
run: | run: |
@ -399,6 +414,7 @@ jobs:
id: key id: key
run: | run: |
echo "Waiting for Convex container..." echo "Waiting for Convex container..."
CID=""
for attempt in $(seq 1 12); do for attempt in $(seq 1 12); do
CID=$(docker ps --format '{{.ID}} {{.Names}}' | awk '/sistema_convex_backend/{print $1; exit}') CID=$(docker ps --format '{{.ID}} {{.Names}}' | awk '/sistema_convex_backend/{print $1; exit}')
if [ -n "$CID" ]; then if [ -n "$CID" ]; then
@ -408,14 +424,24 @@ jobs:
echo "Attempt $attempt: container not ready yet; sleeping 5s" echo "Attempt $attempt: container not ready yet; sleeping 5s"
sleep 5 sleep 5
done done
if [ -z "$CID" ]; then CONVEX_IMAGE="ghcr.io/get-convex/convex-backend:latest"
echo "No convex container" if [ -n "$CID" ]; then
KEY=$(docker exec -i "$CID" /bin/sh -lc './generate_admin_key.sh' | tr -d '\r' | grep -o 'convex-self-hosted|[^ ]*' | tail -n1)
else
echo "No running convex container detected; attempting offline admin key extraction..."
VOLUME="sistema_convex_data"
if docker volume inspect "$VOLUME" >/dev/null 2>&1; then
KEY=$(docker run --rm -v "$VOLUME":/convex/data "$CONVEX_IMAGE" /bin/sh -lc './generate_admin_key.sh' | tr -d '\r' | grep -o 'convex-self-hosted|[^ ]*' | tail -n1)
else
echo "Volume $VOLUME não encontrado; não foi possível extrair a chave admin"
fi
fi
echo "ADMIN_KEY=$KEY" >> $GITHUB_OUTPUT
echo "Admin key acquired? $([ -n "$KEY" ] && echo yes || echo no)"
if [ -z "$KEY" ]; then
docker service ps sistema_convex_backend || true docker service ps sistema_convex_backend || true
exit 1 exit 1
fi fi
KEY=$(docker exec -i "$CID" /bin/sh -lc './generate_admin_key.sh' | tr -d '\r' | grep -o 'convex-self-hosted|[^ ]*' | tail -n1)
echo "ADMIN_KEY=$KEY" >> $GITHUB_OUTPUT
echo "Admin key acquired? $([ -n "$KEY" ] && echo yes || echo no)"
- name: Bring convex.json from live app if present - name: Bring convex.json from live app if present
run: | run: |
@ -550,6 +576,7 @@ jobs:
id: key id: key
run: | run: |
echo "Waiting for Convex container..." echo "Waiting for Convex container..."
CID=""
for attempt in $(seq 1 12); do for attempt in $(seq 1 12); do
CID=$(docker ps --format '{{.ID}} {{.Names}}' | awk '/sistema_convex_backend/{print $1; exit}') CID=$(docker ps --format '{{.ID}} {{.Names}}' | awk '/sistema_convex_backend/{print $1; exit}')
if [ -n "$CID" ]; then if [ -n "$CID" ]; then
@ -559,12 +586,18 @@ jobs:
echo "Attempt $attempt: container not ready yet; sleeping 5s" echo "Attempt $attempt: container not ready yet; sleeping 5s"
sleep 5 sleep 5
done done
if [ -z "$CID" ]; then CONVEX_IMAGE="ghcr.io/get-convex/convex-backend:latest"
echo "No convex container" if [ -n "$CID" ]; then
docker service ps sistema_convex_backend || true KEY=$(docker exec -i "$CID" /bin/sh -lc './generate_admin_key.sh' | tr -d '\r' | grep -o 'convex-self-hosted|[^ ]*' | tail -n1)
exit 1 else
echo "No running convex container detected; attempting offline admin key extraction..."
VOLUME="sistema_convex_data"
if docker volume inspect "$VOLUME" >/dev/null 2>&1; then
KEY=$(docker run --rm -v "$VOLUME":/convex/data "$CONVEX_IMAGE" /bin/sh -lc './generate_admin_key.sh' | tr -d '\r' | grep -o 'convex-self-hosted|[^ ]*' | tail -n1)
else
echo "Volume $VOLUME não encontrado; não foi possível extrair a chave admin"
fi
fi fi
KEY=$(docker exec -i "$CID" /bin/sh -lc './generate_admin_key.sh' | tr -d '\r' | grep -o 'convex-self-hosted|[^ ]*' | tail -n1)
echo "ADMIN_KEY=$KEY" >> $GITHUB_OUTPUT echo "ADMIN_KEY=$KEY" >> $GITHUB_OUTPUT
echo "Admin key acquired? $([ -n "$KEY" ] && echo yes || echo no)" echo "Admin key acquired? $([ -n "$KEY" ] && echo yes || echo no)"
- name: List Convex env and set missing - name: List Convex env and set missing

View file

@ -200,37 +200,50 @@ type PaginatedResult<T> = {
isDone?: boolean; isDone?: boolean;
}; };
type QueryBuilder<T> = {
paginate?: (options: { cursor: string | null; numItems: number }) => Promise<PaginatedResult<T>>;
collect?: () => Promise<T[]>;
};
async function paginateTickets<T>( async function paginateTickets<T>(
buildQuery: () => { buildQuery: () => QueryBuilder<T>,
paginate: (options: { cursor: string | null; numItems: number }) => Promise<PaginatedResult<T>>;
collect?: () => Promise<T[]>;
},
handler: (doc: T) => void | Promise<void>, handler: (doc: T) => void | Promise<void>,
pageSize = REPORTS_PAGE_SIZE, pageSize = REPORTS_PAGE_SIZE,
) { ) {
const query = buildQuery();
if (typeof (query as { paginate?: unknown }).paginate !== "function") {
const collectFn = (query as { collect?: (() => Promise<T[]>) | undefined }).collect;
if (typeof collectFn !== "function") {
throw new ConvexError("Query does not support paginate or collect");
}
const docs = await collectFn.call(query);
for (const doc of docs) {
await handler(doc);
}
return;
}
let cursor: string | null = null; let cursor: string | null = null;
while (true) { while (true) {
const page = await query.paginate({ cursor, numItems: pageSize }); const query = buildQuery();
const paginateFn:
| ((options: { cursor: string | null; numItems: number }) => Promise<PaginatedResult<T>>)
| undefined = query.paginate;
if (typeof paginateFn !== "function") {
if (cursor !== null) {
throw new ConvexError("Query does not support pagination but cursor was provided");
}
const collectFn = query.collect;
if (typeof collectFn !== "function") {
throw new ConvexError("Query does not support paginate or collect");
}
const docs = await collectFn.call(query);
for (const doc of docs) {
await handler(doc);
}
return;
}
const page: PaginatedResult<T> = await paginateFn.call(query, { cursor, numItems: pageSize });
for (const doc of page.page) { for (const doc of page.page) {
await handler(doc); await handler(doc);
} }
const done = page.done ?? page.isDone ?? !page.continueCursor;
const continueCursor = page.continueCursor ?? null;
const done = page.done ?? page.isDone ?? !continueCursor;
if (done) { if (done) {
break; break;
} }
cursor = page.continueCursor ?? null; cursor = continueCursor;
} }
} }