<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <div class="moz-cite-prefix">Привет,</div>
    <div class="moz-cite-prefix"><br>
    </div>
    <div class="moz-cite-prefix">On 13.01.2021 11:26, Vladimir Sharun
      wrote:</div>
    <div class="moz-cite-prefix"><br>
    </div>
    <blockquote type="cite"
      cite="mid:1610525518.533964000.ddaxh9ul@frv53.fwdcdn.com"><span
        style="display:block;" class="xfm_20544594">
        <blockquote style="border-left:1px solid #cccccc;margin:0px 0px
          0px 0.8ex;padding-left:1ex;">
          <div style="display:block;">
            <blockquote type="cite" style="border-left:1px solid
              #cccccc;margin:0px 0px 0px 0.8ex;padding-left:1ex;">
              <div style="display:block;">
                <div><span
                    style="font-size:12pt;line-height:14pt;font-family:Arial;">Постановка
                    задачи требует уточнений. Надо понимать: </span></div>
                <ol style="margin:5px 0;" start="1">
                  <li><span
                      style="font-size:12pt;line-height:14pt;font-family:Arial;">на
                      каждый UDP пакет надо принимать решение,
                      основываясь на критериях из кэша/апдейтов_в_пуше ?
                      что это ?</span></li>
                </ol>
              </div>
            </blockquote>
            <div>каждый пакет - это текстовая строка, состоящая из 4-х
              полей, по одному из которых делается if и есличо, то три
              других проходят проверки на валидность и, дополняясь
              информацией из local cache, уходят в output</div>
            <div>что-то типа</div>
            <pre style="margin:5px 0;"><span style="color:#0033b3;">while True</span>:
    data, address = lsock.recvfrom(<span style="color:#1750eb;">1024</span>)
    try:
        a, b, c, d = [i.strip()) for i in data.decode().split(',)]
        a = int(a)
        if a == 255:
           if not b.isnumeric():
               continue
           va = memcached.get(b)
           if va:
               IPAddress(c)
               d = int(d)
               # we're here because no exception above
               data = b.decode() + socket.inet_aton(c) + d.from_bytes(2, 'big) + va
               for r in remotes:
                   rsock.send(data, r)  # output UDP
        elif a in [3, 5, 7]:
           # smth else
           ...
    except:
        pass
</pre>
          </div>
        </blockquote>
        <div><span
            style="font-size:12pt;font-family:Arial;line-height:14pt;"><br
              data-mce-bogus="1">
          </span></div>
        <div><span
            style="font-size:12pt;font-family:Arial;line-height:14pt;">memcache
            - это <b>TCP</b>, очень очень надо контролировать, чтобы у
            тебя не был каждый запрос - создание класса, коннект,
            прочитали, дисконнект. Т.е. это должен быть какой-то
            pipeline, в котором постоянно открыт коннект к мемкешу.
            Создать класс, коннект-прочитали-дисконнект - это ок
            50-60мкс на лупбеке.<br data-mce-bogus="1">
          </span></div>
      </span></blockquote>
    <p>да, но это (а) у него таки постоянно открытый сокет и (б) смотрим
      в другие варианты несть им числа -
      <a class="moz-txt-link-freetext" href="https://en.wikipedia.org/wiki/List_of_in-memory_databases">https://en.wikipedia.org/wiki/List_of_in-memory_databases</a> - и
      Redis один из них, да<br>
    </p>
    <p><br>
    </p>
    <blockquote type="cite"
      cite="mid:1610525518.533964000.ddaxh9ul@frv53.fwdcdn.com"><span
        style="display:block;" class="xfm_20544594">
        <div><span
            style="font-size:12pt;font-family:Arial;line-height:14pt;">Конструкторы
            и деструкторы - это тоже небесплатно кстати. Т.е.
            обслуживание ООП - это не халява.<br data-mce-bogus="1">
          </span></div>
      </span></blockquote>
    <p>Это Питон, в нём даже int - класс :) Если ты про строку
      "IPAddress(c)", то её можно заменить на проверку скомпиленным
      регекспом - может будет быстрее, но на самом деле там вот так:</p>
    <p>ipa = IPAddress(c)<br>
      af = socket.AF_INET6 if ipa.version == 6 else socket.AF_INET<br>
      ... socket.inet_atop(af, c), ...</p>
    <p>с регекспами придется делать два match:</p>
    <p>if re.match(v4, ...):<br>
        af = socket.AF_INET<br>
      elif re.match(v6, ...)<br>
        af = socket.AF_INET6<br>
      else:<br>
        continue<br>
    </p>
    <p>так шо тут бабка надвое сказала :)</p>
    <p><br>
    </p>
    <blockquote type="cite"
      cite="mid:1610525518.533964000.ddaxh9ul@frv53.fwdcdn.com"><span
        style="display:block;" class="xfm_20544594">
      </span><span style="display:block;" class="xfm_20544594">
        <blockquote style="border-left:1px solid #cccccc;margin:0px 0px
          0px 0.8ex;padding-left:1ex;">
          <div style="display:block;">
            <blockquote type="cite" style="border-left:1px solid
              #cccccc;margin:0px 0px 0px 0.8ex;padding-left:1ex;">
              <div style="display:block;">
                <div><span
                    style="font-size:12pt;line-height:14pt;font-family:Arial;">Да,
                    и inram cache - это тоже штука в себе.</span></div>
              </div>
            </blockquote>
            <div>а какая разумная альтернатива?</div>
          </div>
        </blockquote>
        <div><span
            style="font-size:12pt;font-family:Arial;line-height:14pt;"><br
              data-mce-bogus="1">
          </span></div>
        <div><span
            style="font-size:12pt;font-family:Arial;line-height:14pt;">Тут
            не в альтернативе, а в реализации. Мемкеш например может
            заглючить (не теоретически, а практически) и что ты тогда
            будешь делать ?<br data-mce-bogus="1">
          </span></div>
      </span></blockquote>
    <p>именно поэтому ищется альтернативное решение с синхронной
      репликацей на кшталт Галеры, только in-ram :) Я, собственно,
      именно поэтому в оригинальном письме написал "при старте наполняет
      in-ram cache" - потому что это НЕ memcached :)<br>
    </p>
    <p>если же говорить о "что ты тогда будешь делать", то в данном
      конкретном случае я бы написал в memcached.service что-то на
      кшталт PostExec = "myapp restart" :-)</p>
    <p>Собственно, возвращаясь к исходному топику:</p>
    <ul>
      <li>есть ли у меня шансы получить несколько kpps такой задачи на
        Питоне?</li>
      <li>как правильно распараллелить две задачи:</li>
      <ul>
        <li>сначала computing + периодический Net I/O</li>
        <li>потом толстый Net I/O + периодический Net I/O</li>
        <ul>
          <li>может select() можно?<br>
          </li>
        </ul>
      </ul>
    </ul>
    <p>Спасибо.<br>
    </p>
    <pre class="moz-signature" cols="72">-- 
Volodymyr Litovka
  "Vision without Execution is Hallucination." -- Thomas Edison</pre>
  </body>
</html>