[PEAK] Stopping PEAK application on SIGINT

Alexey Smishlayev alexey at xtech2.lv
Wed Oct 7 06:09:43 EDT 2015


Hello!

The application runs successfully with my patch applied and it even 
reacts gracefully to the ^C, so you could say that the desired behavior 
is achieved. I've done it with the following patch:

     def _patchSelector(self):
         from peak.events.io_events import Selector
         from peak.events.io_events import SignalEvents
         Selector.sigsrc = binding.Make(SignalEvents, attrName="sigsrc")
     _patchSelector = binding.Make(_patchSelector, uponAssembly=True)


I guess, I'll leave it for now, but it is not a kind of code I would 
like my colleagues to inherit. If you would provide some directions, I 
will consider fixing and testing PEAK signaling with Twisted support and 
contributing it to your project.


Regards,
Alexey


On 03/10/15 02:07, PJ Eby wrote:
> The issue is that ISelector is a subclass of ISignalSource, and so
> another Selector is created instead of the SignalSource singleton.  I
> don't really have a good way to fix this right now, but as a
> workaround you could monkeypatch to set Selector.sigsrc to
> io_events.SignalEvents and see how that works.  (In truth, I think the
> real problem may be that PEAK's signals support was never tested in
> conjunction with Twisted, and IIRC, the signals support was only
> half-baked to begin with when most work on PEAK ceased 10-11 years
> ago.)
>
> On Fri, Oct 2, 2015 at 6:51 AM, Alexey Smishlayev <alexey at xtech2.lv> wrote:
>> Hello!
>>
>> I tried using pdb today, to some degree of success. Turns out that
>> eventLoop.sigsrc attribute gets an instance of
>> "peak.events.twisted_support.Selector". eventLoop.signals attribute is
>> "binding.Delegate('sigsrc')", so it gets resolved to
>> "peak.events.twisted_support.Selector.signals", which is
>> "binding.Delegate('sigsrc')" - that's where recursion appears.
>>
>> I've gathered some evidence using pdb:
>>> /Library/Python/2.7/site-packages/peak/config/config_components.py(398)lookup()
>> -> for value in iterValues(component, configKey):
>> (Pdb) component
>> <peak.config.config_components.ServiceArea object at 0x108ba3390>
>> (Pdb) configKey
>> config.MultiKey(<class 'peak.binding.interfaces.IComponentFactory'>, <class
>> 'peak.events.interfaces.ISignalSource'>)
>> (Pdb) [x for x in iterValues(component, configKey)]
>> [<class 'peak.events.twisted_support.Selector'>, <class
>> 'peak.events.io_events.SignalEvents'>]
>>
>> --
>>
>>> /Library/Python/2.7/site-packages/peak/config/config_components.py(384)iterValues()
>> -> value = gcd(forObj, configKey)
>> (Pdb) forObj
>> <peak.config.config_components.ServiceArea object at 0x108ba3390>
>> (Pdb) configKey
>> config.MultiKey(<class 'peak.binding.interfaces.IComponentFactory'>, <class
>> 'peak.events.interfaces.ISignalSource'>)
>> (Pdb) gcd
>> <bound method ServiceArea._getConfigData of
>> <peak.config.config_components.ServiceArea object at 0x108ba3390>>
>> (Pdb) gcd(forObj, configKey)
>> <class 'peak.events.twisted_support.Selector'>
>>
>> --
>>
>>> /Library/Python/2.7/site-packages/peak/config/config_components.py(593)_getConfigData()
>> -> value = rule.get()(self, configKey, forObj)
>> (Pdb) rule.get()
>> <function f at 0x1094bfcf8>
>> (Pdb) rule.get()(self, configKey, forObj)
>> <class 'peak.events.twisted_support.Selector'>
>>
>> Unfortunately, my efforts stop here. I have no idea where from this function
>> f appeared in configuration rules, but it creates Selector instance, which
>> messes up the lookup.
>>  From peak.ini: " peak.events.interfaces.ISignalSource =
>> io_events.SignalEvents"
>> I tried grepping "ISignalSource" in my project's directory, but this gives
>> no results.
>>
>>
>> Regards,
>> Alexey
>>
>>
>>
>> On 30/09/15 02:12, PJ Eby wrote:
>>
>> The failure is in trying to retrieve the `signals()` method from the
>> ISignalSource, which should be the io_events.SignalSource singleton.
>> What I don't understand is why it's recursing on the attempt to
>> retrieve the signals attribute.  Specifically, it seems as though this
>> should only be able to happen if trying to load the 'sigsrc' attribute
>> results in an attempt to load the 'signals' attribute.  I would
>> suggest stepping through with the debugger from line 66 of
>> scheduler.py and see if you can tell what's happening there.
>>
>> On Tue, Sep 29, 2015 at 5:56 PM, Alexey Smishlayev <alexey at xtech2.lv> wrote:
>>
>> Hello, Phillip!
>>
>> I use binding.Obtain() on "peak.running.interfaces.IMainLoop", which seem to
>> be instantiating as "peak.running.scheduler.MainLoop" and the
>> "peak.events.interfaces.IEventLoop" is bound to
>> "peak.events.twisted_support.EventLoop". Did not go that far, looked at the
>> PEAK default event loop and couldn't figure out what's wrong (without
>> investgating links in the project's .ini file).
>>
>> Does that mean I cannot use stopOnSignals with the Twisted event loop? Do I
>> have to implement that method? I believe, it's used because Twisted handles
>> TCP communications for us.
>>
>>
>> Best regards,
>> Alexey Smishlayev
>>
>>
>> On 30/09/15 00:27, PJ Eby wrote:
>>
>> Which event loop are you using?  Twisted, the PEAK default, or
>> something else?  The issue here appears to be that the eventLoop
>> property of the MainLoop instance lacks a `signals()` method -- which
>> would seem to mean it doesn't fully implement IEventLoop or is the
>> wrong type of object to start with.
>>
>> On Tue, Sep 29, 2015 at 8:06 AM, Alexey Smishlayev <alexey at xtech2.lv> wrote:
>>
>> Good day everyone!
>> I would like my PEAK application to stop on ^C or SIGINT. Currently, in that
>> case I get an output something like
>>
>> 29.09.2015 14:56:48.179 [DEBUG] Connect.twisted Unexpected error in main
>> loop.
>> 29.09.2015 14:56:48.190 [ERROR] Connect.twisted Traceback (most recent
>> call last):
>> 29.09.2015 14:56:48.190 [ERROR]   File
>> "/Users/alexey/xtech2/tester/build/lib/ank/BBS/CommandBase.py", line 38, in
>> run
>> 29.09.2015 14:56:48.190 [ERROR]     self.mainLoop.run()
>> 29.09.2015 14:56:48.190 [ERROR]   File
>> "/Library/Python/2.7/site-packages/peak/running/scheduler.py", line 78, in
>> run
>> 29.09.2015 14:56:48.190 [ERROR]     return
>> self.eventLoop.runUntil(self.exitCode,True,idle=self.sleep)[0]
>> 29.09.2015 14:56:48.190 [ERROR]   File
>> "/Library/Python/2.7/site-packages/peak/events/twisted_support.py", line
>> 186, in runUntil
>> 29.09.2015 14:56:48.190 [ERROR]     self.reactor.run(False)
>> 29.09.2015 14:56:48.190 [ERROR]   File
>> "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/twisted/internet/base.py",
>> line 1192, in run
>> 29.09.2015 14:56:48.190 [ERROR]     self.mainLoop()
>> 29.09.2015 14:56:48.190 [ERROR] --- <exception caught here> ---
>> 29.09.2015 14:56:48.190 [ERROR]   File
>> "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/twisted/internet/base.py",
>> line 1204, in mainLoop
>> 29.09.2015 14:56:48.190 [ERROR]     self.doIteration(t)
>> 29.09.2015 14:56:48.190 [ERROR]   File
>> "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/twisted/internet/selectreactor.py",
>> line 105, in doSelect
>> 29.09.2015 14:56:48.190 [ERROR]     [], timeout)
>> 29.09.2015 14:56:48.190 [ERROR] exceptions.KeyboardInterrupt:
>>
>> in the log file. In CommandBase.py attribute self.mainloop is defined as
>>
>> from peak.api import binding
>> from peak.running import commands, interfaces
>> class CommandBase(commands.EventDriven):
>>      mainLoop = binding.Obtain(interfaces.IMainLoop)
>>      ...
>>
>> If I set "peak.running.mainLoop.stopOnSignals" in my project's .ini file to
>> anything else except empty tuple, on the application's startup I get the
>> following error (I tried "stopOnSignals = ('SIGINT',)")
>>
>> Traceback (most recent call last):
>>    File "../ank/BBS/Assembler.py", line 370, in run
>>      _exitCode = _root.run()
>>    File "/Library/Python/2.7/site-packages/peak/running/commands.py", line
>> 229, in run
>>      return self._run() or 0
>>    File "/Library/Python/2.7/site-packages/peak/running/commands.py", line
>> 509, in _run
>>      return self.invoke()
>>    File "/Users/alexey/xtech2/tester/build/lib/ank/BBS/CommandBase.py",
>> line 38, in run
>>      self.mainLoop.run()
>>    File "/Library/Python/2.7/site-packages/peak/running/scheduler.py", line
>> 66, in run
>>      handler = self.eventLoop.signals(*self.stopOnSignals)
>>    File "_once.pyx", line 112, in _once.BaseDescriptor.__get__
>>    File "_once.pyx", line 100, in _once.__get__
>>    File "/Library/Python/2.7/site-packages/peak/binding/components.py",
>> line 682, in delegate
>>      return getattr(getattr(s,delegateAttr),a)
>>    File "_once.pyx", line 112, in _once.BaseDescriptor.__get__
>>    File "_once.pyx", line 100, in _once.__get__
>>    File "/Library/Python/2.7/site-packages/peak/binding/components.py",
>> line 682, in delegate
>>      return getattr(getattr(s,delegateAttr),a)
>>    File "_once.pyx", line 88, in _once.BaseDescriptor.__get__
>> AttributeError: ('Recursive attempt to compute attribute', 'signals')
>>
>> How do I do everything correctly?
>>
>>
>> Best regards,
>> Alexey Smishlayev
>>
>> _______________________________________________
>> PEAK mailing list
>> PEAK at eby-sarna.com
>> http://www.eby-sarna.com/mailman/listinfo/peak
>>
>>
>>
>> _______________________________________________
>> PEAK mailing list
>> PEAK at eby-sarna.com
>> http://www.eby-sarna.com/mailman/listinfo/peak
>>
>>
>>
>> _______________________________________________
>> PEAK mailing list
>> PEAK at eby-sarna.com
>> http://www.eby-sarna.com/mailman/listinfo/peak

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.eby-sarna.com/pipermail/peak/attachments/20151007/8802d7dc/attachment.html


More information about the PEAK mailing list