| <!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">"stillalive"</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">"commit"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span> |
| <span class="w"> </span><span class="nt">"body"</span><span class="p">:</span><span class="w"> </span><span class="s2">"[maven-release-plugin] prepare for next development iteration\n"</span><span class="p">,</span> |
| <span class="w"> </span><span class="nt">"committer"</span><span class="p">:</span><span class="w"> </span><span class="s2">"sblackmon <s...@apache.org>"</span><span class="p">,</span> |
| <span class="w"> </span><span class="nt">"hash"</span><span class="p">:</span><span class="w"> </span><span class="s2">"8e6f956"</span><span class="p">,</span> |
| <span class="w"> </span><span class="nt">"log"</span><span class="p">:</span><span class="w"> </span><span class="s2">"[maven-release-plugin] prepare for next development iteration"</span><span class="p">,</span> |
| <span class="w"> </span><span class="nt">"repository"</span><span class="p">:</span><span class="w"> </span><span class="s2">"git"</span><span class="p">,</span> |
| <span class="w"> </span><span class="nt">"sha"</span><span class="p">:</span><span class="w"> </span><span class="s2">"8e6f956c2eda06ca9debf21634cedcecc96293ff"</span><span class="p">,</span> |
| <span class="w"> </span><span class="nt">"author"</span><span class="p">:</span><span class="w"> </span><span class="s2">"sblackmon"</span><span class="p">,</span> |
| <span class="w"> </span><span class="nt">"files"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"pom.xml"</span><span class="p">,</span><span class="w"> </span><span class="s2">"streams-cli/pom.xml"</span><span class="p">,</span><span class="w"> </span><span class="s2">"streams-components/pom.xml"</span><span class="p">],</span> |
| <span class="w"> </span><span class="nt">"server"</span><span class="p">:</span><span class="w"> </span><span class="s2">"gitbox"</span><span class="p">,</span> |
| <span class="w"> </span><span class="nt">"project"</span><span class="p">:</span><span class="w"> </span><span class="s2">"streams"</span><span class="p">,</span> |
| <span class="w"> </span><span class="nt">"autopublish"</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">"date"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Wed Mar 11 19:25:06 2020 -0500"</span><span class="p">,</span> |
| <span class="w"> </span><span class="nt">"committed"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Wed Mar 11 19:25:06 2020 -0500"</span><span class="p">,</span> |
| <span class="w"> </span><span class="nt">"subject"</span><span class="p">:</span><span class="w"> </span><span class="s2">"[maven-release-plugin] prepare for next development iteration"</span><span class="p">,</span> |
| <span class="w"> </span><span class="nt">"ref"</span><span class="p">:</span><span class="w"> </span><span class="s2">"refs/heads/master"</span><span class="p">,</span> |
| <span class="w"> </span><span class="nt">"email"</span><span class="p">:</span><span class="w"> </span><span class="s2">"s...@apache.org"</span><span class="p">,</span> |
| <span class="w"> </span><span class="nt">"authored"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Wed Mar 11 19:25:06 2020 -0500"</span><span class="p">,</span> |
| <span class="w"> </span><span class="nt">"ref_names"</span><span class="p">:</span><span class="w"> </span><span class="s2">""</span> |
| <span class="w"> </span><span class="p">},</span> |
| <span class="w"> </span><span class="nt">"pubsub_topics"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"git"</span><span class="p">,</span><span class="w"> </span><span class="s2">"streams"</span><span class="p">,</span><span class="w"> </span><span class="s2">"commit"</span><span class="p">],</span> |
| <span class="w"> </span><span class="nt">"pubsub_path"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/git/streams/commit"</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">"Got an event from PyPubSub!"</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">'http://pubsub.apache.org:2069/'</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">"http"</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">"https"</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">=></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">"utf8"</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">''</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">"data"</span><span class="p">,</span><span class="w"> </span><span class="nx">data</span><span class="w"> </span><span class="p">=></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">"\n"</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">''</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">"Got a ping-back"</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">"Got a payload from PyPubSub!"</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">'http://pubsub.apache.org:2069/'</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">'net/http'</span> |
| <span class="nb">require</span><span class="w"> </span><span class="s1">'json'</span> |
| <span class="nb">require</span><span class="w"> </span><span class="s1">'thread'</span> |
| |
| <span class="n">pubsub_URL</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">'https://pubsub.apache.org:2070/'</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">"Got a pubsub event!:</span><span class="se">\n</span><span class="s2">"</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">"</span><span class="se">\n</span><span class="s2">"</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">=></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">''</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">"</span><span class="se">\n</span><span class="s2">"</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">''</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">'stillalive'</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">"ping? PONG!</span><span class="se">\n</span><span class="s2">"</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">=></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">=></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">"Pubsub thread started, waiting for results...</span><span class="se">\n</span><span class="s2">"</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® 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> |