Skip to content
This repository has been archived by the owner on Jan 24, 2019. It is now read-only.

Generate thumbnail generation tails after a bulk transaction #167

Merged
merged 4 commits into from
Aug 19, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions services/api/handlers/bulk.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ exports.post = function(request, reply) {
return reply(Boom.wrap(err));
}

request.server.methods.newrelic.createTracer(
'process cache invalidations',
request.server.methods.bulk.invalidateCaches
);
request.server.methods.bulk.invalidateCaches(request, results.map(function(result) {
var rawResults = results.map(function(result) {
return result.raw;
}));
});

request.server.methods.bulk.invalidateCaches(request, rawResults);

request.server.methods.projects.processBulkThumbnailRequests(request, rawResults);

reply({
status: 'success',
Expand Down
5 changes: 2 additions & 3 deletions services/api/handlers/elements.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,8 @@ exports.patch = {
}

var thumbTail = request.tail('updating project thumbnail');
process.nextTick(function() {
request.server.methods.projects.checkPageId(request.pre.page, thumbTail);
});

request.server.methods.projects.checkPageId(request.pre.page, thumbTail);

request.server.methods.cache.invalidateKey(
'elements',
Expand Down
5 changes: 2 additions & 3 deletions services/api/handlers/pages.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,8 @@ exports.patch = {

var page = request.server.methods.utils.formatPage(result.rows);
var thumbTail = request.tail('updating project thumbnail');
process.nextTick(function() {
request.server.methods.projects.checkPageId(page, thumbTail);
});

request.server.methods.projects.checkPageId(page, thumbTail);

request.server.methods.cache.invalidateKey(
'pages',
Expand Down
125 changes: 91 additions & 34 deletions services/api/lib/thumbnails.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,18 @@ exports.register = function(server, options, done) {
var qs = require('querystring');
var request = require('request');
var pageRenderUrl = process.env.PAGE_RENDER_URL;
var req;

var req = request.defaults({
baseUrl: process.env.THUMBNAIL_SERVICE_URL,
method: 'post',
json: true,
headers: {
accept: 'application/json'
},
body: {
wait: true
}
});

function buildPageRenderUrl(user, project, page) {
var urlObj = url.parse(pageRenderUrl);
Expand Down Expand Up @@ -69,48 +80,94 @@ exports.register = function(server, options, done) {
});
}

// Check if the given page has the lowest id in its parent project
// If it is, then request a new thumbnail
// Check if the given page has the lowest id of all pages in its parent project
// In most cases, this means the first page created when a project is created (situated at 0,0)
function checkPageId(page, tail) {
if ( !process.env.THUMBNAIL_SERVICE_URL ) {
return tail();
}

server.methods.pages.min([
page.project_id
], function(err, result) {
if ( err ) {
server.log('error', {
details: 'Error querying DB for lowest page ID in project: ' + page.project_id,
error: err
});
return tail(err);
}
var row = result.rows[0];

if ( row.page_id !== page.id ) {
server.debug('Thumbnail update not required');
process.nextTick(function() {
if ( !process.env.THUMBNAIL_SERVICE_URL ) {
return tail();
}
server.methods.pages.min([
page.project_id
Copy link
Member

Choose a reason for hiding this comment

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

I'm curious about this - what's the reason that you want the lowest page id in a project?

Copy link
Member

Choose a reason for hiding this comment

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

Like, is the lowest page id always guaranteed to be the center?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's what we determined to be "the thumbnail page" for all projects. in most cases, it's the first page made, unless they delete it.

], function(err, result) {
if ( err ) {
server.log('error', {
details: 'Error querying DB for lowest page ID in project: ' + page.project_id,
error: err
});
return tail(err);
}

var row = result.rows[0];

if ( !row || row.page_id !== page.id ) {
server.debug('Thumbnail update not required');
return tail();
}

server.debug('Updating thumbnail for project');
generateThumbnail(row, tail);
server.debug('Updating thumbnail for project');
generateThumbnail(row, tail);
});
});
}

req = request.defaults({
baseUrl: process.env.THUMBNAIL_SERVICE_URL,
method: 'post',
json: true,
headers: {
accept: 'application/json'
},
body: {
wait: true
// project updates, and any kind of delete don't trigger thumbnail changes.
function filterRawResult(result) {
return result.type !== 'projects' && result.method !== 'remove';
}

// extract just the page_id and project_id from the result data
function transformResult(result) {
var rowData = result.rows[0];
var projectId = rowData.project_id;
var pageId = rowData.page_id || rowData.id;

return {
project_id: +projectId,
page_id: +pageId
};
}

// reduce the array of actions into an array of checks to perform, to determine if a thumbnail update is required
function reduceIntoUpdates(pendingChecks, result) {
var resultData;

// iterate over existing thumbnail updates for comparisons with current action
for (var i = 0; i < pendingChecks.length; i++) {
resultData = pendingChecks[i];
if (resultData.project_id !== result.project_id) {
continue;
}
if (result.page_id < resultData.page_id) {
break;
}
return pendingChecks;
}
});

server.method('projects.checkPageId', checkPageId);
pendingChecks.push(result);
return pendingChecks;
}

// pass each resulting action into checkPageId, generating a request tail
// for each check (we don't want to block the request on these checks)
function checkAction(request, action) {
checkPageId(action, request.tail('updating project thumbnail'));
}

// We need only check if a thumbnail update is necessary for the lowest pageId in a given set of actions
function processBulkThumbnailRequests(request, rawResults) {
rawResults.filter(filterRawResult)
.map(transformResult)
.reduce(reduceIntoUpdates, [])
.forEach(checkAction.bind(this, request));
}

server.method('projects.checkPageId', checkPageId, {
callback: false
});
server.method('projects.processBulkThumbnailRequests', processBulkThumbnailRequests, {
callback: false
});
done();
};

Expand Down