Skip to content

Commit

Permalink
Remove local fetch caching
Browse files Browse the repository at this point in the history
  • Loading branch information
kmcginnes committed Mar 29, 2024
1 parent bcce59b commit f459f72
Show file tree
Hide file tree
Showing 8 changed files with 32 additions and 158 deletions.
5 changes: 2 additions & 3 deletions packages/graph-explorer/src/connector/gremlin/useGremlin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,13 @@ const useGremlin = () => {

const fetchSchemaFunc = useCallback(
async options => {
const ops = { ...options, disableCache: true };
let summary;
try {
const response = await useFetch.request(
`${url}/pg/statistics/summary?mode=detailed`,
{
method: "GET",
...ops,
...options,

Check warning on line 55 in packages/graph-explorer/src/connector/gremlin/useGremlin.ts

View check run for this annotation

Codecov / codecov/patch

packages/graph-explorer/src/connector/gremlin/useGremlin.ts#L55

Added line #L55 was not covered by tests
}
);
summary = (response.payload.graphSummary as GraphSummary) || undefined;
Expand All @@ -62,7 +61,7 @@ const useGremlin = () => {
console.error("[Summary API]", e);
}
}
return fetchSchema(_gremlinFetch(ops), summary);
return fetchSchema(_gremlinFetch(options), summary);

Check warning on line 64 in packages/graph-explorer/src/connector/gremlin/useGremlin.ts

View check run for this annotation

Codecov / codecov/patch

packages/graph-explorer/src/connector/gremlin/useGremlin.ts#L64

Added line #L64 was not covered by tests
},
[_gremlinFetch, url, useFetch]
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ const useOpenCypher = () => {
"Content-Type": "application/json",
},
body: JSON.stringify({ query: queryTemplate }),
disableCache: options?.disableCache,
...options,
});
};
Expand All @@ -36,8 +35,6 @@ const useOpenCypher = () => {

const fetchSchemaFunc = useCallback(
async (options: any) => {
const ops = { ...options, disableCache: true };

let summary;
try {
const endpoint =
Expand All @@ -46,7 +43,7 @@ const useOpenCypher = () => {
: `${url}/summary?mode=detailed`;
const response = await useFetch.request(endpoint, {
method: "GET",
...ops,
...options,

Check warning on line 46 in packages/graph-explorer/src/connector/openCypher/useOpenCypher.ts

View check run for this annotation

Codecov / codecov/patch

packages/graph-explorer/src/connector/openCypher/useOpenCypher.ts#L46

Added line #L46 was not covered by tests
});

summary =
Expand All @@ -58,7 +55,7 @@ const useOpenCypher = () => {
console.error("[Summary API]", e);
}
}
return fetchSchema(_openCypherFetch(ops), summary);
return fetchSchema(_openCypherFetch(options), summary);

Check warning on line 58 in packages/graph-explorer/src/connector/openCypher/useOpenCypher.ts

View check run for this annotation

Codecov / codecov/patch

packages/graph-explorer/src/connector/openCypher/useOpenCypher.ts#L58

Added line #L58 was not covered by tests
},
[_openCypherFetch, url, useFetch, serviceType]
);
Expand Down
5 changes: 2 additions & 3 deletions packages/graph-explorer/src/connector/sparql/useSPARQL.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,14 +160,13 @@ const useSPARQL = (blankNodes: BlankNodesMap) => {

const fetchSchemaFunc = useCallback(
async options => {
const ops = { ...options, disableCache: true };
let summary;
try {
const response = await useFetch.request(
`${url}/rdf/statistics/summary?mode=detailed`,
{
method: "GET",
...ops,
...options,

Check warning on line 169 in packages/graph-explorer/src/connector/sparql/useSPARQL.ts

View check run for this annotation

Codecov / codecov/patch

packages/graph-explorer/src/connector/sparql/useSPARQL.ts#L169

Added line #L169 was not covered by tests
}
);
summary = (response.payload.graphSummary as GraphSummary) || undefined;
Expand All @@ -176,7 +175,7 @@ const useSPARQL = (blankNodes: BlankNodesMap) => {
console.error("[Summary API]", e);
}
}
return fetchSchema(_sparqlFetch(ops), summary);
return fetchSchema(_sparqlFetch(options), summary);

Check warning on line 178 in packages/graph-explorer/src/connector/sparql/useSPARQL.ts

View check run for this annotation

Codecov / codecov/patch

packages/graph-explorer/src/connector/sparql/useSPARQL.ts#L178

Added line #L178 was not covered by tests
},
[_sparqlFetch, url, useFetch]
);
Expand Down
105 changes: 26 additions & 79 deletions packages/graph-explorer/src/connector/useGEFetch.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,8 @@
import { useCallback } from "react";
import localforage from "localforage";
import { CacheItem } from "./useGEFetchTypes";
import { useConfiguration, type ConnectionConfig } from "../core";
import { DEFAULT_SERVICE_TYPE } from "../utils/constants";
import { anySignal } from "./utils/anySignal";

// 10 minutes
const CACHE_TIME_MS = 10 * 60 * 1000;

const localforageCache = localforage.createInstance({
name: "ge",
version: 1.0,
storeName: "connector-cache",
});

/**
* Attempts to decode the error response into a JSON object.
*
Expand Down Expand Up @@ -58,49 +47,8 @@ const useGEFetch = () => {
const connection = useConfiguration()?.connection as
| ConnectionConfig
| undefined;
const _getFromCache = useCallback(
async key => {
if (!connection?.enableCache) {
return;
}

return localforageCache.getItem(key) as Promise<CacheItem | undefined>;
},
[connection?.enableCache]
);

const _setToCache = useCallback(
async (key, value) => {
if (connection?.enableCache) {
return;
}

return localforageCache.setItem(key, value);
},
[connection?.enableCache]
);

const _requestAndCache = useCallback(
async (
url: URL,
options: (RequestInit & { disableCache: boolean }) | undefined
) => {
const response = await fetch(url, options);
if (!response.ok) {
const error = await decodeErrorSafely(response);
throw new Error("Network response was not OK", { cause: error });
}

// A successful response is assumed to be JSON
const data = await response.json();
if (options?.disableCache !== true) {
_setToCache(url, { data, updatedAt: new Date().getTime() });
}
return data as any;
},
[_setToCache]
);

// Construct the request headers based on the connection settings

Check warning on line 51 in packages/graph-explorer/src/connector/useGEFetch.ts

View check run for this annotation

Codecov / codecov/patch

packages/graph-explorer/src/connector/useGEFetch.ts#L51

Added line #L51 was not covered by tests
const getAuthHeaders = useCallback(
typeHeaders => {
const headers: HeadersInit = {};
Expand All @@ -124,41 +72,40 @@ const useGEFetch = () => {
]
);

const request = useCallback(
async (uri, options) => {
const cachedResponse = await _getFromCache(uri);
if (
cachedResponse &&
cachedResponse.updatedAt + (connection?.cacheTimeMs ?? CACHE_TIME_MS) >
new Date().getTime()
) {
return cachedResponse.data;
}
// Construct an AbortSignal for the fetch timeout if configured
const getFetchTimeoutSignal = useCallback(() => {
if (!connection?.fetchTimeoutMs) {
return null;
}

Check warning on line 79 in packages/graph-explorer/src/connector/useGEFetch.ts

View check run for this annotation

Codecov / codecov/patch

packages/graph-explorer/src/connector/useGEFetch.ts#L75-L79

Added lines #L75 - L79 were not covered by tests

if (connection.fetchTimeoutMs <= 0) {
return null;
}

return AbortSignal.timeout(connection.fetchTimeoutMs);
}, [connection?.fetchTimeoutMs]);

const request = useCallback(
async (uri: URL | RequestInfo, options: RequestInit) => {
// Apply connection settings to fetch options

Check warning on line 90 in packages/graph-explorer/src/connector/useGEFetch.ts

View check run for this annotation

Codecov / codecov/patch

packages/graph-explorer/src/connector/useGEFetch.ts#L81-L90

Added lines #L81 - L90 were not covered by tests
const fetchOptions: RequestInit = {
...options,

Check warning on line 92 in packages/graph-explorer/src/connector/useGEFetch.ts

View check run for this annotation

Codecov / codecov/patch

packages/graph-explorer/src/connector/useGEFetch.ts#L92

Added line #L92 was not covered by tests
headers: getAuthHeaders(options.headers),
signal: anySignal(getFetchTimeoutSignal(), options.signal),

Check warning on line 94 in packages/graph-explorer/src/connector/useGEFetch.ts

View check run for this annotation

Codecov / codecov/patch

packages/graph-explorer/src/connector/useGEFetch.ts#L94

Added line #L94 was not covered by tests
};

const connectionFetchTimeout = connection?.fetchTimeoutMs;
const response = await fetch(uri, fetchOptions);

Check warning on line 97 in packages/graph-explorer/src/connector/useGEFetch.ts

View check run for this annotation

Codecov / codecov/patch

packages/graph-explorer/src/connector/useGEFetch.ts#L97

Added line #L97 was not covered by tests

if (connectionFetchTimeout && connectionFetchTimeout > 0) {
const timeoutSignal = AbortSignal.timeout(connectionFetchTimeout);

fetchOptions.signal = anySignal(timeoutSignal, options.signal);
if (!response.ok) {
const error = await decodeErrorSafely(response);
throw new Error("Network response was not OK", { cause: error });

Check warning on line 101 in packages/graph-explorer/src/connector/useGEFetch.ts

View check run for this annotation

Codecov / codecov/patch

packages/graph-explorer/src/connector/useGEFetch.ts#L99-L101

Added lines #L99 - L101 were not covered by tests
}

return _requestAndCache(uri, {
...options,
...fetchOptions,
}) as Promise<any>;
// A successful response is assumed to be JSON
const data = await response.json();
return data;

Check warning on line 106 in packages/graph-explorer/src/connector/useGEFetch.ts

View check run for this annotation

Codecov / codecov/patch

packages/graph-explorer/src/connector/useGEFetch.ts#L104-L106

Added lines #L104 - L106 were not covered by tests
},
[
_getFromCache,
_requestAndCache,
connection?.cacheTimeMs,
connection?.fetchTimeoutMs,
getAuthHeaders,
]
[getAuthHeaders, getFetchTimeoutSignal]

Check warning on line 108 in packages/graph-explorer/src/connector/useGEFetch.ts

View check run for this annotation

Codecov / codecov/patch

packages/graph-explorer/src/connector/useGEFetch.ts#L108

Added line #L108 was not covered by tests
);

return {
Expand Down
7 changes: 0 additions & 7 deletions packages/graph-explorer/src/connector/useGEFetchTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@ import {
} from "../core";

export type QueryOptions = RequestInit & {
disableCache?: boolean;
queryId?: string;
successCallback?: (queryId: string) => void;
};

export type VertexSchemaResponse = Pick<
Expand Down Expand Up @@ -190,8 +188,3 @@ export type ConfigurationWithConnection = Omit<
"connection"
> &
Required<Pick<ConfigurationContextProps, "connection">>;

export type CacheItem = {
updatedAt: number;
data: any;
};
10 changes: 0 additions & 10 deletions packages/graph-explorer/src/core/ConfigurationProvider/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,16 +140,6 @@ export type ConnectionConfig = {
* It is needed to sign requests.
*/
awsRegion?: string;
/**
* Enable or disable connector cache.
* By default, it's enabled.
*/
enableCache?: boolean;
/**
* Number of milliseconds before expiring a cached request.
* By default, 10 minutes.
*/
cacheTimeMs?: number;
/**
* Number of milliseconds before aborting a request.
* By default, 60 seconds.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,6 @@ const ConnectorProvider = ({ children }: PropsWithChildren<any>) => {
"graphDbUrl",
"awsAuthEnabled",
"awsRegion",
"enableCache",
"cacheTimeMs",
"fetchTimeoutMs",
] as const,
[]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ type ConnectionForm = {
awsAuthEnabled?: boolean;
serviceType?: "neptune-db" | "neptune-graph";
awsRegion?: string;
enableCache?: boolean;
cacheTimeMs?: number;
fetchTimeMs?: number;
};

Expand Down Expand Up @@ -78,8 +76,6 @@ const CreateConnection = ({
awsAuthEnabled: data.awsAuthEnabled,
serviceType: data.serviceType,
awsRegion: data.awsRegion,
enableCache: data.enableCache,
cacheTimeMs: data.cacheTimeMs * 60 * 1000,
fetchTimeoutMs: data.fetchTimeMs,
},
};
Expand Down Expand Up @@ -108,7 +104,6 @@ const CreateConnection = ({
awsAuthEnabled: data.awsAuthEnabled,
serviceType: data.serviceType,
awsRegion: data.awsRegion,
cacheTimeMs: data.cacheTimeMs * 60 * 1000,
fetchTimeoutMs: data.fetchTimeMs,
},
});
Expand Down Expand Up @@ -150,8 +145,6 @@ const CreateConnection = ({
awsAuthEnabled: initialData?.awsAuthEnabled || false,
serviceType: initialData?.serviceType || "neptune-db",
awsRegion: initialData?.awsRegion || "",
enableCache: true,
cacheTimeMs: (initialData?.cacheTimeMs ?? 10 * 60 * 1000) / 60000,
fetchTimeMs: initialData?.fetchTimeMs,
});

Expand Down Expand Up @@ -316,48 +309,6 @@ const CreateConnection = ({
</>
)}
</div>
<div className={pfx("configuration-form")}>
<Checkbox
value={"enableCache"}
checked={form.enableCache}
onChange={e => {
onFormChange("enableCache")(e.target.checked);
}}
styles={{
label: {
display: "block",
},
}}
label={
<div style={{ display: "flex", alignItems: "center", gap: 2 }}>
Enable Cache
<Tooltip
text={
<div style={{ maxWidth: 300 }}>
Requests made by the Graph Explorer can be temporarily
stored in the browser cache for quick access to the data.
</div>
}
>
<div>
<InfoIcon style={{ width: 18, height: 18 }} />
</div>
</Tooltip>
</div>
}
/>
{form.enableCache && (
<div className={pfx("input-url")}>
<Input
label="Cache Time (minutes)"
type={"number"}
value={form.cacheTimeMs}
onChange={onFormChange("cacheTimeMs")}
min={0}
/>
</div>
)}
</div>
<div className={pfx("configuration-form")}>
<Checkbox
value={"fetchTimeoutMs"}
Expand Down

0 comments on commit f459f72

Please sign in to comment.