mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-03 21:43:21 +00:00 
			
		
		
		
	markdown: Replace custom cache decorator with functools.lru_cache.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
		
				
					committed by
					
						
						Tim Abbott
					
				
			
			
				
	
			
			
			
						parent
						
							d91d3146ce
						
					
				
				
					commit
					70ac144d57
				
			@@ -10,6 +10,7 @@ import urllib
 | 
				
			|||||||
import urllib.parse
 | 
					import urllib.parse
 | 
				
			||||||
from collections import deque
 | 
					from collections import deque
 | 
				
			||||||
from dataclasses import dataclass
 | 
					from dataclasses import dataclass
 | 
				
			||||||
 | 
					from functools import lru_cache
 | 
				
			||||||
from typing import (
 | 
					from typing import (
 | 
				
			||||||
    Any,
 | 
					    Any,
 | 
				
			||||||
    Callable,
 | 
					    Callable,
 | 
				
			||||||
@@ -101,24 +102,6 @@ html_safelisted_schemes = (
 | 
				
			|||||||
allowed_schemes = ("http", "https", "ftp", "file", *html_safelisted_schemes)
 | 
					allowed_schemes = ("http", "https", "ftp", "file", *html_safelisted_schemes)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def one_time(method: Callable[[], ReturnT]) -> Callable[[], ReturnT]:
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
    Use this decorator with extreme caution.
 | 
					 | 
				
			||||||
    The function you wrap should have no dependency
 | 
					 | 
				
			||||||
    on any arguments (no args, no kwargs) nor should
 | 
					 | 
				
			||||||
    it depend on any global state.
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
    val = None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def cache_wrapper() -> ReturnT:
 | 
					 | 
				
			||||||
        nonlocal val
 | 
					 | 
				
			||||||
        if val is None:
 | 
					 | 
				
			||||||
            val = method()
 | 
					 | 
				
			||||||
        return val
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return cache_wrapper
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class LinkInfo(TypedDict):
 | 
					class LinkInfo(TypedDict):
 | 
				
			||||||
    parent: Element
 | 
					    parent: Element
 | 
				
			||||||
    title: Optional[str]
 | 
					    title: Optional[str]
 | 
				
			||||||
@@ -174,7 +157,7 @@ STREAM_LINK_REGEX = rf"""
 | 
				
			|||||||
                    """
 | 
					                    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@one_time
 | 
					@lru_cache(None)
 | 
				
			||||||
def get_compiled_stream_link_regex() -> Pattern[str]:
 | 
					def get_compiled_stream_link_regex() -> Pattern[str]:
 | 
				
			||||||
    # Not using verbose_compile as it adds ^(.*?) and
 | 
					    # Not using verbose_compile as it adds ^(.*?) and
 | 
				
			||||||
    # (.*?)$ which cause extra overhead of matching
 | 
					    # (.*?)$ which cause extra overhead of matching
 | 
				
			||||||
@@ -197,7 +180,7 @@ STREAM_TOPIC_LINK_REGEX = rf"""
 | 
				
			|||||||
                   """
 | 
					                   """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@one_time
 | 
					@lru_cache(None)
 | 
				
			||||||
def get_compiled_stream_topic_link_regex() -> Pattern[str]:
 | 
					def get_compiled_stream_topic_link_regex() -> Pattern[str]:
 | 
				
			||||||
    # Not using verbose_compile as it adds ^(.*?) and
 | 
					    # Not using verbose_compile as it adds ^(.*?) and
 | 
				
			||||||
    # (.*?)$ which cause extra overhead of matching
 | 
					    # (.*?)$ which cause extra overhead of matching
 | 
				
			||||||
@@ -210,17 +193,12 @@ def get_compiled_stream_topic_link_regex() -> Pattern[str]:
 | 
				
			|||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
LINK_REGEX: Optional[Pattern[str]] = None
 | 
					@lru_cache(None)
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def get_web_link_regex() -> Pattern[str]:
 | 
					def get_web_link_regex() -> Pattern[str]:
 | 
				
			||||||
    # We create this one time, but not at startup.  So the
 | 
					    # We create this one time, but not at startup.  So the
 | 
				
			||||||
    # first message rendered in any process will have some
 | 
					    # first message rendered in any process will have some
 | 
				
			||||||
    # extra costs.  It's roughly 75ms to run this code, so
 | 
					    # extra costs.  It's roughly 75ms to run this code, so
 | 
				
			||||||
    # caching the value in LINK_REGEX is super important here.
 | 
					    # caching the value is super important here.
 | 
				
			||||||
    global LINK_REGEX
 | 
					 | 
				
			||||||
    if LINK_REGEX is not None:
 | 
					 | 
				
			||||||
        return LINK_REGEX
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    tlds = "|".join(list_of_tlds())
 | 
					    tlds = "|".join(list_of_tlds())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -269,16 +247,14 @@ def get_web_link_regex() -> Pattern[str]:
 | 
				
			|||||||
            (?:\Z|\s)                  # followed by whitespace or end of string
 | 
					            (?:\Z|\s)                  # followed by whitespace or end of string
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
    LINK_REGEX = verbose_compile(REGEX)
 | 
					    return verbose_compile(REGEX)
 | 
				
			||||||
    return LINK_REGEX
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def clear_state_for_testing() -> None:
 | 
					def clear_state_for_testing() -> None:
 | 
				
			||||||
    # The link regex never changes in production, but our tests
 | 
					    # The link regex never changes in production, but our tests
 | 
				
			||||||
    # try out both sides of ENABLE_FILE_LINKS, so we need
 | 
					    # try out both sides of ENABLE_FILE_LINKS, so we need
 | 
				
			||||||
    # a way to clear it.
 | 
					    # a way to clear it.
 | 
				
			||||||
    global LINK_REGEX
 | 
					    get_web_link_regex.cache_clear()
 | 
				
			||||||
    LINK_REGEX = None
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
markdown_logger = logging.getLogger()
 | 
					markdown_logger = logging.getLogger()
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user