Skip to content

Commit

Permalink
First pass at switching to a saga
Browse files Browse the repository at this point in the history
  • Loading branch information
alexcottner committed Jun 4, 2024
1 parent 9b2191b commit 8a18ff2
Show file tree
Hide file tree
Showing 8 changed files with 100 additions and 24 deletions.
14 changes: 14 additions & 0 deletions src/actions/heartbeat.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { HEARTBEAT_REQUEST, HEARTBEAT_RESPONSE } from "@src/constants";

export function heartbeatRequest(): {
type: "HEARTBEAT_REQUEST";
} {
return { type: HEARTBEAT_REQUEST };
}

export function heartbeatResponse(response: Record<string, any>): {
type: "HEARTBEAT_RESPONSE";
response: Record<string, any>;
} {
return { type: HEARTBEAT_RESPONSE, response };
}
37 changes: 13 additions & 24 deletions src/components/SessionInfoBar.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import * as HeartbeatActions from "@src/actions/heartbeat";
import * as SessionActions from "@src/actions/session";
import { getClient } from "@src/client";
// import { getClient } from "@src/client";
import { useAppDispatch, useAppSelector } from "@src/hooks/app";
import React, { useEffect, useState } from "react";
import React, { useEffect } from "react";
import {
BoxArrowRight,
CircleFill,
Expand All @@ -11,31 +12,19 @@ import {
} from "react-bootstrap-icons";

export function SessionInfoBar() {
const { url, project_name, project_docs, user } = useAppSelector(
store => store.session.serverInfo
const { heartbeat, url, project_name, project_docs, user } = useAppSelector(
store => {
return {
...store.session.serverInfo,
heartbeat: store.heartbeat,
};
}
);
const dispatch = useAppDispatch();
const [isHealthy, setIsHealthy] = useState(true);
const client = getClient();

const checkHeartbeat = async () => {
try {
let response: Record<string, any> = await client.execute({
path: "/__heartbeat__",
headers: undefined,
});
for (let prop in response) {
if (response[prop] === false) {
setIsHealthy(false);
return;
}
}
setIsHealthy(true);
} catch (ex) {
setIsHealthy(false);
} finally {
setTimeout(checkHeartbeat, 60000);
}
dispatch(HeartbeatActions.heartbeatRequest());
setTimeout(checkHeartbeat, 60000);
};

useEffect(() => {
Expand Down Expand Up @@ -67,7 +56,7 @@ export function SessionInfoBar() {
<Clipboard className="icon" />
</a>
<a href={`${url}__heartbeat__`} target="_blank">
{isHealthy ? (
{heartbeat.success !== false ? (
<CircleFill
color="green"
title="Server heartbeat status is healthy"
Expand Down
3 changes: 3 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ export const GROUP_HISTORY_REQUEST = "GROUP_HISTORY_REQUEST";
export const GROUP_HISTORY_NEXT_REQUEST = "GROUP_HISTORY_NEXT_REQUEST";
export const GROUP_HISTORY_SUCCESS = "GROUP_HISTORY_SUCCESS";

export const HEARTBEAT_REQUEST = "HEARTBEAT_REQUEST";
export const HEARTBEAT_RESPONSE = "HEARTBEAT_RESPONSE";

export const NOTIFICATION_ADDED = "NOTIFICATION_ADDED";
export const NOTIFICATION_REMOVED = "NOTIFICATION_REMOVED";
export const NOTIFICATION_CLEAR = "NOTIFICATION_CLEAR";
Expand Down
21 changes: 21 additions & 0 deletions src/reducers/heartbeat.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { HEARTBEAT_RESPONSE } from "@src/constants";
import { HeartbeatState } from "@src/types";

const INITIAL_STATE: HeartbeatState = {
success: true,
response: {},
};

export default function servers(
state: HeartbeatState = INITIAL_STATE,
action: any
): HeartbeatState {
switch (action.type) {
case HEARTBEAT_RESPONSE: {
return action.response;
}
default: {
return state;
}
}
}
2 changes: 2 additions & 0 deletions src/reducers/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import bucket from "./bucket";
import collection from "./collection";
import group from "./group";
import heartbeat from "./heartbeat";
import notifications from "./notifications";
import record from "./record";
import servers from "./servers";
Expand All @@ -17,6 +18,7 @@ export default function createRootReducer(routerReducer: Reducer<RouterState>) {
bucket,
collection,
group,
heartbeat,
record,
notifications,
servers,
Expand Down
39 changes: 39 additions & 0 deletions src/sagas/heartbeat.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import * as actions from "@src/actions/heartbeat";
import { getClient } from "@src/client";
import { ActionType, GetStateFn, SagaGen } from "@src/types";
import { call, put } from "redux-saga/effects";

export function* heartbeatRequest(
getState: GetStateFn,
action: ActionType<typeof actions.heartbeatRequest>
): SagaGen {
const response = yield call(queryHeartbeat);
yield put(actions.heartbeatResponse(response));
}

async function queryHeartbeat(): Promise<Record<string, any>> {
const client = getClient();

try {
const response: Record<string, any> = await client.execute({
path: "/__heartbeat__",
headers: undefined,
});
let success = true;
for (let prop in response) {
if (response[prop] === false) {
success = false;
break;
}
}
return {
success,
response,
};
} catch (ex) {
return {
success: false,
details: ex,
};
}
}
3 changes: 3 additions & 0 deletions src/sagas/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as bucketSagas from "./bucket";
import * as collectionSagas from "./collection";
import * as groupSagas from "./group";
import * as heartbeatSagas from "./heartbeat";
import * as recordSagas from "./record";
import * as routeSagas from "./route";
import * as sessionSagas from "./session";
Expand Down Expand Up @@ -143,6 +144,8 @@ export default function* rootSaga(getState: GetStateFn): SagaGen {
signoffSagas.handleApproveChanges,
getState
),
// server
takeEvery(c.HEARTBEAT_REQUEST, heartbeatSagas.heartbeatRequest, getState),
];

yield all(sagas);
Expand Down
5 changes: 5 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -529,3 +529,8 @@ export type DestinationInfo = {
bid: string;
cid: string;
};

export type HeartbeatState = {
success: boolean;
response: Record<string, any>;
};

0 comments on commit 8a18ff2

Please sign in to comment.