Skip to content

Commit

Permalink
Split model cache into separate file and use mixin/override style for…
Browse files Browse the repository at this point in the history
… models-server.
  • Loading branch information
Young Hahn committed Feb 21, 2011
1 parent 49a0258 commit 5217244
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 78 deletions.
6 changes: 5 additions & 1 deletion .ndistro
Expand Up @@ -16,7 +16,7 @@ module willwhite node-worker 0.0.1
module felixge node-dirty v0.9.1
module mapbox carto 0.1.1
module tmcw node-get 0.1.0
module developmentseed backbone-dirty 0.0.1
module developmentseed backbone-dirty 0.0.2

# client-side only
module developmentseed openlayers_slim v1.9
Expand All @@ -41,6 +41,10 @@ module kkaefer node-compress master compress
module mapnik node-mapnik grid mapnik
module mapbox tilelive.js grid

# module layout workarounds
cd $ROOT
! test -f lib/node/backbone.js && ln -s ../../modules/backbone/backbone.js lib/node/backbone.js

# download and install a resource
resource() {
local path=$1
Expand Down
17 changes: 9 additions & 8 deletions server/api.js
@@ -1,7 +1,8 @@
// REST endpoints for Backbone models and collections.
var _ = require('underscore'),
mapnik = require('mapnik'),
models = require('models-server'),
models = require('models'),
cache = require('models-cache'),
Step = require('step'),
reference = require('carto').tree.Reference.data;
External = require('carto').External;
Expand Down Expand Up @@ -138,7 +139,7 @@ module.exports = function(app, settings) {
// `type` to determine which library plugin should be used for generating
// the list of assets.
app.get('/api/Library/:id/assets/:page?', function(req, res) {
var model = models.cache.get('Library', req.param('id'));
var model = cache.get('Library', req.param('id'));
model.fetch({
success: function(model, resp) {
var options = _.extend({
Expand All @@ -165,7 +166,7 @@ module.exports = function(app, settings) {
// `library-directory.js`.
app.get('/api/Library/:id/files/*', function(req, res, next) {
var path = require('path');
var model = models.cache.get('Library', req.param('id'));
var model = cache.get('Library', req.param('id'));
model.fetch({
success: function(model, resp) {
if (model.get('type') === 'directory') {
Expand Down Expand Up @@ -201,7 +202,7 @@ module.exports = function(app, settings) {
// ---------------
// GET endpoint for all Backbone models.
app.get('/api/:model/:id', validateModel, function(req, res, next) {
var model = models.cache.get(req.param('model'), req.param('id'));
var model = cache.get(req.param('model'), req.param('id'));
model.fetch({
success: function(model, resp) { res.send(model.toJSON()) },
error: function(model, resp) { res.send(resp, 500); }
Expand All @@ -217,7 +218,7 @@ module.exports = function(app, settings) {
.update(+new Date)
.digest('hex')
.substring(0,6);
var model = models.cache.get(req.param('model'), id);
var model = cache.get(req.param('model'), id);
model.set(req.body);
if (req.param('model') === 'Project') {
model.validateAsync({
Expand All @@ -243,7 +244,7 @@ module.exports = function(app, settings) {
// ---------------
// PUT endpoint for all Backbone models.
app.put('/api/:model/:id', validateModel, function(req, res, next) {
var model = models.cache.get(req.param('model'), req.param('id'));
var model = cache.get(req.param('model'), req.param('id'));
model.set(req.body);
if (req.param('model') === 'Project') {
model.validateAsync({
Expand All @@ -270,13 +271,13 @@ module.exports = function(app, settings) {
// ------------------
// DELETE endpoint for all Backbone models.
app.del('/api/:model/:id', validateModel, function(req, res, next) {
var model = models.cache.get(req.param('model'), req.param('id'));
var model = cache.get(req.param('model'), req.param('id'));
model.trigger('delete');
model.destroy({
success: function(model, resp) { res.send({}) },
error: function(model, resp) { res.send(resp, 500); }
});
models.cache.del(req.param('model'), req.param('id'));
cache.del(req.param('model'), req.param('id'));
});

// Generic error handler.
Expand Down
6 changes: 5 additions & 1 deletion server/bootstrap.js
Expand Up @@ -46,8 +46,12 @@ module.exports = function(app, settings) {
}
} catch (Exception) {}

// Apply server-side mixins/overrides.
require('backbone-dirty')(settings.files + '/app.db');
require('models-server');

// Create a default library for the local data directory.
var models = require('models-server');
var models = require('models');
var data = new models.Library({
id: 'data',
name: 'Local data',
Expand Down
9 changes: 4 additions & 5 deletions server/export.js
@@ -1,10 +1,9 @@
// Loop for scanning and processing exports.
var path = require('path'),
ExportList = require('models-server').ExportList,
Project = require('models-server').Project,
ExportList = require('models').ExportList,
Step = require('step'),
Worker = require('worker').Worker,
models = require('models-server');
cache = require('models-cache');

var Scanner = function(options) {
_.bindAll(this, 'scan', 'process', 'add', 'remove', 'isFull');
Expand Down Expand Up @@ -42,7 +41,7 @@ Scanner.prototype.scan = function() {
// Process an individual export based on its `status`.
Scanner.prototype.process = function(id, callback) {
var that = this;
var model = models.cache.get('Export', id);
var model = cache.get('Export', id);
var project;
Step(
function() {
Expand All @@ -51,7 +50,7 @@ Scanner.prototype.process = function(id, callback) {
},
function() {
var next = this;
project = models.cache.get('Project', model.get('project'));
project = cache.get('Project', model.get('project'));
project.fetch({ success: next, error: next });
},
function() {
Expand Down
33 changes: 33 additions & 0 deletions server/models-cache.js
@@ -0,0 +1,33 @@
// Cache
// -----
// Provides a model instance cache for the server. Used to store and retrieve a
// model instance in memory such that the same model is referenced in separate
// requests as well as in other long-running processes.
//
// The main use-case in TileMill for this instance cache is triggering a model
// `delete` event when a DELETE request is received. In the case of Exports,
// this event is used to terminate and worker processes associated with the
// Export model being deleted.
var models = require('models');
module.exports = {
cache: {},
get: function(type, id) {
if (this.cache[type] && this.cache[type][id]) {
return this.cache[type][id];
}
this.cache[type] = this.cache[type] || {}
this.set(type, id, new models[type]({id: id}));
return this.cache[type][id];
},
set: function(type, id, model) {
this.cache[type] = this.cache[type] || {}
this.cache[type][id] = model;
return this.cache[type][id];
},
del: function(type, id) {
if (this.cache[type][id]) {
delete this.cache[type][id];
}
}
};

46 changes: 2 additions & 44 deletions server/models-server.js
@@ -1,17 +1,13 @@
// Server-side overrides for the Backbone models defined in `shared/models.js`.
// Provides model-specific storage overrides.

var _ = require('underscore'),
Backbone = require('../modules/backbone/backbone.js'),
var _ = require('underscore')._,
Backbone = require('backbone'),
settings = require('settings'),
fs = require('fs'),
Step = require('step'),
path = require('path'),
models = require('models');

// Use backbone-dirty mixin.
require('backbone-dirty')(Backbone, path.join(settings.files, 'app.db'));

// Project
// -------
// Implement custom sync method for Project model. Writes projects to
Expand Down Expand Up @@ -304,41 +300,3 @@ models.Export.prototype.sync = function(method, model, success, error) {
break;
}
};

// Cache
// -----
// Provides a model instance cache for the server. Used to store and retrieve a
// model instance in memory such that the same model is referenced in separate
// requests as well as in other long-running processes.
//
// The main use-case in TileMill for this instance cache is triggering a model
// `delete` event when a DELETE request is received. In the case of Exports,
// this event is used to terminate and worker processes associated with the
// Export model being deleted.
var Cache = function() {
this.cache = {};
};

Cache.prototype.get = function(type, id) {
if (this.cache[type] && this.cache[type][id]) {
return this.cache[type][id];
}
this.cache[type] = this.cache[type] || {}
this.set(type, id, new models[type]({id: id}));
return this.cache[type][id];
};

Cache.prototype.set = function(type, id, model) {
this.cache[type] = this.cache[type] || {}
this.cache[type][id] = model;
return this.cache[type][id];
};

Cache.prototype.del = function(type, id) {
if (this.cache[type][id]) {
delete this.cache[type][id];
}
};

module.exports = _.extend({ cache: new Cache() }, models);

4 changes: 2 additions & 2 deletions server/tiles.js
Expand Up @@ -9,12 +9,12 @@ var _ = require('underscore'),
url = require('url'),
path = require('path'),
Tile = require('tilelive').Tile,
models = require('models-server');
cache = require('models-cache');

module.exports = function(app, settings) {
// Route middleware. Load a project model.
var loadProject = function(req, res, next) {
var model = models.cache.get('Project', req.param('id'));
var model = cache.get('Project', req.param('id'));
model.fetch({
success: function(model, resp) {
res.project = model;
Expand Down
32 changes: 15 additions & 17 deletions shared/models.js
Expand Up @@ -3,9 +3,9 @@
// globally defined Backbone and underscore leaving us with broken objects.
// This is obviously not ideal.
if (typeof require !== 'undefined' && typeof window === 'undefined') {
JSV = require('jsv').JSV;
Backbone = require('../modules/backbone/backbone.js'),
_ = require('underscore')._;
Backbone = require('backbone');
JSV = require('jsv').JSV;
}

// JSON schema validation
Expand Down Expand Up @@ -770,19 +770,17 @@ var LibraryList = Backbone.Collection.extend({
}
});

if (typeof module !== 'undefined') {
module.exports = {
Asset: Asset,
AssetList: AssetList,
AssetListS3: AssetListS3,
Library: Library,
LibraryList: LibraryList,
Project: Project,
ProjectList: ProjectList,
Export: Export,
ExportList: ExportList,
Datasource: Datasource,
Settings: Settings
};
}
(typeof module !== 'undefined') && (module.exports = {
Asset: Asset,
AssetList: AssetList,
AssetListS3: AssetListS3,
Library: Library,
LibraryList: LibraryList,
Project: Project,
ProjectList: ProjectList,
Export: Export,
ExportList: ExportList,
Datasource: Datasource,
Settings: Settings
});

0 comments on commit 5217244

Please sign in to comment.