This is an automated email from the ASF dual-hosted git repository.

sergeykamov pushed a commit to branch NLPCRAFT-477
in repository https://gitbox.apache.org/repos/asf/incubator-nlpcraft.git


The following commit(s) were added to refs/heads/NLPCRAFT-477 by this push:
     new a9dd255  Dialog manager added.
a9dd255 is described below

commit a9dd2551fdea773701eb0e3733ba4c4a5aec93b4
Author: Sergey Kamov <[email protected]>
AuthorDate: Thu Feb 3 16:30:33 2022 +0300

    Dialog manager added.
---
 .../conversation/NCConversationHolder.scala        |  4 +-
 .../conversation/NCConversationManager.scala       | 15 ++--
 .../conversation/NCConversationManagerSpec.scala   | 95 ++++++++++++++++++++++
 .../dialogflow/NCDialogFlowManagerSpec.scala       |  4 +-
 4 files changed, 106 insertions(+), 12 deletions(-)

diff --git 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/conversation/NCConversationHolder.scala
 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/conversation/NCConversationHolder.scala
index de4a0e5..7d62dd5 100644
--- 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/conversation/NCConversationHolder.scala
+++ 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/conversation/NCConversationHolder.scala
@@ -33,7 +33,7 @@ import scala.jdk.CollectionConverters.*
   * An active conversation is an ordered set of utterances for the specific 
user and data model.
   */
 case class NCConversationHolder(
-    usrId: Long,
+    usrId: String,
     mdlId: String,
     timeoutMs: Long,
     maxDepth: Int
@@ -206,7 +206,7 @@ case class NCConversationHolder(
       *
       * @return
       */
-    def getEntity: util.List[NCEntity] =
+    def getEntities: util.List[NCEntity] =
         stm.synchronized {
             val reqIds = ctx.map(_.getRequestId).distinct.zipWithIndex.toMap
             val ents = ctx.groupBy(_.getRequestId).toSeq.sortBy(p => 
reqIds(p._1)).reverse.flatMap(_._2)
diff --git 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/conversation/NCConversationManager.scala
 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/conversation/NCConversationManager.scala
index 0a58184..4377e32 100644
--- 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/conversation/NCConversationManager.scala
+++ 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/conversation/NCConversationManager.scala
@@ -27,9 +27,8 @@ import scala.collection.*
   * Conversation manager.
   */
 class NCConversationManager(mdlCfg: NCModelConfig) extends LazyLogging:
-    case class Key(usrId: Long, mdlId: String)
     case class Value(conv: NCConversationHolder, var tstamp: Long = 0)
-    private final val convs: mutable.Map[Key, Value] = 
mutable.HashMap.empty[Key, Value]
+    private final val convs: mutable.Map[String, Value] = 
mutable.HashMap.empty[String, Value]
     @volatile private var gc: Thread = _
 
     /**
@@ -67,30 +66,30 @@ class NCConversationManager(mdlCfg: NCModelConfig) extends 
LazyLogging:
         require(Thread.holdsLock(convs))
 
         val now = NCUtils.now()
-        val delKeys = mutable.HashSet.empty[Key]
+        val delKeys = mutable.HashSet.empty[String]
 
         for ((key, value) <- convs)
             if value.tstamp < now - mdlCfg.getConversationTimeout then
                 value.conv.getUserData.clear()
                 delKeys += key
 
+
         convs --= delKeys
 
         if convs.nonEmpty then convs.values.map(v => v.tstamp + 
v.conv.timeoutMs).min
         else Long.MaxValue
 
     /**
-      * Gets conversation for given key.
+      * Gets conversation for given user ID.
       *
       * @param usrId User ID.
-      * @param mdlId Model ID.
       * @return New or existing conversation.
       */
-    def getConversation(usrId: Long, mdlId: String): NCConversationHolder =
+    def getConversation(usrId: String): NCConversationHolder =
         convs.synchronized {
             val v = convs.getOrElseUpdate(
-                Key(usrId, mdlId),
-                Value(NCConversationHolder(usrId, mdlId, 
mdlCfg.getConversationTimeout, mdlCfg.getConversationDepth))
+                usrId,
+                Value(NCConversationHolder(usrId, mdlCfg.getId, 
mdlCfg.getConversationTimeout, mdlCfg.getConversationDepth))
             )
 
             v.tstamp = NCUtils.nowUtcMs()
diff --git 
a/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/conversation/NCConversationManagerSpec.scala
 
b/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/conversation/NCConversationManagerSpec.scala
new file mode 100644
index 0000000..61af791
--- /dev/null
+++ 
b/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/conversation/NCConversationManagerSpec.scala
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.nlpcraft.internal.conversation
+
+import org.apache.nlpcraft.*
+import org.apache.nlpcraft.nlp.util.*
+import org.junit.jupiter.api.Test
+
+import java.util.function.Predicate
+
+/**
+  *
+  */
+class NCConversationManagerSpec:
+    case class ModelConfigMock(timeout: Long = Long.MaxValue) extends 
NCModelConfig("testId", "test", "1.0", "Test description", "Test origin"):
+        override def getConversationTimeout: Long = timeout
+
+    @Test
+    def test(): Unit =
+        val mgr = NCConversationManager(ModelConfigMock())
+        val t = NCTestToken()
+        val reqId = "req1"
+
+        val conv = mgr.getConversation("user1")
+
+        def checkSize(size: Int): Unit =
+            require(conv.getEntities.size() == size, s"Unexpected entities 
size: ${conv.getEntities.size()}, expected: $size")
+
+        // Initial empty.
+        checkSize(0)
+
+        // Added. Still empty.
+        conv.addEntities(reqId, Seq(NCTestEntity("e1", reqId, tokens = t), 
NCTestEntity("e2", reqId, tokens = t)))
+        checkSize(0)
+
+        // Updated. Not empty.
+        conv.updateEntities()
+        checkSize(2)
+
+        // Partially cleared.
+        conv.clearEntities(new Predicate[NCEntity]:
+            override def test(t: NCEntity): Boolean = t.getId == "e1"
+        )
+        checkSize(1)
+        require(conv.getEntities.get(0).getId == "e2")
+
+    @Test
+    def testTimeout(): Unit =
+        val timeout = 1000
+
+        val mgr = NCConversationManager(ModelConfigMock(timeout))
+        val t = NCTestToken()
+        val reqId = "req1"
+
+        // TODO: Drop method and use saved conversation instead - error is 
thrown
+        def getConversation: NCConversationHolder = 
mgr.getConversation("user1")
+
+        def checkSize(size: Int): Unit =
+            val conv = getConversation
+            require(conv.getEntities.size() == size, s"Unexpected entities 
size: ${conv.getEntities.size()}, expected: $size")
+
+        // Initial empty.
+        checkSize(0)
+
+        // Added. Still empty.
+        getConversation.addEntities(reqId, Seq(NCTestEntity("e1", reqId, 
tokens = t), NCTestEntity("e2", reqId, tokens = t)))
+        checkSize(0)
+
+        // Updated. Not empty.
+        getConversation.updateEntities()
+        checkSize(2)
+
+        // Cleared by timeout.
+        try
+            mgr.start()
+            Thread.sleep(timeout * 2)
+            checkSize(0)
+        finally
+            mgr.stop()
+
diff --git 
a/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/dialogflow/NCDialogFlowManagerSpec.scala
 
b/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/dialogflow/NCDialogFlowManagerSpec.scala
index be1b559..5e26746 100644
--- 
a/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/dialogflow/NCDialogFlowManagerSpec.scala
+++ 
b/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/dialogflow/NCDialogFlowManagerSpec.scala
@@ -19,8 +19,8 @@ package org.apache.nlpcraft.internal.dialogflow
 
 import org.apache.nlpcraft.internal.util.NCUtils
 import org.apache.nlpcraft.nlp.util.NCTestRequest
-import org.apache.nlpcraft.{NCContext, NCConversation, NCEntity, 
NCIntentMatch, NCModelConfig, NCRequest, NCResult, NCVariant}
-import org.junit.jupiter.api.{AfterEach, Test}
+import org.apache.nlpcraft.*
+import org.junit.jupiter.api.*
 
 import java.util
 

Reply via email to