diff --git a/components/dashboard/src/App.tsx b/components/dashboard/src/App.tsx index 11514d39e43026..0a47a40550cbb1 100644 --- a/components/dashboard/src/App.tsx +++ b/components/dashboard/src/App.tsx @@ -12,7 +12,7 @@ import { Login } from "./Login"; import { UserContext } from "./user-context"; import { getSelectedTeamSlug, TeamsContext } from "./teams/teams-context"; import { ThemeContext } from "./theme-context"; -import { getGitpodService } from "./service/service"; +import { getGitpodService, initGitPodService } from "./service/service"; import { shouldSeeWhatsNew, WhatsNew } from "./whatsnew/WhatsNew"; import gitpodIcon from "./icons/gitpod.svg"; import { ErrorCodes } from "@gitpod/gitpod-protocol/lib/messaging/error"; @@ -159,7 +159,7 @@ function App() { const { user, setUser, refreshUserBillingMode } = useContext(UserContext); const { teams, setTeams } = useContext(TeamsContext); const { setIsDark } = useContext(ThemeContext); - const { usePublicApiTeamsService } = useContext(FeatureFlagContext); + const { usePublicApiTeamsService, useSlowDatabase } = useContext(FeatureFlagContext); const [loading, setLoading] = useState(true); const [isWhatsNewShown, setWhatsNewShown] = useState(false); @@ -167,6 +167,10 @@ function App() { const [isSetupRequired, setSetupRequired] = useState(false); const history = useHistory(); + useEffect(() => { + initGitPodService(useSlowDatabase); + }, [useSlowDatabase]); + useEffect(() => { (async () => { var user: User | undefined; diff --git a/components/dashboard/src/contexts/FeatureFlagContext.tsx b/components/dashboard/src/contexts/FeatureFlagContext.tsx index 76aa2f5ee7db03..05476cd5fa4884 100644 --- a/components/dashboard/src/contexts/FeatureFlagContext.tsx +++ b/components/dashboard/src/contexts/FeatureFlagContext.tsx @@ -21,12 +21,14 @@ const FeatureFlagContext = createContext<{ showUseLastSuccessfulPrebuild: boolean; usePublicApiTeamsService: boolean; enablePersonalAccessTokens: boolean; + useSlowDatabase: boolean; }>({ showPersistentVolumeClaimUI: false, showUsageView: false, showUseLastSuccessfulPrebuild: false, usePublicApiTeamsService: false, enablePersonalAccessTokens: false, + useSlowDatabase: false, }); const FeatureFlagContextProvider: React.FC = ({ children }) => { @@ -40,6 +42,7 @@ const FeatureFlagContextProvider: React.FC = ({ children }) => { const [showUseLastSuccessfulPrebuild, setShowUseLastSuccessfulPrebuild] = useState(false); const [usePublicApiTeamsService, setUsePublicApiTeamsService] = useState(false); const [enablePersonalAccessTokens, setPersonalAccessTokensEnabled] = useState(false); + const [useSlowDatabase, setUseSlowDatabase] = useState(false); useEffect(() => { if (!user) return; @@ -50,6 +53,7 @@ const FeatureFlagContextProvider: React.FC = ({ children }) => { showUseLastSuccessfulPrebuild: { defaultValue: false, setter: setShowUseLastSuccessfulPrebuild }, publicApiExperimentalTeamsService: { defaultValue: false, setter: setUsePublicApiTeamsService }, personalAccessTokensEnabled: { defaultValue: false, setter: setPersonalAccessTokensEnabled }, + slow_database: { defaultValue: false, setter: setUseSlowDatabase }, }; for (const [flagName, config] of Object.entries(featureFlags)) { if (teams) { @@ -88,6 +92,7 @@ const FeatureFlagContextProvider: React.FC = ({ children }) => { showUseLastSuccessfulPrebuild, usePublicApiTeamsService, enablePersonalAccessTokens, + useSlowDatabase, }} > {children} diff --git a/components/dashboard/src/service/service.tsx b/components/dashboard/src/service/service.tsx index efda93aa80e011..f5dc5e0be89de9 100644 --- a/components/dashboard/src/service/service.tsx +++ b/components/dashboard/src/service/service.tsx @@ -19,7 +19,7 @@ import { log } from "@gitpod/gitpod-protocol/lib/util/logging"; export const gitpodHostUrl = new GitpodHostUrl(window.location.toString()); -function createGitpodService() { +function createGitpodService(useSlowDatabase: boolean = false) { if (window.top !== window.self && process.env.NODE_ENV === "production") { const connection = createWindowMessageConnection("gitpodServer", window.parent, "*"); const factory = new JsonRpcProxyFactory(); @@ -48,6 +48,7 @@ function createGitpodService() { onListening: (socket) => { onReconnect = () => socket.reconnect(); }, + subProtocol: useSlowDatabase ? "slow-database" : undefined, }); return new GitpodServiceImpl(proxy, { onReconnect }); @@ -64,4 +65,13 @@ function getGitpodService(): GitpodService { return service; } -export { getGitpodService }; +function initGitPodService(useSlowDatabase: boolean) { + const w = window as any; + const _gp = w._gp || (w._gp = {}); + if (window.location.search.includes("service=mock")) { + _gp.gitpodService = require("./service-mock").gitpodServiceMock; + } + _gp.gitpodService = createGitpodService(useSlowDatabase); +} + +export { getGitpodService, initGitPodService }; diff --git a/components/gitpod-protocol/src/messaging/browser/connection.ts b/components/gitpod-protocol/src/messaging/browser/connection.ts index 1ef3878449a806..f02cd3b5278fa5 100644 --- a/components/gitpod-protocol/src/messaging/browser/connection.ts +++ b/components/gitpod-protocol/src/messaging/browser/connection.ts @@ -16,6 +16,7 @@ import ReconnectingWebSocket, { Event } from "reconnecting-websocket"; export interface WebSocketOptions { onerror?: (event: Event) => void; onListening?: (socket: ReconnectingWebSocket) => void; + subProtocol?: string; } export class WebSocketConnectionProvider { @@ -62,7 +63,7 @@ export class WebSocketConnectionProvider { */ listen(handler: ConnectionHandler, eventHandler: ConnectionEventHandler, options?: WebSocketOptions): WebSocket { const url = handler.path; - const webSocket = this.createWebSocket(url); + const webSocket = this.createWebSocket(url, options); const logger = this.createLogger(); if (options && options.onerror) { @@ -86,8 +87,8 @@ export class WebSocketConnectionProvider { /** * Creates a web socket for the given url */ - createWebSocket(url: string): WebSocket { - return new ReconnectingWebSocket(url, undefined, { + createWebSocket(url: string, options?: WebSocketOptions): WebSocket { + return new ReconnectingWebSocket(url, options?.subProtocol, { maxReconnectionDelay: 10000, minReconnectionDelay: 1000, reconnectionDelayGrowFactor: 1.3,