Skip to content

Commit

Permalink
Merge pull request #583 from DataRecce/feature/drc-1024-telemetry-for…
Browse files Browse the repository at this point in the history
…-experiment-3

[Feature] Telemetry for preset check recommendation
  • Loading branch information
wcchang1115 authored Jan 16, 2025
2 parents 3542c5b + 91ed566 commit c4c341a
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 37 deletions.
120 changes: 83 additions & 37 deletions js/src/components/lineage/PresetCheckRecommendation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { submitRunFromCheck } from "@/lib/api/runs";
import { useRecceActionContext } from "@/lib/hooks/RecceActionContext";
import { sessionStorageKeys } from "@/lib/api/sessionStorageKeys";
import { useRecceServerFlag } from "@/lib/hooks/useRecceServerFlag";
import { trackRecommendCheck } from "@/lib/api/track";

const usePresetCheckRecommendation = () => {
const queryChecks = useQuery({
Expand Down Expand Up @@ -98,17 +99,18 @@ export const PresetCheckRecommendation = () => {
const [affectedModels, setAffectedModels] = useState<string>();
const [performedRecommend, setPerformedRecommend] = useState<boolean>(false);
const [ignoreRecommend, setIgnoreRecommend] = useState<boolean>(false);
const [recommendRefresh, setRecommendRefresh] = useState<boolean>(false);
const [recommendRerun, setRecommendRerun] = useState<boolean>(false);
const { isOpen, onOpen, onClose } = useDisclosure();
const recommendationKey = sessionStorageKeys.recommendationIgnored;
const recommendIgnoreKey = sessionStorageKeys.recommendationIgnored;
const recommendShowKey = sessionStorageKeys.recommendationShowed;
const prevRefreshKey = sessionStorageKeys.prevRefreshTimeStamp;

useEffect(() => {
const ignored = sessionStorage.getItem(recommendationKey);
const ignored = sessionStorage.getItem(recommendIgnoreKey);
if (ignored) {
setIgnoreRecommend(true);
}
}, [recommendationKey]);
}, [recommendIgnoreKey]);

useEffect(() => {
if (!recommendedCheck || !selectedNodes) {
Expand All @@ -120,59 +122,49 @@ export const PresetCheckRecommendation = () => {
recommendedCheck.last_run?.run_at
).getTime();

let currEnvTimeStamp = 0;
let baseEnvTimeStamp = 0;
const dbtInfo = envInfo?.dbt;
if (dbtInfo?.current?.generated_at) {
currEnvTimeStamp = new Date(dbtInfo.current?.generated_at).getTime();
}
if (dbtInfo?.base?.generated_at) {
baseEnvTimeStamp = new Date(dbtInfo?.base?.generated_at).getTime();
}
const currEnvTimeStamp = dbtInfo?.current?.generated_at
? new Date(dbtInfo.current.generated_at).getTime()
: 0;
const baseEnvTimeStamp = dbtInfo?.base?.generated_at
? new Date(dbtInfo.base.generated_at).getTime()
: 0;
const envTimeStamp = Math.max(currEnvTimeStamp, baseEnvTimeStamp);

if (runTimeStamp >= envTimeStamp) {
setPerformedRecommend(true);
return;
}
setPerformedRecommend(false);
setRecommendRerun(true);

// Check if the env has been refreshed
const prevEnvTimeStamp = sessionStorage.getItem(prevRefreshKey);
if (
prevEnvTimeStamp === null ||
parseInt(prevEnvTimeStamp) !== envTimeStamp
) {
sessionStorage.setItem(prevRefreshKey, envTimeStamp.toString());
sessionStorage.removeItem(sessionStorageKeys.recommendationIgnored);
sessionStorage.removeItem(recommendIgnoreKey);
sessionStorage.removeItem(recommendShowKey);
setIgnoreRecommend(false);
}
setPerformedRecommend(false);
setRecommendRefresh(true);
}

const check = recommendedCheck;
const extractNodeNames = (nodeIds: string[]) => {
const nodes = nodeIds.map((nodeId) => lineageGraph?.nodes[nodeId]?.name);
return nodes.join(", ");
};
if (selectedNodes.length > 0 && selectedNodes.length <= 3) {
if (check.params?.node_names) {
const nodeNames = check.params?.node_names.join(", ");
setAffectedModels(`'${nodeNames}'`);
} else if (check.params?.node_ids) {
const nodes = [];
for (const nodeId of check.params?.node_ids) {
const node = lineageGraph?.nodes[nodeId];
if (node) {
nodes.push(node.name);
}
}
const nodeNames = nodes.join(", ");
const nodeNames = extractNodeNames(check.params?.node_ids);
setAffectedModels(`'${nodeNames}'`);
} else if (selectedNodes) {
const nodes = [];
for (const nodeId of selectedNodes) {
const node = lineageGraph?.nodes[nodeId];
if (node) {
nodes.push(node.name);
}
}
const nodeNames = nodes.join(", ");
const nodeNames = extractNodeNames(selectedNodes);
setAffectedModels(`'${nodeNames}'`);
}
} else if (lineageGraph?.modifiedSet?.length === selectedNodes.length) {
Expand All @@ -182,11 +174,22 @@ export const PresetCheckRecommendation = () => {
} else {
setAffectedModels(`${selectedNodes.length} models`);
}

// Track recommendation is shown the first time
if (!sessionStorage.getItem(recommendShowKey)) {
const prevEnvTimeStamp = sessionStorage.getItem(prevRefreshKey);
sessionStorage.setItem(recommendShowKey, "true");
trackRecommendCheck({
action: "recommend",
from: prevEnvTimeStamp === null ? "initial" : "rerun",
});
}
}, [
recommendedCheck,
selectedNodes,
lineageGraph,
recommendationKey,
recommendIgnoreKey,
recommendShowKey,
prevRefreshKey,
envInfo,
]);
Expand Down Expand Up @@ -216,7 +219,7 @@ export const PresetCheckRecommendation = () => {
<>
<HStack width="100%" padding="2pt 8pt" backgroundColor={"blue.50"}>
<HStack flex="1" fontSize={"10pt"} color="blue.600">
{!recommendRefresh ? (
{!recommendRerun ? (
<>
<InfoOutlineIcon />
<Text>
Expand All @@ -238,17 +241,44 @@ export const PresetCheckRecommendation = () => {
size="xs"
onClick={() => {
setIgnoreRecommend(true);
sessionStorage.setItem(recommendationKey, "true");
sessionStorage.setItem(recommendIgnoreKey, "true");
trackRecommendCheck({
action: "ignore",
from: recommendRerun ? "rerun" : "initial",
nodes: numNodes,
});
}}
>
Ignore
</Button>
<Button colorScheme="blue" size="xs" onClick={onOpen}>
<Button
colorScheme="blue"
size="xs"
onClick={() => {
onOpen();
trackRecommendCheck({
action: "perform",
from: recommendRerun ? "rerun" : "initial",
nodes: numNodes,
});
}}
>
Perform
</Button>
</HStack>
</HStack>
<Modal isOpen={isOpen} onClose={onClose} isCentered>
<Modal
isOpen={isOpen}
onClose={() => {
onClose();
trackRecommendCheck({
action: "close",
from: recommendRerun ? "rerun" : "initial",
nodes: numNodes,
});
}}
isCentered
>
<ModalOverlay />
<ModalContent>
<ModalHeader>Row Count Check</ModalHeader>
Expand All @@ -268,13 +298,29 @@ export const PresetCheckRecommendation = () => {
</Stack>
</ModalBody>
<ModalFooter gap="5px">
<Button onClick={onClose}>Cancel</Button>
<Button
onClick={() => {
onClose();
trackRecommendCheck({
action: "close",
from: recommendRerun ? "rerun" : "initial",
nodes: numNodes,
});
}}
>
Cancel
</Button>
<Button
colorScheme="blue"
onClick={() => {
onClose();
performPresetCheck();
setPerformedRecommend(true);
trackRecommendCheck({
action: "execute",
from: recommendRerun ? "rerun" : "initial",
nodes: numNodes,
});
}}
>
Execute on {numNodes} models
Expand Down
1 change: 1 addition & 0 deletions js/src/lib/api/sessionStorageKeys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ const prefix = "recce";

export const sessionStorageKeys = {
recommendationIgnored: `${prefix}-recommendation-ignored`,
recommendationShowed: `${prefix}-recommendation-showed`,
prevRefreshTimeStamp: `${prefix}-prev-refresh-timestamp`,
};
10 changes: 10 additions & 0 deletions js/src/lib/api/track.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,13 @@ interface SingleEnvironmentProps {
export function trackSingleEnvironment(props: SingleEnvironmentProps) {
amplitude.track("[Experiment] single_environment", props);
}

interface RecommendPresetCheckProps {
action: "recommend" | "ignore" | "perform" | "execute" | "close";
from?: "initial" | "rerun";
nodes?: number;
}

export function trackRecommendCheck(props: RecommendPresetCheckProps) {
amplitude.track("[Experiment] recommend_preset_check", props);
}

0 comments on commit c4c341a

Please sign in to comment.