[PEAK] Re: trellis.Set.discard
Sergey Schetinin
maluke at gmail.com
Tue Oct 21 13:45:39 EDT 2008
OK, here's one case:
class C1(Component):
a = attr()
b = attr()
def __init__(self):
self.rule1
self.rule2
@maintain
def rule1(self):
self.b = 10
@maintain
def rule2(self):
self.a = self.b
class C2(Component):
c1 = make(C1)
@maintain
def dep(self):
self.c1.b = 1
c = C2()
If this seems like programmer's fault, consider this variation:
class C2(Component):
c1 = make(C1)#, optional=False)
flag = attr()
@maintain
def dep(self):
if self.flag:
self.c1.b = 1
c = C2()
c.flag = True
It only fails if c1 is optional, even while it's not a necessary requirement.
On Tue, Oct 21, 2008 at 20:12, Sergey Schetinin <maluke at gmail.com> wrote:
>> Yep, I just had the same idea this morning, and I think it's a *lot* simpler
>> to implement correctly than deterministic merge. We could allow todo cells
>> to have a copy function, that defaults to copy.copy(). When a new rule
>> reads the cell's future, it would change_attr to a copy and then return it,
>> and we wouldn't need all the savepoint junk. (Because rules are rolled back
>> in their entirety for redo.)
>
> Indeed a very small change!
>
>
>>> And if we do that it's not a long way from what I propose. Also,
>>> making the merge deterministic would allow us to add a number of
>>> useful properties. For example, currently if one rule adds an item to
>>> the Set and then some other discards it, the outcome depends on the
>>> order they run. But if we choose to merge changes ourselves we can
>>> make sure that such conflicting changes would be detected (no matter
>>> what order they run in), but at the same time, adding then removing an
>>> item wouldn't be considered a conflict as long as it's done in the
>>> same rule.
>>
>> The problem with this is that error detection is deferred, which makes
>> debugging even harder than it already is.
>
> I agree that deferred validation is a problem, but I don't think that
> it makes debugging harder. In case described in one case we have
> non-deterministic behavior and no errors (a nightmare to debug), in
> second case we get an error with useless traceback, but with a lot of
> useful info available, like what rule wanted to add the item and which
> one tried to remove it etc. This isn't the kind of error meant to be
> caught and processed in runtime, but it would be very useful in
> development. Anyway, probably it's a good idea to implement this
> separately instead of stuffing it into todo/future, but merging value
> / todo variant would still be a useful basic building block.
>
>
>>> Actually, it seems to me that rules should see the data structures in
>>> the way they entered the transaction, so if some rule adds a new item
>>> to the set, no other rule should be able to remove it before @todo
>>> cell gets the value (Set.added for this example).
>>>
>>> Anyway, ISTM that .futures the way they are don't fit Trellis model very
>>> well.
>>
>> Futures are just a way to simplify creating trellis-ized data structures, so
>> that you don't have to undo-log everything. Replacing this with a merge
>> requirement rather defeats the point; if you want things to happen
>> deterministically, you can always use separate data structures and a rule
>> that combines them in a specific order.
>>
>>
>>> > The ability to have a side-transaction is a good idea, though. (Really
>>> > a
>>> > "back transaction", since it is sort of happening in the past.) I
>>> > haven't
>>> > thought a lot about the isolation parameters, though.
>>> >
>>> > Prototyping certainly would be helpful.
>>>
>>> I don't think I will have anything interesting to show before next
>>> week, but so far I'm using this monkeypatch:
>>
>> I still need to read back to your original notes on side transactions and
>> why they're important, apart from the futures issue. I think that
>> snapshot-copying futures when accessed by a new rule will prevent futures
>> from triggering rollbacks of the type you originally reported, so I'm not
>> clear at the moment on what else needs to be done with side transactions.
>
> I have searched through my code and I'm not using it right now. I
> remember at least two different cases where side_txn made things work,
> but after refactoring the code there's no need for it anymore. I think
> the use was legitimate, but strangely, I can't reproduce the need in
> first attempt. I'll try a little more and will get back to you if I
> can reproduce it.
>
> One more issue I can't reproduce right away was that in some cases a
> Link is being created with Contant subject. This happens while
> rolling something back, so reproducing it with minimal code is
> problematic. I fixed it by adding "elif name == 'next_listener':
> pass" to ConstantMixin.__setattr__, but can this be a rare, but normal
> case or does it indicate a problem with my code?
>
> File "c:\files\checkouts\trellis\peak\events\stm.py", line 498, in atomically
> return super(Controller,self).atomically(self._process, func, args, kw)
> File "c:\files\checkouts\trellis\peak\events\stm.py", line 187, in atomically
> self.cleanup(*sys.exc_info())
> File "c:\files\checkouts\trellis\peak\events\stm.py", line 183, in atomically
> retval = func(*args, **kw)
> File "c:\files\checkouts\trellis\peak\events\stm.py", line 509, in _process
> self._retry()
> File "c:\files\checkouts\trellis\peak\events\stm.py", line 322, in _retry
> self.rollback_to(min([self.has_run[r] for r in self.to_retry]))
> File "c:\files\checkouts\trellis\peak\events\stm.py", line 263, in rollback_to
> f(*a)
> File "c:\files\checkouts\trellis\peak\events\stm.py", line 142, in __new__
> subject.next_listener = self
> File "c:\files\checkouts\trellis\peak\events\trellis.py", line 233,
> in __setattr__
> raise AttributeError("Constants can't be changed", self)
>
>
>
>
>
> --
> Best Regards,
> Sergey Schetinin
>
> http://s3bk.com/ -- S3 Backup
> http://word-to-html.com/ -- Word to HTML Converter
>
--
Best Regards,
Sergey Schetinin
http://s3bk.com/ -- S3 Backup
http://word-to-html.com/ -- Word to HTML Converter
More information about the PEAK
mailing list