<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <p>Hi Junxiao</p>
    <p>I implemented those changes and reduced the topology to 4 hosts
      to rule the possibility of this being a hardware issue. Now the
      consumers schedule the interest following what is specified in an
      input file, the core expressInterest mechanism looks like this:</p>
    <div style="color: #f6f6f4;background-color: #282a36;font-family: 'source code pro', 'Droid Sans Mono', 'monospace', monospace, 'Droid Sans Fallback';font-weight: normal;font-size: 15px;line-height: 20px;white-space: pre;"><div><span style="color: #f6f6f4;">m_scheduler.</span><span style="color: #62e884;">schedule</span><span style="color: #f6f6f4;">(boost</span><span style="color: #f286c4;">::</span><span style="color: #f6f6f4;">chrono</span><span style="color: #f286c4;">::</span><span style="color: #62e884;">milliseconds</span><span style="color: #f6f6f4;">(dataBuff.nTimeMs), [</span><span style="color: #bf9eee;font-style: italic;">this</span><span style="color: #f6f6f4;">, </span><span style="color: #ffb86c;font-style: italic;">dataBuff</span><span style="color: #f6f6f4;">] { </span><span style="color: #62e884;">delayedInterest</span><span style="color: #f6f6f4;">(dataBuff); });</span></div></div>
    <p>And, after all events are scheduled.<br>
    </p>
    <div style="color: #f6f6f4;background-color: #282a36;font-family: 'source code pro', 'Droid Sans Mono', 'monospace', monospace, 'Droid Sans Fallback';font-weight: normal;font-size: 15px;line-height: 20px;white-space: pre;"><div><span style="color: #f6f6f4;">m_ioService.</span><span style="color: #62e884;">run</span><span style="color: #f6f6f4;">();</span></div></div>
    <p>Inside delayedInterest, the variable nPackets is determined
      according to the 8000 byte payload limit.<br>
    </p>
    <div style="color: #f6f6f4;background-color: #282a36;font-family: 'source code pro', 'Droid Sans Mono', 'monospace', monospace, 'Droid Sans Fallback';font-weight: normal;font-size: 15px;line-height: 20px;white-space: pre;"><div><span style="color: #7b7f8b;">// Express interest for all packets</span></div><div><span style="color: #f6f6f4;">   </span><span style="color: #f286c4;">for</span><span style="color: #f6f6f4;"> (i </span><span style="color: #f286c4;">=</span><span style="color: #f6f6f4;"> </span><span style="color: #bf9eee;">0</span><span style="color: #f6f6f4;">; i </span><span style="color: #f286c4;"><</span><span style="color: #f6f6f4;"> nPackets; i</span><span style="color: #f286c4;">++</span><span style="color: #f6f6f4;">){</span></div>
<div><span style="color: #f6f6f4;">      </span><span style="color: #f286c4;">if</span><span style="color: #f6f6f4;"> ((bHasLeftover) </span><span style="color: #f286c4;">&&</span><span style="color: #f6f6f4;"> (i</span><span style="color: #f286c4;">+</span><span style="color: #bf9eee;">1</span><span style="color: #f6f6f4;"> </span><span style="color: #f286c4;">==</span><span style="color: #f6f6f4;"> nPackets)){</span></div><div><span style="color: #7b7f8b;">         // Last packet</span></div><div><span style="color: #f6f6f4;">         nPacketPayload </span><span style="color: #f286c4;">=</span><span style="color: #f6f6f4;"> dataBuff.nPayload </span><span style="color: #f286c4;">%</span><span style="color: #f6f6f4;"> N_MAX_PACKET_BYTES;</span></div><div><span style="color: #f6f6f4;">      }</span></div><div><span style="color: #f6f6f4;">      </span><span style="color: #f286c4;">else</span><span style="color: #f6f6f4;">{</span></div><div><span style="color: #7b7f8b;">         // Any other packet</span></div><div><span style="color: #f6f6f4;">         nPacketPayload </span><span style="color: #f286c4;">=</span><span style="color: #f6f6f4;"> N_MAX_PACKET_BYTES;</span></div><div><span style="color: #f6f6f4;">      }</span></div>
<div><span style="color: #f6f6f4;">      </span><span style="color: #62e884;">snprintf</span><span style="color: #f6f6f4;">(strBuf, </span><span style="color: #f286c4;">sizeof</span><span style="color: #f6f6f4;">(strBuf), </span><span style="color: #dee492;">"</span><span style="color: #bf9eee;">%s</span><span style="color: #e7ee98;">-</span><span style="color: #bf9eee;">%d</span><span style="color: #e7ee98;">b-</span><span style="color: #bf9eee;">%d</span><span style="color: #e7ee98;">of</span><span style="color: #bf9eee;">%d</span><span style="color: #dee492;">"</span><span style="color: #f6f6f4;">, strPrefix, nPacketPayload, i</span><span style="color: #f286c4;">+</span><span style="color: #bf9eee;">1</span><span style="color: #f6f6f4;">, nPackets);</span></div><div><span style="color: #f6f6f4;">      </span><span style="color: #62e884;">fprintf</span><span style="color: #f6f6f4;">(stdout, </span><span style="color: #dee492;">"</span><span style="color: #e7ee98;">[Consumer::delayedInterest] Expressing interest=</span><span style="color: #bf9eee;">%s</span><span style="color: #e7ee98;"> (</span><span style="color: #bf9eee;">%d</span><span style="color: #e7ee98;">/</span><span style="color: #bf9eee;">%d</span><span style="color: #e7ee98;">)</span><span style="color: #f286c4;">\n</span><span style="color: #dee492;">"</span><span style="color: #f6f6f4;">, strBuf, i</span><span style="color: #f286c4;">+</span><span style="color: #bf9eee;">1</span><span style="color: #f6f6f4;">, nPackets);</span></div>
<div><span style="color: #f6f6f4;">      dtBegin </span><span style="color: #f286c4;">=</span><span style="color: #f6f6f4;"> std</span><span style="color: #f286c4;">::</span><span style="color: #f6f6f4;">chrono</span><span style="color: #f286c4;">::</span><span style="color: #f6f6f4;">steady_clock</span><span style="color: #f286c4;">::</span><span style="color: #62e884;">now</span><span style="color: #f6f6f4;">();</span></div><div><span style="color: #f6f6f4;">      interestName </span><span style="color: #f286c4;">=</span><span style="color: #f6f6f4;"> </span><span style="color: #62e884;">Name</span><span style="color: #f6f6f4;">(strBuf);</span></div><div><span style="color: #f6f6f4;">      interest     </span><span style="color: #f286c4;">=</span><span style="color: #f6f6f4;"> </span><span style="color: #62e884;">Interest</span><span style="color: #f6f6f4;">(interestName);</span></div><div><span style="color: #f6f6f4;">      interest.</span><span style="color: #62e884;">setCanBePrefix</span><span style="color: #f6f6f4;">(</span><span style="color: #bf9eee;">false</span><span style="color: #f6f6f4;">);</span></div><div><span style="color: #f6f6f4;">      interest.</span><span style="color: #62e884;">setMustBeFresh</span><span style="color: #f6f6f4;">(</span><span style="color: #bf9eee;">true</span><span style="color: #f6f6f4;">);</span></div><div><span style="color: #f6f6f4;">      interest.</span><span style="color: #62e884;">setInterestLifetime</span><span style="color: #f6f6f4;">(</span><span style="color: #bf9eee;">6</span><span style="color: #f286c4;">_s</span><span style="color: #f6f6f4;">);</span></div>
<div><span style="color: #f6f6f4;">      m_face.</span><span style="color: #62e884;">expressInterest</span><span style="color: #f6f6f4;">(interest,</span></div><div><span style="color: #f6f6f4;">                           </span><span style="color: #62e884;">bind</span><span style="color: #f6f6f4;">(</span><span style="color: #f286c4;">&</span><span style="color: #f6f6f4;">Consumer</span><span style="color: #f286c4;">::</span><span style="color: #f6f6f4;">onData, </span><span style="color: #bf9eee;font-style: italic;">this</span><span style="color: #f6f6f4;">, _1, _2, dtBegin),</span></div><div><span style="color: #f6f6f4;">                           </span><span style="color: #62e884;">bind</span><span style="color: #f6f6f4;">(</span><span style="color: #f286c4;">&</span><span style="color: #f6f6f4;">Consumer</span><span style="color: #f286c4;">::</span><span style="color: #f6f6f4;">onNack, </span><span style="color: #bf9eee;font-style: italic;">this</span><span style="color: #f6f6f4;">, _1, _2, dtBegin),</span></div><div><span style="color: #f6f6f4;">                           </span><span style="color: #62e884;">bind</span><span style="color: #f6f6f4;">(</span><span style="color: #f286c4;">&</span><span style="color: #f6f6f4;">Consumer</span><span style="color: #f286c4;">::</span><span style="color: #f6f6f4;">onTimeout, </span><span style="color: #bf9eee;font-style: italic;">this</span><span style="color: #f6f6f4;">, _1, dtBegin));</span></div><div><span style="color: #f6f6f4;">   }</span></div></div>
    <p><br>
    </p>
    <p>This runs fine for small requests, but when more interests are
      expressed in a row, making requests of about 60 to 100 8KB
      packages, the producers work for a while but then start becoming
      unresponsive. Once I get a timeout from a specific producer, it
      does not answer to any more requests, even if I kill the
      producer/consumer process and start them back up.</p>
    <p>Looking into the producer's NFD debug logs I found this:</p>
    <p><br>
    </p>
    <p>When the data is received by the consumer:</p>
    <p><font size="+1"><tt>1619483660.357769 DEBUG: [nfd.Forwarder]
          onIncomingInterest in=(271,0)
          interest=/ndn/d0-site/d0/C2Data-21-Type5-8000b-5of26</tt><tt><br>
        </tt><tt>1619483660.357807 DEBUG: [nfd.ContentStore] find
          /ndn/d0-site/d0/C2Data-21-Type5-8000b-5of26 no-match</tt><tt><br>
        </tt><tt>1619483660.357833 DEBUG: [nfd.Forwarder]
          onContentStoreMiss
          interest=/ndn/d0-site/d0/C2Data-21-Type5-8000b-5of26</tt><tt><br>
        </tt><tt>1619483660.357840 DEBUG: [nfd.BestRouteStrategy]
/ndn/d0-site/d0/C2Data-21-Type5-8000b-5of26?MustBeFresh&Nonce=89b7b04a&Lifetime=6000
          from=(271,0) newPitEntry-to=279</tt><tt><br>
        </tt><tt>1619483660.357866 DEBUG: [nfd.Forwarder]
          onOutgoingInterest out=279
          interest=/ndn/d0-site/d0/C2Data-21-Type5-8000b-5of26</tt><tt><br>
        </tt><tt>1619483660.359613 DEBUG: [nfd.Forwarder] onIncomingData
          in=(279,0) data=/ndn/d0-site/d0/C2Data-21-Type5-8000b-5of26</tt><tt><br>
        </tt><tt>1619483660.359631 DEBUG: [nfd.ContentStore] insert
          /ndn/d0-site/d0/C2Data-21-Type5-8000b-5of26</tt><tt><br>
        </tt><tt>1619483660.359641 DEBUG: [nfd.Forwarder] onIncomingData
          matching=/ndn/d0-site/d0/C2Data-21-Type5-8000b-5of26</tt><tt><br>
        </tt><tt>1619483660.359654 DEBUG: [nfd.Strategy]
          afterReceiveData
          pitEntry=/ndn/d0-site/d0/C2Data-21-Type5-8000b-5of26
          in=(279,0) data=/ndn/d0-site/d0/C2Data-21-Type5-8000b-5of26</tt><tt><br>
        </tt><tt>1619483660.359675 DEBUG: [nfd.Strategy]
          beforeSatisfyInterest
          pitEntry=/ndn/d0-site/d0/C2Data-21-Type5-8000b-5of26
          in=(279,0) data=/ndn/d0-site/d0/C2Data-21-Type5-8000b-5of26</tt><tt><br>
        </tt><tt>1619483660.359686 DEBUG: [nfd.Forwarder] onOutgoingData
          out=271 data=/ndn/d0-site/d0/C2Data-21-Type5-8000b-5of26</tt><tt><br>
        </tt><tt>1619483660.359722 DEBUG: [nfd.Forwarder]
          onInterestFinalize
          interest=/ndn/d0-site/d0/C2Data-21-Type5-8000b-5of26 satisfied</tt></font></p>
    <p>When the data times out on the consumer:</p>
    <p><font size="+1"><tt>1619483660.357885 DEBUG: [nfd.Forwarder]
          onIncomingInterest in=(271,0)
          interest=/ndn/d0-site/d0/C2Data-21-Type5-8000b-6of26</tt><tt><br>
        </tt><tt>1619483660.357923 DEBUG: [nfd.ContentStore] find
          /ndn/d0-site/d0/C2Data-21-Type5-8000b-6of26 no-match</tt><tt><br>
        </tt><tt>1619483660.357929 DEBUG: [nfd.Forwarder]
          onContentStoreMiss
          interest=/ndn/d0-site/d0/C2Data-21-Type5-8000b-6of26</tt><tt><br>
        </tt><tt>1619483660.357935 DEBUG: [nfd.BestRouteStrategy]
/ndn/d0-site/d0/C2Data-21-Type5-8000b-6of26?MustBeFresh&Nonce=b423a0c7&Lifetime=6000
          from=(271,0) newPitEntry-to=279</tt><tt><br>
        </tt><tt>1619483660.357942 DEBUG: [nfd.Forwarder]
          onOutgoingInterest out=279
          interest=/ndn/d0-site/d0/C2Data-21-Type5-8000b-6of26</tt><tt><br>
        </tt><tt>1619483666.357128 DEBUG: [nfd.Forwarder]
          onInterestFinalize
          interest=/ndn/d0-site/d0/C2Data-21-Type5-8000b-6of26
          unsatisfied</tt></font></p>
    <p><font size="+1"><tt><br>
        </tt></font></p>
    <p>The core Producer::onInterest is pretty simple and looks like
      this, where nPayloadSize and nTTLMs are extracted from the
      interest string:</p>
    <div style="color: #f6f6f4;background-color: #282a36;font-family: 'source code pro', 'Droid Sans Mono', 'monospace', monospace, 'Droid Sans Fallback';font-weight: normal;font-size: 15px;line-height: 20px;white-space: pre;"><div><span style="color: #7b7f8b;">// Create payload</span></div><div><span style="color: #f6f6f4;">  </span><span style="color: #f286c4;">auto</span><span style="color: #f6f6f4;"> b </span><span style="color: #f286c4;">=</span><span style="color: #f6f6f4;"> </span><span style="color: #62e884;">make_shared</span><span style="color: #f6f6f4;"><</span><span style="color: #97e1f1;font-style: italic;">Buffer</span><span style="color: #f6f6f4;">>();</span></div><div><span style="color: #f6f6f4;">  b</span><span style="color: #f286c4;">-></span><span style="color: #62e884;">assign</span><span style="color: #f6f6f4;">(nPayloadSize, </span><span style="color: #dee492;">'</span><span style="color: #e7ee98;">a</span><span style="color: #dee492;">'</span><span style="color: #f6f6f4;">);</span></div><div><span style="color: #f6f6f4;">  blockPayload </span><span style="color: #f286c4;">=</span><span style="color: #f6f6f4;"> </span><span style="color: #62e884;">Block</span><span style="color: #f6f6f4;">(tlv</span><span style="color: #f286c4;">::</span><span style="color: #f6f6f4;">Content, std</span><span style="color: #f286c4;">::</span><span style="color: #62e884;">move</span><span style="color: #f6f6f4;">(b));</span></div>
<div><span style="color: #7b7f8b;">  // Create packet for interest</span></div><div><span style="color: #f6f6f4;">  </span><span style="color: #f286c4;">auto</span><span style="color: #f6f6f4;"> data  </span><span style="color: #f286c4;">=</span><span style="color: #f6f6f4;"> </span><span style="color: #62e884;">make_shared</span><span style="color: #f6f6f4;"><</span><span style="color: #97e1f1;font-style: italic;">Data</span><span style="color: #f6f6f4;">>(interest.</span><span style="color: #62e884;">getName</span><span style="color: #f6f6f4;">());</span></div><div><span style="color: #f6f6f4;">  data</span><span style="color: #f286c4;">-></span><span style="color: #62e884;">setFreshnessPeriod</span><span style="color: #f6f6f4;">(boost</span><span style="color: #f286c4;">::</span><span style="color: #f6f6f4;">chrono</span><span style="color: #f286c4;">::</span><span style="color: #62e884;">milliseconds</span><span style="color: #f6f6f4;">(nTTLMs));</span></div><div><span style="color: #f6f6f4;">  data</span><span style="color: #f286c4;">-></span><span style="color: #62e884;">setContent</span><span style="color: #f6f6f4;">(blockPayload);</span></div><div><span style="color: #f6f6f4;">  m_keyChain.</span><span style="color: #62e884;">sign</span><span style="color: #f6f6f4;">(</span><span style="color: #f286c4;">*</span><span style="color: #f6f6f4;">data);</span></div>
<div><span style="color: #7b7f8b;">  // Return Data packet to the requester</span></div><div><span style="color: #f6f6f4;">  std</span><span style="color: #f286c4;">::</span><span style="color: #f6f6f4;">cout </span><span style="color: #f286c4;"><<</span><span style="color: #f6f6f4;"> </span><span style="color: #dee492;">"</span><span style="color: #e7ee98;">[Producer::onInterest] << D: </span><span style="color: #dee492;">"</span><span style="color: #f6f6f4;"> </span><span style="color: #f286c4;"><<</span><span style="color: #f6f6f4;"> </span><span style="color: #f286c4;">*</span><span style="color: #f6f6f4;">data </span><span style="color: #f286c4;"><<</span><span style="color: #f6f6f4;"> std</span><span style="color: #f286c4;">::</span><span style="color: #f6f6f4;">endl;</span></div><div><span style="color: #f6f6f4;">  m_face.</span><span style="color: #62e884;">put</span><span style="color: #f6f6f4;">(</span><span style="color: #f286c4;">*</span><span style="color: #f6f6f4;">data);</span></div>
<div><span style="color: #f6f6f4;">  std</span><span style="color: #f286c4;">::</span><span style="color: #f6f6f4;">cout </span><span style="color: #f286c4;"><<</span><span style="color: #f6f6f4;"> </span><span style="color: #dee492;">"</span><span style="color: #e7ee98;">[Producer::onInterest] End</span><span style="color: #dee492;">"</span><span style="color: #f6f6f4;">  </span><span style="color: #f286c4;"><<</span><span style="color: #f6f6f4;"> std</span><span style="color: #f286c4;">::</span><span style="color: #f6f6f4;">endl;</span></div></div>
    <p><br>
    </p>
    <p>I also encountered another issue when testing this. I tried
      starting the consumer processes from the python script that
      creates the experiment (as stated below), but I found that the
      Scheduler does not run for some reason. All the calls to
      m_scheduler.schedule() are made, but after calling
      m_ioService.run(), the delayedInterest() function is not called at
      all. However, the exact same program works when called with the
      same parameters from the host's xterm window. This a pretty by
      problem, because I cannot manually start all the consumers for the
      experiment.<br>
    </p>
    <div style="color: #f6f6f4;background-color: #282a36;font-family: 'source code pro', 'Droid Sans Mono', 'monospace', monospace, 'Droid Sans Fallback';font-weight: normal;font-size: 15px;line-height: 20px;white-space: pre;"><div><span style="color: #62e884;">getPopen</span><span style="color: #f6f6f4;">(pHost, </span><span style="color: #dee492;">'</span><span style="color: #e7ee98;">consumer-with-queue </span><span style="color: #bf9eee;">%s</span><span style="color: #e7ee98;"> /home/vagrant/icnsimulations/topologies/queue_wired-topo4.txt</span><span style="color: #dee492;">'</span><span style="color: #f6f6f4;"> </span><span style="color: #f286c4;">%</span><span style="color: #f6f6f4;"> (</span><span style="color: #97e1f1;font-style: italic;">str</span><span style="color: #f6f6f4;">(pHost)))</span></div></div>
    <div class="moz-cite-prefix"><br>
    </div>
    <div class="moz-cite-prefix"><br>
    </div>
    <div class="moz-cite-prefix">Best regards and thanks for all the
      help so far,<br>
    </div>
    <div class="moz-cite-prefix">AndrĂ© Dexheimer Carneiro<br>
    </div>
    <div class="moz-cite-prefix"><br>
    </div>
    <div class="moz-cite-prefix"><br>
    </div>
    <div class="moz-cite-prefix">On 21/04/2021 17:32, Junxiao Shi wrote:<br>
    </div>
    <blockquote type="cite"
cite="mid:CAOFH+OZWY4cLoym9O1OOQ8FMnq0ZjC73Zn_8ub41Vt5_TkAMTA@mail.gmail.com">
      <meta http-equiv="content-type" content="text/html; charset=UTF-8">
      <div dir="auto">Hi Andre</div>
      <div dir="auto"><br>
      </div>
      <div dir="auto">You can express multiple Interests one after
        another, and then wait for responses.</div>
      <div dir="auto">In ndnping, expressInterest is called at a fixed
        interval, independent from whether previous Interests were
        satisfied.</div>
      <div dir="auto"><br>
      </div>
      <div dir="auto">To retrieve files, or more generally, segmented
        objects, most libraries have a helper for that.</div>
      <div dir="auto">In ndn-cxx it's called SegmentFetcher.</div>
      <div dir="auto"><br>
      </div>
      <div dir="auto">See also <a
          href="https://yoursunny.com/t/2021/NDN-face/"
          moz-do-not-send="true">https://yoursunny.com/t/2021/NDN-face/</a>
        , "Face in Libraries" section, for a deep explanation on how the
        library Face works.</div>
      <div dir="auto"><br>
      </div>
      <div dir="auto">Yours, Junxiao</div>
      <div><br>
        <div class="gmail_quote">
          <div dir="ltr" class="gmail_attr">On Wed, Apr 21, 2021 at
            16:24 Andre <<a href="mailto:adcarneiro@inf.ufrgs.br"
              moz-do-not-send="true">adcarneiro@inf.ufrgs.br</a>>
            wrote:<br>
          </div>
          <blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left-width:1px;border-left-style:solid;padding-left:1ex;border-left-color:rgb(204,204,204)">
            <div>
              <p style="text-align:center"><font
                  style="color:rgb(255,0,0)"><strong>External Email</strong><br>
                </font></p>
              <p>Hi Junxiao,</p>
              <p><br>
              </p>
              <p>that makes sense, thanks for the help so far. <br>
              </p>
              <p><br>
              </p>
              <p>I looked into the ndnping example but one doubt
                remains. What if I want to consume large chunks of data,
                say 10MB or more. In this case, I will need to divide
                that into chunks of 8800 bytes at most, since that is
                the maximum NDN package size allowed. However, using the
                same mechanism as ndnping or
                consumer/consumer-with-timer, the program would have to
                wait until one 8800 B package is received before
                requesting the next one (using face.expressInterest).
                How can I do that so that I don`t have to wait a full
                round-trip-time before consuming the next part?</p>
              <p><br>
              </p>
              <p>Best regards,</p>
              <p>AndrĂ©</p>
            </div>
          </blockquote>
        </div>
      </div>
    </blockquote>
  </body>
</html>