Skip to content

Commit

Permalink
fix(slo): optimistic update (elastic#159208)
Browse files Browse the repository at this point in the history
  • Loading branch information
kdelemme authored Jun 8, 2023
1 parent 59eb4ea commit 9d6846d
Show file tree
Hide file tree
Showing 7 changed files with 36 additions and 47 deletions.
24 changes: 12 additions & 12 deletions x-pack/plugins/observability/public/hooks/slo/query_key_factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,33 +20,33 @@ interface CompositeSloKeyFilter {

export const sloKeys = {
all: ['slo'] as const,
lists: () => [...sloKeys.all, 'sloList'] as const,
lists: () => [...sloKeys.all, 'list'] as const,
list: (filters: SloKeyFilter) => [...sloKeys.lists(), filters] as const,
details: () => [...sloKeys.all, 'sloDetails'] as const,
details: () => [...sloKeys.all, 'details'] as const,
detail: (sloId?: string) => [...sloKeys.details(), sloId] as const,
rules: () => [...sloKeys.all, 'sloRules'] as const,
rules: () => [...sloKeys.all, 'rules'] as const,
rule: (sloIds: string[]) => [...sloKeys.rules(), sloIds] as const,
activeAlerts: () => [...sloKeys.all, 'sloActiveAlerts'] as const,
activeAlerts: () => [...sloKeys.all, 'activeAlerts'] as const,
activeAlert: (sloIds: string[]) => [...sloKeys.activeAlerts(), sloIds] as const,
historicalSummaries: () => [...sloKeys.all, 'sloHistoricalSummary'] as const,
historicalSummaries: () => [...sloKeys.all, 'historicalSummary'] as const,
historicalSummary: (sloIds: string[]) => [...sloKeys.historicalSummaries(), sloIds] as const,
globalDiagnosis: () => [...sloKeys.all, 'sloGlobalDiagnosis'] as const,
globalDiagnosis: () => [...sloKeys.all, 'globalDiagnosis'] as const,
};

export const compositeSloKeys = {
all: ['compositeSlo'] as const,
lists: () => [...compositeSloKeys.all, 'compositeSloList'] as const,
lists: () => [...compositeSloKeys.all, 'list'] as const,
list: (filters: CompositeSloKeyFilter) => [...compositeSloKeys.lists(), filters] as const,
details: () => [...compositeSloKeys.all, 'compositeSloDetails'] as const,
details: () => [...compositeSloKeys.all, 'details'] as const,
detail: (sloId?: string) => [...compositeSloKeys.details(), sloId] as const,
rules: () => [...compositeSloKeys.all, 'compositeSloRules'] as const,
rules: () => [...compositeSloKeys.all, 'rules'] as const,
rule: (sloIds: string[]) => [...compositeSloKeys.rules(), sloIds] as const,
activeAlerts: () => [...compositeSloKeys.all, 'compositeSloActiveAlerts'] as const,
activeAlerts: () => [...compositeSloKeys.all, 'activeAlerts'] as const,
activeAlert: (sloIds: string[]) => [...compositeSloKeys.activeAlerts(), sloIds] as const,
historicalSummaries: () => [...compositeSloKeys.all, 'compositeSloHistoricalSummary'] as const,
historicalSummaries: () => [...compositeSloKeys.all, 'historicalSummary'] as const,
historicalSummary: (sloIds: string[]) =>
[...compositeSloKeys.historicalSummaries(), sloIds] as const,
globalDiagnosis: () => [...compositeSloKeys.all, 'compositeSloGlobalDiagnosis'] as const,
globalDiagnosis: () => [...compositeSloKeys.all, 'globalDiagnosis'] as const,
};

export type SloKeys = typeof compositeSloKeys | typeof sloKeys;
26 changes: 11 additions & 15 deletions x-pack/plugins/observability/public/hooks/slo/use_clone_slo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,40 +23,36 @@ export function useCloneSlo() {
return useMutation<
CreateSLOResponse,
string,
{ slo: CreateSLOInput; idToCopyFrom?: string },
{ slo: CreateSLOInput; originalSloId?: string },
{ previousSloList: FindSLOResponse | undefined }
>(
['cloneSlo'],
({ slo }: { slo: CreateSLOInput; idToCopyFrom?: string }) => {
({ slo }: { slo: CreateSLOInput; originalSloId?: string }) => {
const body = JSON.stringify(slo);
return http.post<CreateSLOResponse>(`/api/observability/slos`, { body });
},
{
onMutate: async ({ slo, idToCopyFrom }) => {
onMutate: async ({ slo, originalSloId }) => {
// Cancel any outgoing refetches (so they don't overwrite our optimistic update)
await queryClient.cancelQueries(sloKeys.lists());

const latestFetchSloListRequest = (
queryClient.getQueriesData<FindSLOResponse>(sloKeys.lists()) || []
const latestQueriesData = (
queryClient.getQueriesData<FindSLOResponse>(sloKeys.lists()) ?? []
).at(0);
const [queryKey, data] = latestQueriesData ?? [];

const [queryKey, data] = latestFetchSloListRequest || [];

const sloUsedToClone = data?.results.find((el) => el.id === idToCopyFrom);

const originalSlo = data?.results?.find((el) => el.id === originalSloId);
const optimisticUpdate = {
...data,
results: [
...(data?.results || []),
{ ...sloUsedToClone, name: slo.name, id: uuidv1(), summary: undefined },
...(data?.results ?? []),
{ ...originalSlo, name: slo.name, id: uuidv1(), summary: undefined },
],
total: data?.total && data.total + 1,
total: data?.total ? data.total + 1 : 1,
};

// Optimistically update to the new value
if (queryKey) {
queryClient.setQueryData(queryKey, optimisticUpdate);
}
queryClient.setQueryData(queryKey ?? sloKeys.lists(), optimisticUpdate);

toasts.addSuccess(
i18n.translate('xpack.observability.slo.clone.successNotification', {
Expand Down
14 changes: 5 additions & 9 deletions x-pack/plugins/observability/public/hooks/slo/use_create_slo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,24 +48,20 @@ export function useCreateSlo() {
// Cancel any outgoing refetches (so they don't overwrite our optimistic update)
await queryClient.cancelQueries(sloKeys.lists());

const latestFetchSloListRequest = (
queryClient.getQueriesData<FindSLOResponse>(sloKeys.lists()) || []
const latestQueriesData = (
queryClient.getQueriesData<FindSLOResponse>(sloKeys.lists()) ?? []
).at(0);

const [queryKey, data] = latestFetchSloListRequest || [];
const [queryKey, data] = latestQueriesData || [];

const newItem = { ...slo, id: uuidv1() };

const optimisticUpdate = {
...data,
results: [...(data?.results || []), { ...newItem }],
results: [...(data?.results ?? []), newItem],
total: data?.total ? data.total + 1 : 1,
};

// Optimistically update to the new value
if (queryKey) {
queryClient.setQueryData(queryKey, optimisticUpdate);
}
queryClient.setQueryData(queryKey ?? sloKeys.lists(), optimisticUpdate);

// Return a context object with the snapshotted value
return { previousSloList: data };
Expand Down
13 changes: 5 additions & 8 deletions x-pack/plugins/observability/public/hooks/slo/use_delete_slo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,22 +37,19 @@ export function useDeleteSlo() {
// Cancel any outgoing refetches (so they don't overwrite our optimistic update)
await queryClient.cancelQueries(sloKeys.lists());

const latestFetchSloListRequest = (
const latestQueriesData = (
queryClient.getQueriesData<FindSLOResponse>(sloKeys.lists()) || []
).at(0);

const [queryKey, data] = latestFetchSloListRequest || [];
const [queryKey, data] = latestQueriesData || [];

const optimisticUpdate = {
...data,
results: data?.results.filter((result) => result.id !== slo.id),
total: data?.total && data.total - 1,
results: data?.results?.filter((result) => result.id !== slo.id) ?? [],
total: data?.total ? data.total - 1 : 0,
};

// Optimistically update to the new value
if (queryKey) {
queryClient.setQueryData(queryKey, optimisticUpdate);
}
queryClient.setQueryData(queryKey ?? sloKeys.lists(), optimisticUpdate);

toasts.addSuccess(
i18n.translate('xpack.observability.slo.slo.delete.successNotification', {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ export function HeaderControl({ isLoading, slo }: Props) {
transformSloResponseToCreateSloInput({ ...slo, name: `[Copy] ${slo.name}` })!
);

cloneSlo({ slo: newSlo, idToCopyFrom: slo.id });
cloneSlo({ slo: newSlo, originalSloId: slo.id });

navigate(basePath.prepend(paths.observability.slos));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ describe('SLO Details Page', () => {
const { id, createdAt, enabled, revision, summary, updatedAt, ...newSlo } = slo;

expect(mockClone).toBeCalledWith({
idToCopyFrom: slo.id,
originalSloId: slo.id,
slo: {
...newSlo,
name: `[Copy] ${newSlo.name}`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ export function SloListItem({
transformSloResponseToCreateSloInput({ ...slo, name: `[Copy] ${slo.name}` })!
);

cloneSlo({ slo: newSlo, idToCopyFrom: slo.id });
cloneSlo({ slo: newSlo, originalSloId: slo.id });
setIsActionsPopoverOpen(false);
};

Expand Down

0 comments on commit 9d6846d

Please sign in to comment.