|
1 | 1 | # Copyright: 2011 MoinMoin:RonnyPfannschmidt |
2 | 2 | # Copyright: 2011 MoinMoin:ThomasWaldmann |
3 | 3 | # Copyright: 2011 MoinMoin:MichaelMayorov |
4 | | -# Copyright: 2024 MoinMoin:UlrichB |
| 4 | +# Copyright: 2024-2025 MoinMoin:UlrichB |
5 | 5 | # License: GNU GPL v2 (or any later version), see LICENSE.txt for details. |
6 | 6 |
|
7 | 7 | """ |
|
105 | 105 | INDEXER_TIMEOUT = 20.0 |
106 | 106 |
|
107 | 107 |
|
108 | | -def get_indexer(fn, **kw): |
109 | | - """ |
110 | | - Return a valid indexer or raise a KeyError. |
111 | | -
|
112 | | - Under heavy loads, the Whoosh AsyncWriter writer may be delayed in writing |
113 | | - indexes to storage. Try several times before failing. |
114 | | -
|
115 | | - FIXME: runs into timeout for a non-existing revid |
116 | | -
|
117 | | - :param fn: the indexer function |
118 | | - :param **kw: "revid" is required, index name optional |
119 | | - """ |
120 | | - until = time.time() + INDEXER_TIMEOUT |
121 | | - while True: |
122 | | - indexer = fn(**kw) |
123 | | - if indexer is not None: |
124 | | - break |
125 | | - time.sleep(2) |
126 | | - if time.time() > until: |
127 | | - raise KeyError(kw.get("revid", "") + " - server overload or corrupt index") |
128 | | - return indexer |
129 | | - |
130 | | - |
131 | 108 | def parent_names(names): |
132 | 109 | """ |
133 | 110 | Compute list of parent names (same order as in names, but no dupes) |
@@ -1045,6 +1022,31 @@ def existing_item(self, **query): |
1045 | 1022 | """ |
1046 | 1023 | return Item.existing(self, **query) |
1047 | 1024 |
|
| 1025 | + def get_document(self, revid: str, retry: bool = False, **kwargs): |
| 1026 | + """ |
| 1027 | + Return a valid indexer document or raise a KeyError. |
| 1028 | +
|
| 1029 | + Under heavy loads, the Whoosh AsyncWriter writer may be delayed in writing |
| 1030 | + indexes to storage. Try several times before failing. |
| 1031 | +
|
| 1032 | + :param revid: revision to search |
| 1033 | + :param retry: retry backend search if document not found, required when server load is high |
| 1034 | + :param kwargs: idx_name, name of index used for searching (optional) |
| 1035 | + """ |
| 1036 | + until = time.monotonic() + INDEXER_TIMEOUT |
| 1037 | + while True: |
| 1038 | + doc = self._document(revid=revid, **kwargs) |
| 1039 | + if doc is not None: |
| 1040 | + break |
| 1041 | + if not retry: |
| 1042 | + msg = f"revid: {revid} not found. Please check meta data and indexes" |
| 1043 | + raise KeyError(msg) |
| 1044 | + if time.monotonic() > until: |
| 1045 | + msg = f"revid: {revid} - Server overload may have corrupted the index; rebuild it." |
| 1046 | + raise KeyError(msg) |
| 1047 | + time.sleep(2) |
| 1048 | + return doc |
| 1049 | + |
1048 | 1050 |
|
1049 | 1051 | class PropertiesMixin: |
1050 | 1052 | """ |
@@ -1357,9 +1359,9 @@ def store_revision( |
1357 | 1359 | self.indexer.index_revision(meta, content, backend_name, force_latest=not overwrite) |
1358 | 1360 | gc.collect() # triggers close of index files from is_latest search |
1359 | 1361 | if not overwrite: |
1360 | | - self._current = get_indexer(self.indexer._document, revid=revid) |
| 1362 | + self._current = self.indexer.get_document(revid=revid, retry=True) |
1361 | 1363 | if return_rev: |
1362 | | - return Revision(self, revid) |
| 1364 | + return Revision(self, revid, retry=True) |
1363 | 1365 |
|
1364 | 1366 | def store_all_revisions(self, meta, data): |
1365 | 1367 | """ |
@@ -1404,13 +1406,13 @@ class Revision(PropertiesMixin): |
1404 | 1406 | An existing revision (exists in the backend). |
1405 | 1407 | """ |
1406 | 1408 |
|
1407 | | - def __init__(self, item: Item, revid: str, doc=None, name=None): |
| 1409 | + def __init__(self, item: Item, revid: str, doc=None, name=None, retry=False): |
1408 | 1410 | is_current = revid == CURRENT |
1409 | 1411 | if doc is None: |
1410 | 1412 | if is_current: |
1411 | 1413 | doc = item._current |
1412 | 1414 | else: |
1413 | | - doc = get_indexer(item.indexer._document, idx_name=ALL_REVS, revid=revid) |
| 1415 | + doc = item.indexer.get_document(idx_name=ALL_REVS, revid=revid, retry=retry) |
1414 | 1416 |
|
1415 | 1417 | if is_current: |
1416 | 1418 | revid = doc.get(REVID) |
|
0 commit comments