Github user tliron commented on a diff in the pull request:
https://github.com/apache/incubator-ariatosca/pull/207#discussion_r153007941
--- Diff: aria/parser/consumption/presentation.py ---
@@ -86,52 +73,193 @@ def dump(self):
self.context.presentation.presenter._dump(self.context)
def _handle_exception(self, e):
- if isinstance(e, AlreadyReadException):
+ if isinstance(e, _Skip):
return
super(Read, self)._handle_exception(e)
- def _present(self, location, origin_location, presenter_class,
executor):
+ def _present_all(self):
+ location = self.context.presentation.location
+
+ if location is None:
+ self.context.validation.report('Read consumer: missing
location')
+ return
+
+ executor = self.context.presentation.create_executor()
+ try:
+ # This call may recursively submit tasks to the executor if
there are imports
+ main = self._present(location, None, None, executor)
+
+ # Wait for all tasks to complete
+ executor.drain()
+
+ # Handle exceptions
+ for e in executor.exceptions:
+ self._handle_exception(e)
+
+ results = executor.returns or []
+ finally:
+ executor.close()
+
+ results.insert(0, main)
+
+ return main, results
+
+ def _present(self, location, origin_canonical_location,
origin_presenter_class, executor):
# Link the context to this thread
self.context.set_thread_local()
- raw = self._read(location, origin_location)
+ # Canonicalize the location
+ if self.context.reading.reader is None:
+ loader, canonical_location = self._create_loader(location,
origin_canonical_location)
+ else:
+ # If a reader is specified in the context then we skip loading
+ loader = None
+ canonical_location = location
+
+ # Skip self imports
+ if canonical_location == origin_canonical_location:
+ raise _Skip()
+
+ if self.context.presentation.cache:
+ # Is the presentation in the global cache?
+ try:
+ presentation = PRESENTATION_CACHE[canonical_location]
--- End diff --
Yes there is. An "if" statement plus a retrieval statement are non-atomic,
and since we are in a concurrent situation it's possible that between the if
and the retrieval that the data will removed from the cache, causing the
retrieval to fail with an exception even though the "if" succeeded. A single
retrieval is atomic.
(This is the generally the idiomatic "Python way" to do this -- always
choose the atomic!)
---