Commit a215b9fe authored by Vincent Pelletier's avatar Vincent Pelletier

Move parser instance pooling mechanism in a class for easier reuse.


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@38358 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 45f7ab81
...@@ -43,28 +43,36 @@ if __name__ == '__main__': ...@@ -43,28 +43,36 @@ if __name__ == '__main__':
else: else:
DEBUG = 0 DEBUG = 0
parser_pool = threading.local() class ParserPool(object):
"""
Per-thread parser pool, because ply is not thread-safe.
"""
@profiler_decorator def __init__(self):
def getAdvancedSearchTextDetector(): self.parser_pool = threading.local()
try: self.parser_registry = {}
return parser_pool.advanced_search_text_detector
except AttributeError:
advanced_search_text_detector = AdvancedSearchTextDetector()
advanced_search_text_detector.init(debug=DEBUG)
parser_pool.advanced_search_text_detector = advanced_search_text_detector
return advanced_search_text_detector
@profiler_decorator def register(self, parser):
def getAdvancedSearchTextParser(): parser_registry = self.parser_registry
name = (parser.__module__, parser.__name__)
if name in parser_registry:
raise ValueError, 'Duplicate parser for name %r' % (name, )
parser_registry[name] = parser
return name
def get(self, name):
try: try:
return parser_pool.parser parser = getattr(self.parser_pool, name)
except AttributeError: except AttributeError:
parser = AdvancedSearchTextParser() parser = self.parser_registry[name]()
parser.init(debug=DEBUG) parser.init(debug=DEBUG)
parser_pool.parser = parser setattr(self.parser_pool, name, parser)
return parser return parser
parser_pool = ParserPool()
DETECTOR_ID = parser_pool.register(AdvancedSearchTextDetector)
PARSER_ID = parser_pool.register(AdvancedSearchTextParser)
def safeParsingDecorator(func): def safeParsingDecorator(func):
""" """
Wrapper hiding parsing errors and returning None when they occur. Wrapper hiding parsing errors and returning None when they occur.
...@@ -84,13 +92,13 @@ def safeParsingDecorator(func): ...@@ -84,13 +92,13 @@ def safeParsingDecorator(func):
@profiler_decorator @profiler_decorator
def isAdvancedSearchText(input, is_column): def isAdvancedSearchText(input, is_column):
return getAdvancedSearchTextDetector()(input, is_column) return parser_pool.get(DETECTOR_ID)(input, is_column)
@profiler_decorator @profiler_decorator
@safeParsingDecorator @safeParsingDecorator
def parse(input, is_column, *args, **kw): def parse(input, is_column, *args, **kw):
if isAdvancedSearchText(input, is_column): if isAdvancedSearchText(input, is_column):
result = getAdvancedSearchTextParser()(input, is_column, *args, **kw) result = parser_pool.get(PARSER_ID)(input, is_column, *args, **kw)
else: else:
result = None result = None
return result return result
...@@ -328,7 +336,8 @@ if __name__ == '__main__': ...@@ -328,7 +336,8 @@ if __name__ == '__main__':
print repr(input) print repr(input)
try: try:
try: try:
detector_result = getAdvancedSearchTextDetector()(input, isColumn) detector_result = parser_pool.get(DETECTOR_ID)(input,
isColumn)
except ParserOrLexerError, message: except ParserOrLexerError, message:
print ' Detector raise: %r' % (message, ) print ' Detector raise: %r' % (message, )
detector_result = False detector_result = False
...@@ -336,7 +345,7 @@ if __name__ == '__main__': ...@@ -336,7 +345,7 @@ if __name__ == '__main__':
print ' Detector: %r' % (detector_result, ) print ' Detector: %r' % (detector_result, )
if detector_result: if detector_result:
print ' LEX:' print ' LEX:'
advanced_parser = getAdvancedSearchTextParser() advanced_parser = parser_pool.get(PARSER_ID)
lexer = advanced_parser.lexer lexer = advanced_parser.lexer
advanced_parser.isColumn = isColumn advanced_parser.isColumn = isColumn
lexer.input(input) lexer.input(input)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment