blob: d27533df1676a357312ff947bd1c41191ba34ab1 [file] [log] [blame]
<!doctype html>
<html class="no-js" lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Subscribe to Apache Software Foundation infrastructure events - Apache Infrastructure Website</title>
<link href="/css/bootstrap.min.css" rel="stylesheet">
<link href="/css/fontawesome.all.min.css" rel="stylesheet">
<link href="/css/headerlink.css" rel="stylesheet">
<script src="/highlight/highlight.min.js"></script> </head>
<body class="d-flex flex-column h-100">
<main class="flex-shrink-0">
<div>
<!-- nav bar -->
<nav class="navbar navbar-expand-lg navbar-dark bg-dark" aria-label="Fifth navbar example">
<div class="container-fluid">
<a class="navbar-brand" href="/"><img src="/images/feather.png" style="height: 32px;"/> Apache Infrastructure</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarADP" aria-controls="navbarADP" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarADP">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" data-bs-toggle="dropdown" aria-expanded="false">About</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="/team.html">About the team</a></li>
<li><a class="dropdown-item" href="/roundtable.html">The Infrastructure Roundtable</a></li>
<li><a class="dropdown-item" href="/blog/">The Infrastructure Blog</a></li>
</ul>
</li>
<li class="nav-item">
<a class="nav-link" href="/policies.html">Policies</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" data-bs-toggle="dropdown" aria-expanded="false">Services and Tools</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="/services.html">Services and Tools</a></li>
<li><a class="dropdown-item" href="/machines.html">Machines and Fingerprints</a></li>
<li><a class="dropdown-item" href="https://blocky.apache.org/">Blocky</a></li>
<li><a class="dropdown-item" href="https://app.datadoghq.com/account/login?next=%2Finfrastructure">DataDog</a></li>
<li><a class="dropdown-item" href="https://whimsy.apache.org/roster/committer/" target="_blank">Committer Search</a></li>
</ul>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" data-bs-toggle="dropdown" aria-expanded="false">Documentation</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="/doc.html">Contribute</a></li>
<li><a class="dropdown-item" href="/infra-volunteer.html">Volunteer with Infra</a></li>
<li><a class="dropdown-item" href="/how-to-mirror.html">Become an ASF download mirror</a></li>
<li><a class="dropdown-item" href="/hosting-external-agent.html">Host a Jenkins or Buildbot agent</a></li>
</ul>
</li>
<li class="nav-item">
<a class="nav-link" href="/stats.html">Status</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/contact.html">Contact Us</a>
</li>
</ul>
</div>
</div>
</nav>
<!-- page contents -->
<div id="contents">
<div class="bg-white p-5 rounded">
<div class="col-sm-8 mx-auto">
<h1>
Subscribe to Apache Software Foundation infrastructure events
</h1>
<p>The ASF employs a plain-text publisher/subscriber service called <strong>PyPubSub</strong> at <code>pubsub.apache.org:2069</code>, which lists most events that happen within the Foundation's infrastructure.</p>
<p>Currently, the service streams the following events:</p>
<ul>
<li>Subversion commits</li>
<li>Git commits and pushes</li>
<li>Emails to publicly archived lists</li>
<li>JIRA updates</li>
<li>Pull Requests and Issues from GitHub</li>
<li>Staging and publishing notifications sent via our <a href="https://s.apache.org/asfyaml">.asf.yaml</a> offering.</li>
</ul>
<p>Events are delivered as JSON objects in a <a href="https://en.wikipedia.org/wiki/Chunked_transfer_encoding" target="_blank">chunked response stream</a>, with each new chunk being either an event payload or a keep-alive ping. </p>
<h2>How to subscribe</h2>
<p>Subscribers can pick one or multiple topics to subscribe to, with more specific subscriptions getting fewer, but more specific, event payloads. Construct subscriptions in the form of: <code>http://pubsub.apache.org:2069/topics/go/here</code>, and separate the topics you want to subscribe to with forward slashes. </p>
<p>The service returns events that match <em>all</em> of the topics you are subscribed to.
To subscribe to multiple topic batches in an OR'ed way, you may use a comma to separate your batches of topics.</p>
<p>Some examples:</p>
<ul>
<li>To subscribe to all svn commits; <code>http://pubsub.apache.org:2069/svn/commit</code></li>
<li>To subscribe to all git commits; <code>http://pubsub.apache.org:2069/git/commit</code></li>
<li>To subscribe to all git events (push+commit) for whimsy.git; <code>http://pubsub.apache.org:2069/git/whimsy</code></li>
<li>To subscribe to all <code>netbeans.apache.org</code> emails: <code>http://pubsub.apache.org:2069/email/netbeans.apache.org</code></li>
<li>To subscribe to PRs opened against <code>beam-foo.git</code>: <code>http://pubsub.apache.org:2069/github/beam-foo.git/pr</code></li>
<li>To subscribe to all commits, both Subversion and git: <code>http://pubsub.apache.org:2069/commit</code></li>
<li>To subscribe to all JIRA events for the HADOOP JIRA instance: <code>http://pubsub.apache.org:2069/jira/HADOOP</code></li>
<li>To subscribe to <em>both</em> JIRA and email streams for tomcat in one go: <code>http://pubsub.apache.org:2069/jira/TOMCAT,email/tomcat.apache.org</code></li>
</ul>
<p>Public SVN repo topics consist of 'svn', the first one or two path segments after the /repos/ in the URL, and 'commit'.
For example, changes to the repository <code>https://dist.apache.org/repos/dist/release/</code> have the topics <code>svn/dist/release/commit</code>.
A commit that involves changes to both <code>dist/release</code> and <code>dist/dev</code> has the topics <code>svn/dist/commit</code>.
Note that <code>svn/dist/release/commit</code> will not match, because the topics in the response do not include <code>release</code>.</p>
<p>Private SVN repos topics are constructed in the same way, but have an additional 'private' topic.
For example <code>https://pubsub.apache.org:2070/private/svn/private/committers/commit</code> returns commits for
<code>https://svn.apache.org/repos/private/committers/board/</code></p>
<h2>Event payload examples</h2>
<p>Pings are simple objects like this:</p>
<div class="highlight"><pre><span></span><code><span class="p">{</span><span class="nt">&quot;stillalive&quot;</span><span class="p">:</span><span class="w"> </span><span class="mf">1583973410.9620552</span><span class="p">}</span>
</code></pre></div>
<p>An example of a real event payload, in this case a git commit, could be (emails redacted in this example):</p>
<div class="highlight"><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;commit&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;body&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;[maven-release-plugin] prepare for next development iteration\n&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;committer&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;sblackmon &lt;s...@apache.org&gt;&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;hash&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;8e6f956&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;log&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;[maven-release-plugin] prepare for next development iteration&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;repository&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;git&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;sha&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;8e6f956c2eda06ca9debf21634cedcecc96293ff&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;author&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;sblackmon&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;files&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;pom.xml&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;streams-cli/pom.xml&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;streams-components/pom.xml&quot;</span><span class="p">],</span>
<span class="w"> </span><span class="nt">&quot;server&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;gitbox&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;project&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;streams&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;autopublish&quot;</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;date&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Wed Mar 11 19:25:06 2020 -0500&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;committed&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Wed Mar 11 19:25:06 2020 -0500&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;subject&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;[maven-release-plugin] prepare for next development iteration&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;ref&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;refs/heads/master&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;email&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;s...@apache.org&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;authored&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Wed Mar 11 19:25:06 2020 -0500&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;ref_names&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;&quot;</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;pubsub_topics&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;git&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;streams&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;commit&quot;</span><span class="p">],</span>
<span class="w"> </span><span class="nt">&quot;pubsub_path&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;/git/streams/commit&quot;</span>
<span class="p">}</span>
</code></pre></div>
<p>Payloads vary depending on what they represent, so check both what sub-objects are present in the payload and the <code>pubsub_path</code> variable, which will show the full payload event path and explain which type is being sent.</p>
<h2>Try it yourself</h2>
<p>To try it out and take a look at the event stream, use <a href="https://en.wikipedia.org/wiki/CURL">cURL</a> in your terminal:</p>
<div class="highlight"><pre><span></span><code>curl<span class="w"> </span>http://pubsub.apache.org:2069/git/commit
</code></pre></div>
<p><br/></p>
<p>A secure version also exists on port 2070, for use with authenticated event streams:</p>
<div class="highlight"><pre><span></span><code>curl<span class="w"> </span>https://pubsub.apache.org:2070/git/commit
</code></pre></div>
<p>Please note that due to limitations in our TLS terminator, payloads larger than 64kb are split into 64kb chunks on
port 2070. If you are using port 2070, you should ensure that the data you receive is terminated with a newline (\n),
or continue fetching data till you hit a chunk terminated with a newline.</p>
<p>N.B. the following curl switches may be added:</p>
<ul>
<li>-N - non-buffered output; used when piping into another command (e.g. tail)</li>
<li>-sS - silent mode (-s) but still shows error messages (-S)</li>
</ul>
<h2>Using PyPubSub in programming</h2>
<h3>Using PyPubSub with Python</h3>
<p>You can listen for and react to payloads in Python using the <a href="https://pypi.org/project/asfpy/">asfpy</a> pip package:</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">asfpy.pubsub</span>
<span class="k">def</span> <span class="nf">process_event</span><span class="p">(</span><span class="n">payload</span><span class="p">):</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Got an event from PyPubSub!&quot;</span><span class="p">)</span>
<span class="o">...</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
<span class="n">pubsub</span> <span class="o">=</span> <span class="n">asfpy</span><span class="o">.</span><span class="n">pubsub</span><span class="o">.</span><span class="n">Listener</span><span class="p">(</span><span class="s1">&#39;http://pubsub.apache.org:2069/&#39;</span><span class="p">)</span>
<span class="n">pubsub</span><span class="o">.</span><span class="n">attach</span><span class="p">(</span><span class="n">process_event</span><span class="p">,</span> <span class="n">raw</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</code></pre></div>
<h3>Using PyPubSub with node.js</h3>
<p>This sample snippet lets you use <code>node.js</code> for listening for and processing pubsub events:</p>
<div class="highlight"><pre><span></span><code><span class="kd">const</span><span class="w"> </span><span class="nx">http</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">require</span><span class="p">(</span><span class="s2">&quot;http&quot;</span><span class="p">);</span>
<span class="kd">const</span><span class="w"> </span><span class="nx">https</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">require</span><span class="p">(</span><span class="s2">&quot;https&quot;</span><span class="p">);</span>
<span class="kd">class</span><span class="w"> </span><span class="nx">PyPubSub</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="kr">constructor</span><span class="p">(</span><span class="nx">url</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">url</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">url</span><span class="p">;</span>
<span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">getter</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">url</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="sr">/^https/i</span><span class="p">)</span><span class="w"> </span><span class="o">?</span><span class="w"> </span><span class="nx">https</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="nx">http</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="nx">attach</span><span class="p">(</span><span class="nx">func</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">getter</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">url</span><span class="p">,</span><span class="w"> </span><span class="nx">res</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nx">res</span><span class="p">.</span><span class="nx">setEncoding</span><span class="p">(</span><span class="s2">&quot;utf8&quot;</span><span class="p">);</span>
<span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="nx">body</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">&#39;&#39;</span><span class="p">;</span>
<span class="w"> </span><span class="nx">res</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s2">&quot;data&quot;</span><span class="p">,</span><span class="w"> </span><span class="nx">data</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="c1">// Be mindful of proxies that split pubsub chunks into smaller ones,</span>
<span class="w"> </span><span class="c1">// only load the JSON blob once we hit a newline (\n)</span>
<span class="w"> </span><span class="nx">body</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="nx">data</span><span class="p">;</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">data</span><span class="p">.</span><span class="nx">endsWith</span><span class="p">(</span><span class="s2">&quot;\n&quot;</span><span class="p">))</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="nx">payload</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">body</span><span class="p">);</span>
<span class="w"> </span><span class="nx">body</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">&#39;&#39;</span><span class="p">;</span>
<span class="w"> </span><span class="nx">func</span><span class="p">(</span><span class="nx">payload</span><span class="p">);</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">});</span>
<span class="w"> </span><span class="p">});</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
<span class="c1">// Test</span>
<span class="kd">function</span><span class="w"> </span><span class="nx">process</span><span class="p">(</span><span class="nx">payload</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="c1">// ping-back?</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">payload</span><span class="p">.</span><span class="nx">stillalive</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&quot;Got a ping-back&quot;</span><span class="p">);</span>
<span class="w"> </span><span class="c1">// Actual payload? process it!</span>
<span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&quot;Got a payload from PyPubSub!&quot;</span><span class="p">);</span>
<span class="w"> </span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">payload</span><span class="p">);</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
<span class="kd">const</span><span class="w"> </span><span class="nx">pps</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="ow">new</span><span class="w"> </span><span class="nx">PyPubSub</span><span class="p">(</span><span class="s1">&#39;http://pubsub.apache.org:2069/&#39;</span><span class="p">);</span>
<span class="nx">pps</span><span class="p">.</span><span class="nx">attach</span><span class="p">(</span><span class="nx">process</span><span class="p">);</span>
</code></pre></div>
<h3>Using PyPubSub with Ruby</h3>
<p>This sample lets you connect to our pubsub service via Ruby:</p>
<div class="highlight"><pre><span></span><code><span class="nb">require</span><span class="w"> </span><span class="s1">&#39;net/http&#39;</span>
<span class="nb">require</span><span class="w"> </span><span class="s1">&#39;json&#39;</span>
<span class="nb">require</span><span class="w"> </span><span class="s1">&#39;thread&#39;</span>
<span class="n">pubsub_URL</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">&#39;https://pubsub.apache.org:2070/&#39;</span>
<span class="k">def</span><span class="w"> </span><span class="nf">do_stuff_with</span><span class="p">(</span><span class="n">event</span><span class="p">)</span>
<span class="w"> </span><span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Got a pubsub event!:</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="w"> </span><span class="nb">print</span><span class="p">(</span><span class="n">event</span><span class="p">)</span>
<span class="w"> </span><span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">def</span><span class="w"> </span><span class="nf">listen</span><span class="p">(</span><span class="n">url</span><span class="p">)</span>
<span class="w"> </span><span class="n">ps_thread</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="no">Thread</span><span class="o">.</span><span class="n">new</span><span class="w"> </span><span class="k">do</span>
<span class="w"> </span><span class="k">begin</span>
<span class="w"> </span><span class="n">uri</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="no">URI</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="n">url</span><span class="p">)</span>
<span class="w"> </span><span class="no">Net</span><span class="o">::</span><span class="no">HTTP</span><span class="o">.</span><span class="n">start</span><span class="p">(</span><span class="n">uri</span><span class="o">.</span><span class="n">host</span><span class="p">,</span><span class="w"> </span><span class="n">uri</span><span class="o">.</span><span class="n">port</span><span class="p">,</span><span class="w"> </span><span class="ss">:use_ssl</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="n">url</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="sr">/^https:/</span><span class="p">)</span><span class="w"> </span><span class="p">?</span><span class="w"> </span><span class="kp">true</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kp">false</span><span class="p">)</span><span class="w"> </span><span class="k">do</span><span class="w"> </span><span class="o">|</span><span class="n">http</span><span class="o">|</span>
<span class="w"> </span><span class="n">request</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="no">Net</span><span class="o">::</span><span class="no">HTTP</span><span class="o">::</span><span class="no">Get</span><span class="o">.</span><span class="n">new</span><span class="w"> </span><span class="n">uri</span><span class="o">.</span><span class="n">request_uri</span>
<span class="w"> </span><span class="n">http</span><span class="o">.</span><span class="n">request</span><span class="w"> </span><span class="n">request</span><span class="w"> </span><span class="k">do</span><span class="w"> </span><span class="o">|</span><span class="n">response</span><span class="o">|</span>
<span class="w"> </span><span class="n">body</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">&#39;&#39;</span>
<span class="w"> </span><span class="n">response</span><span class="o">.</span><span class="n">read_body</span><span class="w"> </span><span class="k">do</span><span class="w"> </span><span class="o">|</span><span class="n">chunk</span><span class="o">|</span>
<span class="w"> </span><span class="n">body</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="n">chunk</span>
<span class="w"> </span><span class="c1"># All chunks are terminated with \n. Since 2070 can split events into 64kb sub-chunks</span>
<span class="w"> </span><span class="c1"># we wait till we have gotten a newline, before trying to parse the JSON.</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">chunk</span><span class="o">.</span><span class="n">end_with?</span><span class="w"> </span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span>
<span class="w"> </span><span class="n">event</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="no">JSON</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="n">body</span><span class="o">.</span><span class="n">chomp</span><span class="p">)</span>
<span class="w"> </span><span class="n">body</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">&#39;&#39;</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">event</span><span class="o">[</span><span class="s1">&#39;stillalive&#39;</span><span class="o">]</span><span class="w"> </span><span class="c1"># pingback</span>
<span class="w"> </span><span class="nb">print</span><span class="p">(</span><span class="s2">&quot;ping? PONG!</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="w"> </span><span class="k">else</span>
<span class="w"> </span><span class="n">do_stuff_with</span><span class="p">(</span><span class="n">event</span><span class="p">)</span>
<span class="w"> </span><span class="k">end</span>
<span class="w"> </span><span class="k">end</span>
<span class="w"> </span><span class="k">end</span>
<span class="w"> </span><span class="k">end</span>
<span class="w"> </span><span class="k">end</span>
<span class="w"> </span><span class="k">rescue</span><span class="w"> </span><span class="no">Errno</span><span class="o">::</span><span class="no">ECONNREFUSED</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="n">e</span>
<span class="w"> </span><span class="n">restartable</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kp">true</span>
<span class="w"> </span><span class="no">STDERR</span><span class="o">.</span><span class="n">puts</span><span class="w"> </span><span class="n">e</span>
<span class="w"> </span><span class="nb">sleep</span><span class="w"> </span><span class="mi">3</span>
<span class="w"> </span><span class="k">rescue</span><span class="w"> </span><span class="no">Exception</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="n">e</span>
<span class="w"> </span><span class="no">STDERR</span><span class="o">.</span><span class="n">puts</span><span class="w"> </span><span class="n">e</span>
<span class="w"> </span><span class="no">STDERR</span><span class="o">.</span><span class="n">puts</span><span class="w"> </span><span class="n">e</span><span class="o">.</span><span class="n">backtrace</span>
<span class="w"> </span><span class="k">end</span>
<span class="w"> </span><span class="k">end</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">ps_thread</span>
<span class="k">end</span>
<span class="k">begin</span>
<span class="w"> </span><span class="n">ps_thread</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">listen</span><span class="p">(</span><span class="n">pubsub_URL</span><span class="p">)</span>
<span class="w"> </span><span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Pubsub thread started, waiting for results...</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="n">ps_thread</span><span class="o">.</span><span class="n">alive?</span>
<span class="w"> </span><span class="nb">sleep</span><span class="w"> </span><span class="mi">10</span>
<span class="w"> </span><span class="k">end</span>
<span class="k">end</span>
</code></pre></div>
<h2>Want to know more? Have questions?</h2>
<p>To learn more, or just get some questions answered, please contact us at <code>users@infra.apache.org</code>, and we'll try our best to help you out.</p>
<h2>Acknowledgements</h2>
<p>PyPubSub is based on <a href="https://paul.querna.org/articles/2010/10/22/evolution-of-apaches-websites/">SvnPubSub</a>
and <a href="/gitpubsub.html">gitpubsub</a>. We wish to thank the Subversion project for building the precursor to this service.</p>
</div>
</div>
</div>
<!-- footer -->
<div class="row">
<div class="large-12 medium-12 columns">
<p style="font-style: italic; font-size: 0.8rem; text-align: center;">
Copyright 2024, <a href="https://www.apache.org/">The Apache Software Foundation</a>, Licensed under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.<br/>
Apache&reg; and the Apache feather logo are trademarks of The Apache Software Foundation...
</p>
</div>
</div>
<script type="application/ecmascript" src="/js/bootstrap.bundle.min.js" integrity="sha384-OERcA2EqjJCMA+/3y+gxIOqMEjwtxJY7qPCqsdltbNJuaOe923+mo//f6V8Qbsw3"></script> </div>
</main>
<script>hljs.initHighlightingOnLoad();</script>
</body>
</html>