changeset 5017:0d61efc6256c lua-heart-beat

Added Lua OnHeartBeat()
author Alain Mazy <am@osimis.io>
date Mon, 13 Jun 2022 18:54:49 +0200
parents c89ffa13173e
children eb8ca3403983
files NEWS OrthancServer/Resources/Configuration.json OrthancServer/Sources/LuaScripting.cpp OrthancServer/Sources/LuaScripting.h
diffstat 4 files changed, 60 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/NEWS	Mon Jun 13 16:55:22 2022 +0200
+++ b/NEWS	Mon Jun 13 18:54:49 2022 +0200
@@ -5,6 +5,8 @@
 -------
 
 * Lua: new "SetHttpTimeout" function
+* Lua: new "OnHeartBeat" callback called at regular interval provided that
+       you have configured "LuaHeartBeatPeriod" > 0.
 
 
 Maintenance
--- a/OrthancServer/Resources/Configuration.json	Mon Jun 13 16:55:22 2022 +0200
+++ b/OrthancServer/Resources/Configuration.json	Mon Jun 13 18:54:49 2022 +0200
@@ -52,6 +52,15 @@
   "LuaScripts" : [
   ],
 
+  // The period (in seconds) between 2 calls of the "OnHeartBeat"
+  // lua callback.  O means the heart beat is disabled.
+  // TODO: text below for Orthanc book:
+  // Note: that the period is not actually the delay between
+  // the end of an execution and the triggering of the next one.
+  // Since there is only one lua context, if other lua code is being
+  // executed, the heart beat might be delayed even more.
+  "LuaHeartBeatPeriod" : 0,
+
   // List of paths to the plugins that are to be loaded into this
   // instance of Orthanc (e.g. "./libPluginTest.so" for Linux, or
   // "./PluginTest.dll" for Windows). These paths can refer to
--- a/OrthancServer/Sources/LuaScripting.cpp	Mon Jun 13 16:55:22 2022 +0200
+++ b/OrthancServer/Sources/LuaScripting.cpp	Mon Jun 13 18:54:49 2022 +0200
@@ -759,7 +759,8 @@
 
   LuaScripting::LuaScripting(ServerContext& context) : 
     context_(context),
-    state_(State_Setup)
+    state_(State_Setup),
+    heartBeatPeriod_(0)
   {
     lua_.SetGlobalVariable("_ServerContext", &context);
     lua_.RegisterFunction("RestApiGet", RestApiGet);
@@ -782,6 +783,36 @@
     }
   }
 
+  void LuaScripting::HeartBeatThread(LuaScripting* that)
+  {
+    static const boost::posix_time::time_duration PERIODICITY =
+      boost::posix_time::seconds(that->heartBeatPeriod_);
+    
+    unsigned int sleepDelay = 100;
+    
+    boost::posix_time::ptime next =
+      boost::posix_time::microsec_clock::universal_time() + PERIODICITY;
+    
+    while (that->state_ != State_Done)
+    {
+      boost::this_thread::sleep(boost::posix_time::milliseconds(sleepDelay));
+
+      if (that->state_ != State_Done &&
+          boost::posix_time::microsec_clock::universal_time() >= next)
+      {
+        LuaScripting::Lock lock(*that);
+
+        if (lock.GetLua().IsExistingFunction("OnHeartBeat"))
+        {
+          LuaFunctionCall call(lock.GetLua(), "OnHeartBeat");
+          call.Execute();
+        }
+
+        next = boost::posix_time::microsec_clock::universal_time() + PERIODICITY;
+      }
+    }
+
+  }
 
   void LuaScripting::EventThread(LuaScripting* that)
   {
@@ -829,6 +860,14 @@
     {
       LOG(INFO) << "Starting the Lua engine";
       eventThread_ = boost::thread(EventThread, this);
+      
+      LuaScripting::Lock lock(*this);
+
+      if (heartBeatPeriod_ > 0 && lock.GetLua().IsExistingFunction("OnHeartBeat"))
+      {
+        LOG(INFO) << "Starting the Lua HeartBeat thread with a period of " << heartBeatPeriod_ << " seconds";
+        heartBeatThread_ = boost::thread(HeartBeatThread, this);
+      }
       state_ = State_Running;
     }
   }
@@ -853,6 +892,10 @@
     {
       LOG(INFO) << "Stopping the Lua engine";
       eventThread_.join();
+      if (heartBeatThread_.joinable())
+      {
+        heartBeatThread_.join();
+      }
       LOG(INFO) << "The Lua engine has stopped";
     }
   }
@@ -989,6 +1032,7 @@
 
     std::list<std::string> luaScripts;
     configLock.GetConfiguration().GetListOfStringsParameter(luaScripts, "LuaScripts");
+    heartBeatPeriod_ = configLock.GetConfiguration().GetIntegerParameter("LuaHeartBeatPeriod", 0);
 
     LuaScripting::Lock lock(*this);
 
--- a/OrthancServer/Sources/LuaScripting.h	Mon Jun 13 16:55:22 2022 +0200
+++ b/OrthancServer/Sources/LuaScripting.h	Mon Jun 13 18:54:49 2022 +0200
@@ -75,10 +75,14 @@
     LuaJobManager            jobManager_;
     State                    state_;
     boost::thread            eventThread_;
+    boost::thread            heartBeatThread_;
+    unsigned int             heartBeatPeriod_;
     SharedMessageQueue       pendingEvents_;
 
     static void EventThread(LuaScripting* that);
 
+    static void HeartBeatThread(LuaScripting* that);
+
     void LoadGlobalConfiguration();
 
   public: