Skip to content

Commit

Permalink
feat: disable subscriptions
Browse files Browse the repository at this point in the history
  • Loading branch information
shreddedbacon committed Jul 2, 2024
1 parent 8588f5d commit 32e750c
Show file tree
Hide file tree
Showing 4 changed files with 339 additions and 239 deletions.
58 changes: 37 additions & 21 deletions src/lib/ApiConnection.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,36 @@
import React from 'react';
import { ApolloProvider } from 'react-apollo';
import React from "react";
import { ApolloProvider } from "react-apollo";

import getConfig from 'next/config';
import getConfig from "next/config";

import { ApolloProvider as ApolloHooksProvider } from '@apollo/react-hooks';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { ApolloClient } from 'apollo-client';
import { ApolloLink } from 'apollo-link';
import { onError } from 'apollo-link-error';
import { HttpLink } from 'apollo-link-http';
import { WebSocketLink } from 'apollo-link-ws';
import { getMainDefinition } from 'apollo-utilities';
import { AuthContext } from 'lib/Authenticator';
import ErrorPage from 'pages/_error.js';
import { ApolloProvider as ApolloHooksProvider } from "@apollo/react-hooks";
import { InMemoryCache } from "apollo-cache-inmemory";
import { ApolloClient } from "apollo-client";
import { ApolloLink } from "apollo-link";
import { onError } from "apollo-link-error";
import { HttpLink } from "apollo-link-http";
import { WebSocketLink } from "apollo-link-ws";
import { getMainDefinition } from "apollo-utilities";
import { AuthContext } from "lib/Authenticator";
import ErrorPage from "pages/_error.js";

const { serverRuntimeConfig, publicRuntimeConfig } = getConfig();

const ds = publicRuntimeConfig.DISABLE_SUBSCRIPTIONS;
const disableSubscriptions =
((!(ds == null) && ds.toLowerCase()) || false) === "true";

const ApiConnection = ({ children }) => (
<AuthContext.Consumer>
{auth => {
{(auth) => {
if (!auth.authenticated) {
return <ErrorPage statusCode={401} title="Login Required" errorMessage="Please wait while we log you in..." />;
return (
<ErrorPage
statusCode={401}
title="Login Required"
errorMessage="Please wait while we log you in..."
/>
);
}

const httpLink = new HttpLink({
Expand All @@ -32,8 +42,12 @@ const ApiConnection = ({ children }) => (

const HttpWebsocketLink = () => {
const wsLink = new WebSocketLink({
uri: publicRuntimeConfig.GRAPHQL_API.replace(/https/, 'wss').replace(/http/, 'ws'),
uri: publicRuntimeConfig.GRAPHQL_API.replace(/https/, "wss").replace(
/http/,
"ws",
),
options: {
lazy: disableSubscriptions,
reconnect: true,
connectionParams: {
authToken: auth.apiToken,
Expand All @@ -44,10 +58,12 @@ const ApiConnection = ({ children }) => (
return ApolloLink.split(
({ query }) => {
const { kind, operation } = getMainDefinition(query);
return kind === 'OperationDefinition' && operation === 'subscription';
return (
kind === "OperationDefinition" && operation === "subscription"
);
},
wsLink,
httpLink
httpLink,
);
};

Expand All @@ -57,10 +73,10 @@ const ApiConnection = ({ children }) => (
if (graphQLErrors)
graphQLErrors.map(({ message, locations, path }) =>
console.log(
`[GraphQL error]: Message: ${message}, Location: ${JSON.stringify(locations)}, Path: ${path}`
)
`[GraphQL error]: Message: ${message}, Location: ${JSON.stringify(locations)}, Path: ${path}`,
),
);
if (networkError) console.log('[Network error]', networkError);
if (networkError) console.log("[Network error]", networkError);
}),
// Disable websockets when rendering server side.
process.browser ? HttpWebsocketLink() : httpLink,
Expand Down
179 changes: 101 additions & 78 deletions src/pages/backups.js
Original file line number Diff line number Diff line change
@@ -1,52 +1,59 @@
import React, { useEffect, useState } from 'react';

import getConfig from 'next/config';
import Head from 'next/head';
import { withRouter } from 'next/router';

import { useQuery } from '@apollo/react-hooks';
import Backups from 'components/Backups';
import BackupsSkeleton from 'components/Backups/BackupsSkeleton';
import Breadcrumbs from 'components/Breadcrumbs';
import EnvironmentBreadcrumb from 'components/Breadcrumbs/Environment';
import ProjectBreadcrumb from 'components/Breadcrumbs/Project';
import NavTabs from 'components/NavTabs';
import NavTabsSkeleton from 'components/NavTabs/NavTabsSkeleton';
import ResultsLimited from 'components/ResultsLimited';
import MainLayout from 'layouts/MainLayout';
import EnvironmentWithBackupsQuery from 'lib/query/EnvironmentWithBackups';
import BackupsSubscription from 'lib/subscription/Backups';
import * as R from 'ramda';

import EnvironmentNotFound from '../components/errors/EnvironmentNotFound';
import QueryError from '../components/errors/QueryError';
import { CommonWrapperWNotification } from '../styles/commonPageStyles';
import { useTourContext } from '../tours/TourContext';
import React, { useEffect, useState } from "react";

import getConfig from "next/config";
import Head from "next/head";
import { withRouter } from "next/router";

import { useQuery } from "@apollo/react-hooks";
import Backups from "components/Backups";
import BackupsSkeleton from "components/Backups/BackupsSkeleton";
import Breadcrumbs from "components/Breadcrumbs";
import EnvironmentBreadcrumb from "components/Breadcrumbs/Environment";
import ProjectBreadcrumb from "components/Breadcrumbs/Project";
import NavTabs from "components/NavTabs";
import NavTabsSkeleton from "components/NavTabs/NavTabsSkeleton";
import ResultsLimited from "components/ResultsLimited";
import MainLayout from "layouts/MainLayout";
import EnvironmentWithBackupsQuery from "lib/query/EnvironmentWithBackups";
import BackupsSubscription from "lib/subscription/Backups";
import * as R from "ramda";

import EnvironmentNotFound from "../components/errors/EnvironmentNotFound";
import QueryError from "../components/errors/QueryError";
import { CommonWrapperWNotification } from "../styles/commonPageStyles";
import { useTourContext } from "../tours/TourContext";

const { publicRuntimeConfig } = getConfig();
const envLimit = parseInt(publicRuntimeConfig.LAGOON_UI_BACKUPS_LIMIT, 10);
const customMessage = publicRuntimeConfig.LAGOON_UI_BACKUPS_LIMIT_MESSAGE;

const ds = publicRuntimeConfig.DISABLE_SUBSCRIPTIONS;
const disableSubscriptions =
((!(ds == null) && ds.toLowerCase()) || false) === "true";

/**
* Displays the backups page, given the name of an openshift project.
*/
export const PageBackups = ({ router }) => {
const [resultLimit, setResultLimit] = useState(null);

const { continueTour } = useTourContext();
const { data, error, loading, subscribeToMore } = useQuery(EnvironmentWithBackupsQuery, {
variables: {
openshiftProjectName: router.query.openshiftProjectName,
limit: resultLimit,
const { data, error, loading, subscribeToMore } = useQuery(
EnvironmentWithBackupsQuery,
{
variables: {
openshiftProjectName: router.query.openshiftProjectName,
limit: resultLimit,
},
},
});
);

useEffect(() => {
let urlResultLimit = envLimit;
if (typeof window !== 'undefined') {
if (typeof window !== "undefined") {
let search = window.location.search;
let params = new URLSearchParams(search);
let limit = params.get('limit');
let limit = params.get("limit");
if (limit) {
if (parseInt(limit.trim(), 10)) {
urlResultLimit = parseInt(limit.trim(), 10);
Expand Down Expand Up @@ -75,7 +82,10 @@ export const PageBackups = ({ router }) => {
<>
<Breadcrumbs>
<ProjectBreadcrumb projectSlug={projectSlug} />
<EnvironmentBreadcrumb environmentSlug={openshiftProjectName} projectSlug={projectSlug} />
<EnvironmentBreadcrumb
environmentSlug={openshiftProjectName}
projectSlug={projectSlug}
/>
</Breadcrumbs>
<CommonWrapperWNotification>
<NavTabsSkeleton
Expand All @@ -85,13 +95,17 @@ export const PageBackups = ({ router }) => {
/>
<div className="content">
<div className="notification">
If you need a current database or files dump, use the tasks "drush sql-dump" or "drush archive-dump"
in the new "Tasks" section!
If you need a current database or files dump, use the tasks
"drush sql-dump" or "drush archive-dump" in the new "Tasks"
section!
</div>
<BackupsSkeleton />
<ResultsLimited
limit={resultLimit}
message={(!customMessage && '') || (customMessage && customMessage.replace(/['"]+/g, ''))}
message={
(!customMessage && "") ||
(customMessage && customMessage.replace(/['"]+/g, ""))
}
/>
</div>
</CommonWrapperWNotification>
Expand All @@ -117,50 +131,56 @@ export const PageBackups = ({ router }) => {
);
}

subscribeToMore({
document: BackupsSubscription,
variables: { environment: environment.id },
updateQuery: (prevStore, { subscriptionData }) => {
if (!subscriptionData.data) return prevStore;
const prevBackups = prevStore.environment.backups;
const incomingBackup = subscriptionData.data.backupChanged;
const existingIndex = prevBackups.findIndex(prevBackup => prevBackup.id === incomingBackup.id);
let newBackups;

// New backup.
if (existingIndex === -1) {
// Don't add new deleted backups.
if (incomingBackup.deleted !== '0000-00-00 00:00:00') {
return prevStore;
}

newBackups = [incomingBackup, ...prevBackups];
}
// Existing backup.
else {
// Updated backup
if (incomingBackup.deleted === '0000-00-00 00:00:00') {
newBackups = Object.assign([...prevBackups], {
[existingIndex]: incomingBackup,
});
if (!disableSubscriptions) {
subscribeToMore({
document: BackupsSubscription,
variables: { environment: environment.id },
updateQuery: (prevStore, { subscriptionData }) => {
if (!subscriptionData.data) return prevStore;
const prevBackups = prevStore.environment.backups;
const incomingBackup = subscriptionData.data.backupChanged;
const existingIndex = prevBackups.findIndex(
(prevBackup) => prevBackup.id === incomingBackup.id,
);
let newBackups;

// New backup.
if (existingIndex === -1) {
// Don't add new deleted backups.
if (incomingBackup.deleted !== "0000-00-00 00:00:00") {
return prevStore;
}

newBackups = [incomingBackup, ...prevBackups];
}
// Deleted backup
// Existing backup.
else {
newBackups = R.remove(existingIndex, 1, prevBackups);
// Updated backup
if (incomingBackup.deleted === "0000-00-00 00:00:00") {
newBackups = Object.assign([...prevBackups], {
[existingIndex]: incomingBackup,
});
}
// Deleted backup
else {
newBackups = R.remove(existingIndex, 1, prevBackups);
}
}
}

const newStore = {
...prevStore,
environment: {
...prevStore.environment,
backups: newBackups,
},
};

return newStore;
},
});
const newStore = {
...prevStore,
environment: {
...prevStore.environment,
backups: newBackups,
},
};

return newStore;
},
});
} else {
subscribeToMore({});
}

return (
<>
Expand All @@ -179,15 +199,18 @@ export const PageBackups = ({ router }) => {
<NavTabs activeTab="backups" environment={environment} />
<div className="content">
<div className="notification">
If you need a current database or files dump, use the tasks "drush sql-dump" or "drush archive-dump" in
the new "Tasks" section!
If you need a current database or files dump, use the tasks "drush
sql-dump" or "drush archive-dump" in the new "Tasks" section!
</div>
<Backups backups={environment.backups} />
<ResultsLimited
limit={resultLimit}
changeLimit={setResultLimit}
results={environment.backups.length}
message={(!customMessage && '') || (customMessage && customMessage.replace(/['"]+/g, ''))}
message={
(!customMessage && "") ||
(customMessage && customMessage.replace(/['"]+/g, ""))
}
/>
</div>
</CommonWrapperWNotification>
Expand Down
Loading

0 comments on commit 32e750c

Please sign in to comment.