Merge lp:~seif/zeitgeist/catch_cache_error into lp:zeitgeist/0.1

Proposed by Seif Lotfy
Status: Merged
Merge reported by: Seif Lotfy
Merged at revision: not available
Proposed branch: lp:~seif/zeitgeist/catch_cache_error
Merge into: lp:zeitgeist/0.1
Diff against target: 63 lines (+30/-9)
1 file modified
_zeitgeist/engine/main.py (+30/-9)
To merge this branch: bzr merge lp:~seif/zeitgeist/catch_cache_error
Reviewer Review Type Date Requested Status
Markus Korn Approve
Review via email: mp+46056@code.launchpad.net

Description of the change

So I just added a little temporary fix that I would like to see with the next release.
Instead of zeitgeist returning nothing when requesting a time-period with a broken event, zeitgeist now can ignore the broken event and return a list with healthy events. The broken events can be seen in the log under Error

To post a comment you must log in.
lp:~seif/zeitgeist/catch_cache_error updated
1659. By Seif Lotfy

add comments to change

Revision history for this message
Markus Korn (thekorn) wrote :

I like the general idea of this workaround: hiding the KeyError to the clients, and log an error server-side instead.
However your solution gives me a bad feeling: It ignores our own policy that all events must have at least one subject. So in your workaround it is possible to get events with no subject back. Also, as we don't know what's going wrong I think it makes no sense to limit this workaround to subjects, are we really sure that this kind of broken db entries can not happen to Event interpretations for example too?

My suggestion is: in case of *any* error in the process of creating Event and Subject objects from a db row let's just block the whole event from being returned, let's return None. And log an error server-side, of course.

review: Needs Fixing
Revision history for this message
Seif Lotfy (seif) wrote :

My work around is not limited to subjects.
if the subject is broken then we ignore returning an event. Thus its valid.
Thus its exactly as you are suggesting here.
You can see here that i try to extract the subject for the event. If I cant
extract the subject I ignore the whole event

subject = self._get_subject_from_row(row)
# Check if subject has a proper value. If none than something went
# wrong while trying to fetch the subject from the row. So instead
# of failing and raising an error. We silently skip the event.
* if subject:*
event.append_subject(subject)
event = self.extensions.apply_get_hooks(event, sender)
if event is not None:
for n in id_hash[event.id]:
# insert the event into all necessary spots (LP: #673916)
sorted_events[n] = event

lp:~seif/zeitgeist/catch_cache_error updated
1660. By Seif Lotfy

update from trunk

Revision history for this message
Markus Korn (thekorn) wrote :

Ok, I think I misread the diff. Everything seems to be ok, good work, +1 from me.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file '_zeitgeist/engine/main.py'
--- _zeitgeist/engine/main.py 2010-12-28 22:32:47 +0000
+++ _zeitgeist/engine/main.py 2011-01-13 22:23:07 +0000
@@ -142,7 +142,15 @@
142 event[0][Event.Id] = row["id"] # Id property is read-only in the public API142 event[0][Event.Id] = row["id"] # Id property is read-only in the public API
143 event.timestamp = row["timestamp"]143 event.timestamp = row["timestamp"]
144 for field in ("interpretation", "manifestation", "actor"):144 for field in ("interpretation", "manifestation", "actor"):
145 setattr(event, field, getattr(self, "_" + field).value(row[field]))145 # Try to get event attributes from row using the attributed field id
146 # If attribute does not exist we break the attribute fetching and return
147 # None instead of of crashing
148 try:
149 setattr(event, field, getattr(self, "_" + field).value(row[field]))
150 except KeyError, e:
151 log.error("Event %i broken: Table %s has no id %i" \
152 %(row["id"], field, row[field]))
153 return None
146 event.payload = row["payload"] or "" # default payload: empty string154 event.payload = row["payload"] or "" # default payload: empty string
147 return event155 return event
148 156
@@ -152,8 +160,16 @@
152 setattr(subject, field, row["subj_" + field])160 setattr(subject, field, row["subj_" + field])
153 setattr(subject, "origin", row["subj_origin_uri"])161 setattr(subject, "origin", row["subj_origin_uri"])
154 for field in ("interpretation", "manifestation", "mimetype"):162 for field in ("interpretation", "manifestation", "mimetype"):
155 setattr(subject, field,163 # Try to get subject attributes from row using the attributed field id
156 getattr(self, "_" + field).value(row["subj_" + field]))164 # If attribute does not exist we break the attribute fetching and return
165 # None instead of of crashing
166 try:
167 setattr(subject, field,
168 getattr(self, "_" + field).value(row["subj_" + field]))
169 except KeyError, e:
170 log.error("Event %i broken: Table %s has no id %i" \
171 %(row["id"], field, row["subj_" + field]))
172 return None
157 return subject173 return subject
158 174
159 def get_events(self, ids, sender=None):175 def get_events(self, ids, sender=None):
@@ -194,12 +210,17 @@
194 events[event.id] = event210 events[event.id] = event
195 else:211 else:
196 event = events[event.id]212 event = events[event.id]
197 event.append_subject(self._get_subject_from_row(row))213 subject = self._get_subject_from_row(row)
198 event = self.extensions.apply_get_hooks(event, sender)214 # Check if subject has a proper value. If none than something went
199 if event is not None:215 # wrong while trying to fetch the subject from the row. So instead
200 for n in id_hash[event.id]:216 # of failing and raising an error. We silently skip the event.
201 # insert the event into all necessary spots (LP: #673916)217 if subject:
202 sorted_events[n] = event218 event.append_subject(subject)
219 event = self.extensions.apply_get_hooks(event, sender)
220 if event is not None:
221 for n in id_hash[event.id]:
222 # insert the event into all necessary spots (LP: #673916)
223 sorted_events[n] = event
203 224
204 log.debug("Got %d events in %fs" % (len(sorted_events), time.time()-t))225 log.debug("Got %d events in %fs" % (len(sorted_events), time.time()-t))
205 return sorted_events226 return sorted_events