views:

70

answers:

1

A little background:

I've written a script that will act as a receiver for incoming Syslog/Email/Snmp(v1) traps. It receives the data and stores it as a custom defined object. My "messageSocket" is a means to control the behavior from a script outside of this general listener. I want to send messages to this to either start/stop on command. The start / stop essentially just change the state of the @running variable.

All of this works fine, except when I stop - if I trigger an event that creates an e-mail/trap etc it won't be registered while @running = false. However, as soon as I set @running = true it will still see this socket data and analyze it.

I tried removing the given socket from my @descriptors array, I tried closing sockets, I tried setting res to different values. I'm guessing I'm just missing something at this point, any assistance or guidance would be greatly appreciated!

def run()  
   while 1 == 1

     res = select(@descriptors, nil, nil, nil)

     if res != nil then

        for sock in res[0]
          if sock == @mailSocket && @running == true then
            accept_new_connection
          elsif sock == @sysSocket && @running == true then
            get_syslog_message
          elsif sock == @snmpSocket && @running == true then
            get_snmp_message
          elsif sock == @mailSocket && @running == false then
            reject_mail
          elsif sock == @messageSocket then
            get_message()
          elsif sock == @snmpSocket && @running == false then
            #do something
          elsif sock == @sysSocket && @running == false then
            #do something
          end
        end   
      end
    end
 end
   #run end 
  end
+1  A: 

If I recall, select is (sort of) level driven, not edge driven. In other words, if select returns descriptors and you do nothing with those descriptors, the next time you call select it will tell you again.

So, if you are not running, you still have to read the data (or whatever else is appropriate for the event), or select will just tell you again later.

To confirm my hypothesis, print "foo" right after the call to select, make @running be false and then try to establish a connection. If you see "foo" scolling by over and over, showing that select is not blocking, then I'm right. If you don't, I'll eat my words/delete my answer.

As an aside, you can (and should) simply say @running instead of @running == true, and !@running instead of @running == false

Wayne Conrad
I can tell you that you are right because that is similar to something I had done before. I also just verified it, select doesn't remove anything from @descriptors. So I guess the real question is with a UDP socket how do I get rid of that data? For e-mail I just spit back the expected Failure response. When I tried to just receive all the data for syslog/snmp and not do anything it didn't seem to work.
Beanish
I'm going to accept your answer. Thanks for making me revisit something I swear I had done :P One of those days where I want to cry because its solved but also cry because I swear I tried it ;)I created a reject_sys() method that just reads from the port and does nothing with the data. Thanks!
Beanish
My pleasure. Thanks for the checkmark!
Wayne Conrad