Przeglądaj źródła

Added a heartbeat mechanism to avoid rouge blender instances.

Signed-off-by: Jason Dela Cruz <[email protected]>
Jason Dela Cruz 2 lat temu
rodzic
commit
0cdc4bebdc

+ 11 - 2
Gems/O3DE/GeomNodes/Code/Source/Editor/Components/EditorGeomNodesComponent.cpp

@@ -199,8 +199,17 @@ namespace GeomNodes
         jsonDocument.Parse((const char*)content, length);
         if (!jsonDocument.HasParseError())
         {
-            //TODO: need to put these hard coded text into one place
-            if (jsonDocument.HasMember(Field::Initialized))
+            // send back an "Alive" message to the client when it asks for a heartbeat. 
+            if (jsonDocument.HasMember(Field::Heartbeat))
+            {
+				AZStd::string msg = R"JSON(
+                                        {
+                                            "Alive": true 
+                                        }
+                                    )JSON";
+				m_instance->SendIPCMsg(msg);
+            }
+            else if (jsonDocument.HasMember(Field::Initialized))
             {
                 AZStd::string msg;
                 if (!m_initialized)

+ 1 - 0
Gems/O3DE/GeomNodes/Code/Source/Editor/Systems/GNParamContext.h

@@ -13,6 +13,7 @@ namespace GeomNodes
     namespace Field
     {
         static constexpr char Initialized[] = "Initialized";
+        static constexpr char Heartbeat[] = "Heartbeat";
         static constexpr char ObjectNames[] = "ObjectNames";
         static constexpr char Objects[] = "Objects";
         static constexpr char Object[] = "Object";

+ 5 - 2
Gems/O3DE/GeomNodes/External/Scripts/GeomNodes.py

@@ -32,14 +32,17 @@ def run():
     #print(json.dumps(get_o3de_materials(), indent=4))
     #print_materials_in_scene()
     
+    heartbeat_sent = False 
     while idle_time < 60:
         from lib_loader import GNLibs
         idle_time = idle_time + update_rate
 
         start = datetime.datetime.now()
-        if poll_for_messages():
+        reset, heartbeat_sent = poll_for_messages(idle_time, heartbeat_sent)
+        if reset:
             idle_time = 0
-
+        if heartbeat_sent and idle_time >= 5: # if we haven't received a reply back after some time(~5 secs) we bail out
+            break
         end = datetime.datetime.now()
         # print('Export time: ' + str((end-start).seconds + (end-start).microseconds/1000000) + 's', flush=True)
         if bpy.app.background:

+ 9 - 7
Gems/O3DE/GeomNodes/External/Scripts/messages.py

@@ -62,10 +62,7 @@ def update_gn_in_blender(msg_dict):
 
     return object_name
 
-
-
-
-def poll_for_messages():
+def poll_for_messages(idle_time: int, heartbeat_sent: bool):
     # poll if there are messages until we exhaust them.
     msg_str = MessageReader().as_string()
     if len(msg_str) > 0:
@@ -91,6 +88,11 @@ def poll_for_messages():
                     map_id = msg_dict['MapId']
                     from lib_loader import GNLibs
                     GNLibs.ClearSHM(map_id)
-
-        return True
-    return False
+        heartbeat_sent = False
+        return True, heartbeat_sent # reset idle_time as we got a message from the server
+    else:
+        if idle_time > 2 and heartbeat_sent == False:
+            MessageWriter().from_buffer(bytes(json.dumps({'Heartbeat' : True }), "UTF-8")) # send a heartbeat message to the server
+            heartbeat_sent = True
+    
+    return False, heartbeat_sent