email: rewrite loading of email status using async
we start a bunch of requests in the background for each domain. when we switch views immediately, to say the eventlog, these requests are still active in the background. canceling the requests will require a much bigger refactor. https://forum.cloudron.io/topic/10434/email-event-log-loading-very-slowly-seems-tied-to-overall-email-domain-list-health-checks
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
/* global $, angular, TASK_TYPES */
|
||||
/* global async */
|
||||
|
||||
angular.module('Application').controller('EmailsController', ['$scope', '$location', '$translate', '$timeout', 'Client', function ($scope, $location, $translate, $timeout, Client) {
|
||||
Client.onReady(function () { if (!Client.getUserInfo().isAtLeastMailManager) $location.path('/'); });
|
||||
@@ -404,44 +405,83 @@ angular.module('Application').controller('EmailsController', ['$scope', '$locati
|
||||
}
|
||||
};
|
||||
|
||||
function refreshDomainStatuses() {
|
||||
$scope.domains.forEach(function (domain) {
|
||||
domain.usage = null; // used by ui to show 'loading'
|
||||
function refreshMailStatus(domain, done) {
|
||||
Client.getMailStatusForDomain(domain.domain, function (error, result) {
|
||||
if (error) {
|
||||
console.error('Failed to fetch mail status for domain', domain.domain, error);
|
||||
return done();
|
||||
}
|
||||
|
||||
Client.getMailStatusForDomain(domain.domain, function (error, result) {
|
||||
if (error) return console.error('Failed to fetch mail status for domain', domain.domain, error);
|
||||
domain.status = result;
|
||||
|
||||
domain.status = result;
|
||||
domain.statusOk = Object.keys(result).every(function (k) {
|
||||
if (k === 'dns') return Object.keys(result.dns).every(function (k) { return result.dns[k].status; });
|
||||
|
||||
domain.statusOk = Object.keys(result).every(function (k) {
|
||||
if (k === 'dns') return Object.keys(result.dns).every(function (k) { return result.dns[k].status; });
|
||||
if (!('status' in result[k])) return true; // if status is not present, the test was not run
|
||||
|
||||
if (!('status' in result[k])) return true; // if status is not present, the test was not run
|
||||
|
||||
return result[k].status;
|
||||
});
|
||||
return result[k].status;
|
||||
});
|
||||
|
||||
Client.getMailConfigForDomain(domain.domain, function (error, mailConfig) {
|
||||
if (error) return console.error('Failed to fetch mail config for domain', domain.domain, error);
|
||||
done();
|
||||
});
|
||||
}
|
||||
|
||||
domain.inbound = mailConfig.enabled;
|
||||
domain.outbound = mailConfig.relay.provider !== 'noop';
|
||||
function refreshMailConfig(domain, done) {
|
||||
Client.getMailConfigForDomain(domain.domain, function (error, mailConfig) {
|
||||
if (error) {
|
||||
console.error('Failed to fetch mail config for domain', domain.domain, error);
|
||||
return done();
|
||||
}
|
||||
|
||||
// do this even if no outbound since people forget to remove mailboxes
|
||||
Client.getMailboxCount(domain.domain, function (error, count) {
|
||||
if (error) return console.error('Failed to fetch mailboxes for domain', domain.domain, error);
|
||||
domain.inbound = mailConfig.enabled;
|
||||
domain.outbound = mailConfig.relay.provider !== 'noop';
|
||||
|
||||
domain.mailboxCount = count;
|
||||
// do this even if no outbound since people forget to remove mailboxes
|
||||
Client.getMailboxCount(domain.domain, function (error, count) {
|
||||
if (error) {
|
||||
console.error('Failed to fetch mailboxes for domain', domain.domain, error);
|
||||
return done();
|
||||
}
|
||||
|
||||
Client.getMailUsage(domain.domain, function (error, usage) {
|
||||
if (error) return console.error('Failed to fetch usage for domain', domain.domain, error);
|
||||
domain.mailboxCount = count;
|
||||
|
||||
domain.usage = 0;
|
||||
// we used to use quotaValue here but it's quite different wrt diskSize. so choose diskSize consistently
|
||||
// also, quotaValue can be missing for deleted mailboxes that are on disk but removed from dovecot/ldap itself
|
||||
Object.keys(usage).forEach(function (m) { domain.usage += usage[m].diskSize; });
|
||||
});
|
||||
done();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function refreshMailUsage(domain, done) {
|
||||
Client.getMailUsage(domain.domain, function (error, usage) {
|
||||
if (error) {
|
||||
console.error('Failed to fetch usage for domain', domain.domain, error);
|
||||
return done();
|
||||
}
|
||||
|
||||
domain.usage = 0;
|
||||
// we used to use quotaValue here but it's quite different wrt diskSize. so choose diskSize consistently
|
||||
// also, quotaValue can be missing for deleted mailboxes that are on disk but removed from dovecot/ldap itself
|
||||
Object.keys(usage).forEach(function (m) { domain.usage += usage[m].diskSize; });
|
||||
|
||||
done();
|
||||
});
|
||||
}
|
||||
|
||||
function refreshDomainStatuses() {
|
||||
async.each($scope.domains, function (domain, iteratorDone) {
|
||||
async.series([
|
||||
refreshMailStatus.bind(null, domain),
|
||||
refreshMailConfig.bind(null, domain),
|
||||
], function () {
|
||||
domain.loading = false;
|
||||
iteratorDone();
|
||||
});
|
||||
}, function () {
|
||||
// mail usage is loaded separately with a cancellation check. when there are a lot of domains, it runs a long time in background and slows down loading of new views
|
||||
async.eachLimit($scope.domains, 5, function (domain, itemDone) {
|
||||
if ($scope.$$destroyed) return itemDone(); // abort!
|
||||
refreshMailUsage(domain, function () {
|
||||
domain.loadingUsage = false;
|
||||
itemDone();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -451,7 +491,9 @@ angular.module('Application').controller('EmailsController', ['$scope', '$locati
|
||||
Client.getDomains(function (error, domains) {
|
||||
if (error) return console.error('Unable to get domain listing.', error);
|
||||
|
||||
domains.forEach(function (domain) { domain.loading = true; domain.loadingUsage = true; }); // used by ui to show 'loading'
|
||||
$scope.domains = domains;
|
||||
|
||||
$scope.ready = true;
|
||||
|
||||
if ($scope.user.isAtLeastAdmin) {
|
||||
|
||||
Reference in New Issue
Block a user