Commit 46844bb7 authored by rswindell's avatar rswindell
Browse files

Add system.get_node() method to read a single node record in one shot:

use this in place of system.node_list[] if you're going to be using a lot of
the properties and passing them around to methods which are going to each
possibly dereference the values, as *each* deference results in a read of the
node record in the node.dab. On my system, a simple node list (e.g. /L
command) would result in between 60 and 100 reads of the node.dab (for a 13
node system), which was nuts.

The system.get_node() method currently leaves the node record unlocked and
there is currently no equivalent put_node() method, so you still need to use
the system.node_list[] for modification of node records. But, I now see there
are race conditions with the current methods of read-modify-writes of the
node_list[] properties. We should be locking a node.dab record, reading it,
modifying it, writing it, and then unlocking it - as is done in the C/C++
code. So... that's a todo item.

Also created system.stats.node_gets to track the number of node.dab reads
from a single instance of the system object. May remove this any time.
parent 681bcbb2
......@@ -42,6 +42,7 @@
typedef struct {
scfg_t* cfg;
int nodefile;
int nodegets;
} js_system_private_t;
extern JSClass js_system_class;
......@@ -564,6 +565,8 @@ enum {
,SYSSTAT_PROP_TOTALMSGS
,SYSSTAT_PROP_TOTALMAIL
,SYSSTAT_PROP_FEEDBACK
,SYSSTAT_PROP_NODE_GETS
};
#ifndef JSDOOR
......@@ -665,6 +668,10 @@ static JSBool js_sysstats_get(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
*vp = INT_TO_JSVAL(getmail(cfg, /* user: */1, /* Sent: */FALSE, /* SPAM: */FALSE));
JS_RESUMEREQUEST(cx, rc);
break;
case SYSSTAT_PROP_NODE_GETS:
*vp = INT_TO_JSVAL(sys->nodegets);
break;
}
return(TRUE);
......@@ -692,6 +699,7 @@ static jsSyncPropertySpec js_sysstats_properties[] = {
{ "feedback_sent_today", SYSSTAT_PROP_FTODAY, SYSSTAT_FLAGS, 310 },
{ "total_users", SYSSTAT_PROP_TOTALUSERS, SYSSTAT_FLAGS, 310 },
{ "new_users_today", SYSSTAT_PROP_NUSERS, SYSSTAT_FLAGS, 310 },
{ "node_gets", SYSSTAT_PROP_NODE_GETS, JSPROP_READONLY, 31702 },
{0}
};
......@@ -1384,6 +1392,54 @@ js_filter_ip(JSContext *cx, uintN argc, jsval *arglist)
return(JS_TRUE);
}
static JSBool
js_get_node(JSContext *cx, uintN argc, jsval *arglist)
{
JSObject* obj=JS_THIS_OBJECT(cx, arglist);
JSObject* nodeobj;
jsval* argv=JS_ARGV(cx, arglist);
node_t node = {0};
int32 node_num;
jsrefcount rc;
JS_SET_RVAL(cx, arglist, JSVAL_NULL);
js_system_private_t* sys;
if((sys = (js_system_private_t*)js_GetClassPrivate(cx,obj,&js_system_class))==NULL)
return JS_FALSE;
scfg_t* cfg = sys->cfg;
node_num=cfg->node_num;
if(argc)
JS_ValueToInt32(cx,argv[0],&node_num);
if(node_num<1)
node_num=1;
rc=JS_SUSPENDREQUEST(cx);
int retval = getnodedat(sys->cfg, node_num, &node, /* lockit: */FALSE, &sys->nodefile);
sys->nodegets++;
JS_RESUMEREQUEST(cx, rc);
if(retval != 0) {
JS_ReportError(cx, "getnodat(%d) returned %d", node_num, retval);
return JS_TRUE;
}
if((nodeobj = JS_NewObject(cx, NULL, NULL, obj)) == NULL) {
JS_ReportError(cx, "JS_NewObject failure");
return JS_TRUE;
}
JS_DefineProperty(cx, nodeobj, "status", INT_TO_JSVAL((int)node.status), NULL, NULL, JSPROP_ENUMERATE);
JS_DefineProperty(cx, nodeobj, "errors", INT_TO_JSVAL((int)node.errors), NULL, NULL, JSPROP_ENUMERATE);
JS_DefineProperty(cx, nodeobj, "action", INT_TO_JSVAL((int)node.action), NULL, NULL, JSPROP_ENUMERATE);
JS_DefineProperty(cx, nodeobj, "useron", INT_TO_JSVAL((int)node.useron), NULL, NULL, JSPROP_ENUMERATE);
JS_DefineProperty(cx, nodeobj, "connection", INT_TO_JSVAL((int)node.connection), NULL, NULL, JSPROP_ENUMERATE);
JS_DefineProperty(cx, nodeobj, "misc", INT_TO_JSVAL((int)node.misc), NULL, NULL, JSPROP_ENUMERATE);
JS_DefineProperty(cx, nodeobj, "aux", INT_TO_JSVAL((int)node.aux), NULL, NULL, JSPROP_ENUMERATE);
JS_DefineProperty(cx, nodeobj, "extaux", INT_TO_JSVAL((int)node.extaux), NULL, NULL, JSPROP_ENUMERATE);
JS_SET_RVAL(cx, arglist, OBJECT_TO_JSVAL(nodeobj));
return JS_TRUE;
}
static JSBool
js_get_node_message(JSContext *cx, uintN argc, jsval *arglist)
{
......@@ -1908,7 +1964,12 @@ static jsSyncMethodSpec js_system_functions[] = {
{"filter_ip", js_filter_ip, 4, JSTYPE_BOOLEAN, JSDOCSTR("[protocol, reason, host, ip, username, filename]")
,JSDOCSTR("add an IP address (with comment) to an IP filter file. If filename is not specified, the ip.can file is used")
,311
},
},
{"get_node", js_get_node, 1, JSTYPE_OBJECT, JSDOCSTR("node_number")
,JSDOCSTR("read a node data record all at once (and leaving the record unlocked) "
"returning an object matching the elements of <tt>system.node_list</tt>")
,31702
},
{"get_node_message",js_get_node_message,0, JSTYPE_STRING, JSDOCSTR("node_number")
,JSDOCSTR("read any messages waiting for the specified node and return in a single string")
,311
......@@ -2034,6 +2095,7 @@ static JSBool js_node_get(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
return(JS_TRUE);
}
JS_RESUMEREQUEST(cx, rc);
sys->nodegets++;
switch(tiny) {
case NODE_PROP_STATUS:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment