[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