diff options
-rw-r--r-- | src/components/settings/settings/EditSettingsForm.js | 2 | ||||
-rw-r--r-- | src/config.ts | 13 | ||||
-rw-r--r-- | src/containers/settings/EditSettingsScreen.js | 27 | ||||
-rw-r--r-- | src/i18n/locales/en-US.json | 2 | ||||
-rw-r--r-- | src/stores/ServicesStore.js | 56 |
5 files changed, 96 insertions, 4 deletions
diff --git a/src/components/settings/settings/EditSettingsForm.js b/src/components/settings/settings/EditSettingsForm.js index bdb8484d4..c92bde346 100644 --- a/src/components/settings/settings/EditSettingsForm.js +++ b/src/components/settings/settings/EditSettingsForm.js | |||
@@ -424,6 +424,8 @@ class EditSettingsForm extends Component { | |||
424 | </p> | 424 | </p> |
425 | 425 | ||
426 | <Select field={form.$('wakeUpStrategy')} /> | 426 | <Select field={form.$('wakeUpStrategy')} /> |
427 | <Select field={form.$('wakeUpHibernationStrategy')} /> | ||
428 | <Toggle field={form.$('wakeUpHibernationSplay')} /> | ||
427 | 429 | ||
428 | <Hr /> | 430 | <Hr /> |
429 | 431 | ||
diff --git a/src/config.ts b/src/config.ts index 5c9fbaee4..3dbcd809b 100644 --- a/src/config.ts +++ b/src/config.ts | |||
@@ -58,6 +58,17 @@ export const WAKE_UP_STRATEGIES = { | |||
58 | 3600: 'Wake up after 1hour', | 58 | 3600: 'Wake up after 1hour', |
59 | }; | 59 | }; |
60 | 60 | ||
61 | export const WAKE_UP_HIBERNATION_STRATEGIES = { | ||
62 | 0: 'Use main hibernation strategy', | ||
63 | 10: 'Extremely Fast Hibernation (10sec)', | ||
64 | 30: 'Very Fast Hibernation (30sec)', | ||
65 | 60: 'Fast Hibernation (1min)', | ||
66 | 300: 'Normal Hibernation (5min)', | ||
67 | 600: 'Slow Hibernation (10min)', | ||
68 | 1800: 'Very Slow Hibernation (30min)', | ||
69 | 3600: 'Extremely Slow Hibernation (1hour)', | ||
70 | }; | ||
71 | |||
61 | export const NAVIGATION_BAR_BEHAVIOURS = { | 72 | export const NAVIGATION_BAR_BEHAVIOURS = { |
62 | custom: 'Show navigation bar on custom websites only', | 73 | custom: 'Show navigation bar on custom websites only', |
63 | always: 'Show navigation bar on all services', | 74 | always: 'Show navigation bar on all services', |
@@ -217,6 +228,8 @@ export const DEFAULT_APP_SETTINGS = { | |||
217 | hibernateOnStartup: true, | 228 | hibernateOnStartup: true, |
218 | hibernationStrategy: '300', // seconds | 229 | hibernationStrategy: '300', // seconds |
219 | wakeUpStrategy: '300', // seconds | 230 | wakeUpStrategy: '300', // seconds |
231 | wakeUpHibernationStrategy: '0', // seconds -- 0 means do the same as hibernationStrategy | ||
232 | wakeUpHibernationSplay: true, | ||
220 | inactivityLock: 0, | 233 | inactivityLock: 0, |
221 | automaticUpdates: true, | 234 | automaticUpdates: true, |
222 | universalDarkMode: true, | 235 | universalDarkMode: true, |
diff --git a/src/containers/settings/EditSettingsScreen.js b/src/containers/settings/EditSettingsScreen.js index eff5f20ff..6e405cd92 100644 --- a/src/containers/settings/EditSettingsScreen.js +++ b/src/containers/settings/EditSettingsScreen.js | |||
@@ -20,6 +20,7 @@ import { | |||
20 | DEFAULT_SETTING_KEEP_ALL_WORKSPACES_LOADED, | 20 | DEFAULT_SETTING_KEEP_ALL_WORKSPACES_LOADED, |
21 | DEFAULT_IS_FEATURE_ENABLED_BY_USER, | 21 | DEFAULT_IS_FEATURE_ENABLED_BY_USER, |
22 | WAKE_UP_STRATEGIES, | 22 | WAKE_UP_STRATEGIES, |
23 | WAKE_UP_HIBERNATION_STRATEGIES, | ||
23 | SPLIT_COLUMNS_MIN, | 24 | SPLIT_COLUMNS_MIN, |
24 | SPLIT_COLUMNS_MAX, | 25 | SPLIT_COLUMNS_MAX, |
25 | } from '../../config'; | 26 | } from '../../config'; |
@@ -115,6 +116,14 @@ const messages = defineMessages({ | |||
115 | id: 'settings.app.form.wakeUpStrategy', | 116 | id: 'settings.app.form.wakeUpStrategy', |
116 | defaultMessage: 'Wake up strategy', | 117 | defaultMessage: 'Wake up strategy', |
117 | }, | 118 | }, |
119 | wakeUpHibernationStrategy: { | ||
120 | id: 'settings.app.form.wakeUpHibernationStrategy', | ||
121 | defaultMessage: 'Hibernation strategy after automatic wake up', | ||
122 | }, | ||
123 | wakeUpHibernationSplay: { | ||
124 | id: 'settings.app.form.wakeUpHibernationSplay', | ||
125 | defaultMessage: 'Splay hibernate/wake cycles to reduce load', | ||
126 | }, | ||
118 | predefinedTodoServer: { | 127 | predefinedTodoServer: { |
119 | id: 'settings.app.form.predefinedTodoServer', | 128 | id: 'settings.app.form.predefinedTodoServer', |
120 | defaultMessage: 'Todo Server', | 129 | defaultMessage: 'Todo Server', |
@@ -295,6 +304,8 @@ class EditSettingsScreen extends Component { | |||
295 | hibernateOnStartup: Boolean(settingsData.hibernateOnStartup), | 304 | hibernateOnStartup: Boolean(settingsData.hibernateOnStartup), |
296 | hibernationStrategy: Number(settingsData.hibernationStrategy), | 305 | hibernationStrategy: Number(settingsData.hibernationStrategy), |
297 | wakeUpStrategy: Number(settingsData.wakeUpStrategy), | 306 | wakeUpStrategy: Number(settingsData.wakeUpStrategy), |
307 | wakeUpHibernationStrategy: Number(settingsData.wakeUpHibernationStrategy), | ||
308 | wakeUpHibernationSplay: Boolean(settingsData.wakeUpHibernationSplay), | ||
298 | predefinedTodoServer: settingsData.predefinedTodoServer, | 309 | predefinedTodoServer: settingsData.predefinedTodoServer, |
299 | customTodoServer: settingsData.customTodoServer, | 310 | customTodoServer: settingsData.customTodoServer, |
300 | lockingFeatureEnabled: Boolean(settingsData.lockingFeatureEnabled), | 311 | lockingFeatureEnabled: Boolean(settingsData.lockingFeatureEnabled), |
@@ -391,6 +402,11 @@ class EditSettingsScreen extends Component { | |||
391 | sort: false, | 402 | sort: false, |
392 | }); | 403 | }); |
393 | 404 | ||
405 | const wakeUpHibernationStrategies = getSelectOptions({ | ||
406 | locales: WAKE_UP_HIBERNATION_STRATEGIES, | ||
407 | sort: false, | ||
408 | }); | ||
409 | |||
394 | const todoApp = getSelectOptions({ | 410 | const todoApp = getSelectOptions({ |
395 | locales: TODO_APPS, | 411 | locales: TODO_APPS, |
396 | sort: false, | 412 | sort: false, |
@@ -511,6 +527,17 @@ class EditSettingsScreen extends Component { | |||
511 | options: wakeUpStrategies, | 527 | options: wakeUpStrategies, |
512 | default: DEFAULT_APP_SETTINGS.wakeUpStrategy, | 528 | default: DEFAULT_APP_SETTINGS.wakeUpStrategy, |
513 | }, | 529 | }, |
530 | wakeUpHibernationStrategy: { | ||
531 | label: intl.formatMessage(messages.wakeUpHibernationStrategy), | ||
532 | value: settings.all.app.wakeUpHibernationStrategy, | ||
533 | options: wakeUpHibernationStrategies, | ||
534 | default: DEFAULT_APP_SETTINGS.wakeUpHibernationStrategy, | ||
535 | }, | ||
536 | wakeUpHibernationSplay: { | ||
537 | label: intl.formatMessage(messages.wakeUpHibernationSplay), | ||
538 | value: settings.all.app.wakeUpHibernationSplay, | ||
539 | default: DEFAULT_APP_SETTINGS.wakeUpHibernationSplay, | ||
540 | }, | ||
514 | predefinedTodoServer: { | 541 | predefinedTodoServer: { |
515 | label: intl.formatMessage(messages.predefinedTodoServer), | 542 | label: intl.formatMessage(messages.predefinedTodoServer), |
516 | value: settings.all.app.predefinedTodoServer, | 543 | value: settings.all.app.predefinedTodoServer, |
diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json index 3f1e5728f..f6b53d501 100644 --- a/src/i18n/locales/en-US.json +++ b/src/i18n/locales/en-US.json | |||
@@ -243,6 +243,8 @@ | |||
243 | "settings.app.form.universalDarkMode": "Enable universal Dark Mode", | 243 | "settings.app.form.universalDarkMode": "Enable universal Dark Mode", |
244 | "settings.app.form.useTouchIdToUnlock": "Allow using TouchID to unlock Ferdi", | 244 | "settings.app.form.useTouchIdToUnlock": "Allow using TouchID to unlock Ferdi", |
245 | "settings.app.form.useVerticalStyle": "Use horizontal style", | 245 | "settings.app.form.useVerticalStyle": "Use horizontal style", |
246 | "settings.app.form.wakeUpHibernationSplay": "Splay hibernate/wake cycles to reduce load", | ||
247 | "settings.app.form.wakeUpHibernationStrategy": "Hibernation strategy after automatic wake up", | ||
246 | "settings.app.form.wakeUpStrategy": "Wake up strategy", | 248 | "settings.app.form.wakeUpStrategy": "Wake up strategy", |
247 | "settings.app.headlineAdvanced": "Advanced", | 249 | "settings.app.headlineAdvanced": "Advanced", |
248 | "settings.app.headlineAppearance": "Appearance", | 250 | "settings.app.headlineAppearance": "Appearance", |
diff --git a/src/stores/ServicesStore.js b/src/stores/ServicesStore.js index e546850f9..e2bfd22f3 100644 --- a/src/stores/ServicesStore.js +++ b/src/stores/ServicesStore.js | |||
@@ -239,7 +239,7 @@ export default class ServicesStore extends Store { | |||
239 | ms(`${this.stores.settings.all.app.wakeUpStrategy}s`) | 239 | ms(`${this.stores.settings.all.app.wakeUpStrategy}s`) |
240 | ) { | 240 | ) { |
241 | // If service is in hibernation and the wakeup time has elapsed, wake it. | 241 | // If service is in hibernation and the wakeup time has elapsed, wake it. |
242 | this._awake({ serviceId: service.id }); | 242 | this._awake({ serviceId: service.id, automatic: true }); |
243 | } | 243 | } |
244 | } | 244 | } |
245 | 245 | ||
@@ -1043,11 +1043,59 @@ export default class ServicesStore extends Store { | |||
1043 | service.lastHibernated = Date.now(); | 1043 | service.lastHibernated = Date.now(); |
1044 | } | 1044 | } |
1045 | 1045 | ||
1046 | @action _awake({ serviceId }) { | 1046 | @action _awake({ serviceId, automatic }) { |
1047 | const now = Date.now(); | ||
1047 | const service = this.one(serviceId); | 1048 | const service = this.one(serviceId); |
1048 | debug(`Waking up from service hibernation for ${service.name}`); | 1049 | const automaticTag = automatic ? ' automatically ' : ' '; |
1050 | debug( | ||
1051 | `Waking up${automaticTag}from service hibernation for ${service.name}`, | ||
1052 | ); | ||
1053 | |||
1054 | if (automatic) { | ||
1055 | // if this is an automatic wake up, use the wakeUpHibernationStrategy | ||
1056 | // which sets the lastUsed time to an offset from now rather than to now. | ||
1057 | // Also add an optional random splay to desync the wakeups and | ||
1058 | // potentially reduce load. | ||
1059 | // | ||
1060 | // offsetNow = now - (hibernationStrategy - wakeUpHibernationStrategy) | ||
1061 | // | ||
1062 | // if wUHS = hS = 60, offsetNow = now. hibernation again in 60 seconds. | ||
1063 | // | ||
1064 | // if wUHS = 20 and hS = 60, offsetNow = now - 40. hibernation again in | ||
1065 | // 20 seconds. | ||
1066 | // | ||
1067 | // possibly also include splay in wUHS before subtracting from hS. | ||
1068 | // | ||
1069 | const mainStrategy = this.stores.settings.all.app.hibernationStrategy; | ||
1070 | let strategy = this.stores.settings.all.app.wakeUpHibernationStrategy; | ||
1071 | debug(`wakeUpHibernationStrategy = ${strategy}`); | ||
1072 | debug(`hibernationStrategy = ${mainStrategy}`); | ||
1073 | if (!strategy || strategy < 1) { | ||
1074 | strategy = this.stores.settings.all.app.hibernationStrategy; | ||
1075 | } | ||
1076 | let splay = 0; | ||
1077 | // Add splay. This will keep the service awake a little longer. | ||
1078 | if ( | ||
1079 | this.stores.settings.all.app.wakeUpHibernationSplay && | ||
1080 | Math.random() >= 0.5 | ||
1081 | ) { | ||
1082 | // Add 10 additional seconds 50% of the time. | ||
1083 | splay = 10; | ||
1084 | debug('Added splay'); | ||
1085 | } else { | ||
1086 | debug('skipping splay'); | ||
1087 | } | ||
1088 | // wake up again in strategy + splay seconds instead of mainStrategy seconds. | ||
1089 | service.lastUsed = now - ms(`${mainStrategy - (strategy + splay)}s`); | ||
1090 | } else { | ||
1091 | service.lastUsed = now; | ||
1092 | } | ||
1093 | debug( | ||
1094 | `Setting service.lastUsed to ${service.lastUsed} (${ | ||
1095 | (now - service.lastUsed) / 1000 | ||
1096 | }s ago)`, | ||
1097 | ); | ||
1049 | service.isHibernationRequested = false; | 1098 | service.isHibernationRequested = false; |
1050 | service.lastUsed = Date.now(); | ||
1051 | service.lastHibernated = null; | 1099 | service.lastHibernated = null; |
1052 | } | 1100 | } |
1053 | 1101 | ||