You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airflow.apache.org by "dheerajturaga (via GitHub)" <gi...@apache.org> on 2025/09/23 18:30:03 UTC

[PR] feat: add server-side hostname search for edge workers [airflow]

dheerajturaga opened a new pull request, #56011:
URL: https://github.com/apache/airflow/pull/56011

   - Add search parameter to backend API endpoint with case-insensitive filtering
   - Implement debounced search input with 300ms delay to optimize API calls
   - Maintain search box visibility across all states (empty, loading, error)
   - Fix input focus issues during search result updates
   - Update placeholder text to 'Search Workers'
   
   <img width="1863" height="683" alt="image" src="https://github.com/user-attachments/assets/a3c6579c-71f2-4dab-a725-9d8cac59199e" />
   
   <img width="1867" height="685" alt="image" src="https://github.com/user-attachments/assets/788a7828-7760-45c0-a217-dba9a3f2ebd5" />
   
   <img width="1171" height="675" alt="image" src="https://github.com/user-attachments/assets/dd5ecb3e-e470-447c-953c-e38c16b11d93" />
   
   
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@airflow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] feat: add server-side hostname search for edge workers [airflow]

Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] commented on PR #56011:
URL: https://github.com/apache/airflow/pull/56011#issuecomment-3505453944

   This pull request has been automatically marked as stale because it has not had recent activity. It will be closed in 5 days if no further activity occurs. Thank you for your contributions.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@airflow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] feat: add server-side hostname search for edge workers [airflow]

Posted by "jscheffl (via GitHub)" <gi...@apache.org>.
jscheffl commented on code in PR #56011:
URL: https://github.com/apache/airflow/pull/56011#discussion_r2373394783


##########
providers/edge3/src/airflow/providers/edge3/plugins/www/src/pages/WorkerPage.tsx:
##########
@@ -28,108 +29,153 @@ import { ScrollToAnchor } from "src/components/ui";
 import { autoRefreshInterval } from "src/utils";
 
 export const WorkerPage = () => {
-  const { data, error, refetch } = useUiServiceWorker(undefined, {
-    enabled: true,
-    refetchInterval: autoRefreshInterval,
-  });
+  const [searchTerm, setSearchTerm] = useState("");
+  const [debouncedSearchTerm, setDebouncedSearchTerm] = useState("");
+  const inputRef = useRef<HTMLInputElement>(null);
+
+  useEffect(() => {
+    const timeout = setTimeout(() => {
+      setDebouncedSearchTerm(searchTerm);
+    }, 300);
+
+    return () => clearTimeout(timeout);
+  }, [searchTerm]);
+
+  const handleSearchChange = (e: React.ChangeEvent<HTMLInputElement>) => {
+    setSearchTerm(e.target.value);
+  };
+
+  const { data, error, refetch } = useUiServiceWorker(
+    { workerNamePattern: debouncedSearchTerm || undefined },
+    undefined,
+    {
+      enabled: true,
+      refetchInterval: autoRefreshInterval,
+    },
+  );
 
   // TODO to make it proper
   // Use DataTable as component from Airflow-Core UI
   // Add sorting
-  // Add filtering
   // Add links with filter to see jobs on worker
   // Add time zone support for time display
   // Translation?
-  if (data?.workers && data.workers.length > 0)
+  const searchInput = (
+    <Box mb={4}>
+      <Input
+        ref={inputRef}
+        placeholder="Search Workers"
+        value={searchTerm}
+        onChange={handleSearchChange}
+        maxWidth="400px"
+        key="worker-search-input"
+      />
+    </Box>
+  );
+
+  if (data) {
     return (
       <Box p={2}>
-        <Table.Root size="sm" interactive stickyHeader striped>
-          <Table.Header>
-            <Table.Row>
-              <Table.ColumnHeader>Worker Name</Table.ColumnHeader>
-              <Table.ColumnHeader>State</Table.ColumnHeader>
-              <Table.ColumnHeader>Queues</Table.ColumnHeader>
-              <Table.ColumnHeader>First Online</Table.ColumnHeader>
-              <Table.ColumnHeader>Last Heartbeat</Table.ColumnHeader>
-              <Table.ColumnHeader>Active Jobs</Table.ColumnHeader>
-              <Table.ColumnHeader>System Information</Table.ColumnHeader>
-              <Table.ColumnHeader>Operations</Table.ColumnHeader>
-            </Table.Row>
-          </Table.Header>
-          <Table.Body>
-            {data.workers.map((worker) => (
-              <Table.Row key={worker.worker_name} id={worker.worker_name}>
-                <Table.Cell>{worker.worker_name}</Table.Cell>
-                <Table.Cell>
-                  <WorkerStateBadge state={worker.state}>{worker.state}</WorkerStateBadge>
-                </Table.Cell>
-                <Table.Cell>
-                  {worker.queues ? (
-                    <List.Root>
-                      {worker.queues.map((queue) => (
-                        <List.Item key={queue}>{queue}</List.Item>
-                      ))}
-                    </List.Root>
-                  ) : (
-                    "(all queues)"
-                  )}
-                </Table.Cell>
-                <Table.Cell>
-                  {worker.first_online ? <TimeAgo date={worker.first_online} live={false} /> : undefined}
-                </Table.Cell>
-                <Table.Cell>
-                  {worker.last_heartbeat ? <TimeAgo date={worker.last_heartbeat} live={false} /> : undefined}
-                </Table.Cell>
-                <Table.Cell>{worker.jobs_active}</Table.Cell>
-                <Table.Cell>
-                  {worker.sysinfo ? (
-                    <List.Root>
-                      {Object.entries(worker.sysinfo).map(([key, value]) => (
-                        <List.Item key={key}>
-                          {key}: {value}
-                        </List.Item>
-                      ))}
-                    </List.Root>
-                  ) : (
-                    "N/A"
-                  )}
-                </Table.Cell>
-                <Table.Cell>
-                  <WorkerOperations worker={worker} onOperations={refetch} />
-                </Table.Cell>
+        {searchInput}
+        {data.workers && data.workers.length > 0 ? (
+          <Table.Root size="sm" interactive stickyHeader striped>
+            <Table.Header>
+              <Table.Row>
+                <Table.ColumnHeader>Worker Name</Table.ColumnHeader>
+                <Table.ColumnHeader>State</Table.ColumnHeader>
+                <Table.ColumnHeader>Queues</Table.ColumnHeader>
+                <Table.ColumnHeader>First Online</Table.ColumnHeader>
+                <Table.ColumnHeader>Last Heartbeat</Table.ColumnHeader>
+                <Table.ColumnHeader>Active Jobs</Table.ColumnHeader>
+                <Table.ColumnHeader>System Information</Table.ColumnHeader>
+                <Table.ColumnHeader>Operations</Table.ColumnHeader>
               </Table.Row>
-            ))}
-          </Table.Body>
-        </Table.Root>
+            </Table.Header>
+            <Table.Body>
+              {data.workers.map((worker) => (
+                <Table.Row key={worker.worker_name} id={worker.worker_name}>
+                  <Table.Cell>{worker.worker_name}</Table.Cell>
+                  <Table.Cell>
+                    <WorkerStateBadge state={worker.state}>{worker.state}</WorkerStateBadge>
+                  </Table.Cell>
+                  <Table.Cell>
+                    {worker.queues ? (
+                      <List.Root>
+                        {worker.queues.map((queue) => (
+                          <List.Item key={queue}>{queue}</List.Item>
+                        ))}
+                      </List.Root>
+                    ) : (
+                      "(all queues)"
+                    )}
+                  </Table.Cell>
+                  <Table.Cell>
+                    {worker.first_online ? <TimeAgo date={worker.first_online} live={false} /> : undefined}
+                  </Table.Cell>
+                  <Table.Cell>
+                    {worker.last_heartbeat ? (
+                      <TimeAgo date={worker.last_heartbeat} live={false} />
+                    ) : undefined}
+                  </Table.Cell>
+                  <Table.Cell>{worker.jobs_active}</Table.Cell>
+                  <Table.Cell>
+                    {worker.sysinfo ? (
+                      <List.Root>
+                        {Object.entries(worker.sysinfo).map(([key, value]) => (
+                          <List.Item key={key}>
+                            {key}: {value}
+                          </List.Item>
+                        ))}
+                      </List.Root>
+                    ) : (
+                      "N/A"
+                    )}
+                  </Table.Cell>
+                  <Table.Cell>
+                    <WorkerOperations worker={worker} onOperations={refetch} />
+                  </Table.Cell>
+                </Table.Row>
+              ))}
+            </Table.Body>
+          </Table.Root>
+        ) : debouncedSearchTerm ? (
+          <Text pl={4} pt={1}>
+            No workers match the search term "{debouncedSearchTerm}".
+          </Text>
+        ) : (
+          <Text pl={4} pt={1}>
+            No known workers. Start one via <Code>airflow edge worker [...]</Code>. See{" "}
+            <Link
+              target="_blank"
+              variant="underline"
+              color="fg.info"
+              href="https://airflow.apache.org/docs/apache-airflow-providers-edge3/stable/deployment.html"
+            >
+              Edge Worker Deployment docs <LuExternalLink />
+            </Link>{" "}
+            how to deploy a new worker.
+          </Text>
+        )}
         <ScrollToAnchor />
       </Box>
     );
-  if (data) {
-    return (
-      <Text as="div" pl={4} pt={1}>
-        No known workers. Start one via <Code>airflow edge worker [...]</Code>. See{" "}
-        <Link
-          target="_blank"
-          variant="underline"
-          color="fg.info"
-          href="https://airflow.apache.org/docs/apache-airflow-providers-edge3/stable/deployment.html"
-        >
-          Edge Worker Deployment docs <LuExternalLink />
-        </Link>{" "}
-        how to deploy a new worker.
-      </Text>
-    );
   }
   if (error) {
     return (
-      <Text as="div" pl={4} pt={1}>
-        <ErrorAlert error={error} />
-      </Text>
+      <Box p={2}>
+        {searchInput}

Review Comment:
   Why do you add the `{searchInput}` to all if/else cases, would it not be easier to render it once generic and have the result views just below?



##########
providers/edge3/src/airflow/providers/edge3/plugins/www/src/pages/WorkerPage.tsx:
##########
@@ -28,108 +29,153 @@ import { ScrollToAnchor } from "src/components/ui";
 import { autoRefreshInterval } from "src/utils";
 
 export const WorkerPage = () => {
-  const { data, error, refetch } = useUiServiceWorker(undefined, {
-    enabled: true,
-    refetchInterval: autoRefreshInterval,
-  });
+  const [searchTerm, setSearchTerm] = useState("");
+  const [debouncedSearchTerm, setDebouncedSearchTerm] = useState("");
+  const inputRef = useRef<HTMLInputElement>(null);
+
+  useEffect(() => {
+    const timeout = setTimeout(() => {
+      setDebouncedSearchTerm(searchTerm);
+    }, 300);
+
+    return () => clearTimeout(timeout);
+  }, [searchTerm]);

Review Comment:
   As being the JS noob bere, need some guidance from UI experts @bbovenzi / @pierrejeambrun / @shubhamraj-git - I understand `useEffect()` is bad in general but this de-bouncing seems good here. Or is there any other best practice to follow to make it "right"?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@airflow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] feat: add server-side hostname search for edge workers [airflow]

Posted by "dheerajturaga (via GitHub)" <gi...@apache.org>.
dheerajturaga closed pull request #56011: feat: add server-side hostname search for edge workers
URL: https://github.com/apache/airflow/pull/56011


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@airflow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] feat: add server-side hostname search for edge workers [airflow]

Posted by "jscheffl (via GitHub)" <gi...@apache.org>.
jscheffl commented on PR #56011:
URL: https://github.com/apache/airflow/pull/56011#issuecomment-3506244853

   Oh, lost track in following-up on this. Probably needs a revive @dheerajturaga ? Would be great to have this as starter and then add more filters later!


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@airflow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] feat: add server-side hostname search for edge workers [airflow]

Posted by "dheerajturaga (via GitHub)" <gi...@apache.org>.
dheerajturaga commented on PR #56011:
URL: https://github.com/apache/airflow/pull/56011#issuecomment-3506503058

   > Oh, lost track in following-up on this. Probably needs a revive @dheerajturaga ? Would be great to have this as starter and then add more filters later!
   
   Yes! Was busy with other things! Let me restart this! 


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@airflow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org