Используя Select с ruby ​​сокетами, что является хорошим способом игнорировать данный сокет, если определенное условие выполнено? - PullRequest
0 голосов
/ 04 февраля 2010

Немного фона:

Я написал скрипт, который будет действовать как приемник для входящих ловушек Syslog / Email / Snmp (v1). Он получает данные и сохраняет их как пользовательский объект. Мой "messageSocket" - это средство для управления поведением из сценария вне этого общего слушателя. Я хочу отправить сообщения на это либо запустить / остановить по команде. Старт / Стоп, по сути, просто изменяет состояние переменной @running.

Все это работает нормально, кроме случаев, когда я останавливаюсь - если я инициирую событие, которое создает электронную почту / ловушку и т. Д., Оно не будет зарегистрировано, пока @running = false. Однако, как только я установлю @running = true, он все равно увидит эти данные сокета и проанализирует их.

Я попытался удалить данный сокет из массива @descriptors, попытался закрыть сокеты, попытался установить res для других значений. Я предполагаю, что на данный момент я что-то упускаю, любая помощь или руководство будет с благодарностью!

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 Ответ

1 голос
/ 05 февраля 2010

Если я помню, select (в некотором роде) управляется уровнем, а не ребром. Другими словами, если select возвращает дескрипторы, и вы ничего не делаете с этими дескрипторами, то при следующем вызове select он сообщит вам снова.

Итак, если вы не работаете, вам все равно придется прочитать данные (или что-то еще, что подходит для события), или select просто скажет вам позже.

Чтобы подтвердить мою гипотезу, напечатайте «foo» сразу после вызова select, сделайте @running be false и затем попытайтесь установить соединение. Если вы видите, что «foo» прокручивает снова и снова, показывая, что select не блокирует, тогда я прав. Если вы этого не сделаете, я буду есть мои слова / удалить мой ответ.

Кроме того, вы можете (и должны) просто сказать @running вместо @running == true и !@running вместо @running == false

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...