Temporarily store promises until they are resolved

The original commit simply stored promises into the cache,
which seemed to work in browsers but failed with karma/PhantomJS.

I'm not yet certain why that is, but I wanted to get rid of complex
objects in sessionStorage anyway, so this commit does:

* temporarily store running promises for a given key
* cache the resolved data directly
pull/3553/head
Oliver Günther 9 years ago
parent 64d5b399c5
commit d3d6cd60ee
  1. 6
      frontend/app/openproject-app.js
  2. 38
      frontend/app/services/cache-service.js
  3. 3
      frontend/app/work_packages/activities/user-activity-directive.js
  4. 64
      frontend/tests/unit/tests/work_packages/activities/user-activity-directive-test.js

@ -74,7 +74,8 @@ angular.module(
'openproject.uiComponents',
'openproject.helpers',
'openproject.workPackages.config',
'openproject.workPackages.helpers'
'openproject.workPackages.helpers',
'angular-cache'
]);
angular.module('openproject.helpers', ['openproject.services']);
angular
@ -191,8 +192,7 @@ var openprojectApp = angular.module('openproject', [
'cgBusy',
'openproject.api',
'openproject.templates',
'monospaced.elastic',
'angular-cache'
'monospaced.elastic'
]);
window.appBasePath = jQuery('meta[name=app_base_path]').attr('content') ||

@ -32,11 +32,16 @@ module.exports = function(
$q,
CacheFactory) {
var cacheName = 'openproject-cache';
var _cache = CacheFactory(cacheName, {
maxAge: 30 * 60 * 1000, // 30 mins
storageMode: 'sessionStorage'
});
var cacheName = 'openproject-cache',
_promises = {},
_cache = CacheFactory.get(cacheName);
if (!_cache) {
_cache = CacheFactory(cacheName, {
maxAge: 10 * 60 * 1000, // 10 mins
storageMode: 'sessionStorage',
});
}
var CacheService = {
@ -48,29 +53,40 @@ module.exports = function(
return _cache.get(key);
},
remove: function(key) {
_cache.remove(key);
},
loadResource: function(resource, force) {
var deferred = $q.defer(),
key = resource.props.href,
cached = CacheService.get(key);
// Got the result directly? Great.
if (cached && !force) {
deferred.resolve(cached);
}
// Return an existing promise if it exists
// Avoids intermittent requests while a first
// is already underway.
if (cached && !force) {
return cached;
if (_promises[key]) {
return _promises[key];
}
var promise = deferred.promise;
CacheService.cache(key, promise);
resource.fetch().then(function(data) {
CacheService.cache(key, data);
deferred.resolve(data);
}, function() {
deferred.reject();
CacheService.remove(key);
});
var promise = deferred.promise;
_promises[key] = promise;
return promise;
},
}
};
return CacheService;

@ -75,7 +75,8 @@ module.exports = function($uiViewScroll,
scope.userCanQuote = !!scope.workPackage.links.addComment;
scope.accessibilityModeEnabled = ConfigurationService.accessibilityModeEnabled();
UserService.getUserByResource(scope.activity.links.user).then(function(user) {
var resource = UserService.getUserByResource(scope.activity.links.user);
resource.then(function(user) {
scope.userId = user.props.id;
scope.userName = user.props.name;
scope.userAvatar = user.props.avatar;

@ -47,7 +47,7 @@ describe('userActivity Directive', function() {
});
});
beforeEach(inject(function($rootScope, $compile, $uiViewScroll, $timeout, $location, I18n, PathHelper, ActivityService, UsersHelper) {
beforeEach(inject(function($rootScope, $compile, $uiViewScroll, $timeout, $location, I18n, PathHelper, ActivityService, UsersHelper, UserService) {
var html;
html = '<user-activity work-package="workPackage" activity="activity" activity-no="activityNo" is-initial="isInitial" input-element-id="inputElementId"></user-activity>';
@ -74,21 +74,20 @@ describe('userActivity Directive', function() {
};
scope.activity = {
links: {
update: true,
user: {
props: { href: '/api/v3/users/1' },
fetch: function() {
return {
then: function(cb) {
cb({
props: {
id: 1,
name: "John Doe",
avatar: 'avatar.png',
status: 1
}
}
);}
};
var deferred = $q.defer();
deferred.resolve({
props: {
id: 1,
name: "John Doe",
avatar: 'avatar.png',
status: 1
}
});
return deferred.promise;
}
}
},
@ -114,7 +113,7 @@ describe('userActivity Directive', function() {
};
scope.isInitial = false;
compile();
});
}));
context("user's avatar", function() {
it('should have an alt attribute', function() {
@ -126,23 +125,28 @@ describe('userActivity Directive', function() {
});
describe('when being empty', function() {
beforeEach(function() {
scope.activity.links.user.fetch = function() {
return {
then: function(cb) {
cb({
props: {
id: 1,
name: "John Doe",
avatar: '',
status: 1
}
});
}
};
beforeEach(inject(function($q) {
scope.activity.links.user = {
props: {
href: '/api/v3/users/2'
},
fetch: function() {
var deferred = $q.defer();
deferred.resolve({
props: {
id: 2,
name: "John Doe",
avatar: '',
status: 1
}
});
return deferred.promise;
}
};
compile();
});
}));
it('should not be rendered', function() {
expect(element.find('.avatar')).to.have.length(0);

Loading…
Cancel
Save