Objects and signals

Submitted by gwolf on Wed, 06/14/2006 - 19:44
So far, Ruby is the only language I have actually liked that imposes a mindset on you. I love Perl's approach of letting you do things your way, whatever you define by that - Ruby forces you to extensively use OOP. But, actually, it is so well implemented that it even makes sense. It is even fun! Of course, that paired to an excellent introspection ability leaves enough room to make the cleverest (and, yes, most obfuscated) code you can think of. Well... But there are limits to everything, and I think I found a spot where all the nice separation and cleanness ends abruptely: When interacting to the always nasty outside world. It might also, of course, have some relation to the fact that I'm too new also for writing GUIs - this is the first nontrivial one I do. And it shows, as it took me some time to properly understand the pairing between the nice Glade elements, how to make a decently modular system, how to properly handle UI (and internal) events... But I've been progressing quite nicely, and I hope to be able to show off my little app to a wider audience soon. At the very least, I hope to be able to show it to my boss by next week, as he is getting impatient ;-) Ok, but where does it all break, according to me? One of the things I must monitor with this app is that a couple of processes spawned by it work happily in the background while I only show a nice interface to my users. Now, how is the best way to do this? Why, by trapping the SIGCHLD signal, of course! Whenever any of the processes in the pipeline die, the parent (controlling) process gets a nice CHLD signal. I trap it, restart the processes, and no harm done. And in Ruby, it looks quite natural: [code="ruby"] Signal.trap(:CHLD) do @processes.each {|p| p.stop if p.active?; sleep 1; p.start} done [/code] How nice, how neat... How buggy :-/ It took me quite a few hours to get this right. And it should be obvious, of course... No matter where you declare a signal handler, there is no reason for you to believe it is tied to a particular instance, or for that matter, to a class. A signal handler breaks and jumps in the execution in the ugliest old-school way. Yes, if your signal handler consists of: [code="ruby"]Signal.trap(:CHLD) do { puts self.class }[/code] you will note that your good friend self is nothing but an Object. Once I realized that, yes, things became reworkable, and I now think I am actually better off even OOP-aly than some hours ago - Some of the classes badly needed to adhere to the Singleton pattern and now work with less worries and ugliness. But, hey, it took me quite a while. Anyway, lets see which new challenges Ruby+Glade2 still have for me. I am sure there will be plenty. And I haven't even started playing with GStreamer!
( categories: )
Peter De Wachter's picture

Re: Objects and signals

I had a similar problem, but my solution was to wait for the process in a new thread: Thread.new { Process.wait pid; do stuff } I found that much easier than using signals.