[#8382] avoid a py3 ming error (on py2 I think flush silently misses the task until the next request flushes)
diff --git a/Allura/allura/config/middleware.py b/Allura/allura/config/middleware.py
index 2e06bb7..a4f8132 100644
--- a/Allura/allura/config/middleware.py
+++ b/Allura/allura/config/middleware.py
@@ -65,6 +65,7 @@
 from allura.lib.custom_middleware import LoginRedirectMiddleware
 from allura.lib.custom_middleware import RememberLoginMiddleware
 from allura.lib.custom_middleware import SetRequestHostFromConfig
+from allura.lib.custom_middleware import MingTaskSessionSetupMiddleware
 from allura.lib import helpers as h
 
 __all__ = ['make_app']
@@ -191,6 +192,7 @@
     # Handle static files (by tool)
     app = StaticFilesMiddleware(app, app_conf.get('static.script_name'))
     # Handle setup and flushing of Ming ORM sessions
+    app = MingTaskSessionSetupMiddleware(app)
     app = MingMiddleware(app)
     # Set up the registry for stacked object proxies (SOPs).
     #    streaming=true ensures they won't be cleaned up till
diff --git a/Allura/allura/lib/custom_middleware.py b/Allura/allura/lib/custom_middleware.py
index 2422981..b38b0b9 100644
--- a/Allura/allura/lib/custom_middleware.py
+++ b/Allura/allura/lib/custom_middleware.py
@@ -31,6 +31,7 @@
 from webob import exc, Request
 import pysolr
 import six
+from ming.odm import session
 
 from allura.lib import helpers as h
 from allura import model as M
@@ -434,3 +435,28 @@
             return start_response(status, headers, exc_info)
 
         return self.app(environ, remember_login_start_response)
+
+
+class MingTaskSessionSetupMiddleware(object):
+    '''
+    This middleware ensures there is a "task" session always established.  This avoids:
+
+          File ".../ming/odm/middleware.py", line 31, in __call__
+            self._cleanup_request()
+          File ".../ming/odm/middleware.py", line 45, in _cleanup_request
+            ThreadLocalODMSession.flush_all()
+          File ".../ming/odm/odmsession.py", line 414, in flush_all
+            for sess in cls._session_registry.values():
+        RuntimeError: dictionary changed size during iteration
+
+    Which would happen when IndexerSessionExtension establishes the first "task" session during a flush of a
+    different session
+    '''
+
+    def __init__(self, app):
+        self.app = app
+
+    def __call__(self, environ, start_response):
+        # this is sufficient to ensure an ODM session is always established
+        session(M.MonQTask).impl
+        return self.app(environ, start_response)