Method: Net::DNS::MDNS::Responder#cacher_loop

Defined in:
lib/net/dns/mdns.rb

#cacher_loopObject



636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
# File 'lib/net/dns/mdns.rb', line 636

def cacher_loop
  delay = 0

  loop do

    if delay > 0
      sleep(delay)
    else
      sleep
    end

    @mutex.synchronize do
      debug( "sweep begin" )

      @waketime = nil

      msg = Message.new(0)
      msg.rd = 0
      msg.qr = 0
      msg.aa = 0

      now = Time.now.to_i

      # the earliest question or answer we need to wake for
      wakefor = nil

      # TODO - A delete expired, that yields every answer before
      # deleting it (so I can log it).
      # TODO - A #each_answer?
      @cache.cached.each do |name,rtypes|
        rtypes.each do |rtype, answers|
          # Delete expired answers.
          answers.delete_if do |an|
            if an.expired?
              debug( "-- a #{an}" )
              true
            end
          end
          # Requery answers that need refreshing, if there is a query that wants it.
          # Remember the earliest one we need to wake for.
          answers.each do |an|
            if an.refresh
              unless @queries.detect { |q| q.subscribes_to? an }
                debug( "no refresh of: a #{an}" )
                next
              end
              if now >= an.refresh
                an.retries += 1
                msg.add_question(name, an.data.class)
              end
              # TODO: cacher_loop exited with comparison of Bignum with nil failed, v2mdns.rb:478:in `<'
              begin
              if !wakefor || an.refresh < wakefor.refresh
                wakefor = an
              end
              rescue
                error( "an #{an.inspect}" )
                error( "wakefor #{wakefor.inspect}" )
                raise
              end
            end
          end
        end
      end

      @cache.asked.each do |name,rtypes|
        # Delete questions no query subscribes to, and that don't need refreshing.
        rtypes.delete_if do |rtype, qu|
          if !qu.refresh || !@queries.detect { |q| q.subscribes_to? qu }
            debug( "no refresh of: q #{qu}" )
            true
          end
        end
        # Requery questions that need refreshing.
        # Remember the earliest one we need to wake for.
        rtypes.each do |rtype, qu|
          if now >= qu.refresh
            msg.add_question(name, rtype)
          end
          if !wakefor || qu.refresh < wakefor.refresh
            wakefor = qu
          end
        end
      end

      msg.question.uniq!

      msg.each_question { |n,r| debug( "-> q #{n} #{DNS.rrname(r)}" ) }

      send(msg) if msg.question.first

      @waketime = wakefor.refresh if wakefor

      if @waketime
        delay = @waketime - Time.now.to_i
        delay = 1 if delay < 1

        debug( "refresh in #{delay} sec for #{wakefor}" )
      else
        delay = 0
      end

      debug( "sweep end" )
    end
  end # end loop
end