Browse Source

app_jsdt: rpc js script reload

Daniel-Constantin Mierla 8 years ago
parent
commit
96da7ff441
1 changed files with 94 additions and 10 deletions
  1. 94 10
      src/modules/app_jsdt/app_jsdt_api.c

+ 94 - 10
src/modules/app_jsdt/app_jsdt_api.c

@@ -28,6 +28,7 @@
 #include "../../core/dprint.h"
 #include "../../core/dprint.h"
 #include "../../core/pvar.h"
 #include "../../core/pvar.h"
 #include "../../core/sr_module.h"
 #include "../../core/sr_module.h"
+#include "../../core/mem/shm.h"
 #include "../../core/rpc.h"
 #include "../../core/rpc.h"
 #include "../../core/rpc_lookup.h"
 #include "../../core/rpc_lookup.h"
 
 
@@ -53,6 +54,9 @@ static sr_jsdt_env_t _sr_J_env = {0};
 
 
 str _sr_jsdt_load_file = STR_NULL;
 str _sr_jsdt_load_file = STR_NULL;
 
 
+static int *_sr_jsdt_reload_version = NULL;
+static int _sr_jsdt_local_version = 0;
+
 /**
 /**
  *
  *
  */
  */
@@ -603,11 +607,37 @@ static int jsdt_load_file(duk_context *ctx, const char *filename)
  */
  */
 int jsdt_sr_init_mod(void)
 int jsdt_sr_init_mod(void)
 {
 {
+	if(_sr_jsdt_reload_version == NULL) {
+		_sr_jsdt_reload_version = (int*)shm_malloc(sizeof(int));
+		if(_sr_jsdt_reload_version == NULL) {
+			LM_ERR("failed to allocated reload version\n");
+			return -1;
+		}
+		*_sr_jsdt_reload_version = 0;
+	}
 	memset(&_sr_J_env, 0, sizeof(sr_jsdt_env_t));
 	memset(&_sr_J_env, 0, sizeof(sr_jsdt_env_t));
 
 
 	return 0;
 	return 0;
 }
 }
 
 
+/**
+ *
+ */
+int jsdt_kemi_load_script(void)
+{
+	if(jsdt_load_file(_sr_J_env.JJ, _sr_jsdt_load_file.s)<0) {
+		LM_ERR("failed to load js script file: %.*s\n",
+				_sr_jsdt_load_file.len, _sr_jsdt_load_file.s);
+		return -1;
+	}
+	if (duk_peval(_sr_J_env.JJ) != 0) {
+		LM_ERR("failed running: %s\n", duk_safe_to_string(_sr_J_env.JJ, -1));
+		duk_pop(_sr_J_env.JJ);  /* ignore result */
+		return -1;
+	}
+	duk_pop(_sr_J_env.JJ);  /* ignore result */
+	return 0;
+}
 /**
 /**
  *
  *
  */
  */
@@ -629,17 +659,9 @@ int jsdt_sr_init_child(void)
 		jsdt_sr_kemi_register_libs(_sr_J_env.JJ);
 		jsdt_sr_kemi_register_libs(_sr_J_env.JJ);
 		LM_DBG("loading js script file: %.*s\n",
 		LM_DBG("loading js script file: %.*s\n",
 				_sr_jsdt_load_file.len, _sr_jsdt_load_file.s);
 				_sr_jsdt_load_file.len, _sr_jsdt_load_file.s);
-		if(jsdt_load_file(_sr_J_env.JJ, _sr_jsdt_load_file.s)<0) {
-			LM_ERR("failed to load js script file: %.*s\n",
-					_sr_jsdt_load_file.len, _sr_jsdt_load_file.s);
-			return -1;
-		}
-		if (duk_peval(_sr_J_env.JJ) != 0) {
-			LM_ERR("failed running: %s\n", duk_safe_to_string(_sr_J_env.JJ, -1));
-			duk_pop(_sr_J_env.JJ);  /* ignore result */
+		if(jsdt_kemi_load_script()<0) {
 			return -1;
 			return -1;
 		}
 		}
-		duk_pop(_sr_J_env.JJ);  /* ignore result */
 	}
 	}
 	LM_DBG("JS initialized!\n");
 	LM_DBG("JS initialized!\n");
 	return 0;
 	return 0;
@@ -661,6 +683,38 @@ void jsdt_sr_destroy(void)
 	memset(&_sr_J_env, 0, sizeof(sr_jsdt_env_t));
 	memset(&_sr_J_env, 0, sizeof(sr_jsdt_env_t));
 }
 }
 
 
+/**
+ *
+ */
+int jsdt_kemi_reload_script(void)
+{
+	int v;
+	if(_sr_jsdt_load_file.s == NULL && _sr_jsdt_load_file.len<=0) {
+		LM_WARN("script file path not provided\n");
+		return -1;
+	}
+	if(_sr_jsdt_reload_version == NULL) {
+		LM_WARN("reload not enabled\n");
+		return -1;
+	}
+	if(_sr_J_env.JJ==NULL) {
+		LM_ERR("load JS context not created\n");
+		return -1;
+	}
+
+	v = *_sr_jsdt_reload_version;
+	if(v == _sr_jsdt_local_version) {
+		/* same version */
+		return 0;
+	}
+	LM_DBG("reloading js script file: %.*s (%d => %d)\n",
+				_sr_jsdt_load_file.len, _sr_jsdt_load_file.s,
+				_sr_jsdt_local_version, v);
+	jsdt_kemi_load_script();
+	_sr_jsdt_local_version = v;
+	return 0;
+}
+
 /**
 /**
  *
  *
  */
  */
@@ -677,6 +731,7 @@ int app_jsdt_run_ex(sip_msg_t *msg, char *func, char *p1, char *p2,
 		return -1;
 		return -1;
 	}
 	}
 	/* check the script version loaded */
 	/* check the script version loaded */
+	jsdt_kemi_reload_script();
 
 
 	LM_DBG("executing js function: [[%s]]\n", func);
 	LM_DBG("executing js function: [[%s]]\n", func);
 	LM_DBG("js top index is: %d\n", duk_get_top(_sr_J_env.JJ));
 	LM_DBG("js top index is: %d\n", duk_get_top(_sr_J_env.JJ));
@@ -775,6 +830,8 @@ int app_jsdt_runstring(sip_msg_t *msg, char *script)
 		return -1;
 		return -1;
 	}
 	}
 
 
+	jsdt_kemi_reload_script();
+
 	LM_DBG("running js string: [[%s]]\n", script);
 	LM_DBG("running js string: [[%s]]\n", script);
 	LM_DBG("js top index is: %d\n", duk_get_top(_sr_J_env.JJ));
 	LM_DBG("js top index is: %d\n", duk_get_top(_sr_J_env.JJ));
 	bmsg = _sr_J_env.msg;
 	bmsg = _sr_J_env.msg;
@@ -1226,7 +1283,34 @@ static const char* app_jsdt_rpc_reload_doc[2] = {
 
 
 static void app_jsdt_rpc_reload(rpc_t* rpc, void* ctx)
 static void app_jsdt_rpc_reload(rpc_t* rpc, void* ctx)
 {
 {
-	rpc->fault(ctx, 500, "Not implemented");
+	int v;
+	void *vh;
+
+	if(_sr_jsdt_load_file.s == NULL && _sr_jsdt_load_file.len<=0) {
+		LM_WARN("script file path not provided\n");
+		rpc->fault(ctx, 500, "No script file");
+		return;
+	}
+	if(_sr_jsdt_reload_version == NULL) {
+		LM_WARN("reload not enabled\n");
+		rpc->fault(ctx, 500, "Reload not enabled");
+		return;
+	}
+
+	LM_INFO("marking for reload js script file: %.*s (%d => %d)\n",
+				_sr_jsdt_load_file.len, _sr_jsdt_load_file.s,
+				_sr_jsdt_local_version, v);
+
+	v = *_sr_jsdt_reload_version;
+	*_sr_jsdt_reload_version += 1;
+
+	if (rpc->add(ctx, "{", &vh) < 0) {
+		rpc->fault(ctx, 500, "Server error");
+		return;
+	}
+	rpc->struct_add(vh, "dd",
+			"old", v,
+			"new", *_sr_jsdt_reload_version);
 }
 }
 
 
 static const char* app_jsdt_rpc_api_list_doc[2] = {
 static const char* app_jsdt_rpc_api_list_doc[2] = {