1
0
Fork 0

added flush

This commit is contained in:
Frank Celler 2013-01-09 11:47:17 +01:00
parent 46e0cc70bf
commit 812360145e
8 changed files with 212 additions and 26 deletions

View File

@ -5,7 +5,7 @@
vars: true,
white: true,
plusplus: true */
/*global require, exports */
/*global require, exports, module */
////////////////////////////////////////////////////////////////////////////////
/// @brief administration actions
@ -36,7 +36,7 @@
var actions = require("org/arangodb/actions");
var internal = require("internal");
var console = require("internal");
var console = require("console");
// -----------------------------------------------------------------------------
// --SECTION-- standard routing
@ -122,7 +122,7 @@ actions.defineHttp({
});
////////////////////////////////////////////////////////////////////////////////
/// @brief returns system status information for the server
/// @brief reloads the routing information
////////////////////////////////////////////////////////////////////////////////
actions.defineHttp({
@ -131,12 +131,13 @@ actions.defineHttp({
prefix : false,
callback : function (req, res) {
internal.executeGlobalContextFunction("require(\"org/arangodb/actions\").reloadRouting()");
console.warn("about to flush the routing cache");
actions.resultOk(req, res, actions.HTTP_OK);
}
});
////////////////////////////////////////////////////////////////////////////////
/// @brief returns system status information for the server
/// @brief returns routing information
////////////////////////////////////////////////////////////////////////////////
actions.defineHttp({
@ -161,6 +162,21 @@ actions.defineHttp({
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief flushes the modules cache
////////////////////////////////////////////////////////////////////////////////
actions.defineHttp({
url : "_admin/modules/flush",
context : "admin",
prefix : false,
callback : function (req, res) {
internal.executeGlobalContextFunction("require(\"internal\").flushModuleCache()");
console.warn("about to flush the modules cache");
actions.resultOk(req, res, actions.HTTP_OK);
}
});
////////////////////////////////////////////////////////////////////////////////
/// @fn JSF_GET_admin_time
/// @brief returns the system time

View File

@ -396,6 +396,16 @@ function help () {
internal.output(level, ": ", msg, "\n");
};
////////////////////////////////////////////////////////////////////////////////
/// @brief flushes the module cache of the server
////////////////////////////////////////////////////////////////////////////////
internal.flushServerModules = function () {
if (typeof arango !== 'undefined') {
arango.POST("/_admin/modules/flush", "");
}
};
////////////////////////////////////////////////////////////////////////////////
/// @brief rebuilds the routing cache
////////////////////////////////////////////////////////////////////////////////

View File

@ -92,7 +92,11 @@ function guessContentType (filename, content) {
}
if (extension === "json") {
return "application/xml; charset=utf-8";
return "application/json; charset=utf-8";
}
if (extension === "js") {
return "application/x-javascript; charset=utf-8";
}
return "text/plain; charset=utf-8";
@ -102,7 +106,7 @@ function guessContentType (filename, content) {
/// @brief normalizes a path
////////////////////////////////////////////////////////////////////////////////
ArangoApp.prototype.normalizePath = function (url) {
function normalizePath (url) {
if (url === "") {
url = "/";
}
@ -111,7 +115,7 @@ ArangoApp.prototype.normalizePath = function (url) {
}
return url;
};
}
////////////////////////////////////////////////////////////////////////////////
/// @brief updates a routing entry
@ -133,6 +137,14 @@ ArangoApp.prototype.updateRoute = function (route) {
routes.push(route);
};
////////////////////////////////////////////////////////////////////////////////
/// @brief prints an application
////////////////////////////////////////////////////////////////////////////////
ArangoApp.prototype._PRINT = function (route) {
internal.output('[ArangoApp "', this._name, '" at "', this._description.urlPrefix, '"]');
};
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
@ -185,6 +197,8 @@ ArangoApp.prototype.mountStaticContent = function (url, content, contentType) {
};
this.updateRoute(pages);
return this;
};
////////////////////////////////////////////////////////////////////////////////
@ -202,7 +216,7 @@ ArangoApp.prototype.mountStaticPages = function (url, collection) {
name = collection;
}
url = this.normalizePath(url);
url = normalizePath(url);
pages = {
type: "StaticPages",
@ -220,6 +234,79 @@ ArangoApp.prototype.mountStaticPages = function (url, collection) {
};
this.updateRoute(pages);
return this;
};
////////////////////////////////////////////////////////////////////////////////
/// @brief mounts a simple action
////////////////////////////////////////////////////////////////////////////////
ArangoApp.prototype.mountAction = function (url, func, methods) {
var pages;
var name;
url = normalizePath(url);
if (methods === undefined) {
methods = [ "GET", "HEAD" ];
}
if (! (methods instanceof Array)) {
var error = new arangodb.ArangoError();
error.errorNum = arangodb.ERROR_BAD_PARAMETER;
error.errorMessage = "methods must be a list of HTTP methods, i. e. [\"GET\"]";
throw error;
}
pages = {
type: "Action",
key: url,
url: { match: url },
action: {
'do': func,
methods: methods,
options: {
path: url,
application: this._name
}
}
};
this.updateRoute(pages);
return this;
};
////////////////////////////////////////////////////////////////////////////////
/// @brief changes the common prefix
////////////////////////////////////////////////////////////////////////////////
ArangoApp.prototype.setPrefix = function (prefix) {
if (prefix !== "" && prefix[prefix.length - 1] === '/') {
prefix = prefix.slice(0, prefix.length - 1);
}
if (prefix !== "" && prefix[0] !== '/') {
prefix = "/" + prefix;
}
if (prefix === "/") {
prefix = "";
}
this._description.urlPrefix = prefix;
return this;
};
////////////////////////////////////////////////////////////////////////////////
/// @brief gets the common prefix
////////////////////////////////////////////////////////////////////////////////
ArangoApp.prototype.prefix = function () {
return this._description.urlPrefix;
};
////////////////////////////////////////////////////////////////////////////////
@ -233,6 +320,8 @@ ArangoApp.prototype.save = function () {
this._description = this._routing.document(doc);
internal.reloadRouting();
return this;
};
////////////////////////////////////////////////////////////////////////////////
@ -248,9 +337,10 @@ ArangoApp.prototype.uploadStaticPages = function (prefix, path) {
var collection;
var error;
var name;
var re = /.*\/([^\/]*)$/;
routes = this._description.routes;
prefix = this.normalizePath(prefix);
prefix = normalizePath(prefix);
for (i = 0; i < routes.length; ++i) {
route = routes[i];
@ -287,6 +377,7 @@ ArangoApp.prototype.uploadStaticPages = function (prefix, path) {
var contentType;
var file = path + "/" + files[i];
var subpath = "/" + files[i];
var filename;
if (fs.isDirectory(file)) {
continue;
@ -298,6 +389,15 @@ ArangoApp.prototype.uploadStaticPages = function (prefix, path) {
continue;
}
filename = re.exec(files[i]);
if (filename !== null) {
filename = filename[1];
}
else {
filename = files[i];
}
contentType = guessContentType(file, content);
collection.save({
@ -305,11 +405,14 @@ ArangoApp.prototype.uploadStaticPages = function (prefix, path) {
prefix: prefix,
path: subpath,
content: content,
contentType: contentType
contentType: contentType,
filename: filename
});
internal.print("imported '" + subpath + "' of type '" + contentType + "'");
}
return this;
};
////////////////////////////////////////////////////////////////////////////////
@ -355,6 +458,46 @@ exports.readApp = function (name) {
return new ArangoApp(routing, doc);
};
////////////////////////////////////////////////////////////////////////////////
/// @brief loads a module directory into the database
////////////////////////////////////////////////////////////////////////////////
exports.uploadModules = function (prefix, path) {
var i;
var files;
var re = /^(.*)\.js$/;
prefix = normalizePath(prefix);
files = fs.listTree(path);
for (i = 0; i < files.length; ++i) {
var content;
var mpath;
var file = path + "/" + files[i];
if (fs.isDirectory(file)) {
continue;
}
mpath = re.exec(files[i]);
if (mpath === null) {
internal.print("skipping file '" + files[i] + "' of unknown type, expecting .js");
continue;
}
mpath = prefix + "/" + mpath[1];
internal.defineModule(mpath, file);
internal.print("imported '" + mpath + "'");
}
internal.flushServerModules();
internal.wait(1);
internal.reloadRouting();
};
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

View File

@ -161,7 +161,7 @@
msg = err + ": " + arguments;
}
internal.log("warn", msg);
internal.log("warning", msg);
};
////////////////////////////////////////////////////////////////////////////////

View File

@ -502,6 +502,14 @@
}
};
////////////////////////////////////////////////////////////////////////////////
/// @brief flushes the module cache
////////////////////////////////////////////////////////////////////////////////
internal.flushModuleCache = function() {
module.unloadAll();
};
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
@ -581,7 +589,7 @@
/// @brief reads a file from the module path or the database
////////////////////////////////////////////////////////////////////////////////
internal.readFile = function (path) {
internal.loadDatabaseFile = function (path) {
var i;
var mc;
var n;
@ -609,7 +617,7 @@
if (internal.db !== undefined) {
mc = internal.db._collection("_modules");
if (mc !== null && mc.hasOwnProperty("firstExample")) {
if (mc !== null && typeof mc.firstExample === "function") {
n = mc.firstExample({ path: path });
if (n !== null) {
@ -618,7 +626,10 @@
return { path : "_collection/" + path, content : n.content };
}
require("console").error("found empty content in '%s'", JSON.stringify(n));
if (Module.prototype.ModuleExistsCache.hasOwnProperty("/console")) {
var console = Module.prototype.ModuleExistsCache["/console"];
console.error("found empty content in '%s'", JSON.stringify(n));
}
}
}
}
@ -684,11 +695,10 @@
m = mc.firstExample({ path: path });
if (m === null) {
mc.save({ path: path, module: content });
mc.save({ path: path, content: content });
}
else {
m.module = content;
mc.replace(m, m);
mc.replace(m, { path: path, content: content });
}
};

View File

@ -74,6 +74,8 @@ Module.prototype.require = function (path) {
var raw;
var sandbox;
internal = this.ModuleCache["/internal"].exports;
// first get rid of any ".." and "."
path = this.normalise(path);
@ -83,8 +85,7 @@ Module.prototype.require = function (path) {
}
// locate file and read content
internal = this.ModuleCache["/internal"].exports;
raw = internal.readFile(path);
raw = internal.loadDatabaseFile(path);
// test for parse errors first and fail early if a parse error detected
if (! internal.parse(raw.content, path)) {
@ -111,6 +112,7 @@ Module.prototype.require = function (path) {
this.ModuleCache["/internal"].exports.print);
}
catch (err) {
delete this.ModuleCache[path];
throw "Javascript exception in file '" + path + "': " + err.stack;
}
@ -122,7 +124,7 @@ Module.prototype.require = function (path) {
////////////////////////////////////////////////////////////////////////////////
Module.prototype.exists = function (path) {
return this.ModuleExistsCache[path];
return Module.prototype.ModuleExistsCache[path];
};
////////////////////////////////////////////////////////////////////////////////
@ -187,12 +189,16 @@ Module.prototype.unload = function (path) {
var norm = module.normalise(path);
if ( norm === "/"
|| norm === "/internal"
|| norm === "/console"
|| norm === "/fs") {
|| norm === "/internal"
|| norm === "/fs"
|| norm === "/org/arangodb"
|| norm === "/org/arangodb/actions") {
return;
}
Module.prototype.ModuleCache["/console"].exports.info("UNLOADING %s", path);
delete this.ModuleCache[norm];
};

View File

@ -31,6 +31,7 @@
var arangodb = require("org/arangodb");
var internal = require("internal");
var console = require("console");
var moduleExists = function(name) { return module.exists; };
// -----------------------------------------------------------------------------
// --SECTION-- private variables
@ -246,7 +247,7 @@ function lookupCallbackAction (route, action) {
}
}
catch (err) {
if (! module.exists(joined)) {
if (! moduleExists(joined)) {
func = notImplementedFunction(route,
"an error occurred while loading action named '" + name
+ "' in module '" + joined + "': " + String(err));
@ -309,7 +310,7 @@ function lookupCallbackAction (route, action) {
};
}
catch (err1) {
if (! module.exists(action.controller)) {
if (! moduleExists(action.controller)) {
return notImplementedFunction(route,
"cannot load/execute action controller module '"
+ action.controller + ": " + String(err1));
@ -345,7 +346,7 @@ function lookupCallbackAction (route, action) {
catch (err) {
efunc = errorFunction;
if (! module.exists(path)) {
if (! moduleExists(path)) {
efunc = notImplementedFunction;
}

View File

@ -5,7 +5,7 @@
vars: true,
white: true,
plusplus: true */
/*global require, db, edges, ModuleCache, Module,
/*global require, db, edges, Module,
ArangoCollection, ArangoDatabase,
ArangoError, ShapedJson,
SYS_DEFINE_ACTION */