fitzee commented on code in PR #45928:
URL: https://github.com/apache/superset/pull/45928#discussion_r4439903444


##########
superset-frontend/src/dashboard/util/loadSharedFilterState.ts:
##########
@@ -0,0 +1,101 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import { logging } from '@apache-superset/core/utils';
+
+// Upper bound on a single attempt to load shared filter state.
+export const SHARED_STATE_ATTEMPT_TIMEOUT_MS = 3000;

Review Comment:
   3 s is tight for a hard abort. `FILTER_STATE_CACHE_CONFIG` defaults to 
`SupersetMetastoreCache`, so this is a metadata DB read, and the permalink 
fetch is a DB read too. A backend that is uniformly slow at about 4 s fails 
both attempts, because each retry starts from zero.
   
   The bug being fixed is an infinite hang, so a bound of 8 to 10 s would still 
fix it with far fewer false fallbacks. Alternatively, make the timeout 
configurable, or let the first request keep running while the second attempt 
starts.



##########
superset-frontend/src/dashboard/containers/DashboardPage.tsx:
##########
@@ -325,37 +455,47 @@ export const DashboardPage: FC<PageProps> = ({ idOrSlug 
}: PageProps) => {
       }
 
       if (readyToRender) {
-        if (!isDashboardHydrated.current) {
-          isDashboardHydrated.current = true;
-        }
-        dispatch(
-          hydrateDashboard({
-            history,
-            dashboard: dashboard!,
-            charts: charts!,
-            activeTabs: activeTabs ?? null,
-            dataMask,
-            chartStates: chartStates ?? null,
-          } as unknown as Parameters<typeof hydrateDashboard>[0]),
-        );
-        dispatch(clearDashboardHistory());
-
-        // Scroll to anchor element if specified in permalink state
-        if (anchor) {
-          // Use setTimeout to ensure the DOM has been updated after hydration
-          setTimeout(() => {
-            const element = document.getElementById(anchor);
-            if (element) {
-              element.scrollIntoView({ behavior: 'smooth' });
-            }
-          }, 0);
-        }
+        hydrateWithState({ dataMask, activeTabs, chartStates, anchor });
       }
       return null;
     }
-    if (id) getDataMaskApplied();
+    if (id && readyToRender) getDataMaskApplied();
+    return () => {
+      cancelled = true;
+      controller.abort();
+      retryController.current?.abort();
+    };
     // eslint-disable-next-line react-hooks/exhaustive-deps
-  }, [readyToRender]);
+  }, [readyToRender, id]);
+
+  // Once the viewer changes a filter the saved state must not be re-applied
+  // over their change, so the banner (and its Try again action) goes away.
+  useEffect(
+    () => subscribeFilterKeyPublishRelease(() => setSharedStateNotice(null)),
+    [],
+  );
+
+  const retrySharedState = useCallback(async () => {
+    const source = sharedStateSource.current;
+    if (!source) return;
+    retryController.current?.abort();
+    const controller = new AbortController();
+    retryController.current = controller;
+    setIsRetryingSharedState(true);
+    const result: SharedStateResult<unknown> = await fetchSharedState(
+      source,
+      controller.signal,
+    );
+    if (controller.signal.aborted) return;
+    setIsRetryingSharedState(false);
+    if (result.status !== 'ok') {
+      setSharedStateNotice(result.status === 'expired' ? 'expired' : 'failed');
+      return;
+    }
+    hydrateWithStateRef.current(toSharedState(source, result.value));

Review Comment:
   This re-hydrates over anything that changed the dataMask without going 
through `handleApply`, which means filters applied from chat via 
`useDashboardFilterSync` and cross-filters. The banner stays up after either of 
those, so Try again is still offered.
   
   One option: release the hold (and hide the banner) on any user-originated 
dataMask change after the initial hydrate, not only on Apply. That would also 
close the cross-filter gap listed under NOT COVERED.



-- 
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: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

  • [PR] fix(da... eschutho (via GitHub) via notifications
    • Re: [P... codecov[bot] (via GitHub) via notifications
    • Re: [P... netlify[bot] (via GitHub) via notifications
    • Re: [P... codeant-ai-for-open-source[bot] (via GitHub) via notifications
    • Re: [P... codeant-ai-for-open-source[bot] (via GitHub) via notifications
    • Re: [P... codeant-ai-for-open-source[bot] (via GitHub) via notifications
    • Re: [P... dpgaspar (via GitHub) via notifications
    • Re: [P... fitzee (via GitHub) via notifications
    • Re: [P... codeant-ai-for-open-source[bot] (via GitHub) via notifications
    • Re: [P... codeant-ai-for-open-source[bot] (via GitHub) via notifications
    • Re: [P... msyavuz (via GitHub) via notifications

Reply via email to