Skip to content

Commit b0de2ee

Browse files
committed
πŸ§‘β€πŸ’»(DX) Use of debug flags
Debug flags allow the application to behave differently. They can be set in various ways and allow to debug certain aspects of the application. They can ease development and help debug errors in production environments. Debug flags need to be enabled with debug namespace(s). e.g."feature:language" would instruct the application to be more verbose about its language features. e.g. "no-cache" would instruct the application to avoid caching entirely. The value for the debug configuration is always a string with debug namespaces separated by comma. Signed-off-by: Robin Weber <[email protected]>
1 parent 9da90a1 commit b0de2ee

File tree

5 files changed

+57
-30
lines changed

5 files changed

+57
-30
lines changed

β€Žsrc/backend/impress/settings.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,14 @@ class Base(Configuration):
5858
* DB_USER
5959
"""
6060

61-
DEBUG = False
61+
DEBUG_RAW = values.Value(
62+
default=False,
63+
environ_name="DEBUG",
64+
environ_prefix=None,
65+
)
66+
DEBUG_NAMESPACES = DEBUG_RAW.split(",") if isinstance(DEBUG_RAW, str) else []
67+
DEBUG = bool(DEBUG_RAW)
68+
6269
USE_SWAGGER = False
6370

6471
API_VERSION = "v1.0"
@@ -761,6 +768,9 @@ def post_setup(cls):
761768
"OIDC_ALLOW_DUPLICATE_EMAILS cannot be set to True simultaneously. "
762769
)
763770

771+
if cls.DEBUG and "no-cache" in cls.DEBUG_NAMESPACES:
772+
cls.THEME_CUSTOMIZATION_CACHE_TIMEOUT = 0
773+
764774

765775
class Build(Base):
766776
"""Settings used when the application is built.
@@ -795,6 +805,17 @@ class Development(Base):
795805
CSRF_TRUSTED_ORIGINS = ["http://localhost:8072", "http://localhost:3000"]
796806
DEBUG = True
797807

808+
# Enable debug namespaces as needed
809+
#
810+
# DEBUG_NAMESPACES = [
811+
# 'no-cache',
812+
# 'features:language'
813+
# ]
814+
#
815+
# They can be enabled in all environments
816+
# via DEBUG environment variable
817+
# DEBUG="features:language,no-cache,..."
818+
798819
SESSION_COOKIE_NAME = "impress_sessionid"
799820

800821
USE_SWAGGER = True

β€Žsrc/frontend/apps/impress/src/core/AppProvider.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,16 @@ import { ConfigProvider } from './config/';
1717
* QueryClient:
1818
* - defaultOptions:
1919
* - staleTime:
20-
* - global cache duration - we decided 3 minutes
21-
* - It can be overridden to each query
20+
* - global time until cache is considered stale and will be refetched in the background
21+
* - instant if debug flag "no-cache" active - 3 minutes otherwise
22+
* - gcTime:
23+
* - global time until cache is purged from the persister and needs to be renewed
24+
* - since its cached in localStorage, we can set it to a long time (48h)
2225
*/
2326
const defaultOptions = {
2427
queries: {
2528
staleTime: debug.enabled('no-cache') ? 0 : 1000 * 60 * 3, // 3 minutes
26-
staleTime: 1000 * 60 * 3,
29+
gcTime: debug.enabled('no-cache') ? 0 : 1000 * 60 * 60 * 48, // 48 hours
2730
retry: 1,
2831
},
2932
};
Lines changed: 5 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { useQuery } from '@tanstack/react-query';
2+
import debug from 'debug';
23

34
import { APIError, errorCauses, fetchAPI } from '@/api';
45
import { Theme } from '@/cunningham/';
@@ -19,45 +20,24 @@ interface ConfigResponse {
1920
SENTRY_DSN?: string;
2021
}
2122

22-
const LOCAL_STORAGE_KEY = 'docs_config';
23-
24-
function getCachedTranslation() {
25-
try {
26-
const jsonString = localStorage.getItem(LOCAL_STORAGE_KEY);
27-
return jsonString ? (JSON.parse(jsonString) as ConfigResponse) : undefined;
28-
} catch {
29-
return undefined;
30-
}
31-
}
32-
33-
function setCachedTranslation(translations: ConfigResponse) {
34-
localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(translations));
35-
}
36-
3723
export const getConfig = async (): Promise<ConfigResponse> => {
3824
const response = await fetchAPI(`config/`);
3925

4026
if (!response.ok) {
41-
throw new APIError('Failed to get the doc', await errorCauses(response));
27+
throw new APIError('Failed to get the config', await errorCauses(response));
4228
}
4329

4430
const config = response.json() as Promise<ConfigResponse>;
45-
setCachedTranslation(await config);
4631

4732
return config;
4833
};
4934

50-
export const KEY_CONFIG = 'config';
35+
export const QKEY_CONFIG = 'config';
5136

5237
export function useConfig() {
53-
const cachedData = getCachedTranslation();
54-
const oneHour = 1000 * 60 * 60;
55-
5638
return useQuery<ConfigResponse, APIError, ConfigResponse>({
57-
queryKey: [KEY_CONFIG],
39+
queryKey: [QKEY_CONFIG],
5840
queryFn: () => getConfig(),
59-
initialData: cachedData,
60-
staleTime: oneHour,
61-
initialDataUpdatedAt: Date.now() - oneHour, // Force initial data to be considered stale
41+
staleTime: debug.enabled('no-cache') ? 0 : 1000 * 60 * 60, // 1 hour
6242
});
6343
}

β€Žsrc/frontend/apps/impress/src/features/auth/api/useAuthQuery.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { UseQueryOptions, useQuery } from '@tanstack/react-query';
2+
import debug from 'debug';
23

34
import { APIError, errorCauses, fetchAPI } from '@/api';
45

@@ -33,7 +34,7 @@ export function useAuthQuery(
3334
return useQuery<User, APIError, User>({
3435
queryKey: [KEY_AUTH],
3536
queryFn: getMe,
36-
staleTime: 1000 * 60 * 15, // 15 minutes
37+
staleTime: debug.enabled('no-cache') ? 0 : 1000 * 60 * 15, // 15 minutes
3738
...queryConfig,
3839
});
3940
}

β€Žsrc/frontend/apps/impress/src/pages/_app.tsx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,28 @@ export default function App({ Component, pageProps }: AppPropsWithLayout) {
1818
const getLayout = Component.getLayout ?? ((page) => page);
1919
const { t } = useTranslation();
2020

21+
if (process.env.NODE_ENV === 'development') {
22+
/**
23+
* Enable debug namespaces as needed
24+
*
25+
* They can be enabled:
26+
*
27+
* via DEBUG environment variable
28+
* DEBUG="features:language,no-cache,..."
29+
*
30+
* via browser console
31+
* window.debug = "features:language,no-cache,...";
32+
*
33+
* via Local storage
34+
* window.localStorage.debug = "features:language,no-cache,...";
35+
*
36+
* via code (uses Local storage)
37+
* import debug from 'debug';
38+
* debug.enable('no-cache,features:language,...');
39+
*/
40+
//debug.enable('no-cache,features:language');
41+
}
42+
2143
return (
2244
<>
2345
<Head>

0 commit comments

Comments
Β (0)