Skip to content

Conversation

@Assem-Uber
Copy link
Contributor

@Assem-Uber Assem-Uber commented Nov 20, 2025

Summary
This is a follow-up on fetcher PRs (#1062, #1063 , #1064 ) to add few missing features:

  • Make the size of first page smaller than subsequent pages.
  • Add onEventsChange prop to useWorkflowHistoryFetcher that allow reacting to events change faster that the throttled state. This will be used for non delayed grouping of events.
  • Move start directly under the creation of the instance.

Also fixing one issue with fetcher:

  • Move the unsubscribe to the to top of the start method to make sure that previous emit wont run after the new emit.

Testing
Tested as part of #1091

@Assem-Uber Assem-Uber changed the title fetcher updates feat: Fetcher updates Nov 20, 2025
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR enhances the workflow history fetcher with several improvements: smaller first page sizes for better initial load performance, a new callback mechanism for immediate event change reactions, and reorganized initialization logic.

  • Separated page size configuration into first page (200) and subsequent pages (1000) for optimized loading
  • Added onEventsChange callback to useWorkflowHistoryFetcher for non-throttled event change handling
  • Moved fetcher initialization (start()) to occur directly after instance creation

Reviewed Changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
workflow-history.tsx Updated import and added placeholder callback for onEventsChange parameter
use-workflow-history-fetcher.ts Added onEventsChange parameter, moved start() call to initialization, and integrated callback in change handler
use-workflow-history-fetcher.test.tsx Updated test setup to include mock onEventsChange callback
workflow-history-fetcher.ts Implemented dynamic page sizing logic and refactored listener management
workflow-history-fetcher.test.tsx Added tests for page size validation and enhanced mock endpoint to capture page sizes
workflow-history-page-size.config.ts Split single page size constant into separate first and subsequent page size exports
workflow-history.test.tsx Updated mock to pass through onEventsChange parameter
workflow-history-v2.tsx Updated import to use named export

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 49 to 50
if (shouldContinue) {
this.shouldContinue = shouldContinue;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if start is called twice?

  1. start( shouldContinue )
  2. start( null )

It appears that the 2nd start would retain the prior shouldContinue. Is this intentional?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

100% correct. You've just reminded me that i thought about it and forgot to change it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But to put more context, it is not an issue.
Null is not allowed as an argument and undefined would use the default method. It just doesn't make sense to keep the condition.

Comment on lines 51 to 57
// if the pages count is greater than the last flattened pages count, then we need to flatten the pages and call the onEventsChange callback
if (pagesCount > lastFlattenedPagesCount) {
lastFlattenedPagesCount = pagesCount;
onEventsChange(
state.data?.pages?.flatMap((page) => page.history?.events || []) || []
);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I follow.

It sounds like historyQuery is throttled.

On the other hand, the unthrottled flow is...

  1. When onChange, then get state.
  2. Take this state and flatten it (for what purpose?)
  3. Then take the flattened result and pass it to onEventsChange (why?)

I'm probably missing something obvious with grouping in the history page.

Copy link
Contributor Author

@Assem-Uber Assem-Uber Nov 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, history queue is throttled. Since it seems hard to understand this pattern i moved lastFlattenedPagesCount to be a ref outside the component.

The reason why we flatten is that Pages is a react-query construct. But helpers and other components accepts arrays of events. It made sense to send events here since the method name is onEventsChange. If we didn't do in this hook we would need to do it in the parent.

Comment on lines 276 to 278
const pageSizes = getCapturedPageSizes();
expect(pageSizes).toHaveLength(1);
expect(pageSizes[0]).toBe('200');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to assert behavior of setup and mockEndpoints rather than the "unit under test".

Is this intended?

Copy link
Contributor Author

@Assem-Uber Assem-Uber Nov 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which part exactly is testing the setup method?

What the test does here is capturing what request msw received and make sure that the first request had a query param of 200. The query for rest APIs are sent from the fetcher but received and captured by the setup method.

Copy link
Member

@macrotim macrotim Nov 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It sounds like your intent is to introspect the inner workings of the fetcher?

To suggest an alternative approach:

  • Let's generalize it beyond pageSize.
  • Unit tests need to assert correct internal behavior.
  • And asserting the outcome falls short.
  • One solution: The fetcher returns an introspection object.
  • Example: Return debugInfo which provides detailed insights.

I suggest this because the purpose of CapturedPageSizes wasn't immediately clear.

const unsubscribe = fetcherRef.current.onChange((state) => {
const pagesCount = state.data?.pages?.length || 0;
// If the pages count is greater than the last flattened pages count, then we need to flatten the pages and call the onEventsChange callback
// Depending on ref variable instead of historyQueue is because historyQueue is throttled.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a typo, means historyQuery instead?

Comment on lines +53 to +58
if (pagesCount > lastFlattenedPagesCountRef.current) {
lastFlattenedPagesCountRef.current = pagesCount;
onEventsChange(
state.data?.pages?.flatMap((page) => page.history?.events || []) || []
);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I must be missing something.

My understanding:

  • When onChange fires
  • Then emit onEventsChange with fresh data

I would have expected:

  • Within onChange
  • Call onEventsChange with state.data.pages

I'm a bit confused why we don't pass state.data.pages directly (bypassing the flattening step)?

The hook, as currently implemented, knows too much about the fetcher internals.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if this is a follow up question on this or the message didn't show up for you as it was outdated. We can continue the discussion there.

@Assem-Uber Assem-Uber merged commit a2af92e into cadence-workflow:master Nov 21, 2025
5 checks passed
@Assem-Uber Assem-Uber deleted the feature/16026/fetcher-updates branch November 21, 2025 12:45
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