Skip to content

Instantly share code, notes, and snippets.

Created January 21, 2015 07:22
Show Gist options
  • Save anonymous/e1ef1383d046384ab56e to your computer and use it in GitHub Desktop.
Save anonymous/e1ef1383d046384ab56e to your computer and use it in GitHub Desktop.
Presentation
<!DOCTYPE html>
<html>
<head>
<title>Foo</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />
<style type='text/css'>
body {
font-family: 'Helvetica Neue';
background:#000;
background-size:100%;
color:#fff;
margin:0;
padding:.5em;
}
h1, h2, h3, p {
margin:0;
font-weight:200;
}
p, li {
margin-bottom: .5em;
}
code {
font-family: "Menlo", monospace;
letter-spacing: 0;
}
em, i {
font-weight: 200;
}
strong, b {
font-weight: 400;
}
mark {
color: orange;
}
a {
background: orange;
color:#000;
text-decoration:none;
}
img {
width:100%;
}
div {
cursor:pointer;
cursor:hand;
position:absolute;
top:0;
left:0;
}
ol, ul {
list-style-type: none;
margin: 0.5em 0;
padding: 0;
}
ul ul, ul ol, ol ol, ol ul {
margin-left: .5em;
}
ol li:before, ul li:before {
color: orange;
}
ol {
counter-reset: list -1;
}
ol li {
list-style-type: none;
counter-increment: list;
}
ol li:before {
content: counter(list, binary) " ";
}
ul li:before {
content: "- ";
}
/*
Sunburst-like style (c) Vasily Polovnyov <vast@whiteants.net>
*/
pre code {
display: block; padding: 0.5em;
background: #000; color: #f8f8f8;
}
pre .comment,
pre .template_comment,
pre .javadoc {
color: #aeaeae;
font-style: italic;
}
pre .keyword,
pre .ruby .function .keyword,
pre .request,
pre .status,
pre .nginx .title {
color: #E28964;
}
pre .function .keyword,
pre .sub .keyword,
pre .method,
pre .list .title {
color: #99CF50;
}
pre .string,
pre .tag .value,
pre .cdata,
pre .filter .argument,
pre .attr_selector,
pre .apache .cbracket,
pre .date,
pre .tex .command {
color: #65B042;
}
pre .subst {
color: #DAEFA3;
}
pre .regexp {
color: #E9C062;
}
pre .title,
pre .sub .identifier,
pre .pi,
pre .tag,
pre .tag .keyword,
pre .decorator,
pre .shebang,
pre .prompt {
color: #89BDFF;
}
pre .class .title,
pre .haskell .type,
pre .smalltalk .class,
pre .javadoctag,
pre .yardoctag,
pre .phpdoc {
text-decoration: underline;
}
pre .symbol,
pre .ruby .symbol .string,
pre .number {
color: #3387CC;
}
pre .params,
pre .variable,
pre .clojure .attribute {
color: #3E87E3;
}
pre .css .tag,
pre .rules .property,
pre .pseudo,
pre .tex .special {
color: #CDA869;
}
pre .css .class {
color: #9B703F;
}
pre .rules .keyword {
color: #C5AF75;
}
pre .rules .value {
color: #CF6A4C;
}
pre .css .id {
color: #8B98AB;
}
pre .annotation,
pre .apache .sqbracket,
pre .nginx .built_in {
color: #9B859D;
}
pre .preprocessor {
color: #8996A8;
}
pre .hexcolor,
pre .css .value .number {
color: #DD7B3B;
}
pre .css .function {
color: #DAD085;
}
pre .diff .header,
pre .chunk,
pre .tex .formula {
background-color: #0E2231;
color: #F8F8F8;
font-style: italic;
}
pre .diff .change {
background-color: #4A410D;
color: #F8F8F8;
}
pre .addition {
background-color: #253B22;
color: #F8F8F8;
}
pre .deletion {
background-color: #420E09;
color: #F8F8F8;
}
pre .coffeescript .javascript,
pre .javascript .xml,
pre .tex .formula,
pre .xml .javascript,
pre .xml .vbscript,
pre .xml .css,
pre .xml .cdata {
opacity: 0.5;
}
</style>
<script type='text/javascript'>
window.onload = function() {
var s = document.getElementsByTagName('div'), cur = 0;
if (!s) return;
function go(n) {
cur = n;
var i = 1e3, e = s[n];
for (var k = 0; k < s.length; k++) s[k].style.display = 'none';
e.style.display = 'inline-block';
e.style.fontSize = i + 'px';
if (e.firstChild.nodeName === 'IMG') {
document.body.style.backgroundImage = 'url(' + e.firstChild.src + ')';
e.firstChild.style.display = 'none';
} else {
document.body.style.backgroundImage = '';
document.body.style.backgroundColor = e.style.backgroundColor;
}
while (
e.offsetWidth > window.innerWidth ||
e.offsetHeight > window.innerHeight) {
e.style.fontSize = (i -= 10) + 'px';
if (i < 0) break;
}
e.style.marginTop = ((window.innerHeight - e.offsetHeight) / 2) + 'px';
if (window.location.hash !== n) window.location.hash = n;
document.title = e.textContent || e.innerText;
}
document.onclick = function() {
go(++cur % (s.length));
};
document.onkeydown = function(e) {
(e.which === 39) && go(Math.min(s.length - 1, ++cur));
(e.which === 37) && go(Math.max(0, --cur));
};
function parse_hash() {
return Math.max(Math.min(
s.length - 1,
parseInt(window.location.hash.substring(1), 10)), 0);
}
if (window.location.hash) cur = parse_hash() || cur;
window.onhashchange = function() {
var c = parse_hash();
if (c !== cur) go(c);
};
go(cur);
};
</script></head><body>
<div><h1>Azure Service Bus Correlation</h1>
</div>
<div><p>Correlation? WTF?</p>
</div>
<div><blockquote>
<p>&quot;I haz many fings to do that must work togeva.&quot;</p>
</blockquote>
</div>
<div><h2>It&#39;s all about <code>SessionId</code></h2>
<pre><code class="lang-javascript">var msg = new BrokeredMessage()<span class="comment">;</span>
msg<span class="preprocessor">.SessionId</span> = <span class="string">"kitteh!"</span><span class="comment">;</span></code></pre>
</div>
<div><h1>So what does that mean?</h1>
</div>
<div><p>Azure promises:</p>
<ul>
<li>FIFO.</li>
<li>Consistent session state</li>
<li>Receivers can still die.</li>
</ul>
</div>
<div><p>What this means for us:</p>
<ul>
<li>&quot;Jobs&quot; (e.g. <em>&quot;scrape&quot;</em>) tracked as whole.</li>
<li>Easier reporting &amp; management.</li>
<li>Developer sanity.</li>
</ul>
</div>
<div><h2>Key points</h2>
<ul>
<li>Queues <em>must</em> require Sessions.</li>
<li><code>msg.SessionId</code> <em>must</em> be set on Session Queues.</li>
<li>Don&#39;t do either and world ends.</li>
<li>Do none and no sessions :)</li>
</ul>
</div>
<div><pre><code class="lang-csharp"><span class="keyword">var</span> qd = <span class="keyword">new</span> QueueDescription(name)
{
<span class="comment">/* Create Session Queue */</span>
RequiresSession = <span class="keyword">true</span>
};</code></pre>
</div>
<div><p>Morph handles transparently in <a href="https://github.com/MoBank/MoPowered.Morph/blob/add-sessions-api/src/MoPowered.Morph/Processing/ProcessingService.cs">ProcessingService</a>:</p>
<pre><code class="lang-csharp">var message = <span class="built_in">x</span><span class="preprocessor">.ToMessage</span>()<span class="comment">;</span>
message<span class="preprocessor">.SessionId</span> = sessionId<span class="comment">;</span>
return Client<span class="preprocessor">.SendAsync</span>(message)<span class="comment">;</span></code></pre>
</div>
<div><p>Any <code>Job</code>&#39;s queued or spawned will have their Session ID set for you.</p>
</div>
<div><p>Questions?</p>
</div>
<div><p><img src="http://static.fjcdn.com/gifs/Dancing_452c8b_395735.gif" alt="Kitteh"></p>
</div>

Azure Service Bus Correlation


Correlation? WTF?


"I haz many fings to do that must work togeva."


It's all about SessionId

var msg = new BrokeredMessage();
msg.SessionId = "kitteh!";

So what does that mean?


Azure promises:

  • FIFO.
  • Consistent session state
  • Receivers can still die.

What this means for us:

  • "Jobs" (e.g. "scrape") tracked as whole.
  • Easier reporting & management.
  • Developer sanity.

Key points

  • Queues must require Sessions.
  • msg.SessionId must be set on Session Queues.
  • Don't do either and world ends.
  • Do none and no sessions :)

var qd = new QueueDescription(name)
{
    /* Create Session Queue */
    RequiresSession = true
};

Morph handles transparently in ProcessingService:

var message = x.ToMessage();
message.SessionId = sessionId;
return Client.SendAsync(message);

Any Job's queued or spawned will have their Session ID set for you.


Questions?


Kitteh

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment