Skip to content
Snippets Groups Projects
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
Branches
Tags
No related merge requests found
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
typedef struct { typedef struct {
scfg_t* cfg; scfg_t* cfg;
int nodefile; int nodefile;
int nodegets;
} js_system_private_t; } js_system_private_t;
extern JSClass js_system_class; extern JSClass js_system_class;
...@@ -564,6 +565,8 @@ enum { ...@@ -564,6 +565,8 @@ enum {
,SYSSTAT_PROP_TOTALMSGS ,SYSSTAT_PROP_TOTALMSGS
,SYSSTAT_PROP_TOTALMAIL ,SYSSTAT_PROP_TOTALMAIL
,SYSSTAT_PROP_FEEDBACK ,SYSSTAT_PROP_FEEDBACK
,SYSSTAT_PROP_NODE_GETS
}; };
#ifndef JSDOOR #ifndef JSDOOR
...@@ -665,6 +668,10 @@ static JSBool js_sysstats_get(JSContext *cx, JSObject *obj, jsid id, jsval *vp) ...@@ -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)); *vp = INT_TO_JSVAL(getmail(cfg, /* user: */1, /* Sent: */FALSE, /* SPAM: */FALSE));
JS_RESUMEREQUEST(cx, rc); JS_RESUMEREQUEST(cx, rc);
break; break;
case SYSSTAT_PROP_NODE_GETS:
*vp = INT_TO_JSVAL(sys->nodegets);
break;
} }
return(TRUE); return(TRUE);
...@@ -692,6 +699,7 @@ static jsSyncPropertySpec js_sysstats_properties[] = { ...@@ -692,6 +699,7 @@ static jsSyncPropertySpec js_sysstats_properties[] = {
{ "feedback_sent_today", SYSSTAT_PROP_FTODAY, SYSSTAT_FLAGS, 310 }, { "feedback_sent_today", SYSSTAT_PROP_FTODAY, SYSSTAT_FLAGS, 310 },
{ "total_users", SYSSTAT_PROP_TOTALUSERS, SYSSTAT_FLAGS, 310 }, { "total_users", SYSSTAT_PROP_TOTALUSERS, SYSSTAT_FLAGS, 310 },
{ "new_users_today", SYSSTAT_PROP_NUSERS, SYSSTAT_FLAGS, 310 }, { "new_users_today", SYSSTAT_PROP_NUSERS, SYSSTAT_FLAGS, 310 },
{ "node_gets", SYSSTAT_PROP_NODE_GETS, JSPROP_READONLY, 31702 },
{0} {0}
}; };
...@@ -1384,6 +1392,54 @@ js_filter_ip(JSContext *cx, uintN argc, jsval *arglist) ...@@ -1384,6 +1392,54 @@ js_filter_ip(JSContext *cx, uintN argc, jsval *arglist)
return(JS_TRUE); 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 static JSBool
js_get_node_message(JSContext *cx, uintN argc, jsval *arglist) js_get_node_message(JSContext *cx, uintN argc, jsval *arglist)
{ {
...@@ -1908,7 +1964,12 @@ static jsSyncMethodSpec js_system_functions[] = { ...@@ -1908,7 +1964,12 @@ static jsSyncMethodSpec js_system_functions[] = {
{"filter_ip", js_filter_ip, 4, JSTYPE_BOOLEAN, JSDOCSTR("[protocol, reason, host, ip, username, filename]") {"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") ,JSDOCSTR("add an IP address (with comment) to an IP filter file. If filename is not specified, the ip.can file is used")
,311 ,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") {"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") ,JSDOCSTR("read any messages waiting for the specified node and return in a single string")
,311 ,311
...@@ -2034,6 +2095,7 @@ static JSBool js_node_get(JSContext *cx, JSObject *obj, jsid id, jsval *vp) ...@@ -2034,6 +2095,7 @@ static JSBool js_node_get(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
return(JS_TRUE); return(JS_TRUE);
} }
JS_RESUMEREQUEST(cx, rc); JS_RESUMEREQUEST(cx, rc);
sys->nodegets++;
switch(tiny) { switch(tiny) {
case NODE_PROP_STATUS: case NODE_PROP_STATUS:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment