[PEAK] Re: trellis.Set.discard

Phillip J. Eby pje at telecommunity.com
Sat Oct 11 12:36:01 EDT 2008


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.




More information about the PEAK mailing list