Skip to content

feat: adjust background sync on user activity #11149

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

SebastianKrupinski
Copy link
Contributor

@SebastianKrupinski SebastianKrupinski commented May 14, 2025

Resolves

#10717

Summary

  • added logic to track mail app activity
  • added logic to skip back ground sync job if the user is active in the ui
  • refactored testIsRequest in IMipServiceTest to perform a fake test instead of skipping to play nice with the CI

@SebastianKrupinski SebastianKrupinski force-pushed the fix/issue-10717-dynamic-sync-interval branch from 71b55f7 to ad65815 Compare June 30, 2025 16:42
@SebastianKrupinski SebastianKrupinski force-pushed the fix/issue-10717-dynamic-sync-interval branch from 95d2bca to ce40db2 Compare June 30, 2025 17:16
@SebastianKrupinski SebastianKrupinski marked this pull request as ready for review June 30, 2025 17:22
@SebastianKrupinski
Copy link
Contributor Author

Failing tests are unrelated, failing due to missing NCU name space interfaces in NC30

@kesselb
Copy link
Contributor

kesselb commented Jul 1, 2025

Failing tests are unrelated, failing due to missing NCU name space interfaces in NC30

I doubt it ;)

@@ -79,6 +84,12 @@ protected function run($argument) {
return;
}

if (($this->userConfig->getValueInt($account->getUserId(), Application::APP_ID, 'ui-hearthbeat') - $this->time->getTime()) > 900) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
if (($this->userConfig->getValueInt($account->getUserId(), Application::APP_ID, 'ui-hearthbeat') - $this->time->getTime()) > 900) {
if (($this->userConfig->getValueInt($account->getUserId(), Application::APP_ID, 'ui-heartbeat') - $this->time->getTime()) > 900) {

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@@ -140,6 +136,8 @@ public function sync(int $id, array $ids = [], ?int $lastMessageTimestamp = null
$account = $this->accountService->find($this->currentUserId, $mailbox->getAccountId());
$order = $sortOrder === 'newest' ? IMailSearch::ORDER_NEWEST_FIRST: IMailSearch::ORDER_OLDEST_FIRST;

$this->userConfig->setValueInt($this->currentUserId, Application::APP_ID, 'ui-hearthbeat', time());
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
$this->userConfig->setValueInt($this->currentUserId, Application::APP_ID, 'ui-hearthbeat', time());
$this->userConfig->setValueInt($this->currentUserId, Application::APP_ID, 'ui-heartbeat', time());

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@@ -140,6 +136,8 @@ public function sync(int $id, array $ids = [], ?int $lastMessageTimestamp = null
$account = $this->accountService->find($this->currentUserId, $mailbox->getAccountId());
$order = $sortOrder === 'newest' ? IMailSearch::ORDER_NEWEST_FIRST: IMailSearch::ORDER_OLDEST_FIRST;

$this->userConfig->setValueInt($this->currentUserId, Application::APP_ID, 'ui-hearthbeat', time());
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
$this->userConfig->setValueInt($this->currentUserId, Application::APP_ID, 'ui-hearthbeat', time());
$this->userConfig->setValueInt($this->currentUserId, Application::APP_ID, 'ui-hearthbeat', time());

To make it testable: Replace time() with ITimeFactoy.getTime.

if (!method_exists(IManager::class, 'handleImipRequest')) {
self::markTestIncomplete();
$this->assertTrue(true);
Copy link
Contributor

Choose a reason for hiding this comment

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

As this seems unrelated, please remove it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is unrelated that is why it is in a separate commit. And need to fix a failing nc30 test

Copy link
Contributor

@kesselb kesselb Jul 1, 2025

Choose a reason for hiding this comment

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

No.

See https://github.com/nextcloud/mail/actions/runs/16008830201/job/45161666190?pr=11340 (copy of this branch, without the IMipServiceTest change => only the warning about the incomplet test is gone, but the incomplet test isn't the problem)

Copy link
Contributor

Choose a reason for hiding this comment

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

IUserManager $userManager,
AccountService $accountService,
MailboxSync $mailboxSync,
ImapToDbSynchronizer $syncService,
LoggerInterface $logger,
IJobList $jobList,
IConfig $config) {
IConfig $config,
private IUserConfig $userConfig,
Copy link
Contributor

Choose a reason for hiding this comment

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

IUserConfig is new in 31.
Use IConfig.getUserValue instread.

Copy link
Member

@ChristophWurst ChristophWurst left a comment

Choose a reason for hiding this comment

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

From when we discussed the feature I remember saying that we want to track when a user accesses Mail. If they access it frequently we keep the hourly sync. If they don't, we drop down to one sync in four hours or even less often.

The current change tries to detect user activity, then skips syncing but also drops the interval from 60 minutes to 15 minutes.

Can you explain why the implementation was done so different to what we discussed? Are there new findings that make the original idea impossible?

@@ -79,6 +84,12 @@ protected function run($argument) {
return;
}

if (($this->userConfig->getValueInt($account->getUserId(), Application::APP_ID, 'ui-heartbeat') - $this->time->getTime()) > 900) {
$this->logger->debug('Detected user activity, skipping background sync job');
$this->setInterval(900);
Copy link
Member

Choose a reason for hiding this comment

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

Does setting the interval of an already running job have any consequence?

@SebastianKrupinski
Copy link
Contributor Author

From when we discussed the feature I remember saying that we want to track when a user accesses Mail. If they access it frequently we keep the hourly sync. If they don't, we drop down to one sync in four hours or even less often.

The current change tries to detect user activity, then skips syncing but also drops the interval from 60 minutes to 15 minutes.

Can you explain why the implementation was done so different to what we discussed? Are there new findings that make the original idea impossible?

Yes, that is what I am trying to do with this.

The idea here is that the background sync will not run as long as there is a up to date heart beat. So as long as the mail UI has been active the background sync will not run, but will revert back to the regular configured interval when there is no activity. Essentially if you are active all day the background sync should not execute. And if you are not active often then it will revert to the default once an hour to sync the mailbox to reduce UI waiting time, and to pick things like iMip.

It only reschdules to 15min when there is a heart beat to check for another heart beat, as the sync can be configure to run every 5min (app.mail.background-sync-interval), I thought it was more sane to check less frequently. We can probably change this to 30min.

@ChristophWurst
Copy link
Member

The cron sync will sync all INBOXes and mailboxes marked for background sync. Frontend will sync INBOXes and the currently open mailbox. Therefore, the background sync should also run when a user has the app open all day.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: 🏗️ In progress
Development

Successfully merging this pull request may close these issues.

3 participants