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 662dcdf  WIP.
662dcdf is described below

commit 662dcdf2100fb0be0b9cc3cdd8735a8c11146f2b
Author: Sergey Kamov <[email protected]>
AuthorDate: Fri Feb 18 11:25:40 2022 +0300

    WIP.
---
 .../scala/org/apache/nlpcraft/NCModelClient.java   |  3 +-
 .../conversation/NCConversationManager.scala       | 73 ++++++++--------
 .../internal/dialogflow/NCDialogFlowManager.scala  | 98 +++++++++++-----------
 .../nlpcraft/internal/impl/NCModelClientImpl.scala | 14 ++--
 .../internal/impl/NCModelPipelineManager.scala     | 22 +----
 .../internal/intent/matcher/NCIntentsManager.scala |  4 +-
 .../internal/impl/NCModelClientImplSpec.scala      |  6 +-
 7 files changed, 100 insertions(+), 120 deletions(-)

diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelClient.java 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelClient.java
index fee87cf..9f465c2 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelClient.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelClient.java
@@ -25,7 +25,7 @@ import java.util.concurrent.*;
 /**
  *
  */
-public class NCModelClient {
+public class NCModelClient implements AutoCloseable {
     private final NCModelClientImpl impl;
 
     /**
@@ -81,6 +81,7 @@ public class NCModelClient {
     /**
      * 
      */
+    @Override
     public void close() {
         impl.close();
     }
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 cc6ba84..77574da 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
@@ -32,33 +32,24 @@ class NCConversationManager(cfg: NCModelConfig) extends 
LazyLogging:
     private final val convs: mutable.Map[String, Value] = 
mutable.HashMap.empty[String, Value]
     @volatile private var gc: Thread = _
 
-    /**
-      *
-      * @return
-      */
-    def start(): Unit =
-        gc = NCUtils.mkThread("conv-mgr-gc", cfg.getId) { t =>
-            while (!t.isInterrupted)
-                try
-                    convs.synchronized {
-                        val sleepTime = clearForTimeout() - NCUtils.now()
-                        if sleepTime > 0 then
-                            logger.trace(s"${t.getName} waits for $sleepTime 
ms.")
-                            convs.wait(sleepTime)
-                    }
-                catch
-                    case _: InterruptedException => // No-op.
-                    case e: Throwable => logger.error(s"Unexpected error for 
thread: ${t.getName}", e)
-        }
-        gc.start()
 
     /**
+      * Gets conversation for given user ID.
       *
+      * @param usrId User ID.
+      * @return New or existing conversation.
       */
-    def close(): Unit =
-        NCUtils.stopThread(gc)
-        gc = null
-        convs.clear()
+    def getConversation(usrId: String): NCConversationHolder =
+        convs.synchronized {
+            val v = convs.getOrElseUpdate(
+                usrId,
+                Value(NCConversationHolder(usrId, cfg.getId, 
cfg.getConversationTimeout, cfg.getConversationDepth))
+            )
+
+            v.tstamp = NCUtils.nowUtcMs()
+            convs.notifyAll()
+            v.conv
+        }
 
     /**
       * Gets next clearing time.
@@ -84,19 +75,29 @@ class NCConversationManager(cfg: NCModelConfig) extends 
LazyLogging:
         else Long.MaxValue
 
     /**
-      * Gets conversation for given user ID.
       *
-      * @param usrId User ID.
-      * @return New or existing conversation.
+      * @return
       */
-    def getConversation(usrId: String): NCConversationHolder =
-        convs.synchronized {
-            val v = convs.getOrElseUpdate(
-                usrId,
-                Value(NCConversationHolder(usrId, cfg.getId, 
cfg.getConversationTimeout, cfg.getConversationDepth))
-            )
-
-            v.tstamp = NCUtils.nowUtcMs()
-            convs.notifyAll()
-            v.conv
+    def start(): Unit =
+        gc = NCUtils.mkThread("conv-mgr-gc", cfg.getId) { t =>
+            while (!t.isInterrupted)
+                try
+                    convs.synchronized {
+                        val sleepTime = clearForTimeout() - NCUtils.now()
+                        if sleepTime > 0 then
+                            logger.trace(s"${t.getName} waits for $sleepTime 
ms.")
+                            convs.wait(sleepTime)
+                    }
+                catch
+                    case _: InterruptedException => // No-op.
+                    case e: Throwable => logger.error(s"Unexpected error for 
thread: ${t.getName}", e)
         }
+        gc.start()
+
+    /**
+      *
+      */
+    def close(): Unit =
+        NCUtils.stopThread(gc)
+        gc = null
+        convs.clear()
diff --git 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/dialogflow/NCDialogFlowManager.scala
 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/dialogflow/NCDialogFlowManager.scala
index 7181c17..1026e3d 100644
--- 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/dialogflow/NCDialogFlowManager.scala
+++ 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/dialogflow/NCDialogFlowManager.scala
@@ -39,6 +39,31 @@ class NCDialogFlowManager(cfg: NCModelConfig) extends 
LazyLogging:
     @volatile private var gc: Thread = _
 
     /**
+      *  Gets next clearing time.
+      */
+    private def clearForTimeout(): Long =
+        require(Thread.holdsLock(flow))
+
+        val timeout = cfg.getConversationTimeout
+        val bound = NCUtils.now() - timeout
+        var next = Long.MaxValue
+
+        val delKeys = mutable.ArrayBuffer.empty[String]
+
+        for ((usrId, values) <- flow)
+            values --= values.filter(_.getRequest.getReceiveTimestamp < bound)
+
+            if values.nonEmpty then
+                val candidate = 
values.map(_.getRequest.getReceiveTimestamp).min + timeout
+                if next > candidate then next = candidate
+                else
+                    delKeys += usrId
+
+        if delKeys.nonEmpty then flow --= delKeys
+
+        next
+
+    /**
       *
       * @return
       */
@@ -60,20 +85,20 @@ class NCDialogFlowManager(cfg: NCModelConfig) extends 
LazyLogging:
 
         gc.start()
     /**
-     *
-     */
+      *
+      */
     def close(): Unit =
         NCUtils.stopThread(gc)
         gc = null
         flow.clear()
 
     /**
-     * Adds matched (winning) intent to the dialog flow.
-     *
-     * @param intentMatch
-     * @param res Intent callback result.
-     * @param ctx Original query context.
-     */
+      * Adds matched (winning) intent to the dialog flow.
+      *
+      * @param intentMatch
+      * @param res Intent callback result.
+      * @param ctx Original query context.
+      */
     def addMatchedIntent(intentMatch: NCIntentMatch, res: NCResult, ctx: 
NCContext): Unit =
         val item: NCDialogFlowItem = new NCDialogFlowItem:
             override val getIntentMatch: NCIntentMatch = intentMatch
@@ -97,10 +122,10 @@ class NCDialogFlowManager(cfg: NCModelConfig) extends 
LazyLogging:
             case None => Seq.empty
 
     /**
-     * Prints out ASCII table for current dialog flow.
-     *
-     * @param usrId User ID.
-     */
+      * Prints out ASCII table for current dialog flow.
+      *
+      * @param usrId User ID.
+      */
     def ack(usrId: String): Unit =
         val tbl = NCAsciiTable(
             "#",
@@ -123,35 +148,10 @@ class NCDialogFlowManager(cfg: NCModelConfig) extends 
LazyLogging:
         logger.info(s"""Current dialog flow (oldest first) for 
[mdlId=${cfg.getId}, usrId=$usrId]\n${tbl.toString()}""")
 
     /**
-     *  Gets next clearing time.
-     */
-    private def clearForTimeout(): Long =
-        require(Thread.holdsLock(flow))
-
-        val timeout = cfg.getConversationTimeout
-        val bound = NCUtils.now() - timeout
-        var next = Long.MaxValue
-
-        val delKeys = mutable.ArrayBuffer.empty[String]
-
-        for ((usrId, values) <- flow)
-            values --= values.filter(_.getRequest.getReceiveTimestamp < bound)
-
-            if values.nonEmpty then
-                val candidate = 
values.map(_.getRequest.getReceiveTimestamp).min + timeout
-                if next > candidate then next = candidate
-            else
-                delKeys += usrId
-
-        if delKeys.nonEmpty then flow --= delKeys
-
-        next
-
-    /**
-     * Clears dialog history for given user ID.
-     *
-     * @param usrId User ID.
-     */
+      * Clears dialog history for given user ID.
+      *
+      * @param usrId User ID.
+      */
     def clear(usrId: String): Unit =
         flow.synchronized {
             flow -= usrId
@@ -159,15 +159,15 @@ class NCDialogFlowManager(cfg: NCModelConfig) extends 
LazyLogging:
         }
 
     /**
-     * Clears dialog history for given user ID and predicate.
-     *
-     * @param usrId User ID.
-     * @param mdlId Model ID.
-     * @param pred Intent ID predicate.
-     * @param parent Parent span, if any.
-     */
+      * Clears dialog history for given user ID and predicate.
+      *
+      * @param usrId User ID.
+      * @param mdlId Model ID.
+      * @param pred Intent ID predicate.
+      * @param parent Parent span, if any.
+      */
     def clearForPredicate(usrId: String, pred: String => Boolean): Unit =
         flow.synchronized {
             flow(usrId) = flow(usrId).filterNot(v => 
pred(v.getIntentMatch.getIntentId))
             flow.notifyAll()
-        }
\ No newline at end of file
+        }
diff --git 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/impl/NCModelClientImpl.scala
 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/impl/NCModelClientImpl.scala
index 541e8e0..2666a8b 100644
--- 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/impl/NCModelClientImpl.scala
+++ 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/impl/NCModelClientImpl.scala
@@ -55,12 +55,11 @@ import scala.jdk.CollectionConverters.*
 class NCModelClientImpl(mdl: NCModel) extends LazyLogging:
     verify()
 
-    private val mdlIntents = NCModelScanner.scan(mdl)
-
+    private val intents = NCModelScanner.scan(mdl)
     private val pipelineMgr = new NCModelPipelineManager(mdl.getConfig, 
mdl.getPipeline)
     private val convMgr = NCConversationManager(mdl.getConfig)
     private val dialogMgr = NCDialogFlowManager(mdl.getConfig)
-    private val intentsMgr = NCIntentsManager(dialogMgr, mdlIntents.map(p => 
p.intent -> p.function).toMap)
+    private val intentsMgr = NCIntentsManager(dialogMgr, intents.map(p => 
p.intent -> p.function).toMap)
 
     /**
       *
@@ -78,6 +77,7 @@ class NCModelClientImpl(mdl: NCModel) extends LazyLogging:
         Objects.requireNonNull(cfg.getVersion, "Model version cannot be null.")
         Objects.requireNonNull(pipeline.getTokenParser, "Token parser cannot 
be null.")
         Objects.requireNonNull(pipeline.getEntityParsers, "List of entity 
parsers in the pipeline cannot be null.")
+
         if pipeline.getEntityParsers.isEmpty then E(s"At least one entity 
parser must be specified in the pipeline.")
 
     /**
@@ -85,7 +85,7 @@ class NCModelClientImpl(mdl: NCModel) extends LazyLogging:
       * @param data
       * @return
       */
-    private def matchVariants(data: NCPipelineVariants): NCResult =
+    private def ask0(data: NCPipelineVariants): NCResult =
         val userId = data.request.getUserId
         val convHldr = convMgr.getConversation(userId)
         val allEnts = data.variants.flatMap(_.getEntities.asScala)
@@ -121,9 +121,7 @@ class NCModelClientImpl(mdl: NCModel) extends LazyLogging:
         val check = () => if fut.isCancelled then
             E(s"Asynchronous ask is interrupted [txt=$txt, usrId=$usrId]")
 
-        fut.completeAsync(() => matchVariants(pipelineMgr.prepare(txt, data, 
usrId, Option(check))))
-
-
+        fut.completeAsync(() => ask0(pipelineMgr.prepare(txt, data, usrId, 
Option(check))))
 
     /**
       *
@@ -133,7 +131,7 @@ class NCModelClientImpl(mdl: NCModel) extends LazyLogging:
       * @return
       */
     def askSync(txt: String, data: JMap[String, AnyRef], usrId: String): 
NCResult =
-        matchVariants(pipelineMgr.prepare(txt, data, usrId))
+        ask0(pipelineMgr.prepare(txt, data, usrId))
 
     /**
       *
diff --git 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/impl/NCModelPipelineManager.scala
 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/impl/NCModelPipelineManager.scala
index d56c04e..d2758c9 100644
--- 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/impl/NCModelPipelineManager.scala
+++ 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/impl/NCModelPipelineManager.scala
@@ -59,31 +59,11 @@ class NCModelPipelineManager(cfg: NCModelConfig, pipeline: 
NCModelPipeline) exte
     private val entVals = nvl(pipeline.getEntityValidators)
     private val varFilterOpt = pipeline.getVariantFilter.toScala
 
-    private var allSrvs: Seq[NCLifecycle] =
+    private val allSrvs: Seq[NCLifecycle] =
         tokEnrichers ++ entEnrichers ++ entParsers ++ tokVals ++ entVals ++ 
varFilterOpt.toSeq
 
     processServices(_.onStart(cfg), "started")
 
-    /**
-      *
-      * @param cfg
-      * @param pipeline
-      */
-    private def init(): Unit =
-        val buf = mutable.ArrayBuffer.empty[NCLifecycle] ++ 
pipeline.getEntityParsers.asScala
-
-        def add[T <: NCLifecycle](list: JList[T]): Unit = if list != null then 
buf ++= list.asScala
-
-        add(pipeline.getTokenEnrichers)
-        add(pipeline.getTokenValidators)
-        add(pipeline.getEntityEnrichers)
-        add(pipeline.getEntityParsers)
-        add(pipeline.getEntityValidators)
-        if pipeline.getVariantFilter.isPresent then 
add(JColls.singletonList(pipeline.getVariantFilter.get()))
-
-        allSrvs = buf.toSeq
-
-        processServices(_.onStart(cfg), "started")
 
     /**
       *
diff --git 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/intent/matcher/NCIntentsManager.scala
 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/intent/matcher/NCIntentsManager.scala
index 37525e5..6f4bd88 100644
--- 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/intent/matcher/NCIntentsManager.scala
+++ 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/intent/matcher/NCIntentsManager.scala
@@ -278,7 +278,7 @@ class NCIntentsManager(dialog: NCDialogFlowManager, 
intents: Map[NCIDLIntent, NC
                         var entIdx = 0
                         for (e <- grp.usedEntities)
                             val conv = if e.conv then "(conv) " else ""
-                            ents += s"    #$entIdx: $conv${e.entity}"
+                            ents += s"    #$entIdx: 
$conv${e.entity.getId}(${e.entity.mkText()})"
                             entIdx += 1
                     else
                         ents += "    <empty>"
@@ -587,11 +587,9 @@ class NCIntentsManager(dialog: NCDialogFlowManager, 
intents: Map[NCIDLIntent, NC
             private var stopped: Boolean = false
 
             def hasNext: Boolean = !stopped
-
             def finish(data: Option[NCResult]): Unit =
                 Loop.data = Option(data)
                 Loop.stopped = true
-
             def result: Option[NCResult] = data.getOrElse(throw new 
NCRejection("No matching intent found - all intents were skipped."))
 
         for (intentRes <- intentResults.filter(_ != null) if Loop.hasNext)
diff --git 
a/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/impl/NCModelClientImplSpec.scala
 
b/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/impl/NCModelClientImplSpec.scala
index 9d09503..fee87e9 100644
--- 
a/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/impl/NCModelClientImplSpec.scala
+++ 
b/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/impl/NCModelClientImplSpec.scala
@@ -56,8 +56,10 @@ class NCModelClientImplSpec:
 
         val res = client.askSync("Lights on at second floor kitchen", null, 
"userId")
 
-        println(res.getIntentId)
-        println(res.getBody)
+        println(s"Intent: ${res.getIntentId}")
+        println(s"Body: ${res.getBody}")
+
+        client.close()
 
 
 

Reply via email to