Re: Trellis: Sensor.listening and iter_listeners()

"Sergey Schetinin" <[email protected]>
Newsgroups gmane.comp.python.peak
Message-ID <[email protected]>
The problem is caused by initialization not being undo-logged, so when
the rule is initialized, its _process_reads sets .next_listener of
some Sensor, but the Link creation is not undo-logged. Later, it all
gets rolled back, and the schedule(self.update_connection) vanishes
from the ctrl.commit, but the .next_listener is not rolled back, so
next time the dependency is recreated was_seen is True and the
_set_listener decides there's no need to schedule update_connection,
so it never runs. Removing one "if undo" condition in final part of
the _process_reads fixes the problem. Trellis test suite never passes
for me (hangs up on "testSequentialCalls
(test_trellis.TestReactorEventLoop) ..."), so I'm not sure if this
breaks anything else.

Initialization is once again a culprit of a hard to detect bug. =)



On Wed, Nov 12, 2008 at 20:16, Sergey Schetinin <[email protected]> wrote:
> Switching to a manager instead of scheduling update_connection
> pseudo-rule fixed the issue.
>
> from peak.util.addons import AddOn
>
> class UpdateConnection(AddOn):
>    def __init__(self, sensor):
>        self.sensor = sensor
>
>    def __enter__(self):
>        pass
>
>    def update_connection(self):
>        sensor = self.sensor
>        descr = type(sensor).listening
>        listening = descr.__get__(sensor)
>        if sensor.next_listener is not None:
>            if listening is NOT_GIVEN:
>                descr.__set__(sensor, sensor.connector.connect(self))
>        elif listening is not NOT_GIVEN:
>            sensor.connector.disconnect(sensor, listening)
>            descr.__set__(sensor, NOT_GIVEN)
>
>    def __exit__(self, *args):
>        self.update_connection()
>        self.delete_from(self.sensor)
>
>
> then manage(UpdateManager(self)) or
>
> from contextlib import contextmanager
>
>    @property
>    def upd_manager(self):
>        if not self._upd_manager:
>            self._upd_manager = self.make_upd_manager()
>        return self._upd_manager
>
>    @contextmanager
>    def make_upd_manager(self):
>        yield
>        descr = type(self).listening
>        listening = descr.__get__(self)
>        if self.next_listener is not None:
>            if listening is NOT_GIVEN:
>                descr.__set__(self, self.connector.connect(self))
>        elif listening is not NOT_GIVEN:
>            self.connector.disconnect(self, listening)
>            descr.__set__(self, NOT_GIVEN)
>        if not isinstance(self, ConstantMixin):
>            self._upd_manager = None
>
> then manage(self.upd_manager).
>
>
>
>
>
> On Wed, Nov 12, 2008 at 19:24, Sergey Schetinin <[email protected]> wrote:
>> After adding `if self.update_connection not in pending:
>> on_undo(pending.remove, self.update_connection)` in relevant places,
>> the printed counts show that all of them get called, so this has to be
>> something else.
>>
>>
>> On Wed, Nov 12, 2008 at 18:25, Sergey Schetinin <[email protected]> wrote:
>>> I forgot to mention that the same debug prints were added to
>>> LazyCell.run right after scheduling of update_connection.
>>>
>>> On Wed, Nov 12, 2008 at 18:19, Sergey Schetinin <[email protected]> wrote:
>>>> I tracked this down to the fact that not all scheduled
>>>> update_connection get called.
>>>>
>>>> In attempt to find out how often does this happen I added the
>>>> following to SensorBase._set_listener (`pending` refers to a global
>>>> set())
>>>>
>>>>            print len(pending), '++'
>>>>            pending.add(self)
>>>>
>>>>  and in update_connection
>>>>
>>>>            print len(pending), '--'
>>>>            pending.remove(self)
>>>>
>>>> And the printed counts don't go back to 1 even for tests that seem to
>>>> work correctly. Am I missing something?
>>>>
>>>>
>>>>
>>>>
>>>> On Wed, Nov 12, 2008 at 16:18, Sergey Schetinin <[email protected]> wrote:
>>>>> I tracked one of the issues I was having periodically to a case when a
>>>>> sensor did not connect when it should have.
>>>>>
>>>>>>>> evt_cell
>>>>> Sensor(<bound method PyEventBinder._events of <wx._core.PyEventBinder
>>>>> object at 0x00E5DD10>>, None, discrete[None])
>>>>>>>> evt_cell.listening
>>>>> NOT_GIVEN
>>>>>>>> list(evt_cell.iter_listeners())
>>>>> [WxCell(221), WxCell(392)]
>>>>>
>>>>> This state is invalid, correct?
>>>>>
>>>>>
>>>>> --
>>>>> 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
>>>>
>>>
>>>
>>>
>>> --
>>> 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
>>
>
>
>
> --
> 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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.