This is an automated email from the ASF dual-hosted git repository. aradzinski 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 7c35083 WIP 7c35083 is described below commit 7c3508314ea1c904a9689a583e66ed471e0aff9d Author: Aaron Radzinski <aradzin...@datalingvo.com> AuthorDate: Wed Feb 2 10:22:15 2022 -0800 WIP --- .../scala/org/apache/nlpcraft/NCModelConfig.java | 38 ++++++++++++++ ...nversation.scala => NCConversationHolder.scala} | 2 +- .../conversation/NCConversationManager.scala | 58 ++++++++-------------- .../impl/scan/NCModelIntentsNestedSpec.scala | 3 +- 4 files changed, 62 insertions(+), 39 deletions(-) diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfig.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfig.java index e29411f..dfd8f96 100644 --- a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfig.java +++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfig.java @@ -17,13 +17,19 @@ package org.apache.nlpcraft; +import java.time.Duration; import java.util.*; /** * */ public class NCModelConfig extends NCPropertyMapAdapter { + public final long DFLT_CONV_TIMEOUT = Duration.ofMinutes(60).toMillis(); + public final int DFLT_CONV_DEPTH = 3; + private final String id, name, ver, desc, origin; + private long convTimeout = DFLT_CONV_TIMEOUT; + private int convDepth = DFLT_CONV_DEPTH; /** * @param id @@ -100,4 +106,36 @@ public class NCModelConfig extends NCPropertyMapAdapter { public String getOrigin() { return origin; } + + /** + * + * @return + */ + public long getConversationTimeout() { + return convTimeout; + } + + /** + * + * @param convTimeout + */ + public void setConversationTimeout(long convTimeout) { + this.convTimeout = convTimeout; + } + + /** + * + * @return + */ + public int getConversationDepth() { + return convDepth; + } + + /** + * + * @param convDepth + */ + public void setConversationDepth(int convDepth) { + this.convDepth = convDepth; + } } diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/conversation/NCConversation.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/conversation/NCConversationHolder.scala similarity index 99% rename from nlpcraft/src/main/scala/org/apache/nlpcraft/internal/conversation/NCConversation.scala rename to nlpcraft/src/main/scala/org/apache/nlpcraft/internal/conversation/NCConversationHolder.scala index e694bee..bad168c 100644 --- a/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/conversation/NCConversation.scala +++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/conversation/NCConversationHolder.scala @@ -32,7 +32,7 @@ import scala.jdk.CollectionConverters.* /** * An active conversation is an ordered set of utterances for the specific user and data model. */ -case class NCConversation( +case class NCConversationHolder( usrId: Long, mdlId: String, timeoutMs: Long, 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 d916e37..2b87f6a 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 @@ -17,38 +17,36 @@ package org.apache.nlpcraft.internal.conversation -import io.opencensus.trace.Span -import org.apache.nlpcraft.common._ -import org.apache.nlpcraft.probe.mgrs.model.NCModelManager +import com.typesafe.scalalogging.LazyLogging +import org.apache.nlpcraft.* +import org.apache.nlpcraft.internal.util.NCUtils -import scala.collection._ +import scala.collection.* /** * Conversation manager. */ -object NCConversationManager: +class NCConversationManager(mdlCfg: NCModelConfig) extends LazyLogging: case class Key(usrId: Long, mdlId: String) - case class Value(conv: NCConversation, var tstamp: Long = 0) - + case class Value(conv: NCConversationHolder, var tstamp: Long = 0) private final val convs: mutable.Map[Key, Value] = mutable.HashMap.empty[Key, Value] - @volatile private var gc: Thread = _ /** * * @return */ - def start(): NCService = - gc = NCUtils.mkThread("conversation-manager-gc") { t => + def start(): Unit = + gc = NCUtils.mkThread(s"conv-mgr-gc-@${mdlCfg.getId}") { t => while (!t.isInterrupted) try convs.synchronized { - val sleepTime = clearForTimeout() - U.now() + val sleepTime = clearForTimeout() - NCUtils.now() if sleepTime > 0 then convs.wait(sleepTime) } catch case _: InterruptedException => // No-op. - case e: Throwable => U.prettyError(logger, s"Unexpected error for thread: ${t.getName}", e) + case e: Throwable => logger.error(s"Unexpected error for thread: ${t.getName}", e) } gc.start() @@ -66,16 +64,11 @@ object NCConversationManager: private def clearForTimeout(): Long = require(Thread.holdsLock(convs)) - val now = U.now() + val now = NCUtils.now() val delKeys = mutable.HashSet.empty[Key] for ((key, value) <- convs) - val del = - NCModelManager.getModelOpt(key.mdlId) match - case Some(mdl) => value.tstamp < now - mdl.model.getConversationTimeout - case None => true - - if del then + if value.tstamp < now - mdlCfg.getConversationTimeout then value.conv.getUserData.clear() delKeys += key @@ -91,21 +84,14 @@ object NCConversationManager: * @param mdlId Model ID. * @return New or existing conversation. */ - def getConversation(usrId: Long, mdlId: String, parent: Span = null): NCConversation = - startScopedSpan("getConversation", parent, "usrId" -> usrId, "mdlId" -> mdlId) { _ => - val mdl = NCModelManager.getModel(mdlId).model - - convs.synchronized { - val v = convs.getOrElseUpdate( - Key(usrId, mdlId), - Value(NCConversation(usrId, mdlId, mdl.getConversationTimeout, mdl.getConversationDepth)) - ) - - v.tstamp = U.nowUtcMs() - - convs.notifyAll() - - v.conv - } + def getConversation(usrId: Long, mdlId: String): NCConversationHolder = + convs.synchronized { + val v = convs.getOrElseUpdate( + Key(usrId, mdlId), + Value(NCConversationHolder(usrId, mdlId, mdlCfg.getConversationTimeout, mdlCfg.getConversationDepth)) + ) + + v.tstamp = NCUtils.nowUtcMs() + convs.notifyAll() + v.conv } -} diff --git a/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/impl/scan/NCModelIntentsNestedSpec.scala b/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/impl/scan/NCModelIntentsNestedSpec.scala index 91e2f09..833832b 100644 --- a/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/impl/scan/NCModelIntentsNestedSpec.scala +++ b/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/impl/scan/NCModelIntentsNestedSpec.scala @@ -50,8 +50,7 @@ class NCModelIntentsNestedSpec: private val MDL_VALID2: NCModel = new NCTestModelAdapter: @NCIntent("import('scan/idl.idl')") - class RefClass: - () + class RefClass @NCIntentObject val nested1: Object = new Object():