Closed tobixen closed 2 years ago
After a restart of xandikos, the problem could not be reproduced anymore. Weird.
So ... I restart xandikos, run the test, it passes, rerun the same test once more, and xandikos fails with a 500-error. This is consistent, same error at the third and fourth run. Restart xandikos ... and test passes again. Once. And fails at the second run.
I conclude that there is some state in xandikos here that should not be there.
There is a cache which is used for performance improvements - it's probably related to that. It should be there but it looks like there's an issue around its deserilalization :)
ed58e93b421b6aa3817211c7c9de49a9d1ca8c7b is the first bad commit
sorry. disregard that. That was one of the other issues messing up with my bisect
873bd39354a7ecf4cad1660869df6f7a0995c5d9 is probably the first bad commit
Disregard that too. Different error traceback.
9c13cfcb01683f126bc1760efc7781d9aaa0d723 is apparently the first commit giving me a traceback from the icalendar module.
Here is the minimal test case that triggers the problem:
evr = """BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Example Corp.//CalDAV Client//EN
BEGIN:VEVENT
UID:19970901T130000Z-123403@example.com
DTSTAMP:19970901T130000Z
DTSTART;VALUE=DATE:19971102
SUMMARY:Our Blissful Anniversary
TRANSP:TRANSPARENT
CLASS:CONFIDENTIAL
CATEGORIES:ANNIVERSARY,PERSONAL,SPECIAL OCCASION
RRULE:FREQ=YEARLY
END:VEVENT
END:VCALENDAR"""
#(...)
def testXandikosCacheIssue(self):
c = self._fixCalendar()
e3=c.save_event(evr)
some_events = c.search(comp_class=Event, category="PERSONAL")
some_events = c.search(comp_class=Event, category="PERSONAL")
some_events = c.search(comp_class=Event, category="PERSONAL")
some_events = c.search(comp_class=Event, category="PERSONAL")
some_events = c.search(comp_class=Event, category="PERSONAL")
some_events = c.search(comp_class=Event, category="PERSONAL")
some_events = c.search(comp_class=Event, category="PERSONAL")
_fixCalendar
does an MKCALENDAR
, save_event
does a PUT
, and search
does the REPORT
with the XML shown in the top post.
Note that it's only that recurring event that causes problems - the other two events will cause the test code above to pass (ah ... probably because they don't include the category PERSONAL). It also consistently fails at the seventh repetition of the search.
Hm. This also breaks:
def testXandikosCacheIssue(self):
c = self._fixCalendar()
e3=c.save_event(evr)
some_events = c.search(comp_class=Event, category="one")
some_events = c.search(comp_class=Event, category="two")
some_events = c.search(comp_class=Event, category="three")
some_events = c.search(comp_class=Event, category="four")
some_events = c.search(comp_class=Event, category="five")
some_events = c.search(comp_class=Event, category="fix")
some_events = c.search(comp_class=Event, category="SEVEN")
while this does not break (obviously because it has no category):
ev1 = """BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Example Corp.//CalDAV Client//EN
BEGIN:VEVENT
UID:20010712T182145Z-123401@example.com
DTSTAMP:20060712T182145Z
DTSTART:20060714T170000Z
DTEND:20060715T040000Z
SUMMARY:Bastille Day Party
END:VEVENT
END:VCALENDAR
"""
def testXandikosCacheIssue(self):
c = self._fixCalendar()
e3=c.save_event(ev1)
some_events = c.search(comp_class=Event, category="one")
some_events = c.search(comp_class=Event, category="two")
some_events = c.search(comp_class=Event, category="three")
some_events = c.search(comp_class=Event, category="four")
some_events = c.search(comp_class=Event, category="five")
some_events = c.search(comp_class=Event, category="fix")
some_events = c.search(comp_class=Event, category="SEVEN")
some_events = c.search(comp_class=Event, category="eight")
some_events = c.search(comp_class=Event, category="nine")
some_events = c.search(comp_class=Event, category="ten")
some_events = c.search(comp_class=Event, category="many")
some_events = c.search(comp_class=Event, category="boring")
Very weird indeed.
(I also tried to search for other things than category, it also made no impact. Apparently it's always the seventh query for category that breaks. In the original case the calendar was even deleted and recreated before things broke).
I'm going afk now.
The index manager obviously has a counter, so that popular stuff is cached while one-off data isn't.
(Pdb) self.index_manager.find_present_keys(necessary_keys)
(Pdb) self.index_manager.find_present_keys(necessary_keys)
(Pdb) self.index_manager.find_present_keys(necessary_keys)
(Pdb) self.index_manager.find_present_keys(necessary_keys)
(Pdb) self.index_manager.find_present_keys(necessary_keys)
(Pdb) self.index_manager.find_present_keys(necessary_keys)
(Pdb) self.index_manager.find_present_keys(necessary_keys)
['C=VCALENDAR/C=VEVENT/P=CATEGORIES']
(Pdb) self.index_manager.find_present_keys(necessary_keys)
['C=VCALENDAR/C=VEVENT/P=CATEGORIES']
I guess the question is not how this caching system works ... the question is more on the data put into it or taken out from it, it probably needs some kind of conversion somewhere.
The objects in the cache seems to be ... objects, but the code is doing a vClass.from_ical(foo)
, which works when foo
is a string. For vText
this works well, since vText
can easily be casted to a string.
The icalendar interface is a bit odd; it needs to be calling vClass(vClass.from_ical(foo)) to work properly
Ah, I think I found it. The first time the index is generated, it's use for filtering and not explicitly serialized.
Now I have a calendar with those three events:
... and doing this report query:
... produces this traceback:
The weird thing here is that while I'm consistently able to reproduce this towards my existing calendar server running stand-alone on the latest HEAD of master (a43ba24a13ac5a8810cc13b031fe73d6505e1e95), I'm not able to reproduce it running the same test code but towards an "internal" xandikos server running the same revision.
I will do more research into this, though not sure if I will catch it today.