( executionId: string, afterEventId: number )
| 661 | } |
| 662 | |
| 663 | export async function readExecutionEventsState( |
| 664 | executionId: string, |
| 665 | afterEventId: number |
| 666 | ): Promise<ExecutionEventsReadResult> { |
| 667 | const redis = getRedisClient() |
| 668 | if (!redis) { |
| 669 | if (canUseMemoryEventBuffer()) { |
| 670 | return readMemoryEvents(executionId, afterEventId) |
| 671 | } |
| 672 | return { status: 'unavailable', error: 'Redis client unavailable' } |
| 673 | } |
| 674 | try { |
| 675 | const meta = await redis.hgetall(getMetaKey(executionId)) |
| 676 | const earliestEventId = |
| 677 | meta?.earliestEventId !== undefined ? Number(meta.earliestEventId) : undefined |
| 678 | const replayStartEventId = |
| 679 | meta?.replayStartEventId !== undefined ? Number(meta.replayStartEventId) : undefined |
| 680 | if (isReplayBeforeAvailableEvents(afterEventId, earliestEventId, replayStartEventId)) { |
| 681 | return { status: 'pruned', earliestEventId } |
| 682 | } |
| 683 | |
| 684 | const raw = await redis.zrangebyscore(getEventsKey(executionId), afterEventId + 1, '+inf') |
| 685 | const latestMeta = await redis.hgetall(getMetaKey(executionId)) |
| 686 | const latestEarliestEventId = |
| 687 | latestMeta?.earliestEventId !== undefined ? Number(latestMeta.earliestEventId) : undefined |
| 688 | const latestReplayStartEventId = |
| 689 | latestMeta?.replayStartEventId !== undefined |
| 690 | ? Number(latestMeta.replayStartEventId) |
| 691 | : undefined |
| 692 | if ( |
| 693 | isReplayBeforeAvailableEvents(afterEventId, latestEarliestEventId, latestReplayStartEventId) |
| 694 | ) { |
| 695 | return { status: 'pruned', earliestEventId: latestEarliestEventId } |
| 696 | } |
| 697 | |
| 698 | return { |
| 699 | status: 'ok', |
| 700 | events: raw |
| 701 | .map((entry) => { |
| 702 | try { |
| 703 | return JSON.parse(entry) as ExecutionEventEntry |
| 704 | } catch { |
| 705 | return null |
| 706 | } |
| 707 | }) |
| 708 | .filter((entry): entry is ExecutionEventEntry => Boolean(entry)), |
| 709 | } |
| 710 | } catch (error) { |
| 711 | const message = toError(error).message |
| 712 | logger.warn('Failed to read execution events', { |
| 713 | executionId, |
| 714 | error: message, |
| 715 | }) |
| 716 | return { status: 'unavailable', error: message } |
| 717 | } |
| 718 | } |
| 719 | |
| 720 | export function createExecutionEventWriter( |
no test coverage detected