From d35204033fafd4c557ceecd2528ff78e1addb5c1 Mon Sep 17 00:00:00 2001
From: Antoine Clausse
Date: Mon, 15 Apr 2024 11:33:46 +0200
Subject: [PATCH] Merge pull request #17909 from
overleaf/ac-tear-down-compile-timeout-tests-2
[web] Remove split-tests `compile-backend-class*` and `compile-timeout-20s*` (attempt 2)
GitOrigin-RevId: 5658f2977d3e7089eec5bbe7a33eee81c153e41d
---
.../src/Features/Compile/CompileController.js | 9 -
.../src/Features/Compile/CompileManager.js | 135 ++-------------
.../Features/Editor/EditorHttpController.js | 58 -------
services/web/config/settings.defaults.js | 1 -
.../web/frontend/extracted-translations.json | 21 ---
...ile-time-warning-upgrade-prompt-inner.tsx} | 15 +-
.../compile-time-warning-upgrade-prompt.tsx | 78 +++++++++
.../components/compile-time-warning.tsx | 116 -------------
.../compile-timeout-changing-soon.tsx | 122 --------------
.../components/compile-timeout-messages.tsx | 126 --------------
.../components/faster-compiles-feedback.tsx | 135 ---------------
.../components/pdf-logs-viewer.jsx | 10 +-
.../components/pdf-preview-pane.jsx | 13 +-
.../components/timeout-upgrade-prompt-new.tsx | 159 +++++++-----------
.../components/timeout-upgrade-prompt.jsx | 62 -------
.../js/features/pdf-preview/util/compiler.js | 8 -
.../shared/context/detach-compile-context.tsx | 29 ++--
.../shared/context/local-compile-context.tsx | 33 ++--
.../js/shared/context/project-context.tsx | 17 --
.../stories/pdf-preview-messages.stories.jsx | 4 +-
.../stories/pdf-preview-messages.stories.tsx | 39 +----
services/web/locales/en.json | 21 ---
.../migration_compile_timeout_60s_to_20s.js | 57 +++++++
.../src/MigrateUserFeatureTimeoutTests.js | 134 +++++++++++++++
.../test/unit/src/Compile/ClsiManagerTests.js | 1 -
.../src/Compile/CompileControllerTests.js | 1 -
.../unit/src/Compile/CompileManagerTests.js | 40 ++---
27 files changed, 393 insertions(+), 1051 deletions(-)
rename services/web/frontend/js/features/pdf-preview/components/{compile-timeout-warning.tsx => compile-time-warning-upgrade-prompt-inner.tsx} (74%)
create mode 100644 services/web/frontend/js/features/pdf-preview/components/compile-time-warning-upgrade-prompt.tsx
delete mode 100644 services/web/frontend/js/features/pdf-preview/components/compile-time-warning.tsx
delete mode 100644 services/web/frontend/js/features/pdf-preview/components/compile-timeout-changing-soon.tsx
delete mode 100644 services/web/frontend/js/features/pdf-preview/components/compile-timeout-messages.tsx
delete mode 100644 services/web/frontend/js/features/pdf-preview/components/faster-compiles-feedback.tsx
delete mode 100644 services/web/frontend/js/features/pdf-preview/components/timeout-upgrade-prompt.jsx
create mode 100644 services/web/scripts/migration_compile_timeout_60s_to_20s.js
create mode 100644 services/web/test/acceptance/src/MigrateUserFeatureTimeoutTests.js
diff --git a/services/web/app/src/Features/Compile/CompileController.js b/services/web/app/src/Features/Compile/CompileController.js
index 99bf62728f..8515e430bb 100644
--- a/services/web/app/src/Features/Compile/CompileController.js
+++ b/services/web/app/src/Features/Compile/CompileController.js
@@ -105,15 +105,6 @@ module.exports = CompileController = {
stopOnFirstError,
}
- // temporary override to force the new compile timeout
- const forceNewCompileTimeout = req.query.force_new_compile_timeout
- if (
- forceNewCompileTimeout === 'active' ||
- forceNewCompileTimeout === 'changing'
- ) {
- options.forceNewCompileTimeout = forceNewCompileTimeout
- }
-
if (req.body.rootDoc_id) {
options.rootDoc_id = req.body.rootDoc_id
} else if (
diff --git a/services/web/app/src/Features/Compile/CompileManager.js b/services/web/app/src/Features/Compile/CompileManager.js
index c65c4fff9e..63badf4dc7 100644
--- a/services/web/app/src/Features/Compile/CompileManager.js
+++ b/services/web/app/src/Features/Compile/CompileManager.js
@@ -8,18 +8,9 @@ const UserGetter = require('../User/UserGetter')
const ClsiManager = require('./ClsiManager')
const Metrics = require('@overleaf/metrics')
const { RateLimiter } = require('../../infrastructure/RateLimiter')
-const SplitTestHandler = require('../SplitTests/SplitTestHandler')
const UserAnalyticsIdCache = require('../Analytics/UserAnalyticsIdCache')
-const NEW_COMPILE_TIMEOUT_ENFORCED_CUTOFF = new Date('2023-09-18T11:00:00.000Z')
-const NEW_COMPILE_TIMEOUT_ENFORCED_CUTOFF_DEFAULT_BASELINE = new Date(
- '2023-10-10T11:00:00.000Z'
-)
-
module.exports = CompileManager = {
- NEW_COMPILE_TIMEOUT_ENFORCED_CUTOFF,
- NEW_COMPILE_TIMEOUT_ENFORCED_CUTOFF_DEFAULT_BASELINE,
-
compile(projectId, userId, options = {}, _callback) {
const timer = new Metrics.Timer('editor.compile')
const callback = function (...args) {
@@ -62,16 +53,6 @@ module.exports = CompileManager = {
const value = limits[key]
options[key] = value
}
- if (options.timeout !== 20) {
- // temporary override to force the new compile timeout
- if (options.forceNewCompileTimeout === 'active') {
- options.timeout = 20
- } else if (
- options.forceNewCompileTimeout === 'changing'
- ) {
- options.timeout = 60
- }
- }
// Put a lower limit on autocompiles for free users, based on compileGroup
CompileManager._checkCompileGroupAutoCompileLimit(
options.isAutoCompile,
@@ -184,78 +165,25 @@ module.exports = CompileManager = {
if (err) {
return callback(err)
}
+ const compileGroup =
+ ownerFeatures.compileGroup ||
+ Settings.defaultFeatures.compileGroup
+ const compileTimeout =
+ ownerFeatures.compileTimeout ||
+ Settings.defaultFeatures.compileTimeout
+
const limits = {
timeout:
- ownerFeatures.compileTimeout ||
- Settings.defaultFeatures.compileTimeout,
- compileGroup:
- ownerFeatures.compileGroup ||
- Settings.defaultFeatures.compileGroup,
+ // temporary override until users' compileTimeout is migrated
+ compileGroup === 'standard' && compileTimeout <= 60
+ ? 20
+ : compileTimeout,
+ compileGroup,
+ compileBackendClass:
+ compileGroup === 'standard' ? 'n2d' : 'c2d',
ownerAnalyticsId: analyticsId,
}
- CompileManager._getCompileBackendClassDetails(
- owner,
- limits.compileGroup,
- (
- err,
- { compileBackendClass, showFasterCompilesFeedbackUI }
- ) => {
- if (err) return callback(err)
- limits.compileBackendClass = compileBackendClass
- limits.showFasterCompilesFeedbackUI =
- showFasterCompilesFeedbackUI
- if (compileBackendClass === 'n2d' && limits.timeout <= 60) {
- // project owners with faster compiles but with <= 60 compile timeout (default)
- // will have a 20s compile timeout
- // The compile-timeout-20s split test exists to enable a gradual rollout
- SplitTestHandler.getAssignmentForMongoUser(
- owner,
- 'compile-timeout-20s',
- (err, assignment) => {
- if (err) return callback(err)
- // users who were on the 'default' servers at time of original rollout
- // will have a later cutoff date for the 20s timeout in the next phase
- // we check the backend class at version 8 (baseline)
- const backendClassHistory =
- owner.splitTests?.['compile-backend-class-n2d'] ||
- []
- const backendClassBaselineVariant =
- backendClassHistory.find(version => {
- return version.versionNumber === 8
- })?.variantName
- const timeoutEnforcedCutoff =
- backendClassBaselineVariant === 'default'
- ? NEW_COMPILE_TIMEOUT_ENFORCED_CUTOFF_DEFAULT_BASELINE
- : NEW_COMPILE_TIMEOUT_ENFORCED_CUTOFF
- if (assignment?.variant === '20s') {
- if (owner.signUpDate > timeoutEnforcedCutoff) {
- limits.timeout = 20
- callback(null, limits)
- } else {
- SplitTestHandler.getAssignmentForMongoUser(
- owner,
- 'compile-timeout-20s-existing-users',
- (err, assignmentExistingUsers) => {
- if (err) return callback(err)
- if (
- assignmentExistingUsers?.variant === '20s'
- ) {
- limits.timeout = 20
- }
- callback(null, limits)
- }
- )
- }
- } else {
- callback(null, limits)
- }
- }
- )
- } else {
- callback(null, limits)
- }
- }
- )
+ callback(null, limits)
}
)
}
@@ -322,39 +250,6 @@ module.exports = CompileManager = {
})
},
- _getCompileBackendClassDetails(owner, compileGroup, callback) {
- const { defaultBackendClass } = Settings.apis.clsi
- if (compileGroup === 'standard') {
- return SplitTestHandler.getAssignmentForMongoUser(
- owner,
- 'compile-backend-class-n2d',
- (err, assignment) => {
- if (err) return callback(err, {})
- const { variant } = assignment
- callback(null, {
- compileBackendClass:
- variant === 'default' ? defaultBackendClass : variant,
- showFasterCompilesFeedbackUI: false,
- })
- }
- )
- }
- SplitTestHandler.getAssignmentForMongoUser(
- owner,
- 'compile-backend-class',
- (err, assignment) => {
- if (err) return callback(err, {})
- const { analytics, variant } = assignment
- const activeForUser = analytics?.segmentation?.splitTest != null
- callback(null, {
- compileBackendClass:
- variant === 'default' ? defaultBackendClass : variant,
- showFasterCompilesFeedbackUI: activeForUser,
- })
- }
- )
- },
-
wordCount(projectId, userId, file, clsiserverid, callback) {
CompileManager.getProjectCompileLimits(projectId, function (error, limits) {
if (error) {
diff --git a/services/web/app/src/Features/Editor/EditorHttpController.js b/services/web/app/src/Features/Editor/EditorHttpController.js
index 6e820c2fe4..7f2d54167c 100644
--- a/services/web/app/src/Features/Editor/EditorHttpController.js
+++ b/services/web/app/src/Features/Editor/EditorHttpController.js
@@ -13,12 +13,6 @@ const Errors = require('../Errors/Errors')
const DocstoreManager = require('../Docstore/DocstoreManager')
const logger = require('@overleaf/logger')
const { expressify } = require('@overleaf/promise-utils')
-const SplitTestHandler = require('../SplitTests/SplitTestHandler')
-const {
- NEW_COMPILE_TIMEOUT_ENFORCED_CUTOFF,
- NEW_COMPILE_TIMEOUT_ENFORCED_CUTOFF_DEFAULT_BASELINE,
-} = require('../Compile/CompileManager')
-const UserGetter = require('../User/UserGetter')
module.exports = {
joinProject: expressify(joinProject),
@@ -72,58 +66,6 @@ async function joinProject(req, res, next) {
if (!project) {
return res.sendStatus(403)
}
- // Compile timeout 20s test
- if (project.features?.compileTimeout <= 60) {
- const compileAssignment =
- await SplitTestHandler.promises.getAssignmentForUser(
- project.owner._id,
- 'compile-backend-class-n2d'
- )
- if (compileAssignment?.variant === 'n2d') {
- const timeoutAssignment =
- await SplitTestHandler.promises.getAssignmentForUser(
- project.owner._id,
- 'compile-timeout-20s'
- )
- if (timeoutAssignment?.variant === '20s') {
- // users who were on the 'default' servers at time of original rollout
- // will have a later cutoff date for the 20s timeout in the next phase
- // we check the backend class at version 8 (baseline)
- const owner = await UserGetter.promises.getUser(project.owner._id, {
- _id: 1,
- 'splitTests.compile-backend-class-n2d': 1,
- })
- const backendClassHistory =
- owner.splitTests?.['compile-backend-class-n2d'] || []
- const backendClassBaselineVariant = backendClassHistory.find(
- version => {
- return version.versionNumber === 8
- }
- )?.variantName
- const timeoutEnforcedCutoff =
- backendClassBaselineVariant === 'default'
- ? NEW_COMPILE_TIMEOUT_ENFORCED_CUTOFF_DEFAULT_BASELINE
- : NEW_COMPILE_TIMEOUT_ENFORCED_CUTOFF
- if (project.owner.signUpDate > timeoutEnforcedCutoff) {
- // New users will see a 10s warning and compile fail at 20s
- project.showNewCompileTimeoutUI = 'active'
- } else {
- const existingUserTimeoutAssignment =
- await SplitTestHandler.promises.getAssignmentForUser(
- project.owner._id,
- 'compile-timeout-20s-existing-users'
- )
- if (existingUserTimeoutAssignment?.variant === '20s') {
- // Older users in treatment see 10s warning and compile fail at 20s
- project.showNewCompileTimeoutUI = 'active'
- } else {
- // Older users in control aren't limited to 20s, but will see a notice of upcoming changes if compile >20s
- project.showNewCompileTimeoutUI = 'changing'
- }
- }
- }
- }
- }
// Hide sensitive data if the user is restricted
if (isRestrictedUser) {
project.owner = { _id: project.owner._id }
diff --git a/services/web/config/settings.defaults.js b/services/web/config/settings.defaults.js
index 956beb62c2..5dfa6b59b6 100644
--- a/services/web/config/settings.defaults.js
+++ b/services/web/config/settings.defaults.js
@@ -272,7 +272,6 @@ module.exports = {
url: `http://${process.env.CLSI_HOST || 'localhost'}:3013`,
// url: "http://#{process.env['CLSI_LB_HOST']}:3014"
backendGroupName: undefined,
- defaultBackendClass: process.env.CLSI_DEFAULT_BACKEND_CLASS || 'e2',
submissionBackendClass:
process.env.CLSI_SUBMISSION_BACKEND_CLASS || 'n2d',
},
diff --git a/services/web/frontend/extracted-translations.json b/services/web/frontend/extracted-translations.json
index 4834acde80..0551e10657 100644
--- a/services/web/frontend/extracted-translations.json
+++ b/services/web/frontend/extracted-translations.json
@@ -70,11 +70,9 @@
"also": "",
"an_email_has_already_been_sent_to": "",
"an_error_occurred_when_verifying_the_coupon_code": "",
- "and_you_can_upgrade_for_plenty_more_compile_time": "",
"anonymous": "",
"anyone_with_link_can_edit": "",
"anyone_with_link_can_view": "",
- "approaching_compile_timeout_limit_upgrade_for_more_compile_time": "",
"archive": "",
"archive_projects": "",
"archived": "",
@@ -86,7 +84,6 @@
"are_you_sure": "",
"ask_proj_owner_to_unlink_from_current_github": "",
"ask_proj_owner_to_upgrade_for_full_history": "",
- "ask_proj_owner_to_upgrade_for_longer_compiles": "",
"ask_proj_owner_to_upgrade_for_references_search": "",
"ask_repo_owner_to_reconnect": "",
"ask_repo_owner_to_renew_overleaf_subscription": "",
@@ -192,7 +189,6 @@
"compile_mode": "",
"compile_terminated_by_user": "",
"compiler": "",
- "compiles_on_our_free_plan_are_now_on_faster_servers": "",
"compiling": "",
"configure_sso": "",
"confirm": "",
@@ -285,7 +281,6 @@
"disabling": "",
"disconnected": "",
"discount_of": "",
- "dismiss": "",
"dismiss_error_popup": "",
"display_deleted_user": "",
"do_you_want_to_change_your_primary_email_address_to": "",
@@ -386,11 +381,6 @@
"failed_to_send_managed_user_invite_to_email": "",
"failed_to_send_sso_link_invite_to_email": "",
"fast": "",
- "faster_compiles_feedback_question": "",
- "faster_compiles_feedback_seems_faster": "",
- "faster_compiles_feedback_seems_same": "",
- "faster_compiles_feedback_seems_slower": "",
- "faster_compiles_feedback_thanks": "",
"file_action_created": "",
"file_action_deleted": "",
"file_action_edited": "",
@@ -426,7 +416,6 @@
"found_matching_deleted_users": "",
"free_7_day_trial_billed_annually": "",
"free_7_day_trial_billed_monthly": "",
- "free_accounts_have_timeout_upgrade_to_increase": "",
"free_plan_label": "",
"free_plan_tooltip": "",
"from_another_project": "",
@@ -918,7 +907,6 @@
"please_wait": "",
"plus_additional_collaborators_document_history_track_changes_and_more": "",
"plus_more": "",
- "plus_upgraded_accounts_receive": "",
"postal_code": "",
"premium_feature": "",
"premium_plan_label": "",
@@ -980,7 +968,6 @@
"react_history_tutorial_content": "",
"react_history_tutorial_title": "",
"reactivate_subscription": "",
- "read_more_about_fix_prevent_timeout": "",
"read_more_about_free_compile_timeouts_servers": "",
"read_only": "",
"read_only_token": "",
@@ -1292,7 +1279,6 @@
"tc_switch_guests_tip": "",
"tc_switch_user_tip": "",
"tell_the_project_owner_and_ask_them_to_upgrade": "",
- "tell_the_project_owner_to_upgrade_plan_for_more_compile_time": "",
"template_approved_by_publisher": "",
"template_description": "",
"template_title_taken_from_project_title": "",
@@ -1322,7 +1308,6 @@
"this_could_be_because_we_cant_support_some_elements_of_the_table": "",
"this_field_is_required": "",
"this_grants_access_to_features_2": "",
- "this_project_compiled_but_soon_might_not": "",
"this_project_exceeded_compile_timeout_limit_on_free_plan": "",
"this_project_is_public": "",
"this_project_is_public_read_only": "",
@@ -1464,8 +1449,6 @@
"upgrade": "",
"upgrade_cc_btn": "",
"upgrade_for_12x_more_compile_time": "",
- "upgrade_for_longer_compiles": "",
- "upgrade_for_plenty_more_compile_time": "",
"upgrade_now": "",
"upgrade_to_get_feature": "",
"upgrade_to_track_changes": "",
@@ -1519,8 +1502,6 @@
"we_sent_new_code": "",
"wed_love_you_to_stay": "",
"welcome_to_sl": "",
- "were_in_the_process_of_reducing_compile_timeout_which_may_affect_this_project": "",
- "were_in_the_process_of_reducing_compile_timeout_which_may_affect_your_project": "",
"were_performing_maintenance": "",
"weve_recently_reduced_the_compile_timeout_limit_which_may_have_affected_this_project": "",
"weve_recently_reduced_the_compile_timeout_limit_which_may_have_affected_your_project": "",
@@ -1571,7 +1552,6 @@
"you_have_been_invited_to_transfer_management_of_your_account": "",
"you_have_been_invited_to_transfer_management_of_your_account_to": "",
"you_have_been_removed_from_this_project_and_will_be_redirected_to_project_dashboard": "",
- "you_may_be_able_to_fix_issues_to_speed_up_the_compile": "",
"you_need_to_configure_your_sso_settings": "",
"you_will_be_able_to_reassign_subscription": "",
"youll_get_best_results_in_visual_but_can_be_used_in_source": "",
@@ -1591,7 +1571,6 @@
"your_new_plan": "",
"your_plan": "",
"your_plan_is_changing_at_term_end": "",
- "your_project_compiled_but_soon_might_not": "",
"your_project_exceeded_compile_timeout_limit_on_free_plan": "",
"your_project_near_compile_timeout_limit": "",
"your_projects": "",
diff --git a/services/web/frontend/js/features/pdf-preview/components/compile-timeout-warning.tsx b/services/web/frontend/js/features/pdf-preview/components/compile-time-warning-upgrade-prompt-inner.tsx
similarity index 74%
rename from services/web/frontend/js/features/pdf-preview/components/compile-timeout-warning.tsx
rename to services/web/frontend/js/features/pdf-preview/components/compile-time-warning-upgrade-prompt-inner.tsx
index 3ab2a235e5..0e957c9b6e 100644
--- a/services/web/frontend/js/features/pdf-preview/components/compile-timeout-warning.tsx
+++ b/services/web/frontend/js/features/pdf-preview/components/compile-time-warning-upgrade-prompt-inner.tsx
@@ -4,10 +4,9 @@ import { useTranslation } from 'react-i18next'
import { FC } from 'react'
import { useSplitTestContext } from '@/shared/context/split-test-context'
-export const CompileTimeoutWarning: FC<{
+export const CompileTimeWarningUpgradePromptInner: FC<{
handleDismissWarning: () => void
- showNewCompileTimeoutUI?: string
-}> = ({ handleDismissWarning, showNewCompileTimeoutUI }) => {
+}> = ({ handleDismissWarning }) => {
const { t } = useTranslation()
const { splitTestVariants } = useSplitTestContext()
@@ -34,14 +33,8 @@ export const CompileTimeoutWarning: FC<{
{t('your_project_near_compile_timeout_limit')}
- {showNewCompileTimeoutUI === 'active' ? (
- <>
- {t('upgrade_for_12x_more_compile_time')}
- {'. '}
- >
- ) : (
- {t('upgrade_for_plenty_more_compile_time')}
- )}
+ {t('upgrade_for_12x_more_compile_time')}
+ {'. '}
}
type="warning"
diff --git a/services/web/frontend/js/features/pdf-preview/components/compile-time-warning-upgrade-prompt.tsx b/services/web/frontend/js/features/pdf-preview/components/compile-time-warning-upgrade-prompt.tsx
new file mode 100644
index 0000000000..d4dd317ae6
--- /dev/null
+++ b/services/web/frontend/js/features/pdf-preview/components/compile-time-warning-upgrade-prompt.tsx
@@ -0,0 +1,78 @@
+import { memo, useCallback, useEffect, useState } from 'react'
+import * as eventTracking from '@/infrastructure/event-tracking'
+import { useDetachCompileContext } from '@/shared/context/detach-compile-context'
+import usePersistedState from '@/shared/hooks/use-persisted-state'
+import { CompileTimeWarningUpgradePromptInner } from '@/features/pdf-preview/components/compile-time-warning-upgrade-prompt-inner'
+
+function CompileTimeWarningUpgradePrompt() {
+ const { isProjectOwner, deliveryLatencies, compiling, showLogs, error } =
+ useDetachCompileContext()
+
+ const [showWarning, setShowWarning] = useState(false)
+ const [dismissedUntilWarning, setDismissedUntilWarning] = usePersistedState<
+ Date | undefined
+ >(`has-dismissed-10s-compile-time-warning-until`)
+
+ const handleNewCompile = useCallback(
+ compileTime => {
+ setShowWarning(false)
+ if (compileTime > 10000) {
+ if (isProjectOwner) {
+ if (
+ !dismissedUntilWarning ||
+ new Date(dismissedUntilWarning) < new Date()
+ ) {
+ setShowWarning(true)
+ eventTracking.sendMB('compile-time-warning-displayed', {
+ time: 10,
+ isProjectOwner,
+ })
+ }
+ }
+ }
+ },
+ [isProjectOwner, dismissedUntilWarning]
+ )
+
+ const handleDismissWarning = useCallback(() => {
+ eventTracking.sendMB('compile-time-warning-dismissed', {
+ time: 10,
+ isProjectOwner,
+ })
+ setShowWarning(false)
+ const until = new Date()
+ until.setDate(until.getDate() + 1) // 1 day
+ setDismissedUntilWarning(until)
+ }, [isProjectOwner, setDismissedUntilWarning])
+
+ useEffect(() => {
+ if (compiling || error || showLogs) return
+ handleNewCompile(deliveryLatencies.compileTimeServerE2E)
+ }, [compiling, error, showLogs, deliveryLatencies, handleNewCompile])
+
+ if (!window.ExposedSettings.enableSubscriptions) {
+ return null
+ }
+
+ if (compiling || error || showLogs) {
+ return null
+ }
+
+ if (!showWarning) {
+ return null
+ }
+
+ // if showWarning is true then the 10s warning is shown
+
+ return (
+
+ {showWarning && isProjectOwner && (
+
+ )}
+
+ )
+}
+
+export default memo(CompileTimeWarningUpgradePrompt)
diff --git a/services/web/frontend/js/features/pdf-preview/components/compile-time-warning.tsx b/services/web/frontend/js/features/pdf-preview/components/compile-time-warning.tsx
deleted file mode 100644
index 4f3ea2a23b..0000000000
--- a/services/web/frontend/js/features/pdf-preview/components/compile-time-warning.tsx
+++ /dev/null
@@ -1,116 +0,0 @@
-import { memo, useCallback, useEffect } from 'react'
-import { Button } from 'react-bootstrap'
-import { Trans, useTranslation } from 'react-i18next'
-import * as eventTracking from '../../../infrastructure/event-tracking'
-import StartFreeTrialButton from '../../../shared/components/start-free-trial-button'
-import { useDetachCompileContext } from '../../../shared/context/detach-compile-context'
-import usePersistedState from '../../../shared/hooks/use-persisted-state'
-import { useSplitTestContext } from '@/shared/context/split-test-context'
-
-const TWENTY_FOUR_DAYS = 24 * 60 * 60 * 24 * 1000
-
-function CompileTimeWarning() {
- const { t } = useTranslation()
-
- const [displayStatus, setDisplayStatus] = usePersistedState(
- 'compile-time-warning-display-status',
- { lastDisplayTime: 0, dismissed: false },
- true
- )
-
- const {
- showCompileTimeWarning,
- setShowCompileTimeWarning,
- deliveryLatencies,
- isProjectOwner,
- } = useDetachCompileContext()
-
- const { splitTestVariants } = useSplitTestContext()
- const hasNewPaywallCta = splitTestVariants['paywall-cta'] === 'enabled'
-
- useEffect(() => {
- if (deliveryLatencies && deliveryLatencies.compileTimeServerE2E) {
- // compile-timeout-20s test
- if (deliveryLatencies.compileTimeServerE2E > 10000) {
- eventTracking.sendMB('compile-time-warning-would-display', {
- time: 10,
- newCompileTimeout: 'control',
- isProjectOwner,
- })
- }
- }
- }, [deliveryLatencies, isProjectOwner])
-
- useEffect(() => {
- if (showCompileTimeWarning) {
- if (
- displayStatus &&
- Date.now() - displayStatus.lastDisplayTime < TWENTY_FOUR_DAYS
- ) {
- return
- }
- setDisplayStatus({ lastDisplayTime: Date.now(), dismissed: false })
- eventTracking.sendMB('compile-time-warning-displayed', { time: 30 })
- }
- }, [showCompileTimeWarning, displayStatus, setDisplayStatus])
-
- const getTimeSinceDisplayed = useCallback(() => {
- return (Date.now() - displayStatus.lastDisplayTime) / 1000
- }, [displayStatus])
-
- const closeWarning = useCallback(() => {
- eventTracking.sendMB('compile-time-warning-dismissed', {
- 'time-since-displayed': getTimeSinceDisplayed(),
- time: 30,
- })
- setShowCompileTimeWarning(false)
- setDisplayStatus(displayStatus => ({ ...displayStatus, dismissed: true }))
- }, [getTimeSinceDisplayed, setShowCompileTimeWarning, setDisplayStatus])
-
- const handleUpgradeClick = useCallback(() => {
- eventTracking.sendMB('compile-time-warning-upgrade-click', {
- 'time-since-displayed': getTimeSinceDisplayed(),
- time: 30,
- })
- setShowCompileTimeWarning(false)
- setDisplayStatus(displayStatus => ({ ...displayStatus, dismissed: true }))
- }, [getTimeSinceDisplayed, setShowCompileTimeWarning, setDisplayStatus])
-
- if (!showCompileTimeWarning || displayStatus.dismissed) {
- return null
- }
-
- return (
-
-
-
-
- ,
- }}
- />
-
-
-
- {hasNewPaywallCta ? t('get_more_compile_time') : t('upgrade')}
-
-
-
-
- )
-}
-
-export default memo(CompileTimeWarning)
diff --git a/services/web/frontend/js/features/pdf-preview/components/compile-timeout-changing-soon.tsx b/services/web/frontend/js/features/pdf-preview/components/compile-timeout-changing-soon.tsx
deleted file mode 100644
index 9ca3135991..0000000000
--- a/services/web/frontend/js/features/pdf-preview/components/compile-timeout-changing-soon.tsx
+++ /dev/null
@@ -1,122 +0,0 @@
-import Notification from '@/shared/components/notification'
-import StartFreeTrialButton from '@/shared/components/start-free-trial-button'
-import { Trans, useTranslation } from 'react-i18next'
-import * as eventTracking from '@/infrastructure/event-tracking'
-import { FC } from 'react'
-import { useSplitTestContext } from '@/shared/context/split-test-context'
-
-const sendInfoClickEvent = () => {
- eventTracking.sendMB('paywall-info-click', {
- 'paywall-type': 'compile-time-warning',
- content: 'blog',
- })
-}
-
-export const CompileTimeoutChangingSoon: FC<{
- isProjectOwner?: boolean
- handleDismissChangingSoon: () => void
-}> = ({ isProjectOwner = false, handleDismissChangingSoon }) => {
- const { t } = useTranslation()
-
- const { splitTestVariants } = useSplitTestContext()
- const hasNewPaywallCta = splitTestVariants['paywall-cta'] === 'enabled'
-
- const compileTimeoutChangesBlogLink = (
- /* eslint-disable-next-line jsx-a11y/anchor-has-content */
-
- )
-
- const fixingCompileTimeoutsLearnLink = (
- /* eslint-disable-next-line jsx-a11y/anchor-has-content */
-
- )
-
- if (isProjectOwner) {
- return (
-
- {hasNewPaywallCta
- ? t('get_more_compile_time')
- : t('start_free_trial_without_exclamation')}
-
- }
- ariaLive="polite"
- content={
-
-
-
-
-
- {' '}
- }}
- />
-
-
- }
- title={t('your_project_compiled_but_soon_might_not')}
- type="warning"
- isActionBelowContent
- isDismissible
- onDismiss={handleDismissChangingSoon}
- />
- )
- }
-
- return (
-
-
- {' '}
-
-
-
- }}
- />
-
-
- }
- title={t('this_project_compiled_but_soon_might_not')}
- type="warning"
- isDismissible
- onDismiss={handleDismissChangingSoon}
- />
- )
-}
diff --git a/services/web/frontend/js/features/pdf-preview/components/compile-timeout-messages.tsx b/services/web/frontend/js/features/pdf-preview/components/compile-timeout-messages.tsx
deleted file mode 100644
index fcb939a549..0000000000
--- a/services/web/frontend/js/features/pdf-preview/components/compile-timeout-messages.tsx
+++ /dev/null
@@ -1,126 +0,0 @@
-import { memo, useCallback, useEffect, useMemo, useState } from 'react'
-import * as eventTracking from '@/infrastructure/event-tracking'
-import { useDetachCompileContext } from '@/shared/context/detach-compile-context'
-import usePersistedState from '@/shared/hooks/use-persisted-state'
-import { CompileTimeoutWarning } from '@/features/pdf-preview/components/compile-timeout-warning'
-import { CompileTimeoutChangingSoon } from '@/features/pdf-preview/components/compile-timeout-changing-soon'
-
-function CompileTimeoutMessages() {
- const {
- showNewCompileTimeoutUI,
- isProjectOwner,
- deliveryLatencies,
- compiling,
- showLogs,
- error,
- } = useDetachCompileContext()
-
- const [showWarning, setShowWarning] = useState(false)
- const [showChangingSoon, setShowChangingSoon] = useState(false)
- const [dismissedUntilWarning, setDismissedUntilWarning] = usePersistedState<
- Date | undefined
- >(`has-dismissed-10s-compile-time-warning-until`)
-
- const segmentation = useMemo(() => {
- return {
- newCompileTimeout: showNewCompileTimeoutUI,
- isProjectOwner,
- }
- }, [showNewCompileTimeoutUI, isProjectOwner])
-
- const handleNewCompile = useCallback(
- compileTime => {
- setShowWarning(false)
- setShowChangingSoon(false)
- if (compileTime > 20000) {
- if (showNewCompileTimeoutUI === 'changing') {
- setShowChangingSoon(true)
- eventTracking.sendMB('compile-time-warning-displayed', {
- time: 20,
- ...segmentation,
- })
- }
- } else if (compileTime > 10000) {
- setShowChangingSoon(false)
- if (
- (isProjectOwner && showNewCompileTimeoutUI === 'active') ||
- showNewCompileTimeoutUI === 'changing'
- ) {
- if (
- !dismissedUntilWarning ||
- new Date(dismissedUntilWarning) < new Date()
- ) {
- setShowWarning(true)
- eventTracking.sendMB('compile-time-warning-displayed', {
- time: 10,
- ...segmentation,
- })
- }
- }
- }
- },
- [
- isProjectOwner,
- showNewCompileTimeoutUI,
- dismissedUntilWarning,
- segmentation,
- ]
- )
-
- const handleDismissWarning = useCallback(() => {
- eventTracking.sendMB('compile-time-warning-dismissed', {
- time: 10,
- ...segmentation,
- })
- setShowWarning(false)
- const until = new Date()
- until.setDate(until.getDate() + 1) // 1 day
- setDismissedUntilWarning(until)
- }, [setDismissedUntilWarning, segmentation])
-
- const handleDismissChangingSoon = useCallback(() => {
- eventTracking.sendMB('compile-time-warning-dismissed', {
- time: 20,
- ...segmentation,
- })
- }, [segmentation])
-
- useEffect(() => {
- if (compiling || error || showLogs) return
- handleNewCompile(deliveryLatencies.compileTimeServerE2E)
- }, [compiling, error, showLogs, deliveryLatencies, handleNewCompile])
-
- if (!window.ExposedSettings.enableSubscriptions) {
- return null
- }
-
- if (compiling || error || showLogs) {
- return null
- }
-
- if (!showWarning && !showChangingSoon) {
- return null
- }
-
- // if showWarning is true then the 10s warning is shown
- // and if showChangingSoon is true then the 20s-60s should show
-
- return (
-
- {showWarning && isProjectOwner && (
-
- )}
- {showChangingSoon && (
-
- )}
-
- )
-}
-
-export default memo(CompileTimeoutMessages)
diff --git a/services/web/frontend/js/features/pdf-preview/components/faster-compiles-feedback.tsx b/services/web/frontend/js/features/pdf-preview/components/faster-compiles-feedback.tsx
deleted file mode 100644
index da89efc4d4..0000000000
--- a/services/web/frontend/js/features/pdf-preview/components/faster-compiles-feedback.tsx
+++ /dev/null
@@ -1,135 +0,0 @@
-import { memo, useEffect, useRef, useState } from 'react'
-import { Button, Alert } from 'react-bootstrap'
-import { useTranslation } from 'react-i18next'
-import Icon from '../../../shared/components/icon'
-import { sendMB } from '../../../infrastructure/event-tracking'
-import usePersistedState from '../../../shared/hooks/use-persisted-state'
-import { useDetachCompileContext as useCompileContext } from '../../../shared/context/detach-compile-context'
-import { useProjectContext } from '../../../shared/context/project-context'
-
-const SAY_THANKS_TIMEOUT = 10 * 1000
-
-function FasterCompilesFeedbackContent() {
- const { clsiServerId, deliveryLatencies, pdfFile, pdfUrl } =
- useCompileContext()
- const { _id: projectId } = useProjectContext()
-
- const [incrementalCompiles, setIncrementalCompiles] = useState(0)
- const [hasRatedProject, setHasRatedProject] = usePersistedState(
- `faster-compiles-feedback:${projectId}`,
- false,
- true
- )
- const [dismiss, setDismiss] = usePersistedState(
- 'faster-compiles-feedback:dismiss',
- false,
- true
- )
- const [sayThanks, setSayThanks] = useState(false)
- const lastClsiServerId = useRef(undefined)
- const lastPdfUrl = useRef(undefined)
-
- useEffect(() => {
- if (
- !pdfUrl ||
- !lastPdfUrl.current ||
- clsiServerId !== lastClsiServerId.current
- ) {
- // Reset history after
- // - clearing cache / server error (both reset pdfUrl)
- // - initial compile after reset of pdfUrl
- // - switching the clsi server, aka we get a _slow_ full compile.
- setIncrementalCompiles(0)
- lastClsiServerId.current = clsiServerId
- } else {
- setIncrementalCompiles(n => n + 1)
- }
- lastPdfUrl.current = pdfUrl
- }, [clsiServerId, lastPdfUrl, pdfUrl, setIncrementalCompiles])
-
- function submitFeedback(feedback = '') {
- sendMB('faster-compiles-feedback', {
- projectId,
- server: clsiServerId?.includes('-c2d-') ? 'faster' : 'normal',
- feedback,
- pdfSize: pdfFile?.size,
- ...deliveryLatencies,
- })
- setHasRatedProject(true)
- setSayThanks(true)
- window.setTimeout(() => {
- setSayThanks(false)
- }, SAY_THANKS_TIMEOUT)
- }
-
- function dismissFeedback() {
- sendMB('faster-compiles-feedback-dismiss')
- setDismiss(true)
- }
-
- const { t } = useTranslation()
-
- // Hide the feedback prompt in all these cases:
- // - the initial compile (0), its always perceived as _slow_.
- // - the first incremental compile (1), its always _faster_ than ^.
- // - the user has dismissed the prompt
- // - the user has rated compile speed already (say thanks if needed)
- switch (true) {
- case sayThanks:
- return (
- setSayThanks(false)}
- >
- {t('faster_compiles_feedback_thanks')}
-
- )
- case dismiss || hasRatedProject:
- return null
- case incrementalCompiles > 1:
- return (
-
-
- {t('faster_compiles_feedback_question')}
-
- {['slower', 'same', 'faster'].map(feedback => (
-
- ))}
-
-
- )
- default:
- return null
- }
-}
-
-function FasterCompilesFeedback() {
- const { showFasterCompilesFeedbackUI } = useCompileContext()
-
- if (!showFasterCompilesFeedbackUI) {
- return null
- }
- return
-}
-
-export default memo(FasterCompilesFeedback)
diff --git a/services/web/frontend/js/features/pdf-preview/components/pdf-logs-viewer.jsx b/services/web/frontend/js/features/pdf-preview/components/pdf-logs-viewer.jsx
index 47e652a143..7996044284 100644
--- a/services/web/frontend/js/features/pdf-preview/components/pdf-logs-viewer.jsx
+++ b/services/web/frontend/js/features/pdf-preview/components/pdf-logs-viewer.jsx
@@ -3,7 +3,6 @@ import { memo } from 'react'
import classnames from 'classnames'
import PdfValidationIssue from './pdf-validation-issue'
import StopOnFirstErrorPrompt from './stop-on-first-error-prompt'
-import TimeoutUpgradePrompt from './timeout-upgrade-prompt'
import TimeoutUpgradePromptNew from './timeout-upgrade-prompt-new'
import PdfPreviewError from './pdf-preview-error'
import PdfClearCacheButton from './pdf-clear-cache-button'
@@ -20,12 +19,12 @@ function PdfLogsViewer() {
const {
codeCheckFailed,
error,
+ hasShortCompileTimeout,
logEntries,
rawLog,
validationIssues,
showLogs,
stoppedOnFirstError,
- showNewCompileTimeoutUI,
} = useCompileContext()
const { loadingError } = usePdfPreviewContext()
@@ -45,13 +44,10 @@ function PdfLogsViewer() {
{loadingError && }
- {showNewCompileTimeoutUI && error === 'timedout' ? (
+ {hasShortCompileTimeout && error === 'timedout' ? (
) : (
- <>
- {error && }
- {error === 'timedout' && }
- >
+ <>{error && }>
)}
{validationIssues &&
diff --git a/services/web/frontend/js/features/pdf-preview/components/pdf-preview-pane.jsx b/services/web/frontend/js/features/pdf-preview/components/pdf-preview-pane.jsx
index 2529309e6b..7a4502efe3 100644
--- a/services/web/frontend/js/features/pdf-preview/components/pdf-preview-pane.jsx
+++ b/services/web/frontend/js/features/pdf-preview/components/pdf-preview-pane.jsx
@@ -5,14 +5,12 @@ import PdfViewer from './pdf-viewer'
import { FullSizeLoadingSpinner } from '../../../shared/components/loading-spinner'
import PdfHybridPreviewToolbar from './pdf-preview-hybrid-toolbar'
import { useDetachCompileContext as useCompileContext } from '../../../shared/context/detach-compile-context'
-import FasterCompilesFeedback from './faster-compiles-feedback'
import { PdfPreviewMessages } from './pdf-preview-messages'
-import CompileTimeWarning from './compile-time-warning'
-import CompileTimeoutMessages from './compile-timeout-messages'
+import CompileTimeWarningUpgradePrompt from './compile-time-warning-upgrade-prompt'
import { PdfPreviewProvider } from './pdf-preview-provider'
function PdfPreviewPane() {
- const { pdfUrl, showNewCompileTimeoutUI } = useCompileContext()
+ const { pdfUrl, hasShortCompileTimeout } = useCompileContext()
const classes = classNames('pdf', 'full-size', {
'pdf-empty': !pdfUrl,
})
@@ -21,16 +19,11 @@ function PdfPreviewPane() {
- {showNewCompileTimeoutUI ? (
-
- ) : (
-
- )}
+ {hasShortCompileTimeout && }
}>
diff --git a/services/web/frontend/js/features/pdf-preview/components/timeout-upgrade-prompt-new.tsx b/services/web/frontend/js/features/pdf-preview/components/timeout-upgrade-prompt-new.tsx
index f46ac9dadc..9999f55ec9 100644
--- a/services/web/frontend/js/features/pdf-preview/components/timeout-upgrade-prompt-new.tsx
+++ b/services/web/frontend/js/features/pdf-preview/components/timeout-upgrade-prompt-new.tsx
@@ -13,7 +13,6 @@ function TimeoutUpgradePromptNew() {
startCompile,
lastCompileOptions,
setAnimateCompileDropdownArrow,
- showNewCompileTimeoutUI,
isProjectOwner,
} = useDetachCompileContext()
@@ -27,35 +26,25 @@ function TimeoutUpgradePromptNew() {
setAnimateCompileDropdownArrow(true)
}, [enableStopOnFirstError, startCompile, setAnimateCompileDropdownArrow])
- if (!window.ExposedSettings.enableSubscriptions) {
- return null
- }
-
- const compileTimeChanging = showNewCompileTimeoutUI === 'changing'
-
return (
<>
-
-
+
+ {window.ExposedSettings.enableSubscriptions && (
+
+ )}
>
)
}
type CompileTimeoutProps = {
- compileTimeChanging?: boolean
isProjectOwner: boolean
}
const CompileTimeout = memo(function CompileTimeout({
- compileTimeChanging,
isProjectOwner,
}: CompileTimeoutProps) {
const { t } = useTranslation()
@@ -67,58 +56,48 @@ const CompileTimeout = memo(function CompileTimeout({
-
- {isProjectOwner
- ? t('your_project_exceeded_compile_timeout_limit_on_free_plan')
- : t('this_project_exceeded_compile_timeout_limit_on_free_plan')}
-
- {isProjectOwner ? (
+ window.ExposedSettings.enableSubscriptions && (
+ <>
- {compileTimeChanging ? (
- <>
- {t('upgrade_for_plenty_more_compile_time')}{' '}
- {t(
- 'plus_additional_collaborators_document_history_track_changes_and_more'
- )}
- >
- ) : (
- <>
- {t('upgrade_for_12x_more_compile_time')}{' '}
- {t(
- 'plus_additional_collaborators_document_history_track_changes_and_more'
- )}
- >
- )}
+ {isProjectOwner
+ ? t('your_project_exceeded_compile_timeout_limit_on_free_plan')
+ : t('this_project_exceeded_compile_timeout_limit_on_free_plan')}
- ) : (
- ,
- ]}
- />
- )}
+ {isProjectOwner ? (
+
+ {t('upgrade_for_12x_more_compile_time')}{' '}
+ {t(
+ 'plus_additional_collaborators_document_history_track_changes_and_more'
+ )}
+
+ ) : (
+ ,
+ ]}
+ />
+ )}
- {isProjectOwner && (
-
-
- {hasNewPaywallCta
- ? t('get_more_compile_time')
- : t('start_a_free_trial')}
-
-
- )}
- >
+ {isProjectOwner && (
+
+
+ {hasNewPaywallCta
+ ? t('get_more_compile_time')
+ : t('start_a_free_trial')}
+
+
+ )}
+ >
+ )
}
// @ts-ignore
entryAriaLabel={t('your_compile_timed_out')}
@@ -128,14 +107,12 @@ const CompileTimeout = memo(function CompileTimeout({
})
type PreventTimeoutHelpMessageProps = {
- compileTimeChanging?: boolean
lastCompileOptions: any
handleEnableStopOnFirstErrorClick: () => void
isProjectOwner: boolean
}
const PreventTimeoutHelpMessage = memo(function PreventTimeoutHelpMessage({
- compileTimeChanging,
lastCompileOptions,
handleEnableStopOnFirstErrorClick,
isProjectOwner,
@@ -227,35 +204,19 @@ const PreventTimeoutHelpMessage = memo(function PreventTimeoutHelpMessage({
- {compileTimeChanging ? (
- <>
- {isProjectOwner ? (
-
- ) : (
-
- )}
- >
- ) : (
- <>
- {isProjectOwner ? (
-
- ) : (
-
- )}
- >
- )}
+ <>
+ {isProjectOwner ? (
+
+ ) : (
+
+ )}
+ >
>
diff --git a/services/web/frontend/js/features/pdf-preview/components/timeout-upgrade-prompt.jsx b/services/web/frontend/js/features/pdf-preview/components/timeout-upgrade-prompt.jsx
deleted file mode 100644
index 30343a6792..0000000000
--- a/services/web/frontend/js/features/pdf-preview/components/timeout-upgrade-prompt.jsx
+++ /dev/null
@@ -1,62 +0,0 @@
-import { useTranslation } from 'react-i18next'
-import { useEditorContext } from '../../../shared/context/editor-context'
-import StartFreeTrialButton from '../../../shared/components/start-free-trial-button'
-import { memo } from 'react'
-import PdfLogEntry from './pdf-log-entry'
-import UpgradeBenefits from '../../../shared/components/upgrade-benefits'
-import { useSplitTestContext } from '@/shared/context/split-test-context'
-
-function TimeoutUpgradePrompt() {
- const { t } = useTranslation()
-
- const { hasPremiumCompile, isProjectOwner } = useEditorContext()
-
- const { splitTestVariants } = useSplitTestContext()
- const hasNewPaywallCta = splitTestVariants['paywall-cta'] === 'enabled'
-
- if (!window.ExposedSettings.enableSubscriptions || hasPremiumCompile) {
- return null
- }
-
- return (
-
- {t('free_accounts_have_timeout_upgrade_to_increase')}
- {t('plus_upgraded_accounts_receive')}:
-
-
-
- {isProjectOwner && (
-
-
- {hasNewPaywallCta
- ? t('get_more_compile_time')
- : t('start_free_trial')}
-
-
- )}
- >
- }
- entryAriaLabel={
- isProjectOwner
- ? t('upgrade_for_longer_compiles')
- : t('ask_proj_owner_to_upgrade_for_longer_compiles')
- }
- level="success"
- />
- )
-}
-
-export default memo(TimeoutUpgradePrompt)
diff --git a/services/web/frontend/js/features/pdf-preview/util/compiler.js b/services/web/frontend/js/features/pdf-preview/util/compiler.js
index b481625031..6aaf362adc 100644
--- a/services/web/frontend/js/features/pdf-preview/util/compiler.js
+++ b/services/web/frontend/js/features/pdf-preview/util/compiler.js
@@ -221,14 +221,6 @@ export default class DocumentCompiler {
params.file_line_errors = 'true'
}
- // temporary override to force the new compile timeout
- const newCompileTimeoutOverride = new URLSearchParams(
- window.location.search
- ).get('force_new_compile_timeout')
- if (newCompileTimeoutOverride) {
- params.set('force_new_compile_timeout', newCompileTimeoutOverride)
- }
-
return params
}
diff --git a/services/web/frontend/js/shared/context/detach-compile-context.tsx b/services/web/frontend/js/shared/context/detach-compile-context.tsx
index c63a23e29e..e9111300b1 100644
--- a/services/web/frontend/js/shared/context/detach-compile-context.tsx
+++ b/services/web/frontend/js/shared/context/detach-compile-context.tsx
@@ -29,6 +29,7 @@ export const DetachCompileProvider: FC = ({ children }) => {
error: _error,
fileList: _fileList,
hasChanges: _hasChanges,
+ hasShortCompileTimeout: _hasShortCompileTimeout,
highlights: _highlights,
isProjectOwner: _isProjectOwner,
lastCompileOptions: _lastCompileOptions,
@@ -52,8 +53,6 @@ export const DetachCompileProvider: FC = ({ children }) => {
setStopOnValidationError: _setStopOnValidationError,
showLogs: _showLogs,
showCompileTimeWarning: _showCompileTimeWarning,
- showNewCompileTimeoutUI: _showNewCompileTimeoutUI,
- showFasterCompilesFeedbackUI: _showFasterCompilesFeedbackUI,
stopOnFirstError: _stopOnFirstError,
stopOnValidationError: _stopOnValidationError,
stoppedOnFirstError: _stoppedOnFirstError,
@@ -126,6 +125,12 @@ export const DetachCompileProvider: FC = ({ children }) => {
'detacher',
'detached'
)
+ const [hasShortCompileTimeout] = useDetachStateWatcher(
+ 'hasShortCompileTimeout',
+ _hasShortCompileTimeout,
+ 'detacher',
+ 'detached'
+ )
const [highlights] = useDetachStateWatcher(
'highlights',
_highlights,
@@ -192,18 +197,6 @@ export const DetachCompileProvider: FC = ({ children }) => {
'detacher',
'detached'
)
- const [showNewCompileTimeoutUI] = useDetachStateWatcher(
- 'showNewCompileTimeoutUI',
- _showNewCompileTimeoutUI,
- 'detacher',
- 'detached'
- )
- const [showFasterCompilesFeedbackUI] = useDetachStateWatcher(
- 'showFasterCompilesFeedbackUI',
- _showFasterCompilesFeedbackUI,
- 'detacher',
- 'detached'
- )
const [stopOnFirstError] = useDetachStateWatcher(
'stopOnFirstError',
_stopOnFirstError,
@@ -386,6 +379,7 @@ export const DetachCompileProvider: FC = ({ children }) => {
error,
fileList,
hasChanges,
+ hasShortCompileTimeout,
highlights,
isProjectOwner,
lastCompileOptions,
@@ -413,8 +407,6 @@ export const DetachCompileProvider: FC = ({ children }) => {
setStopOnValidationError,
showLogs,
showCompileTimeWarning,
- showNewCompileTimeoutUI,
- showFasterCompilesFeedbackUI,
startCompile,
stopCompile,
stopOnFirstError,
@@ -437,10 +429,11 @@ export const DetachCompileProvider: FC = ({ children }) => {
compiling,
deliveryLatencies,
draft,
- error,
editedSinceCompileStarted,
+ error,
fileList,
hasChanges,
+ hasShortCompileTimeout,
highlights,
isProjectOwner,
lastCompileOptions,
@@ -466,8 +459,6 @@ export const DetachCompileProvider: FC = ({ children }) => {
setStopOnValidationError,
showCompileTimeWarning,
showLogs,
- showNewCompileTimeoutUI,
- showFasterCompilesFeedbackUI,
startCompile,
stopCompile,
stopOnFirstError,
diff --git a/services/web/frontend/js/shared/context/local-compile-context.tsx b/services/web/frontend/js/shared/context/local-compile-context.tsx
index 6fded1ce16..5364be93f4 100644
--- a/services/web/frontend/js/shared/context/local-compile-context.tsx
+++ b/services/web/frontend/js/shared/context/local-compile-context.tsx
@@ -49,6 +49,7 @@ export type CompileContext = {
error?: string
fileList?: Record
hasChanges: boolean
+ hasShortCompileTimeout: boolean
highlights?: Record[]
isProjectOwner: boolean
logEntries?: Record
@@ -72,8 +73,6 @@ export type CompileContext = {
setStopOnValidationError: (value: boolean) => void
showCompileTimeWarning: boolean
showLogs: boolean
- showNewCompileTimeoutUI?: string
- showFasterCompilesFeedbackUI: boolean
stopOnFirstError: boolean
stopOnValidationError: boolean
stoppedOnFirstError: boolean
@@ -103,11 +102,7 @@ export const LocalCompileProvider: FC = ({ children }) => {
const { hasPremiumCompile, isProjectOwner } = useEditorContext()
- const {
- _id: projectId,
- rootDocId,
- showNewCompileTimeoutUI,
- } = useProjectContext()
+ const { _id: projectId, rootDocId } = useProjectContext()
const { pdfPreviewOpen } = useLayoutContext()
@@ -122,6 +117,8 @@ export const LocalCompileProvider: FC = ({ children }) => {
// whether to show the compile time warning
const [showCompileTimeWarning, setShowCompileTimeWarning] = useState(false)
+ const [hasShortCompileTimeout, setHasShortCompileTimeout] = useState(false)
+
// the log entries parsed from the compile output log
const [logEntries, setLogEntries] = useScopeValueSetterOnly('pdf.logEntries')
@@ -182,10 +179,6 @@ export const LocalCompileProvider: FC = ({ children }) => {
// whether the logs should be visible
const [showLogs, setShowLogs] = useState(false)
- // whether the faster compiles feedback UI should be displayed
- const [showFasterCompilesFeedbackUI, setShowFasterCompilesFeedbackUI] =
- useState(false)
-
// whether the compile dropdown arrow should be animated
const [animateCompileDropdownArrow, setAnimateCompileDropdownArrow] =
useState(false)
@@ -332,10 +325,13 @@ export const LocalCompileProvider: FC = ({ children }) => {
}, [compiledOnce, currentDoc, compiler])
useEffect(() => {
- const compileTimeWarningEnabled =
+ setHasShortCompileTimeout(
features?.compileTimeout !== undefined && features.compileTimeout <= 60
+ )
+ }, [features])
- if (compileTimeWarningEnabled && compiling && isProjectOwner) {
+ useEffect(() => {
+ if (hasShortCompileTimeout && compiling && isProjectOwner) {
const timeout = window.setTimeout(() => {
setShowCompileTimeWarning(true)
}, 30000)
@@ -344,7 +340,7 @@ export const LocalCompileProvider: FC = ({ children }) => {
window.clearTimeout(timeout)
}
}
- }, [compiling, isProjectOwner, features])
+ }, [compiling, isProjectOwner, hasShortCompileTimeout])
const { splitTestVariants } = useSplitTestContext()
@@ -358,9 +354,6 @@ export const LocalCompileProvider: FC = ({ children }) => {
if (data.clsiServerId) {
setClsiServerId(data.clsiServerId) // set in scope, for PdfSynctexController
}
- setShowFasterCompilesFeedbackUI(
- Boolean(data.showFasterCompilesFeedbackUI)
- )
if (data.outputFiles) {
const outputFiles = new Map()
@@ -606,6 +599,7 @@ export const LocalCompileProvider: FC = ({ children }) => {
error,
fileList,
hasChanges,
+ hasShortCompileTimeout,
highlights,
isProjectOwner,
lastCompileOptions,
@@ -633,8 +627,6 @@ export const LocalCompileProvider: FC = ({ children }) => {
setStopOnFirstError,
setStopOnValidationError,
showLogs,
- showNewCompileTimeoutUI,
- showFasterCompilesFeedbackUI,
startCompile,
stopCompile,
stopOnFirstError,
@@ -661,6 +653,7 @@ export const LocalCompileProvider: FC = ({ children }) => {
error,
fileList,
hasChanges,
+ hasShortCompileTimeout,
highlights,
isProjectOwner,
lastCompileOptions,
@@ -683,8 +676,6 @@ export const LocalCompileProvider: FC = ({ children }) => {
setStopOnValidationError,
showCompileTimeWarning,
showLogs,
- showNewCompileTimeoutUI,
- showFasterCompilesFeedbackUI,
startCompile,
stopCompile,
stopOnFirstError,
diff --git a/services/web/frontend/js/shared/context/project-context.tsx b/services/web/frontend/js/shared/context/project-context.tsx
index f016bc54b4..58f5398906 100644
--- a/services/web/frontend/js/shared/context/project-context.tsx
+++ b/services/web/frontend/js/shared/context/project-context.tsx
@@ -30,7 +30,6 @@ const ProjectContext = createContext<
_id: UserId
email: string
}
- showNewCompileTimeoutUI?: string
tags: {
_id: string
name: string
@@ -74,7 +73,6 @@ export const ProjectProvider: FC = ({ children }) => {
features,
publicAccesLevel: publicAccessLevel,
owner,
- showNewCompileTimeoutUI,
trackChangesState,
} = project || projectFallback
@@ -86,17 +84,6 @@ export const ProjectProvider: FC = ({ children }) => {
[]
)
- // temporary override for new compile timeout
- const forceNewCompileTimeout = new URLSearchParams(
- window.location.search
- ).get('force_new_compile_timeout')
- const newCompileTimeoutOverride =
- forceNewCompileTimeout === 'active'
- ? 'active'
- : forceNewCompileTimeout === 'changing'
- ? 'changing'
- : undefined
-
const value = useMemo(() => {
return {
_id,
@@ -107,8 +94,6 @@ export const ProjectProvider: FC = ({ children }) => {
features,
publicAccessLevel,
owner,
- showNewCompileTimeoutUI:
- newCompileTimeoutOverride || showNewCompileTimeoutUI,
tags,
trackChangesState,
}
@@ -121,8 +106,6 @@ export const ProjectProvider: FC = ({ children }) => {
features,
publicAccessLevel,
owner,
- showNewCompileTimeoutUI,
- newCompileTimeoutOverride,
tags,
trackChangesState,
])
diff --git a/services/web/frontend/stories/pdf-preview-messages.stories.jsx b/services/web/frontend/stories/pdf-preview-messages.stories.jsx
index a857e61a05..b25b9d121b 100644
--- a/services/web/frontend/stories/pdf-preview-messages.stories.jsx
+++ b/services/web/frontend/stories/pdf-preview-messages.stories.jsx
@@ -2,7 +2,7 @@ import { ScopeDecorator } from './decorators/scope'
import { useLocalCompileContext } from '../js/shared/context/local-compile-context'
import { useEffect } from 'react'
import { PdfPreviewMessages } from '../js/features/pdf-preview/components/pdf-preview-messages'
-import CompileTimeWarning from '../js/features/pdf-preview/components/compile-time-warning'
+import CompileTimeWarningUpgradePrompt from '@/features/pdf-preview/components/compile-time-warning-upgrade-prompt'
export default {
title: 'Editor / PDF Preview / Messages',
@@ -20,7 +20,7 @@ export const Dismissible = () => {
return (
)
diff --git a/services/web/frontend/stories/pdf-preview-messages.stories.tsx b/services/web/frontend/stories/pdf-preview-messages.stories.tsx
index 87c0a49a2e..d04c8ff67a 100644
--- a/services/web/frontend/stories/pdf-preview-messages.stories.tsx
+++ b/services/web/frontend/stories/pdf-preview-messages.stories.tsx
@@ -1,10 +1,6 @@
-import { useEffect } from 'react'
import { ScopeDecorator } from './decorators/scope'
-import { useLocalCompileContext } from '@/shared/context/local-compile-context'
import { PdfPreviewMessages } from '@/features/pdf-preview/components/pdf-preview-messages'
-import CompileTimeWarning from '@/features/pdf-preview/components/compile-time-warning'
-import { CompileTimeoutChangingSoon } from '@/features/pdf-preview/components/compile-timeout-changing-soon'
-import { CompileTimeoutWarning } from '@/features/pdf-preview/components/compile-timeout-warning'
+import { CompileTimeWarningUpgradePromptInner } from '@/features/pdf-preview/components/compile-time-warning-upgrade-prompt-inner'
export default {
title: 'Editor / PDF Preview / Messages',
@@ -21,40 +17,9 @@ export default {
],
}
-export const CompileTime = () => {
- const { setShowCompileTimeWarning } = useLocalCompileContext()
-
- useEffect(() => {
- setShowCompileTimeWarning(true)
- }, [setShowCompileTimeWarning])
-
- return
-}
-
-export const CompileTimeoutChangingSoonNotProjectOwner = (args: any) => {
- return
-}
-CompileTimeoutChangingSoonNotProjectOwner.argTypes = {
- handleDismissChangingSoon: { action: 'dismiss changing soon' },
-}
-
-export const CompileTimeoutChangingSoonProjectOwner = (args: any) => {
- return
-}
-CompileTimeoutChangingSoonProjectOwner.argTypes = {
- handleDismissChangingSoon: { action: 'dismiss changing soon' },
-}
-
export const CompileTimeoutWarningActive = (args: any) => {
- return
+ return
}
CompileTimeoutWarningActive.argTypes = {
handleDismissWarning: { action: 'dismiss warning' },
}
-
-export const CompileTimeoutWarningChanging = (args: any) => {
- return
-}
-CompileTimeoutWarningChanging.argTypes = {
- handleDismissWarning: { action: 'dismiss warning' },
-}
diff --git a/services/web/locales/en.json b/services/web/locales/en.json
index 63b774346b..fd2b886c25 100644
--- a/services/web/locales/en.json
+++ b/services/web/locales/en.json
@@ -106,7 +106,6 @@
"an_email_has_already_been_sent_to": "An email has already been sent to <0>__email__0>. Please wait and try again later.",
"an_error_occurred_when_verifying_the_coupon_code": "An error occurred when verifying the coupon code",
"and": "and",
- "and_you_can_upgrade_for_plenty_more_compile_time": "And you can upgrade to get plenty more compile time.",
"annual": "Annual",
"annual_billing_enabled": "Annual billing enabled",
"anonymous": "Anonymous",
@@ -115,7 +114,6 @@
"app_on_x": "__appName__ on __social__",
"apply_educational_discount": "Apply educational discount",
"apply_educational_discount_info": "Overleaf offers a 40% educational discount for groups of 10 or more. Applies to students or faculty using Overleaf for teaching.",
- "approaching_compile_timeout_limit_upgrade_for_more_compile_time": "You are approaching your compile timeout limit. Upgrade to Overleaf Premium for <0>4x more0> compile time.",
"april": "April",
"archive": "Archive",
"archive_projects": "Archive Projects",
@@ -132,7 +130,6 @@
"ascending": "Ascending",
"ask_proj_owner_to_unlink_from_current_github": "Ask the owner of the project (<0>__projectOwnerEmail__0>) to unlink the project from the current GitHub repository and create a connection to a different repository.",
"ask_proj_owner_to_upgrade_for_full_history": "Please ask the project owner to upgrade to access this project’s full history.",
- "ask_proj_owner_to_upgrade_for_longer_compiles": "Please ask the project owner to upgrade to increase the timeout limit.",
"ask_proj_owner_to_upgrade_for_references_search": "Please ask the project owner to upgrade to use the References Search feature.",
"ask_repo_owner_to_reconnect": "Ask the GitHub repository owner (<0>__repoOwnerEmail__0>) to reconnect the project.",
"ask_repo_owner_to_renew_overleaf_subscription": "Ask the GitHub repository owner (<0>__repoOwnerEmail__0>) to renew their __appName__ subscription and reconnect the project.",
@@ -293,7 +290,6 @@
"compile_timeout_short": "Compile timeout",
"compile_timeout_short_info_basic": "This is how much time you get to compile your project on the Overleaf servers. You may need additional time for longer or more complex projects.",
"compiler": "Compiler",
- "compiles_on_our_free_plan_are_now_on_faster_servers": "Compiles on our free plan are now on faster servers, and we’re gradually <0>introducing a shorter compile timeout limit0>. This project currently exceeds the new limit, so it might not compile in future.",
"compiling": "Compiling",
"complete": "Complete",
"compliance": "Compliance",
@@ -420,7 +416,6 @@
"disabling": "Disabling",
"disconnected": "Disconnected",
"discount_of": "Discount of __amount__",
- "dismiss": "Dismiss",
"dismiss_error_popup": "Dismiss first error alert",
"display_deleted_user": "Display deleted users",
"do_not_have_acct_or_do_not_want_to_link": "If you don’t have an __appName__ account, or if you don’t want to link to your __institutionName__ account, please click __clickText__.",
@@ -579,11 +574,6 @@
"faq_what_is_the_difference_between_users_and_collaborators_answer_second_paragraph": "In other words, collaborators are just other Overleaf users that you are working with on one of your projects.",
"faq_what_is_the_difference_between_users_and_collaborators_question": "What’s the difference between users and collaborators?",
"fast": "Fast",
- "faster_compiles_feedback_question": "Was this compile different than usual?",
- "faster_compiles_feedback_seems_faster": "Faster",
- "faster_compiles_feedback_seems_same": "Same",
- "faster_compiles_feedback_seems_slower": "Slower",
- "faster_compiles_feedback_thanks": "Thanks for the feedback!",
"fastest": "Fastest",
"feature_included": "Feature included",
"feature_not_included": "Feature not included",
@@ -650,7 +640,6 @@
"free": "Free",
"free_7_day_trial_billed_annually": "Free 7-day trial, then billed annually",
"free_7_day_trial_billed_monthly": "Free 7-day trial, then billed monthly",
- "free_accounts_have_timeout_upgrade_to_increase": "Free accounts have a one minute timeout, whereas upgraded accounts have a timeout of four minutes.",
"free_dropbox_and_history": "Free Dropbox and History",
"free_plan_label": "You’re on the free plan",
"free_plan_tooltip": "Click to find out how you could benefit from Overleaf premium features.",
@@ -1371,7 +1360,6 @@
"please_wait": "Please wait",
"plus_additional_collaborators_document_history_track_changes_and_more": "(plus additional collaborators, document history, track changes, and more).",
"plus_more": "plus more",
- "plus_upgraded_accounts_receive": "Plus with an upgraded account you get",
"popular_tags": "Popular Tags",
"portal_add_affiliation_to_join": "It looks like you are already logged in to __appName__. If you have a __portalTitle__ email you can add it now.",
"position": "Position",
@@ -1454,7 +1442,6 @@
"react_history_tutorial_content": "To compare a range of versions, use the <0>0> on the versions you want at the start and end of the range. To add a label or to download a version use the options in the three-dot menu. <1>Learn more about using Overleaf History.1>",
"react_history_tutorial_title": "History actions have a new home",
"reactivate_subscription": "Reactivate your subscription",
- "read_more_about_fix_prevent_timeout": "Read more about how to fix and prevent timeouts",
"read_more_about_free_compile_timeouts_servers": "Read more about changes to free compile timeouts and servers",
"read_only": "Read Only",
"read_only_token": "Read-Only Token",
@@ -1864,7 +1851,6 @@
"tc_switch_guests_tip": "Toggle track-changes for all link-sharing guests",
"tc_switch_user_tip": "Toggle track-changes for this user",
"tell_the_project_owner_and_ask_them_to_upgrade": "<0>Tell the project owner0> and ask them to upgrade their Overleaf plan if you need more compile time.",
- "tell_the_project_owner_to_upgrade_plan_for_more_compile_time": "Tell the project owner and ask them to upgrade their Overleaf plan if you need more compile time.",
"template": "Template",
"template_approved_by_publisher": "This template has been approved by the publisher",
"template_description": "Template Description",
@@ -1918,7 +1904,6 @@
"this_field_is_required": "This field is required",
"this_grants_access_to_features_2": "This grants you access to <0>__appName__0> <0>__featureType__0> features.",
"this_is_your_template": "This is your template from your project",
- "this_project_compiled_but_soon_might_not": "This project compiled, but soon it might not",
"this_project_exceeded_compile_timeout_limit_on_free_plan": "This project exceeded the compile timeout limit on our free plan.",
"this_project_is_public": "This project is public and can be edited by anyone with the URL.",
"this_project_is_public_read_only": "This project is public and can be viewed but not edited by anyone with the URL",
@@ -2086,8 +2071,6 @@
"upgrade": "Upgrade",
"upgrade_cc_btn": "Upgrade now, pay after 7 days",
"upgrade_for_12x_more_compile_time": "Upgrade to get 12x more compile time",
- "upgrade_for_longer_compiles": "Upgrade to increase your timeout limit.",
- "upgrade_for_plenty_more_compile_time": "Upgrade to get plenty more compile time.",
"upgrade_now": "Upgrade Now",
"upgrade_to_get_feature": "Upgrade to get __feature__, plus:",
"upgrade_to_track_changes": "Upgrade to track changes",
@@ -2155,8 +2138,6 @@
"website_status": "Website status",
"wed_love_you_to_stay": "We’d love you to stay",
"welcome_to_sl": "Welcome to __appName__",
- "were_in_the_process_of_reducing_compile_timeout_which_may_affect_this_project": "We’re in the process of <0>reducing the compile timeout limit0> on our free plan, which may affect this project in future.",
- "were_in_the_process_of_reducing_compile_timeout_which_may_affect_your_project": "We’re in the process of <0>reducing the compile timeout limit0> on our free plan, which may affect your project in future.",
"were_performing_maintenance": "We’re performing maintenance on Overleaf and you need to wait a moment. Sorry for any inconvenience. The editor will refresh automatically in __seconds__ seconds.",
"weve_recently_reduced_the_compile_timeout_limit_which_may_have_affected_this_project": "We’ve recently <0>reduced the compile timeout limit0> on our free plan, which may have affected this project.",
"weve_recently_reduced_the_compile_timeout_limit_which_may_have_affected_your_project": "We’ve recently <0>reduced the compile timeout limit0> on our free plan, which may have affected your project.",
@@ -2227,7 +2208,6 @@
"you_have_been_removed_from_this_project_and_will_be_redirected_to_project_dashboard": "You have been removed from this project, and will no longer have access to it. You will be redirected to your project dashboard momentarily.",
"you_introed_high_number": " You’ve introduced <0>__numberOfPeople__0> people to __appName__. Good job!",
"you_introed_small_number": " You’ve introduced <0>__numberOfPeople__0> person to __appName__. Good job, but can you get some more?",
- "you_may_be_able_to_fix_issues_to_speed_up_the_compile": "You may be able to fix issues to <0>speed up the compile0>.",
"you_need_to_configure_your_sso_settings": "You need to configure and test your SSO settings before enabling SSO",
"you_not_introed_anyone_to_sl": "You’ve not introduced anyone to __appName__ yet. Get sharing!",
"you_plus_1": "You + 1",
@@ -2255,7 +2235,6 @@
"your_password_has_been_successfully_changed": "Your password has been successfully changed",
"your_plan": "Your plan",
"your_plan_is_changing_at_term_end": "Your plan is changing to <0>__pendingPlanName__0> at the end of the current billing period.",
- "your_project_compiled_but_soon_might_not": "Your project compiled, but soon it might not",
"your_project_exceeded_compile_timeout_limit_on_free_plan": "Your project exceeded the compile timeout limit on our free plan.",
"your_project_near_compile_timeout_limit": "Your project is near the compile timeout limit for our free plan.",
"your_projects": "Your Projects",
diff --git a/services/web/scripts/migration_compile_timeout_60s_to_20s.js b/services/web/scripts/migration_compile_timeout_60s_to_20s.js
new file mode 100644
index 0000000000..5f18f248fa
--- /dev/null
+++ b/services/web/scripts/migration_compile_timeout_60s_to_20s.js
@@ -0,0 +1,57 @@
+#!/usr/bin/env node
+
+const minimist = require('minimist')
+const {
+ db,
+ READ_PREFERENCE_SECONDARY,
+ waitForDb,
+} = require('../app/src/infrastructure/mongodb')
+const { batchedUpdate } = require('./helpers/batchedUpdate')
+
+async function logCount() {
+ const count60s = await db.users.countDocuments(
+ { 'features.compileTimeout': { $lte: 60, $ne: 20 } },
+ { readPreference: READ_PREFERENCE_SECONDARY }
+ )
+ const count20s = await db.users.countDocuments(
+ { 'features.compileTimeout': 20 },
+ { readPreference: READ_PREFERENCE_SECONDARY }
+ )
+ console.log(`Found ${count60s} users with compileTimeout <= 60s && != 20s`)
+ console.log(`Found ${count20s} users with compileTimeout == 20s`)
+}
+
+const main = async ({ COMMIT }) => {
+ console.time('Script Duration')
+
+ await waitForDb()
+
+ await logCount()
+
+ if (COMMIT) {
+ const nModified = await batchedUpdate(
+ 'users',
+ { 'features.compileTimeout': { $lte: 60, $ne: 20 } },
+ { $set: { 'features.compileTimeout': 20 } }
+ )
+ console.log(`Updated ${nModified} records`)
+ }
+
+ console.timeEnd('Script Duration')
+}
+
+const setup = () => {
+ const argv = minimist(process.argv.slice(2))
+ const COMMIT = argv.commit !== undefined
+ if (!COMMIT) {
+ console.warn('Doing dry run. Add --commit to commit changes')
+ }
+ return { COMMIT }
+}
+
+main(setup())
+ .catch(err => {
+ console.error(err)
+ process.exit(1)
+ })
+ .then(() => process.exit(0))
diff --git a/services/web/test/acceptance/src/MigrateUserFeatureTimeoutTests.js b/services/web/test/acceptance/src/MigrateUserFeatureTimeoutTests.js
new file mode 100644
index 0000000000..a256ce8e78
--- /dev/null
+++ b/services/web/test/acceptance/src/MigrateUserFeatureTimeoutTests.js
@@ -0,0 +1,134 @@
+const { expect } = require('chai')
+const { promisify } = require('node:util')
+const { exec } = require('node:child_process')
+const logger = require('@overleaf/logger')
+const { db } = require('../../../app/src/infrastructure/mongodb')
+
+async function runScript(args = []) {
+ try {
+ return await promisify(exec)(
+ ['node', 'scripts/migration_compile_timeout_60s_to_20s.js', ...args].join(
+ ' '
+ )
+ )
+ } catch (error) {
+ logger.error({ error }, 'script failed')
+ throw error
+ }
+}
+
+describe('MigrateUserFeatureTimeoutTests', function () {
+ const usersInput = {
+ noFeatures: {},
+ noFeatureTimeout: { features: {} },
+ timeout10s: { features: { compileTimeout: 10, other: 'val1' }, bar: '1' },
+ timeout20s: { features: { compileTimeout: 20, other: 'val2' }, bar: '2' },
+ timeout30s: { features: { compileTimeout: 30, other: 'val3' }, bar: '3' },
+ timeout60s: { features: { compileTimeout: 60, other: 'val4' }, bar: '4' },
+ timeout120s: { features: { compileTimeout: 120, other: 'val5' }, bar: '5' },
+ timeout180s: { features: { compileTimeout: 180, other: 'val6' }, bar: '6' },
+ }
+
+ const usersKeys = Object.keys(usersInput)
+ const userIds = {}
+
+ beforeEach('insert users', async function () {
+ const usersInsertedValues = await db.users.insertMany(
+ usersKeys.map(key => ({
+ ...usersInput[key],
+ email: `${key}@example.com`,
+ }))
+ )
+ usersKeys.forEach(
+ (key, index) => (userIds[key] = usersInsertedValues.insertedIds[index])
+ )
+ })
+
+ it('gives correct counts in dry mode', async function () {
+ const users = await db.users.find().toArray()
+ expect(users).to.have.lengthOf(usersKeys.length)
+
+ const result = await runScript([])
+
+ expect(result.stderr).to.contain(
+ 'Doing dry run. Add --commit to commit changes'
+ )
+ expect(result.stdout).to.contain(
+ 'Found 3 users with compileTimeout <= 60s && != 20s'
+ )
+ expect(result.stdout).to.contain('Found 1 users with compileTimeout == 20s')
+ expect(result.stdout).not.to.contain('Updated')
+
+ const usersAfter = await db.users.find().toArray()
+
+ expect(usersAfter).to.deep.equal(users)
+ })
+
+ it("updates users compileTimeout when '--commit' is set", async function () {
+ const users = await db.users.find().toArray()
+ expect(users).to.have.lengthOf(usersKeys.length)
+ const result = await runScript(['--commit'])
+
+ expect(result.stdout).to.contain(
+ 'Found 3 users with compileTimeout <= 60s && != 20s'
+ )
+ expect(result.stdout).to.contain('Found 1 users with compileTimeout == 20s')
+ expect(result.stdout).to.contain('Updated 3 records')
+
+ const usersAfter = await db.users.find().toArray()
+
+ expect(usersAfter).to.deep.equal([
+ { _id: userIds.noFeatures, email: 'noFeatures@example.com' },
+ {
+ _id: userIds.noFeatureTimeout,
+ email: 'noFeatureTimeout@example.com',
+ features: {},
+ },
+ {
+ _id: userIds.timeout10s,
+ email: 'timeout10s@example.com',
+ features: { compileTimeout: 20, other: 'val1' },
+ bar: '1',
+ },
+ {
+ _id: userIds.timeout20s,
+ email: 'timeout20s@example.com',
+ features: { compileTimeout: 20, other: 'val2' },
+ bar: '2',
+ },
+ {
+ _id: userIds.timeout30s,
+ email: 'timeout30s@example.com',
+ features: { compileTimeout: 20, other: 'val3' },
+ bar: '3',
+ },
+ {
+ _id: userIds.timeout60s,
+ email: 'timeout60s@example.com',
+ features: { compileTimeout: 20, other: 'val4' },
+ bar: '4',
+ },
+ {
+ _id: userIds.timeout120s,
+ email: 'timeout120s@example.com',
+ features: { compileTimeout: 120, other: 'val5' },
+ bar: '5',
+ },
+ {
+ _id: userIds.timeout180s,
+ email: 'timeout180s@example.com',
+ features: { compileTimeout: 180, other: 'val6' },
+ bar: '6',
+ },
+ ])
+
+ const result2 = await runScript([])
+
+ expect(result2.stdout).to.contain(
+ 'Found 0 users with compileTimeout <= 60s && != 20s'
+ )
+ expect(result2.stdout).to.contain(
+ 'Found 4 users with compileTimeout == 20s'
+ )
+ })
+})
diff --git a/services/web/test/unit/src/Compile/ClsiManagerTests.js b/services/web/test/unit/src/Compile/ClsiManagerTests.js
index a0f58897d5..2abcfee70b 100644
--- a/services/web/test/unit/src/Compile/ClsiManagerTests.js
+++ b/services/web/test/unit/src/Compile/ClsiManagerTests.js
@@ -120,7 +120,6 @@ describe('ClsiManager', function () {
},
clsi: {
url: `http://${CLSI_HOST}`,
- defaultBackendClass: 'e2',
submissionBackendClass: 'n2d',
},
clsi_priority: {
diff --git a/services/web/test/unit/src/Compile/CompileControllerTests.js b/services/web/test/unit/src/Compile/CompileControllerTests.js
index 03de9fb465..ed88c64abd 100644
--- a/services/web/test/unit/src/Compile/CompileControllerTests.js
+++ b/services/web/test/unit/src/Compile/CompileControllerTests.js
@@ -32,7 +32,6 @@ describe('CompileController', function () {
apis: {
clsi: {
url: 'http://clsi.example.com',
- defaultBackendClass: 'e2',
submissionBackendClass: 'n2d',
},
clsi_priority: {
diff --git a/services/web/test/unit/src/Compile/CompileManagerTests.js b/services/web/test/unit/src/Compile/CompileManagerTests.js
index 2b49d6853f..e9501c647a 100644
--- a/services/web/test/unit/src/Compile/CompileManagerTests.js
+++ b/services/web/test/unit/src/Compile/CompileManagerTests.js
@@ -23,7 +23,7 @@ describe('CompileManager', function () {
requires: {
'@overleaf/settings': (this.settings = {
apis: {
- clsi: { defaultBackendClass: 'e2', submissionBackendClass: 'n2d' },
+ clsi: { submissionBackendClass: 'n2d' },
},
redis: { web: { host: 'localhost', port: 42 } },
rateLimit: { autoCompile: {} },
@@ -235,9 +235,8 @@ describe('CompileManager', function () {
.calledWith(null, {
timeout: this.timeout,
compileGroup: this.group,
- compileBackendClass: 'e2',
+ compileBackendClass: 'c2d',
ownerAnalyticsId: 'abc',
- showFasterCompilesFeedbackUI: false,
})
.should.equal(true)
})
@@ -303,7 +302,7 @@ describe('CompileManager', function () {
this.callback
)
this.callback
- .calledWith(null, sinon.match({ timeout: 60 }))
+ .calledWith(null, sinon.match({ timeout: 20 }))
.should.equal(true)
})
describe('user is in the compile-timeout-20s-existing-users treatment', function () {
@@ -388,20 +387,12 @@ describe('CompileManager', function () {
this.callback
)
this.callback
- .calledWith(null, sinon.match({ timeout: 60 }))
+ .calledWith(null, sinon.match({ timeout: 20 }))
.should.equal(true)
})
})
describe('user signed up after the second phase rollout', function () {
- beforeEach(function () {
- const signUpDate = new Date(
- this.CompileManager.NEW_COMPILE_TIMEOUT_ENFORCED_CUTOFF_DEFAULT_BASELINE
- )
- signUpDate.setDate(signUpDate.getDate() + 1)
- this.user.signUpDate = signUpDate
- })
-
it('should reduce compile timeout to 20s', function () {
this.CompileManager.getProjectCompileLimits(
this.project_id,
@@ -441,13 +432,12 @@ describe('CompileManager', function () {
variant: 'default',
})
})
- it('should return the e2 class and disable the ui', function (done) {
+ it('should return the n2d class and disable the ui', function (done) {
this.CompileManager.getProjectCompileLimits(
this.project_id,
- (err, { compileBackendClass, showFasterCompilesFeedbackUI }) => {
+ (err, { compileBackendClass }) => {
if (err) return done(err)
- expect(compileBackendClass).to.equal('e2')
- expect(showFasterCompilesFeedbackUI).to.equal(false)
+ expect(compileBackendClass).to.equal('n2d')
done()
}
)
@@ -463,10 +453,9 @@ describe('CompileManager', function () {
it('should return the n2d class and disable the ui', function (done) {
this.CompileManager.getProjectCompileLimits(
this.project_id,
- (err, { compileBackendClass, showFasterCompilesFeedbackUI }) => {
+ (err, { compileBackendClass }) => {
if (err) return done(err)
expect(compileBackendClass).to.equal('n2d')
- expect(showFasterCompilesFeedbackUI).to.equal(false)
done()
}
)
@@ -489,10 +478,9 @@ describe('CompileManager', function () {
it('should return the default class and disable ui', function (done) {
this.CompileManager.getProjectCompileLimits(
this.project_id,
- (err, { compileBackendClass, showFasterCompilesFeedbackUI }) => {
+ (err, { compileBackendClass }) => {
if (err) return done(err)
- expect(compileBackendClass).to.equal('e2')
- expect(showFasterCompilesFeedbackUI).to.equal(false)
+ expect(compileBackendClass).to.equal('c2d')
done()
}
)
@@ -510,10 +498,9 @@ describe('CompileManager', function () {
it('should return the default class and enable ui', function (done) {
this.CompileManager.getProjectCompileLimits(
this.project_id,
- (err, { compileBackendClass, showFasterCompilesFeedbackUI }) => {
+ (err, { compileBackendClass }) => {
if (err) return done(err)
- expect(compileBackendClass).to.equal('e2')
- expect(showFasterCompilesFeedbackUI).to.equal(true)
+ expect(compileBackendClass).to.equal('c2d')
done()
}
)
@@ -530,10 +517,9 @@ describe('CompileManager', function () {
it('should return the c2d class and enable ui', function (done) {
this.CompileManager.getProjectCompileLimits(
this.project_id,
- (err, { compileBackendClass, showFasterCompilesFeedbackUI }) => {
+ (err, { compileBackendClass }) => {
if (err) return done(err)
expect(compileBackendClass).to.equal('c2d')
- expect(showFasterCompilesFeedbackUI).to.equal(true)
done()
}
)