mbeckerle commented on code in PR #879:
URL: https://github.com/apache/daffodil/pull/879#discussion_r1035064494


##########
daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/DaffodilUnparseContentHandler.scala:
##########
@@ -17,327 +17,486 @@
 
 package org.apache.daffodil.processors
 
-import scala.xml.NamespaceBinding
 
+
+import java.util.concurrent.ArrayBlockingQueue
+import java.util.concurrent.Executors
 import javax.xml.XMLConstants
+
+import scala.concurrent.Await
+import scala.concurrent.ExecutionContext
+import scala.concurrent.Future
+import scala.concurrent.duration.Duration
+
+import scala.xml.NamespaceBinding
+import scala.xml.TopScope
+
+import org.xml.sax.Attributes
+import org.xml.sax.Locator
+import org.xml.sax.SAXException
+
 import org.apache.daffodil.api.DFDL
 import org.apache.daffodil.api.DFDL.DaffodilUnhandledSAXException
 import org.apache.daffodil.api.DFDL.DaffodilUnparseErrorSAXException
-import org.apache.daffodil.api.DFDL.SAXInfosetEvent
 import org.apache.daffodil.exceptions.Assert
-import org.apache.daffodil.infoset.IllegalContentWhereEventExpected
 import org.apache.daffodil.infoset.InfosetInputterEventType.EndDocument
 import org.apache.daffodil.infoset.InfosetInputterEventType.EndElement
 import org.apache.daffodil.infoset.InfosetInputterEventType.StartDocument
 import org.apache.daffodil.infoset.InfosetInputterEventType.StartElement
 import org.apache.daffodil.infoset.SAXInfosetInputter
+import org.apache.daffodil.infoset.SAXInfosetInputterEvent
 import org.apache.daffodil.util.MStackOf
-import org.apache.daffodil.util.Maybe.Nope
+import org.apache.daffodil.util.Maybe
 import org.apache.daffodil.util.Maybe.One
 import org.apache.daffodil.util.Misc
-import org.xml.sax.Attributes
-import org.xml.sax.Locator
 
 /**
- * DaffodilUnparseContentHandler produces SAXInfosetEvent objects for the 
SAXInfosetInputter to
- * consume and convert to events that the Dataprocessor unparse can use. The 
SAXInfosetEvent object
- * is built from information that is passed to the ContentHandler from an 
XMLReader parser. In
- * order to receive the uri and prefix information from the XMLReader, the 
XMLReader must have
- * support for XML Namespaces
+ * Provides a cached thread pool that Scala Futures can use so that SAX
+ * unparse() calls can reuse threads, avoiding overhead related to creating new
+ * threads.
+ */
+object DaffodilUnparseContentHandler {
+  val executionContext = new ExecutionContext {
+    private val threadPool = Executors.newCachedThreadPool()
+    def execute(runnable: Runnable): Unit = threadPool.submit(runnable)
+
+    //$COVERAGE-OFF$
+    def reportFailure(t: Throwable): Unit = {} //do nothing
+    //$COVERAGE-ON$
+  }
+}
+
+/**
+ * DaffodilUnparseContentHandler produces SAXInfosetInputterEvent objects for
+ * the SAXInfosetInputter to consume and convert to events that the
+ * Dataprocessor unparse() can use. The SAXInfosetInputterEvents are built base
+ * on information that is passed to this ContentHandler from an XMLReader.
+ *
+ * This class runs the DataProcessor unparse() method in a separate thread,
+ * with a shared ArrayBlockigQueue to provide SAXInfosetInputerEvents. This
+ * queue has a maximum size defined by the saxUnaprseEventBatchSize tunble

Review Comment:
   tunble > tunable



##########
daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/DaffodilUnparseContentHandler.scala:
##########
@@ -17,327 +17,486 @@
 
 package org.apache.daffodil.processors
 
-import scala.xml.NamespaceBinding
 
+
+import java.util.concurrent.ArrayBlockingQueue
+import java.util.concurrent.Executors
 import javax.xml.XMLConstants
+
+import scala.concurrent.Await
+import scala.concurrent.ExecutionContext
+import scala.concurrent.Future
+import scala.concurrent.duration.Duration
+
+import scala.xml.NamespaceBinding
+import scala.xml.TopScope
+
+import org.xml.sax.Attributes
+import org.xml.sax.Locator
+import org.xml.sax.SAXException
+
 import org.apache.daffodil.api.DFDL
 import org.apache.daffodil.api.DFDL.DaffodilUnhandledSAXException
 import org.apache.daffodil.api.DFDL.DaffodilUnparseErrorSAXException
-import org.apache.daffodil.api.DFDL.SAXInfosetEvent
 import org.apache.daffodil.exceptions.Assert
-import org.apache.daffodil.infoset.IllegalContentWhereEventExpected
 import org.apache.daffodil.infoset.InfosetInputterEventType.EndDocument
 import org.apache.daffodil.infoset.InfosetInputterEventType.EndElement
 import org.apache.daffodil.infoset.InfosetInputterEventType.StartDocument
 import org.apache.daffodil.infoset.InfosetInputterEventType.StartElement
 import org.apache.daffodil.infoset.SAXInfosetInputter
+import org.apache.daffodil.infoset.SAXInfosetInputterEvent
 import org.apache.daffodil.util.MStackOf
-import org.apache.daffodil.util.Maybe.Nope
+import org.apache.daffodil.util.Maybe
 import org.apache.daffodil.util.Maybe.One
 import org.apache.daffodil.util.Misc
-import org.xml.sax.Attributes
-import org.xml.sax.Locator
 
 /**
- * DaffodilUnparseContentHandler produces SAXInfosetEvent objects for the 
SAXInfosetInputter to
- * consume and convert to events that the Dataprocessor unparse can use. The 
SAXInfosetEvent object
- * is built from information that is passed to the ContentHandler from an 
XMLReader parser. In
- * order to receive the uri and prefix information from the XMLReader, the 
XMLReader must have
- * support for XML Namespaces
+ * Provides a cached thread pool that Scala Futures can use so that SAX
+ * unparse() calls can reuse threads, avoiding overhead related to creating new
+ * threads.
+ */
+object DaffodilUnparseContentHandler {
+  val executionContext = new ExecutionContext {
+    private val threadPool = Executors.newCachedThreadPool()
+    def execute(runnable: Runnable): Unit = threadPool.submit(runnable)
+
+    //$COVERAGE-OFF$
+    def reportFailure(t: Throwable): Unit = {} //do nothing
+    //$COVERAGE-ON$
+  }
+}
+
+/**
+ * DaffodilUnparseContentHandler produces SAXInfosetInputterEvent objects for
+ * the SAXInfosetInputter to consume and convert to events that the
+ * Dataprocessor unparse() can use. The SAXInfosetInputterEvents are built base
+ * on information that is passed to this ContentHandler from an XMLReader.
+ *
+ * This class runs the DataProcessor unparse() method in a separate thread,
+ * with a shared ArrayBlockigQueue to provide SAXInfosetInputerEvents. This
+ * queue has a maximum size defined by the saxUnaprseEventBatchSize tunble

Review Comment:
   Can this be set small enough as to enforce sequential behavior, i.e., no 
parallelism between the caller of the content handler and the unparser? 
   
   I continue to be of the opinion that overlap parallelism here is not an 
advantage. It just muddies the waters about timing and overhead of unparsing. 
   
   To reduce overhead, we need to enqueue many events before context switching 
and allowing the unparser to run. Arguably, we should just queue up events to 
some max count, or until we get endDocument. For small messages we would then 
get exactly one context switch per message. 



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to