feat: event polling can process more than one event at a time (#7858)
* refactor: enhance event polling to retrieve all available events and return in NDJSON format Updated the event polling logic to collect all available events from the queue instead of just one. The response format has been changed to NDJSON, allowing multiple events to be returned in a single response. Improved error handling for timeouts by returning an empty response instead of raising an error. * refactor: improve NDJSON event processing in build polling Enhanced the event polling logic to handle NDJSON responses by processing multiple events in a single fetch. Updated the response handling to read the response as text, split it into individual JSON objects, and process each event accordingly. This change improves the efficiency of event handling and maintains a consistent polling interval. * fix: change event list type from list[str] to list in get_flow_events_response * refactor: enhance event stream consumption with timeout and error handling Updated the consume_and_assert_stream function to include a timeout for processing events and improved error handling for JSON parsing failures. Added logging for better debugging and tracking of processed events. Adjusted the event validation logic to ensure both the first and last expected events are present. * refactor: enhance event polling logic with improved limits and JSON validation Updated the event polling mechanism to include configurable limits for total events and empty polls, along with a timeout for requests. Enhanced JSON validation for individual events and added logging for better debugging of polling behavior. This refactor aims to improve robustness and maintainability of the event consumption process. * refactor: update polling interval and streamline event handling Modified the polling interval constant to improve responsiveness and adjusted event handling logic in the get_flow_events_response function to simplify the processing of event values. This change enhances the efficiency of event consumption and maintains a consistent approach to handling NDJSON responses. * refactor: simplify event retrieval in get_flow_events_response Removed unused event_id and put_time variables from the event retrieval logic in the get_flow_events_response function. This change streamlines the code and enhances readability while maintaining the functionality of event handling. * refactor: update consume_and_assert_stream to use asyncio.wait_for for timeout handling Modified the consume_and_assert_stream function to utilize asyncio.wait_for for managing timeouts in event processing. This change improves compatibility with Python 3.10 and enhances the robustness of the event consumption logic while maintaining existing functionality.
This commit is contained in:
parent
102946be72
commit
304e28b48a
5 changed files with 240 additions and 93 deletions
|
|
@ -1024,7 +1024,7 @@ export const POLLING_MESSAGES = {
|
|||
STREAMING_NOT_SUPPORTED: "Streaming not supported",
|
||||
} as const;
|
||||
|
||||
export const POLLING_INTERVAL = 100;
|
||||
export const BUILD_POLLING_INTERVAL = 25;
|
||||
|
||||
export const IS_AUTO_LOGIN =
|
||||
!process?.env?.LANGFLOW_AUTO_LOGIN ||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { MISSED_ERROR_ALERT } from "@/constants/alerts_constants";
|
||||
import {
|
||||
BASE_URL_API,
|
||||
POLLING_INTERVAL,
|
||||
BUILD_POLLING_INTERVAL,
|
||||
POLLING_MESSAGES,
|
||||
} from "@/constants/constants";
|
||||
import { performStreamingRequest } from "@/controllers/API/api";
|
||||
|
|
@ -184,6 +184,7 @@ async function pollBuildEvents(
|
|||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Accept: "application/x-ndjson",
|
||||
},
|
||||
signal: abortController.signal, // Add abort signal to fetch
|
||||
},
|
||||
|
|
@ -197,34 +198,51 @@ async function pollBuildEvents(
|
|||
);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
if (!data.event) {
|
||||
// No event in this request, try again
|
||||
// Get the response text - will be NDJSON format (one JSON per line)
|
||||
const responseText = await response.text();
|
||||
|
||||
// Skip if empty response
|
||||
if (!responseText.trim()) {
|
||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||
continue;
|
||||
}
|
||||
|
||||
// Process the event
|
||||
const event = JSON.parse(data.event);
|
||||
const result = await onEvent(
|
||||
event.event,
|
||||
event.data,
|
||||
buildResults,
|
||||
verticesStartTimeMs,
|
||||
callbacks,
|
||||
);
|
||||
if (!result) {
|
||||
isDone = true;
|
||||
abortController.abort();
|
||||
// Split by newlines to get individual JSON objects
|
||||
const eventLines = responseText.split("\n").filter((line) => line.trim());
|
||||
|
||||
// If no events, continue polling
|
||||
if (eventLines.length === 0) {
|
||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if this was the end event or if we got a null value
|
||||
if (event.event === "end" || data.event === null) {
|
||||
isDone = true;
|
||||
// Process all events in the NDJSON response
|
||||
for (const eventStr of eventLines) {
|
||||
// Process the event
|
||||
const event = JSON.parse(eventStr);
|
||||
const result = await onEvent(
|
||||
event.event,
|
||||
event.data,
|
||||
buildResults,
|
||||
verticesStartTimeMs,
|
||||
callbacks,
|
||||
);
|
||||
|
||||
if (!result) {
|
||||
isDone = true;
|
||||
abortController.abort();
|
||||
break;
|
||||
}
|
||||
|
||||
// Check if this was the end event
|
||||
if (event.event === "end") {
|
||||
isDone = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Add a small delay between polls to avoid overwhelming the server
|
||||
await new Promise((resolve) => setTimeout(resolve, POLLING_INTERVAL));
|
||||
// Add a small delay between polls
|
||||
await new Promise((resolve) => setTimeout(resolve, BUILD_POLLING_INTERVAL));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue