Skip to content

Commit 39a8217

Browse files
authored
Merge pull request #1877 from UlrichB22/add_whoosh_idx
Add 3rd minimal whoosh index for performance
2 parents 107ad31 + a15b8be commit 39a8217

File tree

10 files changed

+163
-87
lines changed

10 files changed

+163
-87
lines changed

src/moin/app.py

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -169,16 +169,8 @@ class ItemNameConverter(PathConverter):
169169
clock.stop("create_app flask-cache")
170170
# init storage
171171
clock.start("create_app init backends")
172-
try:
173-
init_backends(app)
174-
except EmptyIndexError:
175-
# create-instance has no index at start and index-* subcommands check the index individually
176-
if info_name not in ["create-instance", "build-instance"] and not info_name.startswith("index-"):
177-
clock.stop("create_app init backends")
178-
clock.stop("create_app total")
179-
logging.error("Error: Wiki index not found. Try 'moin help' or 'moin --help' to get further information.")
180-
raise SystemExit(1)
181-
logging.debug("Wiki index not found.")
172+
# start init_backends
173+
_init_backends(app, info_name, clock)
182174
clock.stop("create_app init backends")
183175
clock.start("create_app flask-babel")
184176
i18n_init(app)
@@ -212,6 +204,32 @@ def destroy_app(app):
212204
deinit_backends(app)
213205

214206

207+
def _init_backends(app, info_name, clock):
208+
"""
209+
initialize the backends with exception handling
210+
"""
211+
try:
212+
init_backends(app)
213+
except EmptyIndexError:
214+
# create-instance has no index at start and index-* subcommands check the index individually
215+
if info_name not in ["create-instance", "build-instance"] and not info_name.startswith("index-"):
216+
missing_indexes = app.storage.missing_index_check()
217+
if missing_indexes == "all":
218+
logging.error(
219+
"Error: all wiki indexes missing. Try 'moin help' or 'moin --help' to get further information."
220+
)
221+
elif missing_indexes == "'latest_meta'": # TODO: remove this check after 6-12 month
222+
logging.error(
223+
"Error: Wiki index 'latest_meta' missing. Please see https://github.com/moinwiki/moin/pull/1877"
224+
)
225+
else:
226+
logging.error(f"Error: Wiki index {missing_indexes} missing, please check.")
227+
clock.stop("create_app init backends")
228+
clock.stop("create_app total")
229+
raise SystemExit(1)
230+
logging.debug("Wiki index not found.")
231+
232+
215233
def init_backends(app, create_backend=False):
216234
"""
217235
initialize the backends

src/moin/apps/frontend/views.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,8 @@ def wrapper(item_name, rev):
585585
abort(404, item_name)
586586
if add_trail:
587587
flaskg.user.add_trail(item_name, aliases=item.meta.revision.fqnames)
588+
"""if view has been called with default rev=CURRENT we can avoid an index query in flash_if_item_deleted"""
589+
item.is_current = rev == CURRENT
588590
return wrapped(item)
589591

590592
return wrapper
@@ -602,6 +604,7 @@ def flash_if_item_deleted(item_name, rev_id, itemrev):
602604
Show flash info message if target item is deleted, show another message if revision is deleted.
603605
Return True if item is deleted or this revision is deleted.
604606
"""
607+
rev_id = CURRENT if getattr(itemrev, "is_current", False) else rev_id
605608
if not rev_id == CURRENT:
606609
ret = False
607610
current_item = Item.create(item_name, rev_id=CURRENT)
@@ -1503,13 +1506,13 @@ def name_initial(files, uppercase=False, lowercase=False):
15031506
# request.args is a MultiDict instance, which degenerates into a normal
15041507
# single-valued dict on most occasions (making the first value the *only*
15051508
# value for a specific key) unless explicitly told to expose multiple
1506-
# values, eg. calling items with multi=True. See Werkzeug documentation for
1509+
# values, e.g. calling items with multi=True. See Werkzeug documentation for
15071510
# more.
15081511

15091512
form = IndexForm.from_flat(request.args.items(multi=True))
15101513
selected_groups = form["contenttype"].value
15111514
startswith = request.values.get("startswith")
1512-
dirs, files = item.get_index(startswith, selected_groups)
1515+
dirs, files = item.get_index(startswith, selected_groups, short=True)
15131516
dirs_fullname = [x.fullname for x in dirs]
15141517
initials = request.values.get("initials")
15151518
if initials:

src/moin/cli/_tests/__init__.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
from moin._tests import get_dirs
1818
from moin import log
19+
from moin.constants.keys import ALL_REVS, LATEST_META
1920

2021
logging = log.getLogger(__name__)
2122

@@ -131,7 +132,9 @@ def read_index_dump(out: str, latest=False):
131132
if item:
132133
yield item
133134
item = {}
134-
if latest and "all_revs" in line:
135+
if latest and ALL_REVS in line:
136+
break
137+
if LATEST_META in line:
135138
break
136139
continue
137140
space_index = line.index(" ")

src/moin/cli/maint/index.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from flask.cli import FlaskGroup
1414

1515
from moin.app import create_app, init_backends
16-
from moin.constants.keys import LATEST_REVS, ALL_REVS
16+
from moin.constants.keys import LATEST_REVS, ALL_REVS, LATEST_META
1717
from moin.utils.filesys import wiki_index_exists
1818

1919

@@ -134,7 +134,7 @@ def IndexDump(tmp, truncate):
134134
logging.error(ERR_NO_INDEX)
135135
raise SystemExit(1)
136136
logging.info("Index dump started")
137-
for idx_name in [LATEST_REVS, ALL_REVS]:
137+
for idx_name in [LATEST_REVS, ALL_REVS, LATEST_META]:
138138
print(f" {'-' * 10} {idx_name} {'-' * 60}")
139139
for kvs in app.storage.dump(tmp=tmp, idx_name=idx_name):
140140
for k, v in kvs:

src/moin/constants/keys.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@
170170
# index names
171171
LATEST_REVS = "latest_revs"
172172
ALL_REVS = "all_revs"
173+
LATEST_META = "latest_meta"
173174

174175
# values for ACTION key
175176
ACTION_SAVE = "SAVE"

src/moin/items/__init__.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@
8383
TAGS,
8484
TEMPLATE,
8585
LATEST_REVS,
86+
LATEST_META,
8687
EDIT_ROWS,
8788
FQNAMES,
8889
USERGROUP,
@@ -1186,7 +1187,6 @@ def handle_variables(self, data, meta):
11861187
@rtype: string
11871188
@return: new text of wikipage, variables replaced
11881189
"""
1189-
logging.debug(f"handle_variable data: {data!r}")
11901190
if self.contenttype not in CONTENTTYPE_VARIABLES:
11911191
return data
11921192
if "@" not in data:
@@ -1196,6 +1196,7 @@ def handle_variables(self, data, meta):
11961196
if TEMPLATE in meta["tags"]:
11971197
return data
11981198

1199+
logging.debug(f"handle_variable data: {data!r}") # log only if necessary
11991200
item_name = request.path.split("/", 2)[-1]
12001201
signature = flaskg.user.name0 if flaskg.user.valid else request.remote_addr
12011202

@@ -1356,7 +1357,7 @@ def build_index_query(self, startswith=None, selected_groups=None, isglobalindex
13561357

13571358
return query
13581359

1359-
def get_index(self, startswith=None, selected_groups=None, regex=None):
1360+
def get_index(self, startswith=None, selected_groups=None, regex=None, short=False):
13601361
"""
13611362
Get index enties for descendents of the matching items
13621363
@@ -1371,11 +1372,12 @@ def get_index(self, startswith=None, selected_groups=None, regex=None):
13711372
- one for "dirs" (direct descendents that also contain descendents)
13721373
"""
13731374
fqname = self.fqname
1375+
idx_name = LATEST_META if short else LATEST_REVS
13741376
isglobalindex = not fqname.value or fqname.value == NAMESPACE_ALL
13751377
query = self.build_index_query(startswith, selected_groups, isglobalindex)
13761378
if not fqname.value.startswith(NAMESPACE_ALL + "/") and fqname.value != NAMESPACE_ALL:
13771379
query = Term(NAMESPACE, fqname.namespace) & query
1378-
revs = flaskg.storage.search_meta(query, idx_name=LATEST_REVS, sortedby=NAME_EXACT, limit=None, regex=regex)
1380+
revs = flaskg.storage.search_meta(query, idx_name=idx_name, sortedby=NAME_EXACT, limit=None, regex=regex)
13791381
return self.make_flat_index(revs, isglobalindex)
13801382

13811383

src/moin/macros/ItemList.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ def macro(self, content, arguments, page_url, alternative):
131131
item = ""
132132
# verify item exists and current user has read permission
133133
elif item != "":
134-
if not flaskg.storage.get_item(**(split_fqname(item).query)):
134+
if not flaskg.storage.get_item(short=True, **(split_fqname(item).query)):
135135
err_msg = _("Item does not exist or read access blocked by ACLs: {0}").format(item)
136136
return fail_message(err_msg, alternative)
137137

src/moin/macros/_base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ def get_item_names(name="", startswith="", kind="files", skiptag="", tag="", reg
4949
item = Item.create(name)
5050
except AccessDenied:
5151
abort(403)
52-
dirs, files = item.get_index(startswith, regex=regex)
52+
dirs, files = item.get_index(startswith, regex=regex, short=True)
5353
item_names = []
5454
if not kind or kind == "files" or kind == "both":
5555
for item in files:

0 commit comments

Comments
 (0)