Sophie

Sophie

distrib > Mageia > 4 > x86_64 > by-pkgid > c3732731228538f6126cae930c10ad71 > files > 201

python-pyro4-4.21-3.mga4.noarch.rpm



<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">


<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    
    <title>Tips &amp; Tricks &mdash; Pyro 4.21 documentation</title>
    
    <link rel="stylesheet" href="_static/default.css" type="text/css" />
    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
    
    <script type="text/javascript">
      var DOCUMENTATION_OPTIONS = {
        URL_ROOT:    '',
        VERSION:     '4.21',
        COLLAPSE_INDEX: false,
        FILE_SUFFIX: '.html',
        HAS_SOURCE:  true
      };
    </script>
    <script type="text/javascript" src="_static/jquery.js"></script>
    <script type="text/javascript" src="_static/underscore.js"></script>
    <script type="text/javascript" src="_static/doctools.js"></script>
    <link rel="top" title="Pyro 4.21 documentation" href="index.html" />
    <link rel="next" title="Configuring Pyro" href="config.html" />
    <link rel="prev" title="Flame: Foreign Location Automatic Module Exposer" href="flame.html" /> 
  </head>
  <body>
    <div class="related">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="genindex.html" title="General Index"
             accesskey="I">index</a></li>
        <li class="right" >
          <a href="config.html" title="Configuring Pyro"
             accesskey="N">next</a> |</li>
        <li class="right" >
          <a href="flame.html" title="Flame: Foreign Location Automatic Module Exposer"
             accesskey="P">previous</a> |</li>
        <li><a href="index.html">Pyro 4.21 documentation</a> &raquo;</li> 
      </ul>
    </div>  

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body">
            
  <div class="section" id="tips-tricks">
<span id="tipstricks"></span><h1>Tips &amp; Tricks<a class="headerlink" href="#tips-tricks" title="Permalink to this headline">¶</a></h1>
<div class="section" id="best-practices">
<h2>Best practices<a class="headerlink" href="#best-practices" title="Permalink to this headline">¶</a></h2>
<div class="section" id="avoid-circular-communication-topologies">
<h3>Avoid circular communication topologies.<a class="headerlink" href="#avoid-circular-communication-topologies" title="Permalink to this headline">¶</a></h3>
<p>When you can have a circular communication pattern in your system (A&#8211;&gt;B&#8211;&gt;C&#8211;&gt;A) this can cause some problems:</p>
<ul class="simple">
<li>when reusing a proxy it causes a deadlock because the proxy is already being used for an active remote call. See the <tt class="file docutils literal"><span class="pre">deadlock</span></tt> example.</li>
<li>with the multiplex servertype, the server itself may also block for all other remote calls because the handling of the first is not yet completed.</li>
</ul>
<p>Avoid circularity, or use <em>oneway</em> method calls on at least one of the links in the chain.</p>
</div>
<div class="section" id="release-your-proxies-if-you-can">
<h3>Release your proxies if you can.<a class="headerlink" href="#release-your-proxies-if-you-can" title="Permalink to this headline">¶</a></h3>
<p>A connected proxy that is unused takes up resources on the server. In the case of the threadpool server type,
it locks up a single thread. If you have too many connected proxies at the same time, the server may run out
of threads and stops responding. (The multiplex server doesn&#8217;t have this particular issue).
It is a good thing to think about when you can release a proxy in your code.
Don&#8217;t worry about reconnecting, that&#8217;s done automatically once it is used again.
You can use explicit <tt class="docutils literal"><span class="pre">_pyroRelease</span></tt> calls or use the proxy from within a context manager.
It&#8217;s not a good idea to release it after every single remote method call though, because then the cost
of reconnecting the socket will cause a serious drop in performance (unless every call is at least a few seconds after the previous one).</p>
</div>
<div class="section" id="avoid-large-binary-blobs-over-the-wire">
<h3>Avoid large binary blobs over the wire.<a class="headerlink" href="#avoid-large-binary-blobs-over-the-wire" title="Permalink to this headline">¶</a></h3>
<p>Pyro is not designed to efficiently transfer large amounts of binary data over the network.
Try to find another protocol that better suits this requirement.
Read <a class="reference internal" href="#binarytransfer"><em>Binary data transfer</em></a> for some more details about this.</p>
</div>
<div class="section" id="minimize-object-graphs-that-travel-over-the-wire">
<h3>Minimize object graphs that travel over the wire.<a class="headerlink" href="#minimize-object-graphs-that-travel-over-the-wire" title="Permalink to this headline">¶</a></h3>
<p>Pyro will serialize the whole object graph you&#8217;re passing, even when only a tiny fraction
of it is used on the receiving end. Be aware of this: it may be necessary to define special lightweight objects
for your Pyro interfaces that hold the data you need, rather than passing a huge object structure.</p>
</div>
</div>
<div class="section" id="logging">
<h2>Logging<a class="headerlink" href="#logging" title="Permalink to this headline">¶</a></h2>
<p>If you configure it (see <a class="reference internal" href="config.html#config-items"><em>Overview of Config Items</em></a>) Pyro will write a bit of debug information, errors, and notifications to a log file.
It uses Python&#8217;s standard <tt class="xref py py-mod docutils literal"><span class="pre">logging</span></tt> module for this.
Once enabled, your own program code could use Pyro&#8217;s logging setup as well.
But if you want to configure your own logging, make sure you do that before any Pyro imports. Then Pyro will skip its own autoconfig.</p>
</div>
<div class="section" id="multiple-network-interfaces">
<h2>Multiple network interfaces<a class="headerlink" href="#multiple-network-interfaces" title="Permalink to this headline">¶</a></h2>
<p>This is a difficult subject but here are a few short notes about it.
<em>At this time, Pyro doesn&#8217;t support running on multiple network interfaces at the same time</em>.
You can bind a deamon on INADDR_ANY (0.0.0.0) though, including the name server.
But weird things happen with the URIs of objects published through these servers, because they
will point to 0.0.0.0 and your clients won&#8217;t be able to connect to the actual objects.</p>
<p>The name server however contains a little trick. The broadcast responder can also be bound on 0.0.0.0
and it will in fact try to determine the correct ip address of the interface that a client needs to use
to contact the name server on. So while you cannot run Pyro daemons on 0.0.0.0 (to respond to requests
from all possible interfaces), sometimes it is possible to run only the name server on 0.0.0.0.
The success ratio of all this depends heavily on your network setup.</p>
</div>
<div class="section" id="same-major-python-version-required">
<h2>Same major Python version required<a class="headerlink" href="#same-major-python-version-required" title="Permalink to this headline">¶</a></h2>
<p>When Pyro is configured to use pickle as its serialization format, it is required to have the same <em>major</em> Python versions
on your clients and your servers. Otherwise the different parties cannot decipher each others serialized data.
This means you cannot let Python 2.x talk to Python 3.x with Pyro. However
it should be fine to have Python 2.6.2 talk to Python 2.7.3 for instance.
Using one of the implementation independent protocols (serpent or json) will avoid this limitation.</p>
</div>
<div class="section" id="wire-protocol-version">
<h2>Wire protocol version<a class="headerlink" href="#wire-protocol-version" title="Permalink to this headline">¶</a></h2>
<p>Here is a little tip to find out what wire protocol version a given Pyro server is using.
This could be useful if you are getting <tt class="docutils literal"><span class="pre">ProtocolError:</span> <span class="pre">invalid</span> <span class="pre">data</span> <span class="pre">or</span> <span class="pre">unsupported</span> <span class="pre">protocol</span> <span class="pre">version</span></tt>
or something like that. It also works with Pyro 3.x.</p>
<p><strong>Server</strong></p>
<p>This is a way to figure out the protocol version number a given Pyro server is using:
by reading the first 6 bytes from the server socket connection.
The Pyro daemon will respond with a 4-byte string &#8220;<tt class="docutils literal"><span class="pre">PYRO</span></tt>&#8221; followed by a 2-byte number
that is the protocol version used:</p>
<div class="highlight-python"><pre>$ nc pyroservername pyroserverport | od -N 6 -t x1c
0000000  50  59  52  4f  00  05
          P   Y   R   O  \0 005</pre>
</div>
<p>This one is talking protocol version <tt class="docutils literal"><span class="pre">00</span> <span class="pre">05</span></tt> (5).
This low number means it is a Pyro 3.x server. When you try it on a Pyro 4 server:</p>
<div class="highlight-python"><pre>$ nc pyroservername pyroserverport | od -N 6 -t x1c
0000000  50  59  52  4f  00  2c
          P   Y   R   O  \0   ,</pre>
</div>
<p>This one is talking protocol version <tt class="docutils literal"><span class="pre">00</span> <span class="pre">2c</span></tt> (44).
For Pyro4 the protocol version started at 40 for the first release
and is now at 44 for the current release at the time of writing.</p>
<p><strong>Client</strong></p>
<p>To find out the protocol version that your client code is using, you can use this:</p>
<div class="highlight-python"><pre>$ python -c "import Pyro4.constants as c; print(c.PROTOCOL_VERSION)"</pre>
</div>
<p>or for Pyro3:</p>
<div class="highlight-python"><pre>$ python -c "import Pyro.protocol as p; print(p.PYROAdapter.version)"</pre>
</div>
</div>
<div class="section" id="asynchronous-future-normal-function-calls">
<span id="future-functions"></span><h2>Asynchronous (&#8216;future&#8217;) normal function calls<a class="headerlink" href="#asynchronous-future-normal-function-calls" title="Permalink to this headline">¶</a></h2>
<p>Pyro provides an async proxy wrapper to call remote methods asynchronously, see <a class="reference internal" href="clientcode.html#async-calls"><em>Asynchronous (&#8216;future&#8217;) remote calls &amp; call chains</em></a>.
For normal Python code, Python provides a similar mechanism in the form of the
<a class="reference internal" href="api/futures.html#Pyro4.futures.Future" title="Pyro4.futures.Future"><tt class="xref py py-class docutils literal"><span class="pre">Pyro4.futures.Future</span></tt></a> class (also available as <tt class="docutils literal"><span class="pre">Pyro4.Future</span></tt>).
With a syntax that is slightly different from normal method calls,
it provides the same asynchronous function calls as the async proxy has.
Note that Python itself has a similar thing in the standard library since version 3.2, see
<a class="reference external" href="http://docs.python.org/3/library/concurrent.futures.html#future-objects">http://docs.python.org/3/library/concurrent.futures.html#future-objects</a> . However Pyro&#8217;s Future
object is available on older Python versions too, and works slightly differently. It&#8217;s
also a little bit easier to work with.</p>
<p>You create a <tt class="docutils literal"><span class="pre">Future</span></tt> object for a callable that you want to execute in the background,
and receive its results somewhere in the future:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">def</span> <span class="nf">add</span><span class="p">(</span><span class="n">x</span><span class="p">,</span><span class="n">y</span><span class="p">):</span>
    <span class="k">return</span> <span class="n">x</span><span class="o">+</span><span class="n">y</span>

<span class="n">futurecall</span> <span class="o">=</span> <span class="n">Pyro4</span><span class="o">.</span><span class="n">Future</span><span class="p">(</span><span class="n">add</span><span class="p">)</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">futurecall</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span><span class="mi">5</span><span class="p">)</span>
<span class="c"># do some other stuff... then access the value</span>
<span class="n">summation</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">value</span>
</pre></div>
</div>
<p>Actually calling the <cite>Future</cite> object returns control immediately and results in a <a class="reference internal" href="api/futures.html#Pyro4.futures.FutureResult" title="Pyro4.futures.FutureResult"><tt class="xref py py-class docutils literal"><span class="pre">Pyro4.futures.FutureResult</span></tt></a>
object. This is the exact same class as with the async proxy. The most important attributes are <tt class="docutils literal"><span class="pre">value</span></tt>, <tt class="docutils literal"><span class="pre">ready</span></tt>
and the <tt class="docutils literal"><span class="pre">wait</span></tt> method. See <a class="reference internal" href="clientcode.html#async-calls"><em>Asynchronous (&#8216;future&#8217;) remote calls &amp; call chains</em></a> for more details.</p>
<p>You can also chain multiple calls, so that the whole call chain is executed sequentially in the background.
Rather than doing this on the <tt class="docutils literal"><span class="pre">FutureResult</span></tt> result object, you should do it directly on the <tt class="docutils literal"><span class="pre">Future</span></tt> object,
with the <a class="reference internal" href="api/futures.html#Pyro4.futures.Future.then" title="Pyro4.futures.Future.then"><tt class="xref py py-meth docutils literal"><span class="pre">Pyro4.futures.Future.then()</span></tt></a> method. It has the same signature as the <tt class="docutils literal"><span class="pre">then</span></tt> method from
the <tt class="docutils literal"><span class="pre">FutureResult</span></tt> class:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">futurecall</span> <span class="o">=</span> <span class="n">Pyro4</span><span class="o">.</span><span class="n">Future</span><span class="p">(</span><span class="n">something</span><span class="p">)</span>
<span class="n">futurecall</span><span class="o">.</span><span class="n">then</span><span class="p">(</span><span class="n">somethingelse</span><span class="p">,</span> <span class="mi">44</span><span class="p">)</span>
<span class="n">futurecall</span><span class="o">.</span><span class="n">then</span><span class="p">(</span><span class="n">lastthing</span><span class="p">,</span> <span class="n">optionalargument</span><span class="o">=</span><span class="s">&quot;something&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>See the <tt class="file docutils literal"><span class="pre">futures</span></tt> example for more details and example code.</p>
</div>
<div class="section" id="dns-setup">
<h2>DNS setup<a class="headerlink" href="#dns-setup" title="Permalink to this headline">¶</a></h2>
<p>Pyro depends on a working DNS configuration, at least for your local hostname (i.e. &#8216;pinging&#8217; your local hostname should work).
If your local hostname doesn&#8217;t resolve to an IP address, you&#8217;ll have to fix this.
This can usually be done by adding an entry to the hosts file. For OpenSUSE, you can also use Yast to fix it
(go to Network Settings, enable &#8220;Assign hostname to loopback IP&#8221;).</p>
<p>If Pyro detects a problem with the dns setup it will log a WARNING in the logfile (if logging is enabled),
something like: <tt class="docutils literal"><span class="pre">weird</span> <span class="pre">DNS</span> <span class="pre">setup:</span> <span class="pre">your-computer-hostname</span> <span class="pre">resolves</span> <span class="pre">to</span> <span class="pre">localhost</span> <span class="pre">(127.x.x.x)</span></tt></p>
</div>
<div class="section" id="pyro-behind-a-nat-router-firewall">
<span id="nat-router"></span><h2>Pyro behind a NAT router/firewall<a class="headerlink" href="#pyro-behind-a-nat-router-firewall" title="Permalink to this headline">¶</a></h2>
<p>You can run Pyro behind a NAT router/firewall.
Assume the external hostname is &#8216;pyro.server.com&#8217; and the external port is 5555.
Also assume the internal host is &#8216;server1.lan&#8217; and the internal port is 9999.
You&#8217;ll need to have a NAT rule that maps pyro.server.com:5555 to server1.lan:9999.
You&#8217;ll need to start your Pyro daemon, where you specify the <tt class="docutils literal"><span class="pre">nathost</span></tt> and <tt class="docutils literal"><span class="pre">natport</span></tt> arguments,
so that Pyro knows it needs to &#8216;publish&#8217; URIs containing that <em>external</em> location instead of just
using the internal addresses:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="c"># running on server1.lan</span>
<span class="n">d</span> <span class="o">=</span> <span class="n">Pyro4</span><span class="o">.</span><span class="n">Daemon</span><span class="p">(</span><span class="n">port</span><span class="o">=</span><span class="mi">9999</span><span class="p">,</span> <span class="n">nathost</span><span class="o">=</span><span class="s">&quot;pyro.server.com&quot;</span><span class="p">,</span> <span class="n">natport</span><span class="o">=</span><span class="mi">5555</span><span class="p">)</span>
<span class="n">uri</span> <span class="o">=</span> <span class="n">d</span><span class="o">.</span><span class="n">register</span><span class="p">(</span><span class="n">Something</span><span class="p">(),</span> <span class="s">&quot;thing&quot;</span><span class="p">)</span>
<span class="k">print</span> <span class="n">uri</span>     <span class="c"># &quot;PYRO:thing@pyro.server.com:5555&quot;</span>
</pre></div>
</div>
<p>As you see, the URI now contains the external address.</p>
<p><a class="reference internal" href="api/core.html#Pyro4.core.Daemon.uriFor" title="Pyro4.core.Daemon.uriFor"><tt class="xref py py-meth docutils literal"><span class="pre">Pyro4.core.Daemon.uriFor()</span></tt></a> by default returns URIs with a NAT address in it (if <tt class="docutils literal"><span class="pre">nathost</span></tt>
and <tt class="docutils literal"><span class="pre">natport</span></tt> were used). You can override this by setting <tt class="docutils literal"><span class="pre">nat=False</span></tt>:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">print</span> <span class="n">d</span><span class="o">.</span><span class="n">uriFor</span><span class="p">(</span><span class="s">&quot;thing&quot;</span><span class="p">)</span>                 <span class="c"># &quot;PYRO:thing@pyro.server.com:5555&quot;</span>
<span class="k">print</span> <span class="n">d</span><span class="o">.</span><span class="n">uriFor</span><span class="p">(</span><span class="s">&quot;thing&quot;</span><span class="p">,</span> <span class="n">nat</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>      <span class="c"># &quot;PYRO:thing@localhost:36124&quot;</span>
<span class="n">uri2</span> <span class="o">=</span> <span class="n">d</span><span class="o">.</span><span class="n">uriFor</span><span class="p">(</span><span class="n">uri</span><span class="o">.</span><span class="n">object</span><span class="p">,</span> <span class="n">nat</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>  <span class="c"># get non-natted uri</span>
</pre></div>
</div>
<p>The Name server can also be started behind a NAT: it has a couple of command line options that
allow you to specify a nathost and natport for it. See <a class="reference internal" href="nameserver.html#nameserver-nameserver"><em>Starting the Name Server</em></a>.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">The broadcast responder always returns the internal address, never the external NAT address.
Also, the name server itself won&#8217;t translate any URIs that are registered with it.
So if you want it to publish URIs with &#8216;external&#8217; locations in them, you have to tell
the Daemon that registers these URIs to use the correct nathost and natport as well.</p>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">In some situations the NAT simply is configured to pass through any port one-to-one to another
host behind the NAT router/firewall. Pyro facilitates this by allowing you to set the natport
to 0, in which case Pyro will replace it by the internal port number.</p>
</div>
</div>
<div class="section" id="binary-data-transfer">
<span id="binarytransfer"></span><h2>Binary data transfer<a class="headerlink" href="#binary-data-transfer" title="Permalink to this headline">¶</a></h2>
<p>Pyro is not meant as a tool to transfer large amounts of binary data (images, sound files, video clips).
Its wire protocol is not optimized for these kinds of data. The occasional transmission of such data
is fine (<a class="reference internal" href="flame.html"><em>Flame: Foreign Location Automatic Module Exposer</em></a> even provides a convenience method for that, if you like:
<a class="reference internal" href="api/flame.html#Pyro4.utils.flame.Flame.sendfile" title="Pyro4.utils.flame.Flame.sendfile"><tt class="xref py py-meth docutils literal"><span class="pre">Pyro4.utils.flame.Flame.sendfile()</span></tt></a>) but usually it is better to use something else to do
the actual data transfer (file share+file copy, ftp, scp, rsync).</p>
<p>The serpent and json serializers are particularly inefficient when dealing with binary data,
so try to avoid it, or don&#8217;t rely on efficient transfer of large amounts of binary data.</p>
<p>That being said, here is a short overview of the <tt class="docutils literal"><span class="pre">pickle</span></tt> wire protocol overhead for the possible types
you can use when transferring binary data using Pyro:</p>
<dl class="docutils">
<dt><tt class="docutils literal"><span class="pre">str</span></tt></dt>
<dd><em>Python 2.x:</em> efficient; directly encoded as a byte sequence, because that&#8217;s what it is.
<em>Python 3.x:</em> inefficient; encoded in UTF-8 on the wire, because it is a unicode string.</dd>
<dt><tt class="docutils literal"><span class="pre">bytes</span></tt></dt>
<dd><em>Python 2.x:</em> same as <tt class="docutils literal"><span class="pre">str</span></tt> (available in Python 2.6 and 2.7)
<em>Python 3.x:</em> efficient; directly encoded as a byte sequence.</dd>
<dt><tt class="docutils literal"><span class="pre">bytearray</span></tt></dt>
<dd>Inefficient; encoded as UTF-8 on the wire (pickle does this in both Python 2.x and 3.x)</dd>
<dt><tt class="docutils literal"><span class="pre">array(&quot;B&quot;)</span></tt> (array of unsigned ints of size 1)</dt>
<dd><em>Python 2.x:</em> very inefficient; every element is encoded as a separate token+value.
<em>Python 3.x:</em> efficient; uses machine type encoding on the wire (a byte sequence).</dd>
</dl>
<p>Your best choice, if you want to transfer binary data using Pyro, seems to be to use the <tt class="docutils literal"><span class="pre">bytes</span></tt> type
(and possibly the <tt class="docutils literal"><span class="pre">array(&quot;B&quot;)</span></tt> type if you&#8217;re using Python 3.x, or just <tt class="docutils literal"><span class="pre">str</span></tt> if you&#8217;re stuck on 2.5).
Stay clear from the rest. It is strange that the <tt class="docutils literal"><span class="pre">bytearray</span></tt> type is encoded so inefficiently by pickle.</p>
</div>
<div class="section" id="msg-waitall-socket-option">
<h2>MSG_WAITALL socket option<a class="headerlink" href="#msg-waitall-socket-option" title="Permalink to this headline">¶</a></h2>
<p>Pyro will use the <tt class="docutils literal"><span class="pre">MSG_WAITALL</span></tt> socket option to receive large messages, if it decides that
the feature is available and working correctly. On most systems that define the <tt class="docutils literal"><span class="pre">socket.MSG_WAITALL</span></tt>
symbol, it does, except on Windows: even though the option is there, it doesn&#8217;t work reliably.
If you want to check in your code what Pyro&#8217;s behavior is, see the <tt class="docutils literal"><span class="pre">socketutil.USE_MSG_WAITALL</span></tt> attribute
(it&#8217;s a boolean that will be set to False if Pyro decides it can&#8217;t or should not use MSG_WAITALL).</p>
</div>
<div class="section" id="ipv6-support">
<h2>IPV6 support<a class="headerlink" href="#ipv6-support" title="Permalink to this headline">¶</a></h2>
<p>Pyro4 supports IPv6 since version 4.18. You can use IPv6 addresses in the same places where you would
normally have used IPv4 addresses. There&#8217;s one exception: the address notation in a Pyro URI. For a numeric
IPv6 address in a Pyro URI, you have to enclose it in brackets. For example:</p>
<p><tt class="docutils literal"><span class="pre">PYRO:objectname&#64;[::1]:3456</span></tt></p>
<p>points at a Pyro object located on the IPv6 &#8221;::1&#8221; address (localhost). When Pyro displays a numeric
IPv6 location from an URI it will also use the bracket notation. This bracket notation is only used
in Pyro URIs, everywhere else you just type the IPv6 address without brackets.</p>
<p>To tell Pyro to prefer using IPv6 you can use the <tt class="docutils literal"><span class="pre">PREFER_IP_VERSION</span></tt> config item. It is set to 4 by default,
for backward compatibility reasons.
This means that unless you change it to 6 (or 0), Pyro will be using IPv4 addressing.</p>
<p>There is a new method to see what IP addressing is used: <a class="reference internal" href="api/util.html#Pyro4.socketutil.getIpVersion" title="Pyro4.socketutil.getIpVersion"><tt class="xref py py-meth docutils literal"><span class="pre">Pyro4.socketutil.getIpVersion()</span></tt></a>,
and a few other methods in <a class="reference internal" href="api/util.html#module-Pyro4.socketutil" title="Pyro4.socketutil"><tt class="xref py py-mod docutils literal"><span class="pre">Pyro4.socketutil</span></tt></a>  gained a new optional argument to tell it if
it needs to deal with an ipv6 address rather than ipv4, but these are rarely used in client code.</p>
</div>
</div>


          </div>
        </div>
      </div>
      <div class="sphinxsidebar">
        <div class="sphinxsidebarwrapper">
            <p class="logo"><a href="index.html">
              <img class="logo" src="_static/pyro.png" alt="Logo"/>
            </a></p>
  <h3><a href="index.html">Table Of Contents</a></h3>
  <ul>
<li><a class="reference internal" href="#">Tips &amp; Tricks</a><ul>
<li><a class="reference internal" href="#best-practices">Best practices</a><ul>
<li><a class="reference internal" href="#avoid-circular-communication-topologies">Avoid circular communication topologies.</a></li>
<li><a class="reference internal" href="#release-your-proxies-if-you-can">Release your proxies if you can.</a></li>
<li><a class="reference internal" href="#avoid-large-binary-blobs-over-the-wire">Avoid large binary blobs over the wire.</a></li>
<li><a class="reference internal" href="#minimize-object-graphs-that-travel-over-the-wire">Minimize object graphs that travel over the wire.</a></li>
</ul>
</li>
<li><a class="reference internal" href="#logging">Logging</a></li>
<li><a class="reference internal" href="#multiple-network-interfaces">Multiple network interfaces</a></li>
<li><a class="reference internal" href="#same-major-python-version-required">Same major Python version required</a></li>
<li><a class="reference internal" href="#wire-protocol-version">Wire protocol version</a></li>
<li><a class="reference internal" href="#asynchronous-future-normal-function-calls">Asynchronous (&#8216;future&#8217;) normal function calls</a></li>
<li><a class="reference internal" href="#dns-setup">DNS setup</a></li>
<li><a class="reference internal" href="#pyro-behind-a-nat-router-firewall">Pyro behind a NAT router/firewall</a></li>
<li><a class="reference internal" href="#binary-data-transfer">Binary data transfer</a></li>
<li><a class="reference internal" href="#msg-waitall-socket-option">MSG_WAITALL socket option</a></li>
<li><a class="reference internal" href="#ipv6-support">IPV6 support</a></li>
</ul>
</li>
</ul>

  <h4>Previous topic</h4>
  <p class="topless"><a href="flame.html"
                        title="previous chapter">Flame: Foreign Location Automatic Module Exposer</a></p>
  <h4>Next topic</h4>
  <p class="topless"><a href="config.html"
                        title="next chapter">Configuring Pyro</a></p>
<div id="searchbox" style="display: none">
  <h3>Quick search</h3>
    <form class="search" action="search.html" method="get">
      <input type="text" name="q" />
      <input type="submit" value="Go" />
      <input type="hidden" name="check_keywords" value="yes" />
      <input type="hidden" name="area" value="default" />
    </form>
    <p class="searchtip" style="font-size: 90%">
    Enter search terms or a module, class or function name.
    </p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
        </div>
      </div>
      <div class="clearer"></div>
    </div>
    <div class="related">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="genindex.html" title="General Index"
             >index</a></li>
        <li class="right" >
          <a href="config.html" title="Configuring Pyro"
             >next</a> |</li>
        <li class="right" >
          <a href="flame.html" title="Flame: Foreign Location Automatic Module Exposer"
             >previous</a> |</li>
        <li><a href="index.html">Pyro 4.21 documentation</a> &raquo;</li> 
      </ul>
    </div>
    <div class="footer">
        &copy; Copyright Irmen de Jong.
      Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
    </div>
  </body>
</html>