Re: Re: trellis.Set.discard
"Phillip J. Eby" <pje-Wh6+Hckhi6HFNGf7iClzIwC/[email protected]>
| Newsgroups | gmane.comp.python.peak |
|---|---|
| Message-ID | <[email protected]> |
At 04:32 AM 10/11/2008 +0300, Sergey Schetinin wrote: >It's not that different from .remove though.. > >Anyway here's a test: > >class CV(Component): > v = attr(False) > s = make(Set) > > @maintain > def maintain(self): > if self.v: > self.s.add(1) > else: > self.s.discard(1) > > @perform > def perform(self): > print self.v > > >@TaskCell >def task(): > cv = CV() > cv.v = True > yield Pause > >EventLoop.run() > >It silently undoes the task changes. I would have expected at least an >exception. Congratulations; you just found a way to violate causality in a task. :) What I don't understand is why this works when it's NOT in a task. That is, if you change TaskCell to @trellis.atomically and take out the yield, it does what we expect it to. The discard operation uses to_add, which sets up a savepoint at a time when .v is false. Later, when .v is true, the add operation adds to to_add. This second operation is also critical, because if you don't do the add, no rollback occurs. Clearly, there is some reason why the second execution of the maintain rule is being rolled back, which then forces a rollback all the way to the first execution of the rule. This would seem to imply that there is something dreadfully wrong with using these sorts of savepoints in "futures"; it is a flaw that they are allowed to rollback to the middle of a rule's execution. They *should* be required to roll back all the way to the beginning of the rule, or something of that sort. But I am still baffled as to why this only seems to be triggered in the task case.