Skip to content

Wait for cron to finish before running upgrade command - #9900

Merged
MorrisJobke merged 1 commit into
masterfrom
feature/noid/wait-for-cron-to-finish
Jun 20, 2018
Merged

Wait for cron to finish before running upgrade command#9900
MorrisJobke merged 1 commit into
masterfrom
feature/noid/wait-for-cron-to-finish

Conversation

@MorrisJobke

Copy link
Copy Markdown
Member

To test this, add this:

diff --git a/lib/private/Authentication/Token/DefaultTokenProvider.php b/lib/private/Authentication/Token/DefaultTokenProvider.php
index 7a43dbb23e..fb2b33f564 100644
--- a/lib/private/Authentication/Token/DefaultTokenProvider.php+++ b/lib/private/Authentication/Token/DefaultTokenProvider.php@@ -281,9 +281,11 @@ class DefaultTokenProvider implements IProvider {
public function invalidateOldTokens() {
$olderThan = $this->time->getTime() - (int) $this->config->getSystemValue('session_lifetime', 60 * 60 * 24);
$this->logger->debug('Invalidating session tokens older than ' . date('c', $olderThan), ['app' => 'cron']);
+ sleep(15);
$this->mapper->invalidateOld($olderThan, IToken::DO_NOT_REMEMBER);
$rememberThreshold = $this->time->getTime() - (int) $this->config->getSystemValue('remember_login_cookie_lifetime', 60 * 60 * 24 * 15);
$this->logger->debug('Invalidating remembered session tokens older than ' . date('c', $rememberThreshold), ['app' => 'cron']);
+ sleep(15);
$this->mapper->invalidateOld($rememberThreshold, IToken::REMEMBER);
}

Then start a cron job cron.php, raise the version number in version.php or lower it in config/config.php and then trigger the upgrade by calling occ upgrade.

It then looks like this:

$ occ upgrade
Nextcloud or one of the apps require upgrade - only a limited number of commands are available
You may use your browser or the occ upgrade command to do the upgrade
Set log level to debug
Turned on maintenance mode
Waiting for cron to finish (checks again in 5 seconds)...
Waiting for cron to finish (checks again in 5 seconds)...
Waiting for cron to finish (checks again in 5 seconds)...
Waiting for cron to finish (checks again in 5 seconds)...
Updating database schema
Updated database
Checking for update of app activity in appstore
Checked for update of app "activity" in appstore Checking for update of app bruteforcesettings in appstore
Checked for update of app "bruteforcesettings" in appstore Checking for update of app comments in appstore
Checked for update of app "comments" in appstore ...

When no cron job runs, then it looks like this:

$ occ upgrade
Nextcloud or one of the apps require upgrade - only a limited number of commands are available
You may use your browser or the occ upgrade command to do the upgrade
Set log level to debug
Turned on maintenance mode
Updating database schema
Updated database
Checking for update of app activity in appstore
Checked for update of app "activity" in appstore Checking for update of app bruteforcesettings in appstore
Checked for update of app "bruteforcesettings" in appstore Checking for update of app comments in appstore
Checked for update of app "comments" in appstore ...

@MorrisJobke

Copy link
Copy Markdown
MemberAuthor

The web UI looks like this:

bildschirmfoto 2018-06-18 um 17 28 22

@MorrisJobke

Copy link
Copy Markdown
MemberAuthor

I'm tempted to backport this, because we think that this could fix the issue #4978

@codecov

codecovBot commented Jun 18, 2018

Copy link
Copy Markdown

Codecov Report

Merging #9900 into master will decrease coverage by 0.16%.
The diff coverage is 3.33%.

@@ Coverage Diff @@## master #9900 +/- ##
===========================================
- Coverage 52.07% 51.9% -0.17% + Complexity 25901 25813 -88 
===========================================
Files 1642 1637 -5 Lines 95884 95539 -345 Branches 1318 1318 ===========================================
- Hits 49929 49593 -336 + Misses 45955 45946 -9
Impacted FilesCoverage ΔComplexity Δ
lib/private/BackgroundJob/JobList.php72.84% <0%> (-6.29%)31 <2> (+2)
core/Command/Upgrade.php0% <0%> (ø)68 <1> (+1)⬆️
core/ajax/update.php0% <0%> (ø)11 <0> (ø)⬇️
lib/private/Updater.php5.31% <11.11%> (+0.2%)120 <2> (+2)⬆️
lib/private/Authentication/Token/DefaultToken.php85.24% <0%> (-6.69%)20% <0%> (ø)
...B/QueryBuilder/FunctionBuilder/FunctionBuilder.php77.77% <0%> (-2.23%)9% <0%> (-1%)
lib/private/User/Database.php79.47% <0%> (-1.78%)43% <0%> (+1%)
apps/files_trashbin/lib/Expiration.php90.32% <0%> (-1.62%)29% <0%> (ø)
settings/Controller/AuthSettingsController.php77.5% <0%> (-0.88%)20% <0%> (+2%)
...vate/Authentication/Token/DefaultTokenProvider.php98.03% <0%> (-0.02%)32% <0%> (ø)
... and 9 more

@skjnldsvskjnldsv left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes a lot of sense!

$query = $this->connection->getQueryBuilder();
$query->select('*')
->from('jobs')
->where($query->expr()->gt('reserved_at', $query->createNamedParameter($this->timeFactory->getTime() - 12 * 3600, IQueryBuilder::PARAM_INT)))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's document why this is supposed to be working. The code is clear, but the thought behinds should be expressed.

Strictly speaking, it does only report whether a job should run (it might be running, or it might be due with the next job run). Correct me if I am wrong. It could perhaps lead to an infinite loop when a job reincarnates and registers to run next time again. Though, cron should not be triggered when maintenance mode is enabled, which in the whole scenario is the case, so it would block for 12 hours instead.

Are the 12 hours based on something?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 12 hours is the same timeout that is also used to re-schedule an non-terminated job (see a bit above in this file - getNextJob(). The idea here is: give a job enough time to run very long and then after a timeout re-schedule it nevertheless. It's more likely to be crashed than to run that long.

In theory it could lead to an endless loop (as in - at most 12 hours), because the cron will not start when maintenance mode is active and this method is only executed in maintenance mode (see where it is added in the upgrader class. I could add this as comments of course.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment added.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From a UX perspective it still is problematic if it will take that long, as it'll look that nothing is happening. Of course stating "it might take up to 12 hours" in the GUI would scare people away. OK, let's get it in and collect some experience.

* fixes#9562
Signed-off-by: Morris Jobke <hey@morrisjobke.de>
@MorrisJobke
MorrisJobkeforce-pushed the feature/noid/wait-for-cron-to-finish branch from b0c929d to 18e9631CompareJune 19, 2018 12:22
@MorrisJobke
MorrisJobke merged commit 50df29d into masterJun 20, 2018
@MorrisJobke
MorrisJobke deleted the feature/noid/wait-for-cron-to-finish branch June 20, 2018 12:14
@MorrisJobke

Copy link
Copy Markdown
MemberAuthor

This will only trigger for 14.0.0.7+, because it would cause #9992 otherwise. See #10010

@MorrisJobke

Copy link
Copy Markdown
MemberAuthor

Let's not backport this.

@MorrisJobke

Copy link
Copy Markdown
MemberAuthor

Reverted in #12188

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Check before running "upgrade" if cronjob is still running and wait for it to finish

3 participants

@MorrisJobke@blizzz@skjnldsv