Some context: I am trying to write a framework for a Perl peer. A slightly out of date version is at Net::Distributed. My previous woes are at HTTP::Daemon and broken pipes.

My problem is that as soon as a network of peers gets a lot of messages passing around, some peer gets a SIGPIPE. Then no further messages get through to that peer, and lots of other peers start getting SIGPIPEs, and soon the whole network is fscked.

I initially thought that I was somehow handling SIGPIPEs wrongly, so that after a SIGPIPE the peer wouldn't recover. But nobody has pointed out any problems with my code in this area. So another possibility seems likely.

My code doesn't fork. It just comes round once in a while to Net::Distributed::Transport->_accept_messages(), which uses a HTTP::Daemon to listen. I set timeouts, and a listen queue, for the Daemon, which is a persistent object.

I think the problem is this. Peer X tries to send a message to peer Y and - for any reason - can't get through. So it times out after write timeout wt. By this time, peer Z is trying to connect to peer X, and has also almost reached the end of it's own wt. Worse still, maybe peer Y wants to talk to peer X - for various reasons this is fairly common in the sort of network I am playing with - and it too times out because peer X is trying to write to it! End result: all my peers lock up trying to talk to each other, and none of them ever get through.

I ought to know whether this is really the problem, but I am not yet sure. It is bloody hard trying to debug 10 simultaneous peers all chatting to each other in realtime over the loopback. So one question is - how do I do realtime debugging on a network peer?

More centrally: if I am right, I need a solution. I need my peer to listen all the time, so that other peers don't normally time out.

I could fork but the problem is that my peer process needs to know what message has been sent to it - it's not like a web server which can just dumbly serve information, while storing state in a database backend. What the peer does depends on what other peers say to it.

I could fork and have a separate listener process which writes to a file, and the main peer reads messages from that file. But this touches the hard disk, which I am loth to do, and just seems fundamentally ugly and wrong.

I could fork and open a pipe to the listener child. But how can I stop the listener blocking while it tries to write to the parent (which is away doing other things)?

Or I could do something brilliant and wondrous. Maybe you have an idea.

dave hj~


In reply to Listening without forking by dash2

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.