<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>posts · michaelprimeaux.com</title><link>https://michaelprimeaux.com/en/posts/</link><description>Parallel and Distributed Systems</description><generator>Hugo</generator><language>en</language><managingEditor>michael@michaelprimeaux.com (Michael Primeaux)</managingEditor><webMaster>michael@michaelprimeaux.com (Michael Primeaux)</webMaster><copyright>&#169; 2026 Michael Primeaux</copyright><lastBuildDate>Fri, 22 May 2026 00:06:00 +0000</lastBuildDate><atom:link href="https://michaelprimeaux.com/en/posts/index.xml" rel="self" type="application/rss+xml"/><image><url>https://michaelprimeaux.com/sixafter-logo-150x150.png</url><title>michaelprimeaux.com</title><link>https://michaelprimeaux.com/en/</link></image><item><title>Three Identifier Constructions for a Human Research Pipeline: Hash, HMAC, NanoID</title><link>https://michaelprimeaux.com/en/posts/2026-05-09-human-research-pipeline/</link><pubDate>Fri, 08 May 2026 00:06:00 +0000</pubDate><author>michael@michaelprimeaux.com (Michael Primeaux)</author><guid>https://michaelprimeaux.com/en/posts/2026-05-09-human-research-pipeline/</guid><description>&amp;ldquo;If you think cryptography will solve your problem, then you don&amp;rsquo;t understand cryptography and you don&amp;rsquo;t understand your problem.&amp;rdquo; — Roger Needham
A few colleagues and I recently revisited a familiar debate. In most data systems, identifier generation is treated as undifferentiated infrastructure—one library, one default, applied everywhere. The implicit assumption is that a sufficiently random identifier is a sufficient answer to whatever question the system happens to ask of it; that the differences between identifier classes—surrogate keys, content fingerprints, anonymized handles, span identifiers, request correlations—are differences of usage rather than differences of construction. That assumption is convenient. It survives precisely until the system encounters constraints that aren&amp;rsquo;t engineering constraints.</description><content:encoded><![CDATA[<blockquote><p><em>&ldquo;If you think cryptography will solve your problem, then you don&rsquo;t understand cryptography and you don&rsquo;t understand your problem.&rdquo;</em>
— Roger Needham</p>
</blockquote>
<p>A few colleagues and I recently revisited a familiar debate. In most data systems, identifier generation is treated as undifferentiated infrastructure—one library, one default, applied everywhere. The implicit assumption is that a sufficiently random identifier is a sufficient answer to whatever question the system happens to ask of it; that the differences between identifier classes—surrogate keys, content fingerprints, anonymized handles, span identifiers, request correlations—are differences of <em>usage</em> rather than differences of <em>construction</em>. That assumption is convenient. It survives precisely until the system encounters constraints that aren&rsquo;t engineering constraints.</p>
<p>For the past several years, I&rsquo;ve designed and currently operate a clinical research data pipeline serving multiple concurrent 
<a href="https://en.wikipedia.org/wiki/Institutional_review_board" class="link-external" rel="noopener noreferrer" target="_blank">Institutional Review Board
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 (IRB)-approved studies against 
<a href="https://en.wikipedia.org/wiki/Electronic_health_record" class="link-external" rel="noopener noreferrer" target="_blank">Electronic Health Record
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 (EHR)-sourced data at production scale. Though, implementation specifics are abstracted from this post, I want to highlight the architectural patterns. In human-subjects research, identifier construction stops being a performance choice and becomes a <em>regulatory</em> and <em>ethical</em> primitive.</p>
<p>Why? Because the constraints are different from those that arise in commercial systems. Re-identification resistance is enforceable under the 
<a href="https://en.wikipedia.org/wiki/Health_Insurance_Portability_and_Accountability_Act" class="link-external" rel="noopener noreferrer" target="_blank">Health Insurance Portability and Accountability Act
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 (HIPAA) and the 
<a href="https://en.wikipedia.org/wiki/Common_Rule" class="link-external" rel="noopener noreferrer" target="_blank">Common Rule
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
. Per-study isolation is an IRB requirement. Provenance 
<a href="https://www.ietf.org/rfc/rfc2119.txt" class="link-external" rel="noopener noreferrer" target="_blank">MUST
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 survive transformation but MUST NOT enable cross-study linkage. Workflows that depend on the operator&rsquo;s <em>inability</em> to reverse a transformation can&rsquo;t be retrofitted onto a single global identifier scheme; they have to be built into the construction itself. None of these properties emerge from a generic randomness primitive applied uniformly to every identifier the pipeline produces.</p>
<p>So let me state the pattern plainly. A real human-research pipeline needs at least three distinct identifier constructions. Each answers a different question. Each lives at a different boundary. Treating identifier generation as a single problem with a single answer breaks one architectural pillar in service of another. The failure mode isn&rsquo;t that any single construction is wrong, but that <em>no single construction is right for every boundary the pipeline must respect.</em></p>
<h2 id="three-pillars-three-constructions" class="heading">Three Pillars, Three Constructions
    <a class="heading__anchor" href="#three-pillars-three-constructions" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h2>
<p>A human-subjects research pipeline must answer three questions of every row that flows through it. The questions are independent and every row is interrogated by the following pillars:</p>
<ol>
<li>
<p><strong>Fidelity</strong>. Is this row the same as before, or has it changed? A pipeline that can&rsquo;t answer this can&rsquo;t deduplicate, can&rsquo;t detect drift, and can&rsquo;t reason about whether a transformation preserved meaning. Fidelity is the substrate on which idempotency, change detection, and lineage are built. Without it, every other property the pipeline claims to provide is conjectural.</p>
</li>
<li>
<p><strong>Governance</strong>. Can this row be re-linked to a person, or to the same person across studies? In a research context, the answer must be no, and the answer must be <em>enforceable</em> rather than promised. Policy is necessary but not sufficient; if the construction permits re-linkage, then policy is the only thing preventing it, and policy can be circumvented, misconfigured, or socially engineered. Governance asks whether the construction itself denies the operations that policy forbids.</p>
</li>
<li>
<p><strong>Provenance</strong>. Which pipeline run produced this row, from which source, on which day, by which transformation? Provenance is the operational substrate of accountability. It allows any finding to be traced back to its derivation, any anomaly to be localized to a stage and a run, any audit to reconstruct what happened without depending on the cooperation of the system that produced the result.</p>
</li>
</ol>
<p>Each question is answered by a different cryptographic construction at a different boundary:</p>
<ul>
<li>Content-addressed 
<a href="https://en.wikipedia.org/wiki/SHA-2" class="link-external" rel="noopener noreferrer" target="_blank">SHA-256
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 hashing answers <strong>fidelity</strong> at the ingest boundary.</li>
<li>Per-tenant keyed 
<a href="https://en.wikipedia.org/wiki/HMAC" class="link-external" rel="noopener noreferrer" target="_blank">HMAC
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 hashing answers <strong>governance</strong> at the publication boundary.</li>
<li>
<a href="https://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator" class="link-external" rel="noopener noreferrer" target="_blank">CSPRNG
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
-backed identifier generation answers <strong>provenance</strong> at the operational layer.</li>
</ul>
<p>The constructions are not interchangeable. Using any one of them outside its intended boundary either fails the question its boundary is supposed to answer or undermines a pillar that some other boundary was responsible for. Let me walk each in turn, identify the constraint it answers, and explain why the substitution of a generic identifier scheme is an architectural mistake rather than a minor inefficiency.</p>
<h2 id="fidelity-at-the-ingest-boundary" class="heading">Fidelity at the Ingest Boundary
    <a class="heading__anchor" href="#fidelity-at-the-ingest-boundary" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h2>
<p>At the ingest boundary, the pipeline receives raw data from a source system that doesn&rsquo;t coordinate with the pipeline about identity. Files arrive on a schedule, are written to a lake in raw form, and become the substrate from which everything downstream is derived. The question fidelity asks of every row at this boundary is whether it&rsquo;s the same row that arrived yesterday, last week, or in any prior incremental load. If the pipeline can&rsquo;t answer that question cheaply and unambiguously, then:</p>
<ul>
<li>Deduplication becomes guesswork.</li>
<li>Idempotency becomes a hope.</li>
<li>The lake&rsquo;s role as the recovery anchor for the entire pipeline is compromised.</li>
</ul>
<p>The construction that answers this question is a SHA-256 hash computed over the row&rsquo;s sorted <em>business columns</em> at the moment of lake ingestion. Simply put, &ldquo;business columns&rdquo; are all columns except for metadata columns that were added by the pipeline itself. The hash is written into a metadata column that is then carried unchanged through every downstream stage. It MUST NOT be recomputed at the warehouse boundary, must not be recomputed after foreign-key re-keying at segmentation, and must not be recomputed under any condition the pipeline operator may otherwise consider reasonable. The construction is content-addressed and immutable.</p>
<p>The non-randomness of this identifier is the point. Two rows with identical business-column content produce identical hashes. Two rows with any meaningful difference produce different hashes with overwhelming probability. The hash is unique by virtue of its <em>content</em>, not by virtue of its randomness, and that property is what makes change detection tractable across overlapping daily exports without requiring the source system to participate in a coordination protocol it was never designed to support. A randomized identifier would be wrong here in the strongest sense: it would foreclose exactly the property the boundary needs.</p>
<p>The same property that enables change detection also serves as a duplicate pre-filter. Rows that share identical business-column values are duplicates by definition, and the hash exposes that fact at the moment of ingestion rather than deferring it to a downstream reconciliation step. Duplicate detection becomes a comparison of fixed-width hashes rather than a comparison of arbitrarily wide row contents, and the cost of identifying duplicates collapses to the cost of comparing two values. The work the pipeline would otherwise have to do further downstream is done once, at the boundary, by the construction itself.</p>
<p>The hash also serves as the first link in the lineage chain that fidelity, governance, and provenance all eventually depend upon. Any row anywhere in the pipeline can be traced back to its source by following the hash. Any divergence between a stage&rsquo;s input and its output can be diagnosed by comparing hashes. Any claim that two rows in different marts derive from the same source row is verifiable without consulting either source or mart, because the hash is the same in both places. The hash is the substrate; everything else is built on top of it.</p>
<p>A subtlety worth naming is that the hash construction itself sits on a hot path. At ingest scale, tens of millions of rows pass through the pipeline on every full load, and the hash is computed for every one of them. The disciplines that apply to identifier generation under sustained concurrency apply equally here: allocation behavior MUST be controlled, primitive selection MUST avoid implicit coordination, and the cost of the construction MUST NOT become the dominant cost of ingestion. The arguments I developed in 
<a href="https://michaelprimeaux.com/posts/2024-11-12-optimizing-nano-id-generation-in-go/">my earlier post on NanoID hot-path optimization</a>
 generalize directly to hash construction in pipelines of this kind. The construction is different; the discipline is the same.</p>
<h2 id="governance-at-the-publication-boundary" class="heading">Governance at the Publication Boundary
    <a class="heading__anchor" href="#governance-at-the-publication-boundary" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h2>
<p>The boundary between the warehouse and the data marts is where the pipeline transitions from internal computation to <em>external publication</em>. Inside the warehouse, identity is managed by the pipeline operator, and the SHA-256 hash from the ingest boundary serves every internal purpose well. Outside the warehouse, identity becomes a research artifact, and a fundamentally different requirement asserts itself: the identifier that reaches the mart MUST NOT enable re-identification of the underlying subject, and it 
<a href="https://www.ietf.org/rfc/rfc2119.txt" class="link-external" rel="noopener noreferrer" target="_blank">MUST NOT
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 enable cross-mart linkage of the same subject across separate research projects.</p>
<p>Both requirements are properties of the <em>construction</em>, not properties of the <em>data</em>. A SHA-256 hash carried untouched into a mart would satisfy neither. Why? The hash is deterministic; identical inputs produce identical outputs; an attacker with sufficient knowledge of the source schema could attempt to reconstruct the input space and brute-force the mapping. More immediately, the same warehouse row would carry the same hash into every mart, and any researcher with access to two marts could link rows trivially by comparing hashes. The construction permits exactly the operations that governance forbids.</p>
<p>Stay with me—the answer here is a small but architecturally decisive change. The construction that answers governance at this boundary is HMAC-SHA256, keyed with a per-mart secret stored in a 
<a href="https://en.wikipedia.org/wiki/Hardware_security_module" class="link-external" rel="noopener noreferrer" target="_blank">Hardware Security Module
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 (HSM)-backed secrets manager and never exposed to the pipeline operator. At the segmentation stage that produces each mart, the warehouse-side SHA-256 hash is replaced by HMAC-SHA256(<code>warehouse-hash</code>, <code>per-mart-secret</code>). The result is a new identifier that is:</p>
<ul>
<li><strong>Deterministic</strong> with respect to the same inputs.</li>
<li><strong>Cryptographically opaque</strong> without the secret.</li>
<li><strong>Distinct across marts</strong>, because the secret is distinct across marts.</li>
</ul>
<p>This construction has a property that&rsquo;s easy to overlook and architecturally decisive: the HMAC operates on the <em>SHA-256 hash</em>, not on the <em>raw business columns</em>. An attacker who somehow obtained a per-mart secret would not face the relatively constrained problem of inverting the HMAC over a known schema of patient identifiers; they would face the problem of inverting it over the <em>full output space of SHA-256</em>, which is 2^256 possible inputs. A dictionary attack against patient identifiers, plausible in principle against a single-layer keyed hash, is eliminated by construction. The two-layer design—content hash first, keyed hash of the hash second—is what makes the cryptographic claim survive contact with a realistic threat model.</p>
<p>The architectural consequence is that the publication boundary becomes a place where identity is not merely <em>transformed</em> but <em>severed</em>. The original SHA-256 hash never reaches the mart. The mart receives the HMAC, and only the HMAC, as its identifier for that row. The pipeline operator, who has access to the warehouse and to the segmentation code, can&rsquo;t reverse the transformation, because the operator doesn&rsquo;t have the per-mart secret. The secret lives in an HSM-backed store that the operator can use but can&rsquo;t extract. The same warehouse row, written into three different marts, carries three different identifiers, and no party—including the pipeline operator—can establish that the three identifiers refer to the same subject without simultaneous access to all three secrets and the cooperation of the secrets manager.</p>
<p>This is what makes the honest-broker workflow <em>cryptographically</em> tenable rather than <em>merely operationally promised</em>. In human-subjects research, there are workflows where the operator&rsquo;s inability to reverse the transformation is structurally required: the team that operates the pipeline MUST be able to publish the data, but MUST NOT be able to re-identify the subjects whose data it published. Under a single-layer construction, the operator can always be compelled, suborned, or compromised into reversing the mapping. Under the two-layer construction described here, the operator simply doesn&rsquo;t have the capability to reverse, and therefore can&rsquo;t be compelled to exercise it. The construction enforces what policy could only request.</p>
<p>The bridge to my 
<a href="https://michaelprimeaux.com/posts/2025-07-20-aes-ctr-drbg/">earlier work on AES-CTR-DRBG</a>
 is direct. In that post I argued that deterministic cryptographic constructions belong in environments where reproducibility, auditability, and explicit state evolution are required. The HMAC-at-publication pattern is the same disposition applied to <em>identity</em> rather than to byte streams. The construction is deterministic with respect to its inputs; the state that determines its output evolves only when the per-mart secret is rotated; the auditor can reason about what the construction produces without having to reverse-engineer the library that implements it. Configuration is a contract. Boundaries are explicit. The cryptographic posture doesn&rsquo;t change mid-flight.</p>
<p>A randomized identifier would be wrong here in a different way than at the ingest boundary, but no less wrong. A randomized identifier is non-deterministic; the same row processed twice would produce different identifiers; the mart&rsquo;s referential integrity would collapse on the first re-run. What the boundary needs is <em>deterministic-but-cryptographically-opaque</em>, and the only construction that delivers both properties is a keyed hash.</p>
<h2 id="provenance-at-the-operational-layer" class="heading">Provenance at the Operational Layer
    <a class="heading__anchor" href="#provenance-at-the-operational-layer" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h2>
<p>The constructions described so far handle the headline identity story—the identity of the rows themselves. They&rsquo;re computed once per row and carried thereafter. They&rsquo;re also, by a substantial margin, <em>not</em> the identifiers the pipeline generates most often.</p>
<p>A pipeline of any operational seriousness produces identifiers continuously for things that <em>aren&rsquo;t</em> rows. Pipeline runs need identifiers. Stage executions need identifiers. Batch tasks under a thread pool need identifiers. Observability spans, if the pipeline exports traces, need identifiers. Synthetic sentinel rows injected at segmentation need identifiers distinguishable from real source identifiers. Project allocations need identifiers that survive across systems. Honest-broker requests need identifiers that the requesting system, the secrets manager, and the provisioning workflow can all reference unambiguously. Quality diagnostic runs need identifiers for the audit trail that links them to the pipeline run that triggered them.</p>
<p>These identifiers have a constraint regime distinct from anything the row-level constructions answer:</p>
<ol>
<li>They are allocated at high concurrency, often from many worker threads or pods simultaneously, with no central allocator available.</li>
<li>They MUST be collision-resistant by virtue of their construction, because no coordinator exists to detect and resolve a collision after the fact.</li>
<li>They MUST be URL-safe and human-tractable, because they will appear in logs, dashboards, audit trails, and the bodies of cross-system requests.</li>
<li>They MUST be allocation-cheap, because the pipeline generates them at orders of magnitude higher volume than it generates SHA-256 row hashes or per-mart HMACs.</li>
<li>They MUST NOT leak temporal patterns or sequence structure that an observer could exploit to infer pipeline behavior or correlate identifiers from independent runs.</li>
</ol>
<p>In raw call volume, this class of identifier dominates the SHA-256 and HMAC constructions by orders of magnitude. The hash is computed once per source row at ingest. The HMAC is computed once per row per mart at segmentation. The operational identifiers are generated continuously: on every notebook, on every span, on every parallel task, on every cross-system request. If the construction here is wrong, the cost is paid everywhere the pipeline does any work at all.</p>
<p>This is the design space my 
<a href="https://github.com/sixafter/nanoid" class="link-external" rel="noopener noreferrer" target="_blank">NanoID library
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 was built for, and the disposition that produced it is the disposition that earlier governed its randomness backends. The construction at the call site is identical regardless of the workload—a single function call returning a compact, URL-safe identifier—but the randomness <em>source</em> behind it is configurable, and the choice of source is made per identifier <em>class</em> rather than per <em>call site</em>. The architectural payoff is that the cryptographic posture of the identifier is determined at construction time and survives every downstream invocation without requiring the call site to be aware of it.</p>
<p>For the highest-volume operational identifiers—span identifiers, batch identifiers, stage execution identifiers, the thousands of small handles that a pipeline produces in the course of doing its work—the appropriate backend is the 
<a href="https://michaelprimeaux.com/posts/2025-12-26-prng-chacha/">ChaCha20-based PRNG</a>
 I developed in an earlier post. It&rsquo;s designed for predictable behavior under sustained concurrency, with allocation discipline on the hot path and no shared coordination between worker threads. It doesn&rsquo;t target any particular compliance regime, because none applies at this layer; what applies is the constraint that identifier generation MUST remain invisible in profiling output even at the volumes the pipeline reaches.</p>
<p>For the identifiers that participate in audit, IRB, or compliance trails—project allocations, honest-broker request identifiers, anything that ends up in a Key Vault audit log or a regulatory submission—the appropriate backend is the 
<a href="https://michaelprimeaux.com/posts/2025-07-20-aes-ctr-drbg/">AES-CTR-DRBG</a>
 construction I developed in the post before that. It targets 
<a href="https://csrc.nist.gov/publications/detail/fips/140/2/final" class="link-external" rel="noopener noreferrer" target="_blank">FIPS 140-2
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
-aligned cryptographic randomness with deterministic state evolution, allowing the identifiers it produces to be traceable, auditable, and defensible under scrutiny in ways that a general-purpose PRNG is not. The construction is the same NanoID library, configured with a different randomness source via the same <code>WithRandReader</code> option, called identically at the call site.</p>
<p>The two backends are not competing; they answer two different constraints within the same pipeline, on the same library surface, decided once at construction time. The same disposition that governs SHA-256 and HMAC at their boundaries—<em>the construction is chosen for the boundary, not for the codebase</em>—governs NanoID at the operational layer.</p>
<h2 id="one-library-three-backends" class="heading">One Library, Three Backends
    <a class="heading__anchor" href="#one-library-three-backends" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h2>
<p>The library design that makes this tractable isn&rsquo;t a convenience feature. It&rsquo;s an architectural commitment that allows per-boundary construction choice to coexist with a single call-site surface. NanoID exposes a <code>WithRandReader</code> option that accepts any <code>io.Reader</code> as its randomness source. The choice of source is made once, at generator construction time, and survives every subsequent identifier the generator produces. The call site doesn&rsquo;t change; the cryptographic posture does.</p>
<p>This mirrors the architectural move SHA-256 and HMAC are making at their respective boundaries. Both belong to the SHA-2 family. Both compose with the same underlying hash primitive. The difference between them is whether a per-tenant key is involved, and whether the construction can therefore enforce the cryptographic break that publication requires. The primitive is shared; the construction is chosen for what the boundary MUST guarantee. Same disposition, same shape, different layer.</p>
<p>The negation is instructive. A pipeline that uses <code>uuid_generate_v4()</code> everywhere—or NanoID with a single hardcoded randomness source applied to every identifier it produces—collapses distinctions that the architecture is doing real work to preserve. Surrogate keys for fact tables receive the same construction as project identifiers feeding IRB submissions, which receive the same construction as observability spans. Each is correct for some workload and wrong for at least one other. The pipeline that adopts a single global construction hasn&rsquo;t simplified its identifier story; it has merely declined to make decisions that its boundaries will eventually force it to revisit.</p>
<p>The pipeline that adopts the layered model described here makes those decisions once, at the boundary where each one belongs, and then stops thinking about them.</p>
<ul>
<li>The hash is content-addressed at ingest.</li>
<li>The HMAC is per-tenant keyed at publication.</li>
<li>The NanoID is randomly allocated at the operational layer, with the randomness backend chosen for the identifier class.</li>
</ul>
<p>Each construction is correct for its boundary. Each construction is composable with the others, because the boundaries are explicit and the constructions don&rsquo;t interfere. The architecture isn&rsquo;t more complex than the alternative; it&rsquo;s more honest about the complexity that was already present.</p>
<h2 id="wrapping-it-all-up" class="heading">Wrapping it all up&hellip;
    <a class="heading__anchor" href="#wrapping-it-all-up" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h2>
<p>The earlier articles in this sequence each followed a single constraint to its conclusion. My 
<a href="https://michaelprimeaux.com/posts/2024-11-12-optimizing-nano-id-generation-in-go/">2024 article on NanoID</a>
 followed the hot-path discipline that emerges when identifier generation moves from incidental utility to infrastructure. My 
<a href="https://michaelprimeaux.com/posts/2025-07-20-aes-ctr-drbg/">2025 article on AES-CTR-DRBG</a>
 followed the requirements of compliance, auditability, and explicit state evolution. My article on the 
<a href="https://michaelprimeaux.com/posts/2025-12-26-prng-chacha/">ChaCha20-based PRNG</a>
 followed the constraints of portability, concurrency, and operational simplicity. In each case, a single set of requirements produced a single construction.</p>
<p>This article inverts that move. Given a domain—human-subjects research—that imposes <em>multiple</em> constraint regimes simultaneously, the architectural response isn&rsquo;t a single construction but a layered one. Fidelity, governance, and provenance aren&rsquo;t competing concerns to be balanced against one another. They&rsquo;re independent questions answered by independent constructions at independent boundaries, and the pipeline that respects the independence of the questions can satisfy all three without trading any of them off against the others.</p>
<p>Make no mistake; the constructions themselves are unremarkable. SHA-256 has been a standard primitive for two decades. HMAC has been a standard primitive for longer. CSPRNG-backed identifier generation is a solved problem with well-understood implementations. The architectural work isn&rsquo;t in the <em>choice of primitives.</em> It&rsquo;s in the <em>recognition</em> that each primitive is correct only for the boundary that actually needs the property it provides, and in the <em>discipline</em> of refusing to substitute one for another where the substitution would be easier but wrong.</p>
<p>Good architecture emerges when constraints are 
<a href="https://www.ietf.org/rfc/rfc2119.txt" class="link-external" rel="noopener noreferrer" target="_blank">REQUIRED
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 and followed to their conclusions, even when those conclusions lead to different constructions under different constraints. The earlier articles argued this for randomness. The pipeline architecture described here argues it for <em>identity</em>. The answer is the same in both cases: make the boundaries explicit, choose the construction the boundary needs, and let the disposition do the rest.</p>
<p>My next post will take a step back and explore the data analytics and insights pipeline from an architectural perspective.</p>
<hr>
<p>Implementation: 
<a href="https://github.com/sixafter/nanoid" class="link-external" rel="noopener noreferrer" target="_blank">https://github.com/sixafter/nanoid
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
</p>]]></content:encoded><category>computing</category><category>distributed systems</category><category>software</category><category>cryptography</category><category>research</category><category>data science</category><category>data analytics</category></item><item><title>Randomness Under Different Constraints: A ChaCha20-Based PRNG in Go</title><link>https://michaelprimeaux.com/en/posts/2025-12-26-prng-chacha/</link><pubDate>Thu, 25 Dec 2025 00:06:00 +0000</pubDate><author>michael@michaelprimeaux.com (Michael Primeaux)</author><guid>https://michaelprimeaux.com/en/posts/2025-12-26-prng-chacha/</guid><description>“A system is not determined by the algorithms it uses, but by the assumptions it makes.”
— Leslie Lamport
Randomness appears deceptively uniform in most software systems. A call is made, bytes are returned, and execution proceeds. The details of how those bytes were produced rarely matter—until they do. As with many foundational components, the assumptions baked into a randomness source tend to surface only when systems scale, diversify, or are subjected to constraints they were not originally designed to accommodate.
In the previous article , I explored deterministic cryptographic randomness under compliance and auditability constraints, where explicit state evolution and reproducibility were not optional. That work followed inevitably from environments shaped by regulation and forensic accountability. This article explores a different design space: one where the constraints are imposed not by certification regimes, but by software portability, concurrency, and operational simplicity.
The result is a ChaCha20-based (opens in a new window) pseudorandom number generator (PRNG) designed for predictable behavior in real systems, rather than alignment with formal validation programs.</description><content:encoded><![CDATA[<blockquote><p><em>“A system is not determined by the algorithms it uses, but by the assumptions it makes.”</em><br>
— Leslie Lamport</p>
</blockquote>
<p>Randomness appears deceptively uniform in most software systems. A call is made, bytes are returned, and execution proceeds. The details of how those bytes were produced rarely matter—until they do. As with many foundational components, the assumptions baked into a randomness source tend to surface only when systems scale, diversify, or are subjected to constraints they were not originally designed to accommodate.</p>
<p>In the 
<a href="https://michaelprimeaux.com/posts/2025-07-20-aes-ctr-drbg/">previous article</a>
, I explored deterministic cryptographic randomness under compliance and auditability constraints, where explicit state evolution and reproducibility were not optional. That work followed inevitably from environments shaped by regulation and forensic accountability. This article explores a different design space: one where the constraints are imposed not by certification regimes, but by software portability, concurrency, and operational simplicity.</p>
<p>The result is a 
<a href="https://datatracker.ietf.org/doc/html/rfc8439" class="link-external" rel="noopener noreferrer" target="_blank">ChaCha20-based
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 pseudorandom number generator (PRNG) designed for predictable behavior in real systems, rather than alignment with formal validation programs.</p>
<p>What distinguishes this space from compliance-driven designs is not weaker security assumptions, but different priorities. Software systems are often judged not by formal proofs or certifications, but by how they behave under sustained load, across diverse platforms, and in the presence of concurrency. In those environments, simplicity is not aesthetic—it is operational. Every implicit dependency, hidden allocation, or global coordination point becomes a liability over time.</p>
<h2 id="constraints-shape-constructions" class="heading">Constraints Shape Constructions
    <a class="heading__anchor" href="#constraints-shape-constructions" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h2>
<p>Cryptographic primitives are often discussed as interchangeable building blocks. In practice, the surrounding constraints determine which properties matter and which can be safely ignored. A construction optimized for auditability and deterministic replay will look very different from one optimized for simplicity, portability, and high-throughput concurrent use.</p>
<p>In software-heavy environments—particularly those spanning multiple platforms or deployed as libraries rather than systems—certain requirements surface repeatedly. The randomness source must behave predictably under concurrency. It must avoid surprising allocation behavior. It must scale without coordination bottlenecks. And it must do so without pulling in complex dependencies or imposing policy decisions on its callers.</p>
<p>These are not compliance constraints. They are engineering constraints.</p>
<p>Engineering constraints tend to accumulate quietly. A library that is easy to use in isolation may behave very differently when embedded in larger systems, reused across services, or exercised under high concurrency. Over time, small assumptions compound: about allocation behavior, about shared state, about initialization cost. What begins as a convenient abstraction can become a systemic bottleneck. Designs that survive this environment are rarely the most general ones; they are the ones that make their tradeoffs explicit early.</p>
<p>ChaCha20 fits naturally into this space. As a stream cipher designed for efficient software implementation, it offers strong cryptographic properties without reliance on specialized hardware instructions or platform-specific optimizations. That makes it a practical foundation for a general-purpose PRNG intended to behave consistently across environments.</p>
<h2 id="state-not-entropy-does-the-work" class="heading">State, Not Entropy, Does the Work
    <a class="heading__anchor" href="#state-not-entropy-does-the-work" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h2>
<p>As with any PRNG, the core of the design is not entropy acquisition but state evolution. Entropy enters the system at initialization. From that point forward, output is a function of internal state advancing according to a defined algorithm.</p>
<p>This distinction matters. By treating entropy acquisition as a boundary rather than a continuous process, the generator remains honest about its dependencies. The operating system provides unpredictability at startup. The PRNG provides expansion, isolation, and repeatable behavior thereafter.</p>
<p>ChaCha20’s design reinforces this model. Once keyed and initialized, the cipher produces a stream of pseudorandom bytes derived entirely from its internal state. There are no conditional branches based on environmental input, no opportunistic refreshes, and no hidden coordination with external sources. State advances monotonically. Output follows deterministically.</p>
<p>Thinking in terms of state rather than entropy also clarifies responsibility. Once initialization completes, the generator no longer depends on the operating system or the environment for correctness. The burden shifts entirely to the implementation and its callers. That boundary is important: it allows failures, assumptions, and limitations to be localized rather than diffused across layers. When something goes wrong, there is no ambiguity about where to look.</p>
<p>This makes the generator easier to reason about, test, and integrate. The absence of implicit behavior is not a limitation; it is a deliberate choice that keeps responsibility visible.</p>
<h2 id="concurrency-without-contention" class="heading">Concurrency Without Contention
    <a class="heading__anchor" href="#concurrency-without-contention" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h2>
<p>Concurrency tends to expose the weaknesses of otherwise elegant designs. Shared mutable state invites contention. Global locks introduce unpredictable latency. Per-call initialization imposes overhead that scales poorly as systems grow.</p>
<p>The ChaCha20 PRNG approaches concurrency as a distribution problem rather than a synchronization problem. Independent generator instances maintain independent state. A pooling strategy amortizes initialization costs while avoiding shared counters or global coordination. Each request draws from a generator whose behavior is local, predictable, and isolated from others.</p>
<p>This approach mirrors patterns commonly used in distributed systems: partition state, avoid global serialization, and accept modest duplication in exchange for clarity and scalability.</p>
<p>In practice, this means resisting the temptation to centralize randomness behind a single shared construct. While such designs appear simpler at first, they introduce hidden coupling that surfaces under load. Contention becomes observable latency. Synchronization becomes an availability concern. By allowing each generator instance to evolve independently, the system preserves the same semantic behavior regardless of how many consumers are active.</p>
<h2 id="runtime-semantics-and-predictable-behavior" class="heading">Runtime Semantics and Predictable Behavior
    <a class="heading__anchor" href="#runtime-semantics-and-predictable-behavior" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h2>
<p>Allocation behavior is treated as a semantic concern rather than a micro-optimization. A PRNG that allocates unpredictably during output generation cedes part of its execution model to the runtime.</p>
<p>The effects of these choices are observable in practice. Small reads primarily reflect fixed overhead. Larger reads scale linearly with the amount of data processed, as expected from a stream cipher advancing its internal counter. Under concurrent workloads, latency remains stable because requests are serviced independently rather than serialized behind shared state.</p>
<p>What matters is not the absolute numbers, but their predictability. The behavior matches the design model, rather than fluctuating with runtime conditions.</p>
<p>This predictability has secondary effects that are easy to underestimate. Monitoring becomes more meaningful when latency distributions are stable. Capacity planning becomes tractable when throughput degrades linearly rather than catastrophically. Perhaps most importantly, anomalies become visible. When behavior deviates from expectation, it signals a real change in conditions rather than noise introduced by the runtime.</p>
<h2 id="failure-modes-and-explicit-boundaries" class="heading">Failure Modes and Explicit Boundaries
    <a class="heading__anchor" href="#failure-modes-and-explicit-boundaries" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h2>
<p>Boundaries are explicit. Initialization depends on a trusted entropy source. Once initialized, the generator’s behavior is deterministic and bounded by construction. Errors are surfaced rather than hidden.</p>
<p>Surfacing errors is not merely a defensive choice; it is an architectural one. Silent degradation may preserve uptime in the short term, but it undermines trust in the system over time. By making failure explicit, the generator avoids the pretense of correctness under conditions it was not designed to handle. This makes integration more demanding, but also more honest.</p>
<p>This approach does not attempt to cover every possible threat model. It does not claim resistance to state compromise beyond what the underlying primitive provides. It does not attempt to retrofit compliance semantics onto a software-oriented design.</p>
<h2 id="closing-thoughts" class="heading">Closing Thoughts
    <a class="heading__anchor" href="#closing-thoughts" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h2>
<p>This 
<a href="https://github.com/sixafter/prng-chacha" class="link-external" rel="noopener noreferrer" target="_blank">ChaCha20-based PRNG
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 is used as the randomness source in other systems, including my 
<a href="https://github.com/sixafter/nanoid" class="link-external" rel="noopener noreferrer" target="_blank">NanoID
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 implementation, where predictable behavior, low overhead, and concurrency safety are practical requirements rather than abstract goals.</p>
<p>Randomness is not a single problem. Different environments impose different constraints, and those constraints shape the constructions that make sense within them.</p>
<p>This ChaCha20-based PRNG exists because certain systems demand a randomness source that behaves predictably under concurrency, avoids unnecessary complexity, and makes its assumptions explicit. It treats randomness as evolving state rather than as an opaque service call.</p>
<p>The tension between generality and specificity is unavoidable in systems design. Libraries that attempt to serve every use case often end up serving none particularly well. By contrast, designs that accept their constraints openly tend to age more gracefully. They are easier to reason about, easier to integrate, and harder to misuse.</p>
<hr>
<p>Implementation: 
<a href="https://github.com/sixafter/prng-chacha" class="link-external" rel="noopener noreferrer" target="_blank">https://github.com/sixafter/prng-chacha
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
</p>]]></content:encoded><category>computing</category><category>distributed systems</category><category>software</category><category>cryptography</category></item><item><title>AES-CTR-DRBG in Go: Allocation-Free, Low-Latency, Deterministic Cryptographic Randomness</title><link>https://michaelprimeaux.com/en/posts/2025-07-20-aes-ctr-drbg/</link><pubDate>Sun, 20 Jul 2025 00:06:00 +0000</pubDate><author>michael@michaelprimeaux.com (Michael Primeaux)</author><guid>https://michaelprimeaux.com/en/posts/2025-07-20-aes-ctr-drbg/</guid><description>&amp;ldquo;The purpose of abstraction is not to be vague, but to create a new semantic level in which one can be absolutely precise.&amp;rdquo; — Edsger W. Dijkstra
Randomness occupies an unusual position in software systems. We rely on it for security, for fairness, for simulation, and yet we rarely scrutinize its behavior with the same rigor we apply to storage engines or replication protocols. We accept entropy as something that simply happens, mediated by an operating system call or a library abstraction, and move on.
That approach works—until it doesn’t.</description><content:encoded><![CDATA[<blockquote><p>&ldquo;The purpose of abstraction is not to be vague, but to create a new semantic level in which one can be absolutely precise.&rdquo;
— Edsger W. Dijkstra</p>
</blockquote>
<p>Randomness occupies an unusual position in software systems. We rely on it for security, for fairness, for simulation, and yet we rarely scrutinize its behavior with the same rigor we apply to storage engines or replication protocols. We accept entropy as something that simply <em>happens</em>, mediated by an operating system call or a library abstraction, and move on.</p>
<p>That approach works—until it doesn’t.</p>
<p>When I began working on systems that required both cryptographic correctness and operational predictability, the implicit assumptions around randomness became a liability. Latency mattered. Allocation behavior mattered. Reproducibility mattered. And in certain environments, auditability mattered most of all. The standard tools did not fail outright, but they failed quietly, by obscuring behavior that ought to be explicit.</p>
<p>At its core, the problem is not randomness itself, but how cryptographic state evolves over time—and whether that evolution remains visible, bounded, and predictable.</p>
<p>This article is about addressing that gap.</p>
<h2 id="determinism-is-not-the-enemy" class="heading">Determinism Is Not the Enemy
    <a class="heading__anchor" href="#determinism-is-not-the-enemy" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h2>
<p>In distributed systems, we accept a fundamental axiom: there is no way to guarantee complete knowledge of global state at any given moment. We design for tolerance, convergence, and recovery, not for omniscience; ref 
<a href="https://michaelprimeaux.com/posts/2012-08-05-parallel-and-distributed-system-design-part-1/">Parallel and Distributed System Design</a>
). Randomness, however, often escapes this discipline. It is treated as an oracle—invoked, trusted, and forgotten.</p>
<p>Cryptographic systems take a different view. They do not reject determinism; they constrain it. Given a fixed internal state and a fixed construction, output must follow. This is not a weakness but a requirement. It is precisely what allows us to reason about forward security, backtracking resistance, and compromise scenarios.</p>
<p>AES-CTR-DRBG sits squarely in this space. It provides a deterministic construction based on a well-understood primitive, AES, and defines explicit rules for how internal state evolves over time. Once you accept that premise, several consequences follow naturally. Hidden entropy sources become suspect. Implicit reseeding becomes problematic. Mutable configuration becomes dangerous.</p>
<p>The design space narrows considerably.</p>
<h2 id="deterministic-constructions-and-cryptographic-honesty" class="heading">Deterministic Constructions and Cryptographic Honesty
    <a class="heading__anchor" href="#deterministic-constructions-and-cryptographic-honesty" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h2>
<p>Cryptography is often discussed in terms of strength, but strength alone is not sufficient. A system can employ strong primitives and still behave in ways that are difficult to reason about. When that happens, security becomes an emergent property rather than an explicit one.</p>
<p>Deterministic constructions reject that ambiguity.</p>
<p>An 
<a href="https://github.com/sixafter/aes-ctr-drbg" class="link-external" rel="noopener noreferrer" target="_blank">AES-CTR-DRBG
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 does not attempt to surprise the reader. Given a key, a counter, and a defined update function, the output follows directly. There is no hidden mixing, no opportunistic entropy acquisition, and no conditional behavior based on environmental state. This predictability is not merely convenient; it is foundational. It allows one to reason about compromise without first reverse-engineering library behavior.</p>
<p>Once determinism is accepted as a requirement, architectural freedoms disappear. You can no longer “improve” security by quietly pulling in entropy. You can no longer treat reseeding as an implementation detail. You must decide, explicitly, when state changes and why.</p>
<p>This is not a limitation of AES-CTR-DRBG. It is a discipline imposed by cryptography itself.</p>
<p>These constraints do not arise in isolation. They emerge most clearly in regulated, multi-tenant, and distributed systems, where randomness is no longer an incidental utility but a component subject to scrutiny. In such environments, deterministic and auditable cryptographic randomness becomes a requirement rather than a preference. Reproducibility matters for forensic analysis. Isolation matters for per-tenant security. Predictable resource behavior matters when concurrency and throughput are no longer theoretical concerns.</p>
<p>The standard random primitives in Go do not address this space. They make no guarantees around deterministic output, explicit key management, or resource predictability under concurrency, nor do they target alignment with 
<a href="https://csrc.nist.gov/publications/detail/sp/800-90a/rev-1/final" class="link-external" rel="noopener noreferrer" target="_blank">NIST SP 800-90A
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 or 
<a href="https://csrc.nist.gov/publications/detail/fips/140/2/final" class="link-external" rel="noopener noreferrer" target="_blank">FIPS 140-2
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 requirements. Third-party alternatives often complicate matters further, introducing additional dependencies or obscuring allocation behavior and latency characteristics behind opaque abstractions.</p>
<p>At scale, these gaps become operational risks. System 
<a href="https://en.wikipedia.org/wiki/Pseudorandom_number_generator" class="link-external" rel="noopener noreferrer" target="_blank">PRNGs
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 do not ensure reproducibility. Key lifecycle management and tenant isolation are left to the caller. Failure modes relevant to compliance and auditability remain implicit, even as entropy sources degrade or cryptographic assumptions are violated. What is missing is not another source of randomness, but a generator whose behavior remains explicit, bounded, and inspectable over time.</p>
<p>These constraints define the space for a deterministic random bit generator based on 
<a href="https://en.wikipedia.org/wiki/Advanced_Encryption_Standard" class="link-external" rel="noopener noreferrer" target="_blank">AES
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 in counter mode (
<a href="https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Counter_%28CTR%29" class="link-external" rel="noopener noreferrer" target="_blank">CTR
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
), as specified in NIST SP 800-90A and aligned with FIPS 140-2. The implementation discussed here relies solely on Go’s standard library cryptography and targets allocation-free output and low, predictable latency, making it suitable for high-throughput and regulated environments where correctness and observability are inseparable.</p>
<h2 id="entropy-state-and-the-shape-of-time" class="heading">Entropy, State, and the Shape of Time
    <a class="heading__anchor" href="#entropy-state-and-the-shape-of-time" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h2>
<p>Many practical failures in cryptographic systems arise not from broken primitives, but from blurred boundaries. Entropy acquisition is a boundary. Deterministic generation is another. When the two are conflated, responsibility becomes unclear.</p>
<p>Operating systems are good at collecting entropy. Applications are good at applying policy. A DRBG sits between the two, which is why many implementations quietly collapse the distinction.</p>
<p>I chose not to.</p>
<p>In this design, entropy enters the system at a clearly defined point and nowhere else. The generator consumes seed material and expands it deterministically. If reseeding occurs, it occurs because the caller has decided that new entropy is available and appropriate. This makes the system honest about its dependencies. It also makes it auditable. One can trace exactly when and how entropy influences output, which is a prerequisite for meaningful analysis.</p>
<p>This mirrors a lesson learned repeatedly in distributed systems: implicit coordination is coordination nonetheless. If you depend on entropy, say so.</p>
<p>It is helpful to visualize the generator not as a black box, but as a state machine evolving over time.</p>
<p>Imagine a simple diagram with three persistent elements: <strong>Key</strong>, <strong>Counter (V)</strong>, and <strong>Limits</strong>. At initialization, these are set from seed material and configuration. Each request for output advances the counter deterministically, producing a block of output via AES encryption. The key remains fixed until a reseed event occurs. Limits monotonically decrease as output is generated.</p>
<p>Time, in this model, does not pass in seconds. It passes in blocks generated.</p>
<p>A reseed event resets the key and counter and restores limits. Absent a reseed, state evolution is linear, irreversible, and predictable. There are no side paths, no hidden refreshes, and no conditional jumps based on runtime conditions. The diagram contains no feedback loops other than the explicit reseed boundary.</p>
<p>This mental model is intentionally simple. It allows one to reason about compromise, exhaustion, and recovery without hand-waving.</p>
<p>Reseeding is often presented as a binary feature: enabled or disabled. In practice, it is a temporal question. How long may a generator safely operate on a given internal state? How much output may be derived before assumptions begin to erode?</p>
<p>FIPS-aligned guidance does not answer these questions abstractly; it answers them in terms of limits. Maximum bytes per key. Maximum requests between reseeds. Defined update functions. These limits exist not because AES is fragile, but because systems operate over time, and time introduces exposure.</p>
<p>In a deterministic generator, time is measured not in seconds but in output. Each block generated advances the internal counter. Each advancement is irreversible. By enforcing explicit limits, the generator treats time as a first-class dimension rather than an afterthought.</p>
<p>This perspective aligns closely with how we reason about versioning and state evolution in distributed systems. State does not merely exist; it progresses. If you do not bound that progression, you eventually lose the ability to reason about it.</p>
<p>Prediction resistance is frequently discussed as an absolute good. In reality, it is a trade. Enabling it increases resilience against certain compromise scenarios, but it also introduces new operational dependencies. Reseeding requires entropy. Entropy requires coordination with the environment. Coordination introduces latency and failure modes.</p>
<p>Rather than treating prediction resistance as a default, this design treats it as a conscious decision. When enabled, reseeding behavior is strict and enforced. When disabled, the generator behaves as a pure deterministic expander. Neither mode is inherently superior; each corresponds to a different threat model.</p>
<p>Cryptographic systems fail when they attempt to serve all threat models simultaneously. By forcing the caller to choose, the system avoids pretending that one size fits all.</p>
<h2 id="runtime-semantics-and-predictability" class="heading">Runtime Semantics and Predictability
    <a class="heading__anchor" href="#runtime-semantics-and-predictability" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h2>
<p>Garbage collection is often discussed in terms of performance, but in latency-sensitive systems it also becomes a semantic concern. Allocation introduces nondeterminism: not in output, but in timing. When a generator allocates during its hot path, it cedes control of latency to the runtime.</p>
<p>The effects of these choices are observable in practice. Under serial workloads, small reads complete in tens of nanoseconds, largely reflecting fixed overhead rather than per-byte cost. Larger reads exhibit higher absolute latency, not because of inefficiency, but because AES-CTR scales linearly with the number of blocks processed. Encrypting a few blocks versus a few hundred necessarily occupies different regions of the CPU pipeline, even when the underlying primitive is highly optimized. What matters is that this behavior is predictable and stable under load, matching expectations derived from the algorithm and the memory hierarchy rather than fluctuating with runtime conditions.</p>
<p>Achieving zero allocations in the output path was, therefore, non-negotiable; read &ldquo;
<a href="https://datatracker.ietf.org/doc/html/rfc2119" class="link-external" rel="noopener noreferrer" target="_blank">MUST
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
&rdquo;.</p>
<p>What matters here is not raw speed, but control. A system that allocates implicitly hands part of its execution semantics to the runtime. In many contexts that is acceptable; in some, it is not. When randomness participates in protocol boundaries, scheduling decisions, or security-sensitive operations, latency variance becomes observable behavior. Treating allocation as a semantic choice forces the design to acknowledge that reality. Once allocation is removed from the generation path, timing becomes a property of the algorithm itself rather than a side effect of memory management. That shift restores a degree of predictability that is otherwise difficult to recover.</p>
<p>The decision to make this DRBG allocation-free during generation was not an optimization exercise; it was a correctness constraint. Once generation begins, no heap allocations occur. The caller owns the buffers. The internal state resides in fixed-size structures. The runtime remains uninvolved. Latency variance collapses. Throughput becomes predictable. The generator behaves the same under load as it does in isolation.</p>
<p>Concurrency often exposes design shortcuts. Shared mutable state invites contention; global locks invite collapse. In the context of deterministic randomness, concurrency introduces an additional risk: accidental nondeterminism caused by interleaving.</p>
<p>The solution follows a familiar distributed-systems pattern: partition the state. Each shard maintains its own independent DRBG state. Shards do not share counters, keys, or reseed thresholds. They share only configuration. This trades a small amount of memory for clarity and scalability. Concurrency improves throughput, not entropy.</p>
<p>Determinism remains intact.</p>
<p>Configuration is where many security failures quietly begin. Defaults accrete. Options multiply. Behavior changes without callers noticing. Over time, the configuration surface becomes an implicit API, understood only by convention.</p>
<p>Here, configuration is a contract.</p>
<p>All configuration occurs at construction time. Options are explicit. Once initialized, the generator does not change its behavior. There is no hidden reseeding, no dynamic mutation, no silent fallback. If prediction resistance is enabled, it is enabled because the caller said so.</p>
<p>A generator whose security posture can change mid-flight violates basic architectural discipline. A useful way to evaluate a DRBG is to ask a simple question: if an attacker learns the internal state at time <em>t</em>, what can they infer? With a deterministic construction, the answer is precise. Past output remains secure if the construction provides backtracking resistance. Future output becomes predictable unless new entropy is introduced. These are not surprising conclusions; they are the expected consequences of the model.</p>
<p>What matters is that the model makes these consequences explicit. By avoiding hidden entropy and implicit reseeding, the generator ensures that compromise scenarios are analyzable rather than speculative. An auditor does not need to guess whether the library refreshed itself “recently.” The code tells the story plainly.</p>
<p>In cryptography, clarity is often mistaken for weakness. In practice, it is the opposite.</p>
<h2 id="closing-thoughts" class="heading">Closing Thoughts
    <a class="heading__anchor" href="#closing-thoughts" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h2>
<p>
<a href="https://github.com/sixafter/aes-ctr-drbg" class="link-external" rel="noopener noreferrer" target="_blank">This
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 AES-CTR-DRBG implementation exists because certain systems demand more from randomness than opacity and convenience. They demand predictability, auditability, and explicit control. They demand that design choices surface in code rather than hide behind defaults.</p>
<p>If you need a general-purpose source of entropy, the standard library remains an excellent choice.</p>
<p>If you need deterministic cryptographic randomness whose behavior you can reason about—whose latency you can predict and whose state evolution you can audit—then the design presented here follows inevitably from that requirement. Once randomness is treated as state evolving over time, rather than as an oracle invoked on demand, many familiar shortcuts stop making sense. What remains is a system whose behavior is explicit, bounded, and knowable. Good architectures do not happen by accident. They emerge when constraints are taken seriously and followed to their logical conclusions—even when those conclusions lead to different constructions under different constraints.</p>
<p>This design is not theoretical; the AES-CTR-DRBG implementation described here is used as the underlying randomness source in my 
<a href="https://github.com/sixafter/nanoid" class="link-external" rel="noopener noreferrer" target="_blank">NanoID
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 library, where deterministic behavior and predictable performance are equally important.</p>
<hr>
<p>Implementation: 
<a href="https://github.com/sixafter/aes-ctr-drbg" class="link-external" rel="noopener noreferrer" target="_blank">https://github.com/sixafter/aes-ctr-drbg
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
</p>]]></content:encoded><category>computing</category><category>distributed systems</category><category>software</category></item><item><title>Optimizing Nano ID Generation in Go: Concurrency, Memory, and Precomputation Strategies</title><link>https://michaelprimeaux.com/en/posts/2024-11-12-optimizing-nano-id-generation-in-go/</link><pubDate>Thu, 07 Nov 2024 00:06:00 +0000</pubDate><author>michael@michaelprimeaux.com (Michael Primeaux)</author><guid>https://michaelprimeaux.com/en/posts/2024-11-12-optimizing-nano-id-generation-in-go/</guid><description>“All problems in computer science can be solved by another level of indirection.” — David J. Wheeler
Identifier generation is one of those concerns that quietly disappears into the background of a system. At small scale, it is effectively free. A call to a random number generator, a string conversion, and the work is done. There is little reason to revisit it, and even less reason to question its design. This holds largely because identifier generation tends to be invisible: it sits at the edges of requests, happens quickly, and rarely shows up in profiling output. When it does, it is usually dismissed as noise.</description><content:encoded><![CDATA[<blockquote><p>“All problems in computer science can be solved by another level of indirection.”
— David J. Wheeler</p>
</blockquote>
<p>Identifier generation is one of those concerns that quietly disappears into the background of a system. At small scale, it is effectively free. A call to a random number generator, a string conversion, and the work is done. There is little reason to revisit it, and even less reason to question its design. This holds largely because identifier generation tends to be invisible: it sits at the edges of requests, happens quickly, and rarely shows up in profiling output. When it does, it is usually dismissed as noise.</p>
<p>That assumption holds only as long as the surrounding system remains small. As concurrency increases and identifier generation moves onto hot paths, what was once incidental becomes part of the system’s observable behavior. Identifiers are created everywhere: at request boundaries, inside storage layers, across services that never coordinate with one another. They are infrastructure in the most literal sense—pervasive, unavoidable, and relied upon precisely because they are assumed to be cheap. When they stop being cheap, the cost is paid everywhere.</p>
<p>
<a href="https://github.com/sixafter/nanoid" class="link-external" rel="noopener noreferrer" target="_blank">NanoID
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 fits neatly into this mental model. It produces compact, URL-safe identifiers with reasonable entropy and a simple interface, and in most environments it behaves exactly as expected. It is easy to adopt and difficult to misuse, which reinforces the idea that identifier generation is a solved problem. The difficulty is not with NanoID itself, but with the way its cost profile changes when it is exercised continuously and concurrently.</p>
<p>In Go, the most direct implementation of NanoID draws randomness from <code>crypto/rand.Reader</code>. From a correctness standpoint, this is beyond reproach. The operating system provides high-quality entropy, the guarantees are well understood, and the resulting identifiers are unpredictable in exactly the ways they should be. Under light use, the cost of doing so is effectively invisible, which further entrenches the assumption that there is nothing here worth examining.</p>
<p>Under sustained concurrency, that assumption no longer holds. Each call to <code>crypto/rand</code> crosses into the kernel, sources entropy, fills a buffer, and returns. Temporary buffers are allocated and discarded. None of this is problematic in isolation, but taken together and repeated at scale, it becomes the dominant cost of identifier generation. At that point, “generating an ID” is no longer a small operation. It is a collection of system calls, allocations, and coordination that happens to terminate in a string.</p>
<p>This is not a criticism of <code>crypto/rand</code>. It is doing exactly what it is designed to do. The issue is one of proximity. Entropy acquisition and identifier construction are tightly coupled, even though they serve different purposes. Correctness requires the former. Performance becomes sensitive when it occupies the hottest path of the system.</p>
<p>Concurrency has a way of making these relationships visible. Throughput flattens earlier than expected. Latency becomes uneven. Profilers begin to attribute meaningful time to what was assumed to be trivial. In practice, the profiler does not report time spent “generating IDs”; it reports time spent in the kernel, allocation paths, and garbage collection. Identifier generation becomes visible not because it is conceptually complex, but because it is structurally misplaced.</p>
<h2 id="separating-entropy-from-generation" class="heading">Separating Entropy from Generation
    <a class="heading__anchor" href="#separating-entropy-from-generation" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h2>
<p>At that point, there are two broad directions a system can move. One is to accept the cost and design capacity around it. The other is to separate concerns that were previously implicit. The former tends to entrench friction around an otherwise unremarkable operation. The latter introduces an architectural boundary.</p>
<p>NanoID does not require fresh entropy for every identifier. What it requires is unpredictability. Those two properties are related, but they are not equivalent. Entropy must originate from a trusted source, but once acquired, it can be expanded safely using a cryptographically sound construction. There is no requirement to consult the operating system on every invocation, and doing so ties correctness to cost in a way that becomes increasingly visible under load.</p>
<p>This observation reshapes the implementation. Instead of treating identifier generation as a single indivisible operation, it becomes possible to draw a boundary between entropy acquisition and identifier construction. In practical terms, this means seeding a generator once from <code>crypto/rand</code> and then producing random bytes locally. The operating system remains the root of trust, but it no longer sits in the inner loop.</p>
<h2 id="the-shape-of-the-hot-path" class="heading">The Shape of the Hot Path
    <a class="heading__anchor" href="#the-shape-of-the-hot-path" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h2>
<p>A stream cipher such as ChaCha20 fits this role naturally. It is designed to generate large volumes of pseudorandom output from a fixed key and nonce, and its properties are well understood. Once initialized, it produces random bytes without further system interaction. Used this way, it does not replace the operating system’s entropy source; it amortizes it.</p>
<p>Each generator instance is seeded once using <code>crypto/rand</code> and then used to satisfy multiple NanoID generations. The generator itself is not shared across callers. Sharing would introduce contention and obscure the very boundary the design is trying to establish. Instead, generator instances are treated as independent state machines that can be reused opportunistically.</p>
<p>This is where <code>sync.Pool</code> becomes useful, not as a micro-optimization, but as a way to preserve locality without introducing coordination. Generator instances are pooled so that goroutines can borrow them briefly, generate the required bytes, and return them. There is no shared mutable state and no locking around generation itself. The pool exists solely to reduce repeated setup cost when reuse is inexpensive.</p>
<p>Once entropy is decoupled, other sources of variability become apparent. NanoID generation requires temporary byte buffers—first for random data, then for mapping those bytes into an alphabet. These buffers are uniform in size and short-lived. Allocating and discarding them repeatedly introduces allocation pressure that is unrelated to the semantics of identifier generation. Pooling these buffers follows the same reasoning as pooling generator state: reuse when convenient, allow reclamation when not.</p>
<p>The same discipline applies to configuration. NanoID relies on derived values such as alphabet size, bit masks, and the number of random bytes required to generate an identifier of a given length. These values do not change per call, yet they are often computed as part of the generation path. Computing them once and fixing them at construction time pushes variability outward and keeps the inner loop small and predictable. The generation path becomes a straight-line transformation from random bytes to characters, without branching or recomputation.</p>
<p>At this stage, the hot path is deliberately unremarkable. There are no system calls, no locks, and no dynamic allocation beyond the final string itself. The work performed is exactly the work required to produce an identifier, and nothing else. What remains visible in benchmarks is not overhead, but the irreducible cost of string construction in Go.</p>
<p>The effect of these changes is straightforward to measure. Allocation counts collapse to a single allocation per identifier. Latency stabilizes. Throughput scales with available CPU until saturation. More importantly, behavior becomes predictable. Identifier generation stops appearing as a source of variance and resumes its role as infrastructure.</p>
<p>An implementation of the approach described here is available as an open-source Go module, along with a small command-line tool built on top of it:</p>
<ul>
<li>
<a href="https://github.com/sixafter/nanoid" class="link-external" rel="noopener noreferrer" target="_blank">https://github.com/sixafter/nanoid
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
</li>
<li>
<a href="https://github.com/sixafter/nanoid-cli" class="link-external" rel="noopener noreferrer" target="_blank">https://github.com/sixafter/nanoid-cli
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
</li>
</ul>
<p>What does not change is the security model. Entropy still originates from the operating system. Generator state is seeded from a cryptographically secure source. Unpredictability is preserved. There is no attempt to weaken guarantees in exchange for speed. The improvement comes from respecting boundaries, not from relaxing them.</p>
<p>Identifier generation stops being trivial when it becomes infrastructure. At that point, it deserves the same architectural treatment as any other component that occupies a hot path. Once those boundaries are made explicit, the problem largely resolves itself.</p>
<p>At that point, the choice of entropy source becomes an explicit design decision rather than an incidental one. The NanoID implementation described here does not assume a single generator, nor does it require that entropy be sourced directly from the operating system on every invocation. Instead, it is structured to accept a well-defined pseudorandom generator that is seeded from a trusted source and then exercised locally.</p>
<p>For environments where throughput and steady behavior under concurrency are the primary concerns, a 
<a href="https://michaelprimeaux.com/posts/2025-12-26-prng-chacha/">ChaCha20-based</a>
 generator provides a practical balance. Seeded once from <code>crypto/rand</code>, it offers high-quality pseudorandom output with predictable performance characteristics, making it well suited for systems where identifier generation sits on a hot path and must remain invisible.</p>
<p>In environments where regulatory or compliance requirements apply, particularly those that mandate 
<a href="https://csrc.nist.gov/publications/detail/fips/140/2/final" class="link-external" rel="noopener noreferrer" target="_blank">FIPS 140-2
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 validation, an 
<a href="https://michaelprimeaux.com/posts/2025-07-20-aes-ctr-drbg/">AES-CTR-DRBG</a>
 construction becomes the appropriate choice. In that context, the same architectural separation applies: entropy is sourced from the operating system, expanded via a standards-aligned deterministic generator, and consumed locally. The difference is not architectural, but contractual—the guarantees are defined externally rather than operationally.</p>
<p>The important point is that these choices do not alter the shape of the system. Whether the generator is ChaCha20-based or an AES-CTR-DRBG, the boundary between entropy acquisition and identifier construction remains intact. The cost model is stable, the hot path is predictable, and the guarantees are explicit rather than implicit.</p>
<hr>
<p>Implementation: 
<a href="https://github.com/sixafter/nanoid" class="link-external" rel="noopener noreferrer" target="_blank">https://github.com/sixafter/nanoid
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
</p>]]></content:encoded><category>computing</category><category>distributed systems</category><category>software</category></item><item><title>Fare Collection Revenue Stream</title><link>https://michaelprimeaux.com/en/posts/2018-07-25-devops-interview-busride-magazine/</link><pubDate>Wed, 25 Jul 2018 00:06:00 +0000</pubDate><author>michael@michaelprimeaux.com (Michael Primeaux)</author><guid>https://michaelprimeaux.com/en/posts/2018-07-25-devops-interview-busride-magazine/</guid><description>I recently spoke with Richard Tackett, Editor in Chief of American trade publication BUSRide (opens in a new window) , to discuss fare collection best practices with a focus on revenue.
Originally posted on BUSRide Magazine (opens in a new window) and subsequently referenced by Vix Technology (opens in a new window) , here are my responses featured alongside other industry commentators. It shouldn&amp;rsquo;t be a surprise to anyone that DevOps and software engineering displine are fundamental when designing and constructing parallel and distributed systems at a quality level commensurate with that of commercial software.</description><content:encoded><![CDATA[<p>I recently spoke with <strong>Richard Tackett</strong>, Editor in Chief of American trade publication 
<a href="https://busride.com" class="link-external" rel="noopener noreferrer" target="_blank">BUSRide
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
, to discuss fare collection best practices with a focus on revenue.</p>
<p>Originally posted on 
<a href="https://busride.com/official-busride-roundtable-discussion-9/" class="link-external" rel="noopener noreferrer" target="_blank">BUSRide Magazine
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 and subsequently referenced by 
<a href="https://vixtechnology.com/news/busride-magazine-focus-on-fare-collection-michael-primeaux" class="link-external" rel="noopener noreferrer" target="_blank">Vix Technology
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
, here are my responses featured alongside other industry commentators. It shouldn&rsquo;t be a surprise to anyone that DevOps and software engineering displine are fundamental when designing and constructing parallel and distributed systems at a quality level commensurate with that of commercial software.</p>
<h2 id="in-what-ways-does-your-platform-enable-a-reliable-dependable-revenue-stream-throughout-its-useable-life" class="heading">In what ways does your platform enable a reliable, dependable revenue stream throughout its useable life?
    <a class="heading__anchor" href="#in-what-ways-does-your-platform-enable-a-reliable-dependable-revenue-stream-throughout-its-useable-life" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h2>
<p>Building on three generations of advanced automated fare collection (AFC) and payments solutions, the Vix solution provides an advanced platform supporting account-based ticketing, card-based ticketing, open payments and closed loop features in a single, highly configurable product. Sophisticated financial management tools, including transit clearing house capabilities, are also core capabilities, all of which can be deployed &ldquo;on premise&rdquo; within customer data centers or &ldquo;as a Service&rdquo; in a public cloud.</p>
<p>Our solution enables a reliable, dependable revenue stream throughout its usable life because, for Vix, the most important aspect of public transportation is a better journey for our customers. Our relentless focus on building a flexible, scalable, and reliable AFC and payments platform is fundamental to delivering this vision for our customers and for ensuring dependable revenue streams for agencies.</p>
<h2 id="what-best-practices-can-agencies-use-to-decrease-fare-system-deployment-times-to-maximize-benefits-and-minimize-revenue-disruption" class="heading">What best practices can agencies use to decrease fare system deployment times, to maximize benefits and minimize revenue disruption?
    <a class="heading__anchor" href="#what-best-practices-can-agencies-use-to-decrease-fare-system-deployment-times-to-maximize-benefits-and-minimize-revenue-disruption" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h2>
<p>At Vix, there are many lenses through which we measure how we deliver value to our customers: we recognize the need to reduce build, deployment, operating, and maintenance costs along one dimension whilst ensuring a repeatable and secure quality level commensurate with that of a world-class commercial solution along another dimension.</p>
<p>Full automation for forming, deploying, and upgrading all operational environments and the Vix solution is critically important in reducing overall costs, reducing the risk of human error, increasing operational efficiency, ensuring consistent quality and enable measurable compliance with security practices and governance. To this end, the Vix solution focuses on the best practice of DevOps automation as a core engineering practice across three phases to align with design, build, operations, and maintenance in support of continuous improvement.</p>
<p>Our investment in this area has resulted in vastly reduced build and deployment times. Our relentless focus in this area allows us to minimize costs for systems operations, security operations and disaster recovery scenarios while greatly reducing the timelines for our solution engagement schedules, resulting in a direct savings for our customers without the need to compromise their revenue protection and business continuity objectives.</p>
<h2 id="how-does-a-flexible-open-architecture-lend-itself-to-increased-revenue-over-time" class="heading">How does a flexible, open architecture lend itself to increased revenue over time?
    <a class="heading__anchor" href="#how-does-a-flexible-open-architecture-lend-itself-to-increased-revenue-over-time" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h2>
<p>An open architecture lends itself to increased revenue over time because the inherent standards-based design patterns and technologies fosters a wide array of integration scenarios within the surrounding and transit payments ecosystem. The APIs that come with an open architecture allow for a range of integrations to be supported as part of a fare collection system, allowing agencies to, for example, partner with coffee shops or other retail outlets to offer deals for transit riders. This provides another revenue stream for the transit agencies, as well as the partner retailers, etc.</p>
<p>However, simply supporting an open architecture isn&rsquo;t enough. Software and hardware engineering teams must possess the discipline and rigor required to produce quality, scalable, and flexible architectural patterns to support not only revenue streams that we can think of but, equally as important, with forward looking attention to market trends.</p>
<h2 id="how-can-agencies-utilize-improved-data-collection-and-analysis-to-leverage-new-revenue-streams" class="heading">How can agencies utilize improved data collection and analysis to leverage new revenue streams?
    <a class="heading__anchor" href="#how-can-agencies-utilize-improved-data-collection-and-analysis-to-leverage-new-revenue-streams" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h2>
<p>To begin to utilize improved data collection and analysis to leverage new revenue streams, agencies must first make it a priority. Analytics and the field of data science are now foundational to nearly all industries - so much so that data itself has become an important strategic and competitive asset. This data represents a rather rich taxonomy for enabling a variety of revenue opportunities for agencies to improve a rider&rsquo;s experience.</p>
<p>At Vix, our focus on a better customer journey shapes how we support agencies in the areas of analytics. The areas of analytics that are important to us, and thus to our solution, are predictive journey analytics, predictive maintenance analytics, fraud prevention, real-time passenger information, capacity and pricing optimization, customer analytics and loyalty marketing, intelligent transportation system (ITS) optimization and the co-occurrence of information from each of these areas to model how to improve the overall transit experience.</p>
<p><em>Originally posted on 
<a href="https://busride.com/official-busride-roundtable-discussion-9/" class="link-external" rel="noopener noreferrer" target="_blank">BUSRide Magazine
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
</em>.</p>]]></content:encoded><category>computing</category><category>software</category><category>observability</category></item><item><title>Test Driven Development: Mocks</title><link>https://michaelprimeaux.com/en/posts/2016-03-13-dummies-mocks-stubs-fakes/</link><pubDate>Mon, 14 Mar 2016 00:06:00 +0000</pubDate><author>michael@michaelprimeaux.com (Michael Primeaux)</author><guid>https://michaelprimeaux.com/en/posts/2016-03-13-dummies-mocks-stubs-fakes/</guid><description>The importance of dummies, mocks, stubs, and fakes is fundamental to test-driven development.</description><content:encoded><![CDATA[<p>The importance of dummies, mocks, stubs, and fakes is fundamental to test-driven development.</p>
<p>Dummy objects are passed around but never actually used. Usually, they&rsquo;re simply used to fill parameter lists.</p>
<p>Fake objects actually have working implementations, but usually take some shortcut which makes them not suitable for production (an in memory database is a good example).</p>
<p>Stubs provide answers to calls made during the test, usually not responding to anything outside what&rsquo;s programmed for the test. Stubs may also record information about calls, such as an email gateway stub that remembers the messages it &lsquo;sent&rsquo; or only how many messages it &lsquo;sent&rsquo;.</p>
<p>Mocks are what we&rsquo;re talking about here. Mocks are objects pre-programmed with expectations forming a specification of the calls they expect to receive.</p>]]></content:encoded><category>software engineering</category></item><item><title>Developer Testing</title><link>https://michaelprimeaux.com/en/posts/2016-02-22-developer-testing/</link><pubDate>Mon, 22 Feb 2016 00:06:00 +0000</pubDate><author>michael@michaelprimeaux.com (Michael Primeaux)</author><guid>https://michaelprimeaux.com/en/posts/2016-02-22-developer-testing/</guid><description>Why is it important to write automated tests? I&amp;rsquo;m asked this question far too often by software engineering teams. The usual response I receive after asking someone why they don&amp;rsquo;t write tests usually is because &amp;ldquo;I don&amp;rsquo;t have time&amp;rdquo;. Nothing could be further from the truth. In reality, valuable time is saved by writing tests first. Writing tests is an important and fundamental concept to our craft. So much so that I thought best to write about it.</description><content:encoded><![CDATA[<p>Why is it important to write automated tests? I&rsquo;m asked this question far too often by software engineering teams.  The usual response I receive after asking someone why they don&rsquo;t write tests usually is because &ldquo;I don&rsquo;t have time&rdquo;. Nothing could be further from the truth. In reality, valuable time is saved by writing tests <em>first</em>. Writing tests is an important and fundamental concept to our craft. So much so that I thought best to write about it.</p>
<p>But as with all things, first a bit of context.</p>
<h2 id="the-agile-development-methodology" class="heading">The Agile Development Methodology
    <a class="heading__anchor" href="#the-agile-development-methodology" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h2>
<p>Agile is a software development methodology that borrows from 
<a href="http://en.wikipedia.org/wiki/Scrum_%28software_development%29" class="link-external" rel="noopener noreferrer" target="_blank">Scrum
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 project management practices, 
<a href="http://en.wikipedia.org/wiki/Extreme_programming" class="link-external" rel="noopener noreferrer" target="_blank">Extreme Programming
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 (XP), and 
<a href="http://en.wikipedia.org/wiki/Test-driven_development" class="link-external" rel="noopener noreferrer" target="_blank">Test Driven Development
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 (TDD).</p>
<p>It&rsquo;s not my intention to write about Scrum, XP, and TDD in excruciating detail since there are many excellent books on these subjects. I would, however, like to share my view on why TDD is foundational to any software engineering effort.</p>
<h2 id="scrum" class="heading">Scrum
    <a class="heading__anchor" href="#scrum" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h2>
<p>As most are aware, Scrum is an iterative, incremental framework for managing complex work and though intended for management of software development projects, it can be used as a general program management approach.  Contrary to popular belief, however, Scrum is not an acronym. First used to describe hyper-productive development in 1987 by 
<a href="http://en.wikipedia.org/wiki/Ikujiro_Nonaka" class="link-external" rel="noopener noreferrer" target="_blank">Ikujiro Nonaka
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 and 
<a href="http://en.wikipedia.org/wiki/Hirotaka_Takeuchi" class="link-external" rel="noopener noreferrer" target="_blank">Hirotaka Takeuchi
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
, Scrum actually refers to the mechanism used in rugby for getting an out-of-play ball back into play.</p>
<p>Many software engineering teams still practice the Waterfall development methodology and for some projects &ndash; in particular when requirements are static and rarely change &ndash; it&rsquo;s an appropriate practice. The building of a jet propulsion engine is a good example of a project that likely benefits from the Waterfall development methodology. In contrast, Scrum&rsquo;s two pillars are team empowerment and adaptability:</p>
<ol>
<li>
<p>Team empowerment: Once teams are given work to do, they are responsible for figuring out how to do it. The team does the best it can during each iteration. While a team works, their only interaction with management is to tell management what is getting in their way and needs to be removed to improve their productivity.</p>
</li>
<li>
<p>Adaptability: Scrum uses &ldquo;punctuated equilibrium&rdquo;. The team maintains an equilibrium during each iteration, insulated from outside disturbance. Iteration are generally punctuated every thirty days so that the team and management can evaluate what should be done during the next iteration; this decision is based on what the team has accomplished and what the environment dictates is the next most important thing to do.</p>
</li>
</ol>
<h3 id="velocity" class="heading">Velocity
    <a class="heading__anchor" href="#velocity" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h3>
<p>It&rsquo;s difficult to discuss the importance of writing tests without first discussing the notion of velocity and while I could write a dissertation just on the notion of velocity, it is simply defined as how many story points of effort a team can <em>complete</em> in a single iteration. Once established, velocity can be used to plan projects and forecast release and product completion dates. A team&rsquo;s velocity is an important key performance indicator.</p>
<h2 id="extreme-programming" class="heading">eXtreme Programming
    <a class="heading__anchor" href="#extreme-programming" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h2>
<p>From XP, we borrow pair programming and continuous integration. Code reviews are good so let’s do them all the time; this is pair programming. Measuring code quality and ensuring a source level change didn’t cause any regressions is good so let’s do it as often as possible; continuous integration.</p>
<p>It should be no surprise that writing automated tests and measuring code coverage go hand-in-hand with continuous integration.</p>
<h2 id="test-driven-development" class="heading">Test-Driven Development
    <a class="heading__anchor" href="#test-driven-development" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h2>
<p>For any particular software engineering effort, there are three axes to control: quality, schedule, and scope. Quality remains locked at “high” and so the engineering team must choose how to balance the remaining two.</p>

<blockquote><p>Clean code that works&hellip;now. This is the seeming contradiction that lies behind much of the pain of programming. Test driven development replies to this contradiction with a paradox &ndash; test the program before you write it.</p>
<ul>
<li>Test Driven Development: By Example, 2002</li>
</ul>
</blockquote>
<p>Regardless of your development methodology, writing tests are important. Automated testing underpins many Agile practices, most significantly as part of 
<a href="http://en.wikipedia.org/wiki/Continuous_integration" class="link-external" rel="noopener noreferrer" target="_blank">Continuous Integration
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
.  TDD is a process by which the tests are written <em>before</em> the code itself. Through a rapid cycle of adding new tests, making them pass, and then refactoring to clean code, the software design evolves through the tests.</p>
<h3 id="red-green-refactor" class="heading">Red, Green, Refactor
    <a class="heading__anchor" href="#red-green-refactor" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h3>
<p>When a test is first written, it most likely won&rsquo;t even compile - the implementation hasn&rsquo;t been written. Modern IDEs allow a developer to rapidly create code and then refactor it into shape. After adding a test, a developer strives to reach a &ldquo;green bar&rdquo; (all tests passing) as quickly as possible, and then refactors backed up by the safety of the tests. This quickly becomes a cycle of &ldquo;red, green, refactor&rdquo;, adding a kind of rhythm to the development process. When a new feature is required, tests are added, code is written to make the tests pass, and finally refactoring removes any duplication.</p>
<h2 id="benefits-of-writing-tests" class="heading">Benefits of Writing Tests
    <a class="heading__anchor" href="#benefits-of-writing-tests" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h2>
<p>Whether your project is open source, commercial, or corporate, there are clear and important advantages to writing automated tests.</p>
<ol>
<li><strong>Courage</strong>. Writing tests allows one to move from a state of uncertainty to that of courage. When you write tests, you know the state of the your code. Intimately.  You know if your code works or if it doesn’t. You know if your old code, and the code of your colleagues works as expected.</li>
<li><strong>Communication</strong>. Tests can also be used for communication. This works well to communicate what the software does.  We all may not know how to speak the same language but as a member of a particular software engineering team, we all know how to communicate using a specific programming language. We all can read and write code with good clarity.</li>
<li><strong>Documentation</strong>. Beyond shore-to-shore communication, tests also make a good candidate to use as examples in documentation and in comments.</li>
<li><strong>Refactoring</strong>.  Setting your minimum allowable test coverage percentage to a respectable number (90 percent and greater) allows you to refactor your source code with confidence. Use cases pivot. You refactor the code. Then simply make all failing tests pass again.</li>
<li><strong>Design</strong>. Writing tests <em>first</em> leads to a better design.
<ol>
<li>It forces you to think about the shape of your API up front; to really understand how your consumer uses the API before you spend valuable time writing the implementation.</li>
<li>It allows you to understand any possible frustrations and complexities with the shape of your API before your consumer.</li>
<li>It saves time by ensuring the API satisfies your design goals and <em>nothing</em> more.</li>
</ol>
</li>
</ol>
<p>All of these points are critical to a team&rsquo;s velocity.</p>
<h2 id="rules-of-engagement" class="heading">Rules of Engagement
    <a class="heading__anchor" href="#rules-of-engagement" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h2>
<p>The keywords MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD, SHOULD NOT, RECOMMENDED, MAY and OPTIONAL, when they appear in this document, are to be interpreted as described in 
<a href="http://datatracker.ietf.org/doc/rfc2119/" class="link-external" rel="noopener noreferrer" target="_blank">RFC-2119
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
.</p>
<p>In the end, automated tests are just code. Even with best intentions, they can be written incorrectly and contain bugs. Here are a few rules to consider.</p>
<ol>
<li>Keep unit tests small and fast. Ideally the entire test suite SHOULD be executed before every code check in. Keeping the tests fast reduce the development turnaround time.</li>
<li>Tests MUST be fully automated and non-interactive.</li>
<li>Keep tests independent. To ensure testing robustness and simplify maintenance, tests SHALL NOT rely on other tests and SHALL NOT depend on the order in which other tests are executed.</li>
<li>A test MUST leave the environment exactly as it was before execution began. This is an extremely important point since test execution order is never guaranteed and so environmental changes may cause sporadic test failures, which can waste precious time.</li>
<li>A test MUST contain at least one assertion.</li>
<li>A test MUST contain 3 logical sections: arrange, act, and assert.</li>
<li>A test MUST cover boundary cases.</li>
<li>A test fixture MUST provide negative tests. Negative tests intentionally misuse the code and verify robustness and appropriate error handling.</li>
<li>Write tests to reproduce bugs. When a bug is reported, write a test to reproduce the bug (i.e. a failing test) and use this test as success criteria when fixing the code.</li>
<li>Conduct peer 
<a href="http://en.wikipedia.org/wiki/Code_review" class="link-external" rel="noopener noreferrer" target="_blank">code reviews
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 on all tests.</li>
</ol>
<p>Regarding bullet 6, William C. Wake 
<a href="http://c2.com/cgi/wiki?ArrangeActAssert" class="link-external" rel="noopener noreferrer" target="_blank">wrote about
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 using the &ldquo;arrange, act, assert&rdquo; pattern in 2003.  Here&rsquo;s a summary:</p>
<ul>
<li><strong>Arrange</strong>: What is being set up and initialized is contained in the arrange section.</li>
<li><strong>Act</strong>: What method is being executed is contained in the act section</li>
<li><strong>Assert</strong>: What determines the outcome of the test is in the the assert section.</li>
</ul>
<p>I&rsquo;ll write about dummies, mocks, stubs, and fakes in a future post.</p>
<h2 id="conclusion" class="heading">Conclusion
    <a class="heading__anchor" href="#conclusion" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h2>
<p>With test-driven development, robust code is delivered along with a comprehensive suite of tests, allowing developers to make future changes with confidence.  I firmly believe that unless you&rsquo;ve been a contributing member of a software team responsible for a complex code base that it may be difficult to appreciate the critical importance of having a suite of automated unit, integration, and story tests.</p>
<p>Move away from a position of uncertainty to one of confidence. Write tests.</p>]]></content:encoded><category>software engineering</category></item><item><title>A Healthy Lifestyle: Part 2</title><link>https://michaelprimeaux.com/en/posts/2014-02-02-a-healthy-lifestyle-part-2/</link><pubDate>Sun, 02 Feb 2014 00:06:00 +0000</pubDate><author>michael@michaelprimeaux.com (Michael Primeaux)</author><guid>https://michaelprimeaux.com/en/posts/2014-02-02-a-healthy-lifestyle-part-2/</guid><description>A year ago today, I posted an article describing my decision to raise the priority of a healthy lifestyle.
Last year was very busy for me professionally. I decided very early that in order to become healthier, I needed to design my workout schedule and nutritional plan with efficiency in mind. The fundamental areas of physical health are nutrition and exercise. The purpose of this post is simply to share my thoughts on what I&amp;rsquo;ve learned over the past year with respect to nutrition.</description><content:encoded><![CDATA[<p>A year ago today, I posted an 
<a href="/posts/2013-02-02-a-healthy-lifestyle-part-1/">article</a>
 describing my decision to raise the priority of a healthy lifestyle.</p>
<p>Last year was very busy for me professionally. I decided very early that in order to become healthier, I needed to design my workout schedule and nutritional plan with efficiency in mind. The fundamental areas of physical health are nutrition and exercise. The purpose of this post is simply to share my thoughts on what I&rsquo;ve learned over the past year with respect to nutrition.</p>
<h1 id="nutrition" class="heading">Nutrition
</h1>
<p>You are what you eat. It&rsquo;s that simple. The cornerstone of becoming healthier is consuming nutrients that aid in a strong immune system, muscle recovery, vital organ functioning, and a reduction of gynoid and android (visceral) fat. The production of visceral fat is your body&rsquo;s survival strategy as a result of the internal organs insulating themselves from toxins by encapsulating the toxins in fat.</p>
<p>I&rsquo;ll first provide a bit of basic background information on foods that I&rsquo;ve decided to incorporate into my daily routine and end with two of my favorite health smoothie recipes.</p>
<p><strong>Orange Juice:</strong></p>
<p>Usually, orange juice and almond milk are the base liquids of my smoothie. Orange juice 
<a href="http://www.ncbi.nlm.nih.gov/pubmed/11063434" class="link-external" rel="noopener noreferrer" target="_blank">increases HDL significantly
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
. I use 
<a href="https://www.coca-cola.com/us/en/brands/simply" class="link-external" rel="noopener noreferrer" target="_blank">Simply Orange
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
, which you can purchase from most any grocer.</p>
<p><strong>Greek Yogurt:</strong></p>
<p>I add yogurt to my smoothies for protein, flavor, and the 
<a href="http://www.webmd.com/digestive-disorders/tc/probiotics-topic-overview" class="link-external" rel="noopener noreferrer" target="_blank">probiotics
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
. I used to use regular yogurt but switched to Greek yogurt because the amount of protein in Greek yogurt is much higher.</p>
<p><strong>Almond Milk:</strong></p>
<p>Almond milk is especially beneficial to our health. For starters, it&rsquo;s filled with vitamin D, which is known to improve cell function and immunity, and this has also been proven that it can help decrease the risk of Alzheimer’s.</p>
<p>Sources: The Science of Eating: Benefits of Almond Milk 
<a href="http://thescienceofeating.com/proteins/benefits-of-almond-milk/" class="link-external" rel="noopener noreferrer" target="_blank">URL
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
</p>
<p><strong>Flaxseed Oil:</strong></p>
<p>Flaxseed oil contains alpha-linolenic acid (
<a href="http://en.wikipedia.org/wiki/Alpha-linolenic_acid" class="link-external" rel="noopener noreferrer" target="_blank">ALA
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
), which is converted by the body into EPA and DHA, the same omega-3 fatty acids found in fish oil. I do also take a fish oil pill once daily before bed but I like getting the additional fatty acids in the smoothie. I use 
<a href="http://www.spectrumorganics.com/?id=59" class="link-external" rel="noopener noreferrer" target="_blank">Spectrum Organic Flaxseed Oil
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 from Whole Foods.</p>
<p><strong>Protein Powder:</strong></p>
<p>The types of protein used in protein powders can be divided into two categories: animal source proteins and vegetable source proteins. Animal source proteins include milk protein derivatives like whey and casein, goat&rsquo;s milk and egg white protein. Vegetable source proteins include soy, rice, pea and hemp proteins. Nutritionally animal proteins are superior to vegetable proteins. Of the animal protein types, the most popular is whey protein. Of the vegetable protein types, soy is the most popular. Most people using vegetable protein powders do so as part of a vegetarian or vegan lifestyle, although many people use soy protein primarily for its heart-health and/or hormone-balancing benefits.</p>
<p>Whey protein is derived from milk. The protein portion of whole milk consists of 20% whey protein and 80% casein protein. Whey is by far the most popular type of protein used in protein powders. For most people, it’s the best all-around choice in terms of taste (it’s one of the best-tasting), quality (it’s the highest) and cost (it’s the most economical). Another unique benefit of whey protein, and one that is often overlooked, is that it enhances the immune system in several ways.</p>
<p>Whey protein comes in two varieties; whey concentrate and whey isolate. The advantages of each are:</p>
<ul>
<li><strong>Whey Concentrate</strong>. Whey concentrate is more economical per gram of protein. It has a low lactose level that is well tolerated by most lactose-sensitive people. It has trivial amounts of fat and carbs relative to your overall nutrient intake.</li>
<li><strong>Whey Isolate</strong>. Whey isolate is virtually fat-free for those wishing to eliminate as much fat from their diet as possible. It is typically lactose free for those few individuals who are very sensitive to the low-lactose levels found in whey concentrate. Whey isolate tends to taste slightly better than whey concentrate, yet its consistency is a little thinner, without the fat.</li>
</ul>
<p>My choice in protein is 
<a href="https://jayrobb.com/pages/protein-page" class="link-external" rel="noopener noreferrer" target="_blank">Jay Robb whey protein
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
, which is a 
<a href="http://www.non-gmoreport.com/whatisnon-gmo.php" class="link-external" rel="noopener noreferrer" target="_blank">non-GMO
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 whey protein isolate powder that delivers 25 grams of first class protein, 0-fat, 0-cholesterol, 0-sugars, and only 1 gram of carbohydrate per 30 gram serving.</p>
<p><strong>Green Tea:</strong></p>
<p>Green tea has special antioxidants called catechins which appear to have 
<a href="http://www.webmd.com/food-recipes/features/health-benefits-of-green-tea" class="link-external" rel="noopener noreferrer" target="_blank">many health benefits
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
. Rather than sip endless cups of green tea throughout the day, I add a single teaspoon of green tea powder called 
<a href="http://en.wikipedia.org/wiki/Matcha" class="link-external" rel="noopener noreferrer" target="_blank">matcha
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
.  I use 
<a href="http://domatcha.com/product/" class="link-external" rel="noopener noreferrer" target="_blank">organic ceremonial matcha
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 from DoMatcha.</p>
<p><strong>Kale:</strong></p>
<p>Kale&rsquo;s 
<a href="https://www.healthline.com/nutrition/10-proven-benefits-of-kale" class="link-external" rel="noopener noreferrer" target="_blank">health benefits
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 are incredible.</p>
<p><strong>Raw Honey:</strong></p>
<p>Raw honey is honey that has not been heated, pasteurized or processed in any manner. The differences between raw and pasteurized honey are substantial. Raw honey has anti-viral, anti-bacterial, and anti-fungal properties. It promotes body and digestive health, is a powerful antioxidant, and strengthens the immune system.</p>
<p><strong>Cacao Nibs:</strong></p>
<p>Cacao nibs are cacao beans that have been roasted, separated from their husks, and broken into smaller pieces.   Think of cacao nibs as having the benefits of chocolate but without all the sugar and fat and other non-beneficial disadvantages of chocolate.</p>
<p>Sources:</p>
<ul>
<li>Live Super Foods. 
<a href="http://livesuperfoods.com/raw-cacao-nibs.html" class="link-external" rel="noopener noreferrer" target="_blank">URI
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
.</li>
<li>Natural News 
<a href="http://www.naturalnews.com/022610_cacao_chocolate_raw.html" class="link-external" rel="noopener noreferrer" target="_blank">URI
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
.</li>
<li>Huffington Post. 
<a href="http://www.huffingtonpost.ca/2013/08/02/cacao-nibs_n_3695571.html" class="link-external" rel="noopener noreferrer" target="_blank">URI
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
.</li>
</ul>
<p><strong>Vietnamese Cinnamon:</strong></p>
<p>The health benefits are quite 
<a href="http://www.healthdiaries.com/eatthis/10-health-benefits-of-cinnamon.html" class="link-external" rel="noopener noreferrer" target="_blank">impressive
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
. The most health beneficial harvest is organic Vietnamese &ldquo;Saigon&rdquo; Cassia Cinnamon, which I order from 
<a href="http://www.thespicehouse.com/spices/organic-ground-vietnamese-saigon-cassia-cinnamon" class="link-external" rel="noopener noreferrer" target="_blank">The Spice House
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
.</p>
<p><strong>Coconut Oil:</strong></p>
<p>Nearly 50 percent of the fat in coconut oil is of a type rarely found in nature called lauric acid, a &ldquo;miracle&rdquo; compound because of its unique health promoting properties. Your body converts lauric acid into monolaurin, which has anti-viral, anti-bacterial and anti-protozoa properties. More excellent information can be found 
<a href="http://www.huffingtonpost.com/dr-mercola/coconut-oil-benefits_b_821453.html" class="link-external" rel="noopener noreferrer" target="_blank">here
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
.</p>
<p>I prefer 
<a href="http://www.amazon.com/Natures-Way-Coconut-Oil-32-Ounce/dp/B003OGKCDC" class="link-external" rel="noopener noreferrer" target="_blank">Nature&rsquo;s Way Organic Coconut Oil
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
.</p>
<p><strong>Sunflower Lecithin:</strong></p>
<p>Sunflower lecithin is a type of phospholipid abundant in sunflower seeds that supports healthy brain function and nervous system.</p>
<p>Source: Real Raw Food 
<a href="http://realrawfood.com/sunflower-lecithin-health-benefits" class="link-external" rel="noopener noreferrer" target="_blank">URI
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
</p>
<h1 id="a-few-healthy-smoothies" class="heading">A Few Healthy Smoothies&hellip;
</h1>
<p>After a bit of refinement of smoothie recipes over the past year, I&rsquo;ve settled on two of my favorite ones that I have for breakfast and post-workout recovery.</p>
<p><strong>Breakfast Smoothie:</strong></p>
<ul>
<li>250 ml organic, unsweetended almond milk</li>
<li>1 Tbsp Flaxseed oil</li>
<li>1 Tbsp raw organic honey</li>
<li>1/2 cup organic, non-fat greek yogurt</li>
<li>1 scoop Jay Robb whey protein</li>
<li>1 tsp organic 
<a href="http://domatcha.com/health/" class="link-external" rel="noopener noreferrer" target="_blank">DoMacha
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
</li>
<li>1 to 2 cups of mixed berries. Strawberries, blackberries, blueberries, etc.</li>
<li>3 cups fresh organic Kale</li>
<li>1 cup fresh organic Spinach</li>
<li>Approximately 10 to 16 ice cubes</li>
</ul>
<p>Add the ingredients in the order listed and blend well. This recipe makes approximately 32 oz. of smoothie.</p>
<p><strong>Post-Workout Smoothie:</strong></p>
<ul>
<li>250 ml organic, unsweetended almond milk</li>
<li>1 Tbsp Flaxseed oil</li>
<li>1 Tbsp raw organic honey</li>
<li>1/2 cup organic, non-fat greek yogurt</li>
<li>1 scoop Jay Robb whey protein</li>
<li>1/2 cup Cacao nibs, organic.</li>
<li>1 tsp Vietnamese &ldquo;Saigon&rdquo; Cassia Cinnamon, organic.</li>
<li>1 frozen Banana, organic</li>
<li>1 Tbsp Coconut oil, organic.</li>
<li>1 Tbsp fresh ground almond butter, organic</li>
<li>Approximately 10 to 12 ice cubes</li>
</ul>
<p>Add the ingredients in the order listed and blend well. This recipe makes approximately 24 oz. of smoothie.</p>
<h1 id="paleolithic" class="heading">Paleolithic
</h1>
<p>On a related note, I began to focus on a Paleolithic nutritional plan, which is a nutritional plan based on the presumed diet of Paleolithic humans. It is based on the premise that human genetics have scarcely changed since the dawn of agriculture, which marked the end of the Paleolithic era, around 15,000 years ago, and that modern humans are adapted to the Paleolithic diet.</p>
<p>The Paleolithic diet consists mainly of fish, grass-fed pasture raised meats, eggs, vegetables, fruit, fungi, roots, and nuts, and excludes grains, legumes, dairy products, potatoes, refined salt, refined sugar, and processed oils.</p>
<p>Though my next post is focused on exercise, I&rsquo;ll certainly touch on my experiences with a Paleolithic nutritional plan and how I think it&rsquo;s worked with my my overall CrossFit routine and corresponding recovery cycle at 
<a href="http://www.thefoundrychicago.com" class="link-external" rel="noopener noreferrer" target="_blank">The Foundry
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
.</p>]]></content:encoded><category>wellness</category></item><item><title>The Convergence of Mobile, Cloud, Social, and Big Data</title><link>https://michaelprimeaux.com/en/posts/2013-05-29-mobile-cloud-social-big-data/</link><pubDate>Thu, 30 May 2013 00:06:00 +0000</pubDate><author>michael@michaelprimeaux.com (Michael Primeaux)</author><guid>https://michaelprimeaux.com/en/posts/2013-05-29-mobile-cloud-social-big-data/</guid><description>There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult. &amp;ndash; C.A.R. Hoare</description><content:encoded><![CDATA[<blockquote><p>There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult. &ndash; C.A.R. Hoare</p>
</blockquote>
<p>Mobile, cloud, social, and non-relational storage technologies (big data) represent agility for many businesses. In particular, the convergence of these technologies equip businesses with efficient methods to attribute key performance indicators, optimize direction, and, equally as important, allocate changes in business processes; all in real-time and for a vast array of incoming data formats.  Individually, each of these technology areas are immense and yet are enablers for each other; and so in early 2008, I began to focus my attention, application of algorithms, and research to the convergence of these technologies.</p>
<p>The technology shifts created by mobile, cloud, social, and big data have changed and are drastically changing the business landscape. The convergence of these technologies began years ago and has matured considerably since 2008. Social media has contributed to this significantly. 
<a href="http://research.google.com/archive/bigtable.html" class="link-external" rel="noopener noreferrer" target="_blank">Big Table
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 and, subsequently, 
<a href="http://hbase.apache.org" class="link-external" rel="noopener noreferrer" target="_blank">HBase
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 was born out of need within Google and the open source community, respectively. The Apache 
<a href="http://cassandra.apache.org" class="link-external" rel="noopener noreferrer" target="_blank">Cassandra
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 project was born out of need within Facebook. We’re able to learn interesting statistics like the half-life of links shared on Twitter is approximately 2.8 hours, sports stories spread the fastest of any topics, and there’s a material difference between what people <em>share</em> and what they <em>click</em>.  From a sales and marketing perspective, we can use big data to better leverage social channels to rapidly detect changes in buyer activities and preferences, identify market shifts, monitor competitive activity, and identify opportunities for your business. Social media is analyzed to understand behavior, although it’s important to remember as with all population sampling, it only provides a specialized <em>subset</em> of opinions about a particular topic.</p>
<h2 id="big-data-and-analytics" class="heading">Big Data and Analytics
    <a class="heading__anchor" href="#big-data-and-analytics" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h2>
<p>Big Data is primarily classified by the use of non-relational durable storage solutions that embrace the following characteristics of information technology.</p>
<ul>
<li><strong>Volume</strong>. As of 2012, about 2.5 exabytes of data are created each day, and that number is doubling every 40 months or so. More data cross the internet every second than were stored in the entire internet just 20 years ago. For example, it is estimated that Wal Mart collects more than 2.5 
<a href="http://en.wikipedia.org/wiki/Petabyte" class="link-external" rel="noopener noreferrer" target="_blank">petabytes
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 of data every hour from its customer transactions.</li>
<li><strong>Velocity</strong>. For many applications, the speed of data creation is more important than the volume. Real-time or nearly real time information makes it possible for a company to be much more agile than its competitors. Just consider the speed at which information is collected from the sheer number of active mobile devices each and every day.</li>
<li><strong>Variety</strong>. Information now flows from a plethora of sources in the form of messages, updates, and images from social networks; electronic communication; instrumented machinery; readings from sensors; GPS signals from mobile phones; point of sale terminals; and so on. Structured databases are not well suited to storing and processing information from these disparate sources.</li>
</ul>
<p>&hellip;and it’s only becoming even more challenging. Each and every day, three times per second, we produce the equivalent of the amount of data that the Library of Congress has in its entire print collection. Most of the data produced is irrelevant noise. Clearly, the challenge is in filtering this noise and distilling the remaining information into meaningful results. This vast amount of information is essentially useless without analytics. Timely analytics. Accurate analytics. Technical solutions in this space must be able to traverse multiple data centers, the cloud, and geographical zones. Accurate, real-time analysis affords us an opportunity to answer crucial business questions by those wanting to confidently pivot in response to key performance indicators (KPI).</p>
<p>Before you delve into the non-relational storage arena, it’s important to understand the 
<a href="http://lpd.epfl.ch/sgilbert/pubs/BrewersConjecture-SigAct.pdf" class="link-external" rel="noopener noreferrer" target="_blank">CAP theorem
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
.  The theorem began as a conjecture made by University of California, Berkeley computer scientist 
<a href="http://en.wikipedia.org/wiki/Eric_Brewer_%28scientist%29" class="link-external" rel="noopener noreferrer" target="_blank">Eric Brewer
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 at the 2000 Symposium on Principles of Distributed Computing (PODC). In 2002, Seth Gilbert and Nancy Lynch of 
<a href="http://www.mit.edu" class="link-external" rel="noopener noreferrer" target="_blank">MIT
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 published a formal proof of Brewer&rsquo;s conjecture, rendering it a theorem.</p>
<p>Formally, in theoretical computer science, the CAP theorem states that it is impossible for a distributed computer system to simultaneously satisfy all three of the following characteristics:</p>
<ol>
<li><strong>Consistency</strong>. All nodes possess the same data at the same time.</li>
<li><strong>Availability</strong>. A guarantee the system is available at all times to fully operate.</li>
<li><strong>Partition tolerance</strong>. The system continues to operate despite arbitrary message loss or failure of part of the system.</li>
</ol>
<p>In May 2012, 
<a href="http://www.infoq.com/articles/cap-twelve-years-later-how-the-rules-have-changed" class="link-external" rel="noopener noreferrer" target="_blank">Brewer clarified some of his positions
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 on why the oft-used &ldquo;two out of three&rdquo; concept can be misleading or misapplied.</p>
<p>Broadly speaking, durable storage technologies are divided into two innate categories: relational and non-relational.  Relational databases have been widely used for the past 40 years and are still quite widely used today. Microsoft SQL Server,  IBM DB2, Oracle, and MySQL are all examples of relational database implementations. Suffice it to say most non-relational database system architectures favor partition tolerance and availability over strong consistency.  Other implementations such as 
<a href="http://cassandra.apache.org" class="link-external" rel="noopener noreferrer" target="_blank">Cassandra
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 offer per-operation control over which two characteristics of the  CAP theorem you would like to favor. My favorite distribution of Cassandra is 
<a href="http://www.datastax.com" class="link-external" rel="noopener noreferrer" target="_blank">DataStax
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
, which combines Cassandra, 
<a href="http://hadoop.apache.org" class="link-external" rel="noopener noreferrer" target="_blank">Hadoop
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
, and 
<a href="http://lucene.apache.org/solr/" class="link-external" rel="noopener noreferrer" target="_blank">SOLR
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 into a single packaged distribution. Their 
<a href="http://www.datastax.com/what-we-offer/products-services/datastax-enterprise" class="link-external" rel="noopener noreferrer" target="_blank">enterprise edition
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 is free to developers, which is convenient.</p>
<p>With respect to non-relational databases, one must consider a few orientations.</p>
<ul>
<li><strong>Object</strong>. Object databases work to void object-relational impedance mismatch that occurs when trying to use a relational database under an application written in an object-oriented programming language. These databases store information in terms of the object themselves and not in terms of columns and rows.</li>
<li><strong>XML</strong>. XML databases are optimized specifically for working with XML and are, essentially, a special form of a document-oriented database. XML databases have one core function: to allow for efficient storage and query of XML documents. Examples of XML databases are 
<a href="http://www.softwareag.com/corporate/products/wm/tamino/default.asp" class="link-external" rel="noopener noreferrer" target="_blank">Tamino
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 (Software AG), 
<a href="http://exist-db.org" class="link-external" rel="noopener noreferrer" target="_blank">eXist
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
, 
<a href="http://www.oracle.com/technetwork/products/berkeleydb/overview/index.html" class="link-external" rel="noopener noreferrer" target="_blank">Berkeley XML DB
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 (Oracle), 
<a href="http://www.marklogic.com" class="link-external" rel="noopener noreferrer" target="_blank">MarkLogic
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 Server, and 
<a href="http://www.sedna.org" class="link-external" rel="noopener noreferrer" target="_blank">Sedna
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
.</li>
<li><strong>Document</strong>.  The basic unit or storage for a document database is a complete document. 
<a href="http://couchdb.apache.org" class="link-external" rel="noopener noreferrer" target="_blank">CouchDB
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 and 
<a href="http://www.mongodb.org" class="link-external" rel="noopener noreferrer" target="_blank">MongoDB
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 are examples of document databases. This storage model offers several key advantages over a relational model:
<ul>
<li>A document can store any number of fields of any length, and each field can store multiple values. A relational model requires all fields to be present for every record.</li>
<li>An empty (or null) value (and the related field) does not need to be stored, which can save space. On a related note, many relational databases currently offer support for sparse tables.</li>
<li>Full text search capabilities are typically an intrinsic feature.</li>
<li>Security can be assigned at an individual document level.</li>
<li>A predefined schema is not required whereas a relational database does require schema to be defined in advance of performing any storage or retrieval operation.</li>
</ul>
</li>
<li><strong>Key-Value</strong>. A key/value database stores values based on keys and are classically represented as a Distributed Hashtable (DHT). In a relational model, we tend to first consider the tables that our domain requires, then think of how we can normalize the tables to avoid duplicate data. In a key-value store, however, typically we don’t define a schema. Examples of key-value databases are 
<a href="http://www.mongodb.org" class="link-external" rel="noopener noreferrer" target="_blank">MongoDB
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
, 
<a href="http://redis.io" class="link-external" rel="noopener noreferrer" target="_blank">Redis
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
, Amazon 
<a href="http://aws.amazon.com/dynamodb/" class="link-external" rel="noopener noreferrer" target="_blank">Dynamo
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
, and 
<a href="http://www.project-voldemort.com" class="link-external" rel="noopener noreferrer" target="_blank">Project Voldemort
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
.</li>
<li><strong>Graph</strong>. Graph databases differ from other non-relational database offerings (such as key-value stores) in that they represent the <em>edge</em> intrinsically. Instead of tables and columns, a graph database uses three basic constructs to represent data: nodes, edges, and properties. A <em>node</em> is a standalone, independent object. An <em>edge</em> is an object that depends on the existence of two nodes. <em>Properties</em> represent attributes of a node. Examples of graph databases are 
<a href="http://en.wikipedia.org/wiki/FlockDB" class="link-external" rel="noopener noreferrer" target="_blank">FlockDB
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 (open sourced by Twitter in April 2010) and 
<a href="http://www.neo4j.org" class="link-external" rel="noopener noreferrer" target="_blank">Neo4J
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
.</li>
<li><strong>Columnar</strong>. A columnar database organizes data around columns instead of rows. This subtle difference optimizes some workloads—in particular, data warehouse and analytics applications that require computing aggregate values over very large sets of data—for certain kinds of problems. Databases that follow this orientation represent distributed hash tables (
<a href="http://michaelprimeaux.com/blog/2007/06/04/peer-to-peer-p2p/">DHTs</a>
). Examples of columnar databases are 
<a href="http://cassandra.apache.org" class="link-external" rel="noopener noreferrer" target="_blank">Cassandra
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
, Google 
<a href="http://research.google.com/archive/bigtable.html" class="link-external" rel="noopener noreferrer" target="_blank">Bigtable
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
, 
<a href="http://hbase.apache.org" class="link-external" rel="noopener noreferrer" target="_blank">HBase
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
, and 
<a href="http://hypertable.org" class="link-external" rel="noopener noreferrer" target="_blank">Hypertable
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
.</li>
</ul>
<p>It’s worth noting, a few databases exist that represent hybrid orientation implementations; for example, 
<a href="http://basho.com/riak/" class="link-external" rel="noopener noreferrer" target="_blank">Riak
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 is a hybrid implementation based on Amazon’s Dynamo in that it is both a document-oriented and key-value implementation.</p>
<p>Though, just as with relational databases, planning is key when thinking about launching a non-relational database project.  Non-relational database projects require a slightly different software engineering approach. In a relational model, we tend to consider our data model first and then we build queries to satisfy application requirements. Even though a database may be schema-less, in a non-relational model we 
<a href="http://tools.ietf.org/html/rfc2119" class="link-external" rel="noopener noreferrer" target="_blank">MUST
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 first understand an application’s queries as a starting point since that influences database and table layout.</p>
<p>Even companies with a large investment in relational-based analytics tools can leverage non-relational storage technologies but even so, the definition of a taxonomy (or multiple taxonomies) for analytics processing is of paramount importance.  Typically, companies that are heavily invested in relational technology as their primary systems of record employ extract transform and load (ETL) processes to periodically restructure information based on defined taxonomies into non-relational storage products so they are able to take advantage of more efficient and real-time processing using massively parallel analytics technologies such as Hadoop and Map Reduce.</p>
<p>Capturing data without analytics in mind from a business’ point of view is generally moot. Consider the goals, and what key data sets are needed to reach those goals. More important is to consider the set of business questions you are attempting to answer and, to that point, I strongly recommend you bring in a data scientist to perform an audit of an existing data architecture.</p>
<h2 id="mobile" class="heading">Mobile
    <a class="heading__anchor" href="#mobile" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h2>
<p>Business-to-consumer (B2C) mobile applications impose different requirements than that of business-to-business (B2B) and corporate applications not only in terms of marketing but in terms of the requirement for an extremely efficient and aesthetically pleasant user experience (UX) and more stringent software engineering practices.  It’s very difficult to recover from poor reviews and customer feedback.</p>
<p>In the mobile space, three companies represent the majority globally: Apple, Google, and Microsoft. Apple and Google make up 96% of the entire mobile space. Microsoft is less than 1% with the remaining (just over 3%) still on others such as RIM, Symbian, etc. If we add tablets to the equation (so now not just mobile phones) then as of April 2013 Apple iOS represents 59.04%, Google Android represents 26.02%, and Microsoft Windows Phone represents 1.14%; see 
<a href="http://www.netmarketshare.com/mobile-market-share" class="link-external" rel="noopener noreferrer" target="_blank">Net Marketshare
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
.</p>
<p>Across all mobile operating systems, if you observe how people use smartphones and look beyond telephone calls, email, and texting then you&rsquo;ll see that native applications dominate. Users spend on average, 82% of their mobile minutes with native applications and 18% with web browsers. They download approximately 50 to 75 applications to their phones (out of more than a million available) but regularly use about 10.</p>
<p>As another data point, mobile applications broadly fall into six categories:</p>
<ol>
<li>Games and Entertainment</li>
<li>Social Networks (
<a href="http://facebook.com" class="link-external" rel="noopener noreferrer" target="_blank">FaceBook
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
, 
<a href="http://twitter.com" class="link-external" rel="noopener noreferrer" target="_blank">Twitter
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
, 
<a href="http://pinterest.com" class="link-external" rel="noopener noreferrer" target="_blank">Pinterest
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
, 
<a href="http://path.com" class="link-external" rel="noopener noreferrer" target="_blank">Path
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
, 
<a href="http://tumblr.com" class="link-external" rel="noopener noreferrer" target="_blank">Tumblr
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
, etc)</li>
<li>Utilities (maps, clocks, calendars, cameras, email, etc.)</li>
<li>Discovery (
<a href="http://www.yelp.com" class="link-external" rel="noopener noreferrer" target="_blank">Yelp
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
, 
<a href="http://grubhub.com" class="link-external" rel="noopener noreferrer" target="_blank">GrubHub
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
, etc.)</li>
<li>Education (
<a href="http://renkara.com/applications-accelastudy.php" class="link-external" rel="noopener noreferrer" target="_blank">AccelaStudy
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
, 
<a href="http://contig.renkara.com" class="link-external" rel="noopener noreferrer" target="_blank">Contig
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
, 
<a href="http://flashcardchampion.renkara.com" class="link-external" rel="noopener noreferrer" target="_blank">Flashcard Champion
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
, etc.)</li>
<li>Brands (
<a href="http://www.nike.com" class="link-external" rel="noopener noreferrer" target="_blank">Nike
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
, 
<a href="http://redbull.com" class="link-external" rel="noopener noreferrer" target="_blank">Red Bull
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
, etc.)</li>
</ol>
<p>Regardless of your application’s category, native mobile applications offer the absolute best user experience in many aspects with frame rates, offline support, and access to the device’s hardware to name but a few. Contrary to what some may espouse, mobile devices are not well connected; even within major United States and European cities where connectivity is commonly sporadic and network latency is commonly high. Consider many scenarios whereby consumers pass in and out of good network connectivity while on mass transit systems; even mobile applications that “think” they are connected to a hi-fidelity wireless network may really be connected to a personal hotspot that is in turn connected to the internet over a cellular channel.  It is for these reasons I strongly discourage the creation of hybrid and HTML 5 mobile applications. Granted, hybrid and HTML 5 mobile applications may prove satisfactory in some corporate settings  but if you want your application to be among the 10 regularly used ones then write native applications; it’s that simple. And for the record, I am not a fan of “
<a href="http://en.wikipedia.org/wiki/Fourth-generation_programming_language" class="link-external" rel="noopener noreferrer" target="_blank">4GL
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
” Integrated Development Environments (IDE) that generate code for multiple mobile platforms. Perhaps I am a purist but I prefer to have direct access to and control over the core mobile platform rather than having to interact with process and technical abstractions. Your consumers do appreciate this level of attention to detail and UX refinement.</p>
<p>If you do write applications in the consumer space and if you&rsquo;ve purchased a smartphone or tablet recently, and if it doesn&rsquo;t have an Apple logo on it then it&rsquo;s likely you already know of Android. Android is an open sourced Linux-based operating system (OS) launched approximately 5 years ago as of the time of this writing. The Android operating system dates back to 2003 when Rich Milner, Nick Sears, Chris White, and Andy Rubin began working on a mobile operating system, which Google would eventually purchase in 2005.</p>
<p>For years, the dominant OS was Symbian, which has its roots in Psion&rsquo;s 
<a href="http://en.wikipedia.org/wiki/EPOC_%28operating_system%29" class="link-external" rel="noopener noreferrer" target="_blank">EPOC
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 OS.  By 2007, Symbian accounted for over 63% of the worldwide smartphone market. However, by 2008, when it was purchased by Nokia, that number dropped to 52%. At that time, the closest competitors were Research in Motion&rsquo;s Blackberry OS (16.6%), Microsoft Windows Mobile (11.8%), and the still very new iOS (8.2%). With Nokia&rsquo;s OS was poorly equipped to compete with iOS, RIM not wanting to leave its business focus comfort zone and Microsoft&rsquo;s mobile attempts clearly failing, it was Google&rsquo;s purchase of Android Inc in 2005 that would eventually provide competition. The Linux-based, open-source mobile operating system would eventually find its way to the market with the release of the T-Mobile G1 in 2008. The G1 sold well and that elevated Android to reach a 3.9% share in the smartphone market in 2009. At this point, iOS had doubled its share to 14.4%, RIM grew to just under 20%, Windows Mobile had dropped to 8.7%, and Symbian correspondingly dropped to 46.9%. Today, Android is used in 61% of the smartphones (excluding tablets) sold worldwide, which is primarily attributed to the fact it can be found in both high-end handsets (targeting the Apple iPhone) and in lower budget smartphones (where Symbian once dominated). Apple iOS commands 20.5% of the worldwide smartphone marketshare, which is impressive considering it&rsquo;s only included in Apple&rsquo;s own high-end phones. RIM is now down to less than 1.5%.</p>
<p>In general, it’s easier to get an application released onto Android, but from technical engineering and business points of view, Android does have significant disadvantages over Apple’s iOS:</p>
<ul>
<li>Google Play is not nearly as mature as Apple’s AppStore</li>
<li>People are reluctant to pay for Android applications</li>
<li>Piracy of applications is widespread</li>
<li>Security concerns and malware</li>
<li>Little to no enterprise penetration</li>
<li>OS upgrades are cumbersome, slow, and generally require intervention by the carrier</li>
</ul>
<p>However, one can’t ignore Android these days; and in particular for the consumer space. Corporate and business applications are a different matter altogether and I’ll save that discussion for a later point in time time.</p>
<h2 id="cloud" class="heading">Cloud
    <a class="heading__anchor" href="#cloud" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h2>
<p>So, where does cloud technology fit into all of this? Everywhere. Cloud is the cohesive technology between mobile, social, and big data. Over the past nearly 6 years, and after nearly 500 mobile applications shipped, I can think of exactly one mobile application I’ve written that did not involve hosted cloud services; and cloud providers are only getting better. Cloud providers such as Amazon 
<a href="http://aws.amazon.com" class="link-external" rel="noopener noreferrer" target="_blank">AWS
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 and Microsoft Windows 
<a href="http://www.windowsazure.com" class="link-external" rel="noopener noreferrer" target="_blank">Azure
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 provide full featured platform-as-a-service (PaaS) and infrastructure-as-a-service (IaaS) offerings that complement solutions spanning the mobile, social, and non-relational database solution domains. There are other providers such as 
<a href="http://linode.com" class="link-external" rel="noopener noreferrer" target="_blank">Linode
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 that offer competitive IaaS offerings and with a very approachable cost model.  Discussing the technical offering of each cloud provider is not in scope of this post; perhaps at a later point in time.</p>
<p>The use of cloud computing technologies offer companies an opportunity to recognize cost savings that would otherwise not be possible with on-premise hardware. For example, it’s not uncommon to develop scripts that create an environment starting with mere credentials to a fully functioning application stack in a matter of minutes only to tear it down once the day is over. Patterns such as this are quite attractive to stakeholders.</p>
<h2 id="conclusion" class="heading">Conclusion
    <a class="heading__anchor" href="#conclusion" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h2>
<p>For organizations seeking a fast, easy and cost-effective way to manage business operations, the convergence of mobile, cloud, social, and non-relational storage technologies equips parallel and distributed system designers and business stakeholders with a unique opportunity and insight into new patterns that would otherwise require a much higher degree of cooperation and effort among disperate teams. an architecture that seeks signals, models them for their impact, and then adapts to the business process of the organization.  These technologies also facilitate pattern-based strategy architectures, which are attractive to both technical architects and business stakeholders. A pattern-based strategy identifies signals, models them for their impact, and then adapts to the business process of the organization instead of current strategies defined by making hypotheses, performing analyses, and reaching conclusions that are often wrong given the time to implement the change and pivot occurs at a slower pace than the tracked market trends.</p>
<p>Good architectures don’t just happen, they are designed.</p>
<p><strong>References:</strong></p>
<ul>
<li>Andrew McAfee and Erik Brynjolfsson. “Big Data: The Management Revolution”. Harvard Business Review,  October 2012.</li>
</ul>]]></content:encoded><category>software engineering</category><category>mobile</category></item><item><title>A Healthy Lifestyle: Part 1</title><link>https://michaelprimeaux.com/en/posts/2013-02-02-a-healthy-lifestyle-part-1/</link><pubDate>Sat, 02 Feb 2013 00:06:00 +0000</pubDate><author>michael@michaelprimeaux.com (Michael Primeaux)</author><guid>https://michaelprimeaux.com/en/posts/2013-02-02-a-healthy-lifestyle-part-1/</guid><description>I recently moved to Chicago and, as part of that overall effort, decided to raise the priority of a healthy lifestyle. As with most people who have a pulse, I am not getting any younger and so am very keen to avoid prescription medication. Fundamentally, understanding how the changes I decide to make toward this goal must start with the measurement of a set of baseline indicators and, more importantly, the method of inquiry to attain this baseline and the resulting influence of changes in my diet and lifestyle must be based on empirical and measurable evidence.</description><content:encoded><![CDATA[<p>I recently moved to Chicago and, as part of that overall effort, decided to raise the priority of a healthy lifestyle. As with most people who have a pulse, I am not getting any younger and so am very keen to avoid prescription medication. Fundamentally, understanding how the changes I decide to make toward this goal must start with the measurement of a set of baseline indicators and, more importantly, the method of inquiry to attain this baseline and the resulting influence of changes in my diet and lifestyle must be based on empirical and measurable evidence.</p>
<p>I constantly reason through and research, among other things, many aspects of health and fitness.  Categorically speaking, the two cornerstone aspects of heath and fitness are diet and exercise. As a former athelete, I am quite familiar with elements and mechanics of muscle development, diet, and exercise and the implications of each on one&rsquo;s health and wellness. I’ve been actively involved in sports since very early in life; throughout middle school, high school and college . From my experience, the set of baseline measurements to gather are our metabolic rates, body fat percentages, and blood chemistry. Once we have these baselines, then we simply employ 
<a href="http://en.wikipedia.org/wiki/Scientific_method" class="link-external" rel="noopener noreferrer" target="_blank">the scientific method
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
.</p>
<p><strong>BMR and RMR:</strong></p>
<p>Muscle burns more calories than fat and so understanding how many calories one burns at rest over a specific duration is important and particularly in the context of your body fat percentage, which I discuss later in this post.</p>
<p>BMR and RMR are estimates of how many calories you would burn if you were to do nothing but rest for 24 hours. Together, they represent the minimum amount of energy required to keep your body functioning, including your heart beating, lungs breathing, and body temperature normal.</p>
<ul>
<li>BMR stands for Basal Metabolic Rate, and is synonymous with Basal Energy Expenditure or BEE. BMR measurements are typically taken in a darkened room upon waking after 8 hours of sleep; 12 hours of fasting to ensure that the digestive system is inactive; and resting in a reclining position.</li>
<li>RMR stands for Resting Metabolic Rate, and is synonymous with Resting Energy Expenditure or REE. RMR measurements are typically taken under less restricted conditions than BMR, and do not require that the subject spend the night sleeping in the test facility prior to testing.</li>
</ul>
<p>All this said, however, BMR and RMR does not represent the minimum amount of calories one burns in a day. Why? Because many of us don’t normally sit around all day in a horizontal position with our eyes closed. We perform tasks. Therefore, for a more accurate estimate of how many calories one burns in a day you may consider looking into an “activity calculator”. If you do find one, then do not add your BMR or RMR to those results. Use one method or the other.</p>
<p>Oh, and please keep in mind that “calories burned” calculations are based on your weight. As you lose weight and activity becomes easier, you’ll burn fewer calories performing the same activities. Therefore as you lose weight, you will need to periodically recalculate the number of calories you burn in a day.</p>
<p><strong>The apple, the pear, and the egg&hellip;</strong></p>
<p>There are essentially three prolific body shapes represented in the different obese classifications for people: the apple, the pear, and the egg.  With these shapes in mind, let’s discuss the notion of android and gynoid fat.</p>
<p>Android fat is the fat stored in the midsection of the body predominantly in the abdomen, but also the fat stored in the chest and upper arms. This is a common fat-storage location among men and is associated with an apple shape and is consistently associated with increased risk of heart disease and diabetes, hormonal imbalances, some cancers, sleep apnea, and more.  In this type, the fat is mainly accumulated within the abdomen and around the vital organs (visceral fat).</p>
<p>Gynoid fat storage represents the “pear” shape and is more common among women. This fat is stored primarily around the buttox, hips and thigh areas. Overweight pear-shaped people tend to suffer from mechanical problems such as hip, knee and other joint issues due to an excess of fat (weight stress) on the lower half of their body.</p>
<p>The Ovoid, or egg, shape represents a unisex body type wherein a generalized coverage of body fat is exhibited.</p>
<p>It’s important that both one’s subcutaneous fat (the fat under your skin) and visceral fat (fat around your internal organs) be specifically measured. Determining the ratio of android to gynoid fat (the A/G ratio) and monitoring that ratio is critical important because it directly correlates to the prevalence of visceral fat. The production of viceral fat is your body’s survival strategy as a result of the internal organs insulating themselves from toxins by encapsulating the toxins in fat. Unfortunately, this may impede organ function and, as a result of this diminished function, increase the risk for disease.  Ideally, your android fat should be lower than your gynoid fat; so a value below 1.0 is in the ideal range of the threshold metrics.</p>
<p>I scheduled an appointment with 
<a href="http://dexafit.com" class="link-external" rel="noopener noreferrer" target="_blank">DexaFit
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 to have them conduct a DexaFit DXA Total Body Composition Scan. In short, this scan is very accurate and produces an exact measurement of one’s A/G ratio along with other vitally important infomation; and best of all, the entire process takes approximately 7 minutes.  I certainly encourage anyone interested in their body fat analysis to strongly consider DexaFit.</p>
<p>Incidentally, this is why body fat analysis methods that use the notion of simple subcutanous clamps or water immersion are vastly inferior to the DexaFit method of measurement since those methods do not measure visceral fat and so the overall body fat percentage calcualation is, therefore, inaccurate.</p>
<p><strong>Blood Chemistry Analysis:</strong></p>
<p>A blood chemistry analysis provides an important set of baseline measurements to serve as key indicators for a person’s overall picture of health and wellness. For a male over the age of 40, a comprehensive blood chemistry analysis is recommended on an annual basis.  I use 
<a href="http://directlabs.com" class="link-external" rel="noopener noreferrer" target="_blank">DirectLabs
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
. DirectLabs provides direct access laboratory testing for those who want to take charge of their own health and personally monitor their own wellness. In the course of time, they assist in the prevention or early detection of disease by providing discounted, high quality online blood and laboratory testing services directly and confidentially to consumers.</p>
<p>There are of course many tests offered by DirectLabs but the ones I chose are panel-selected as the most important battery of tests for males over the age of 40:</p>
<p><strong>Comprehensive Wellness Profile. This profile measures&hellip;</strong></p>
<ul>
<li>Lipids: This is a group of simple blood tests that reveal important information about the types, amount and distribution of the various types of fats (lipids) in the bloodstream. Includes Total Cholesterol, HDL (good) Cholesterol, LDL (bad) Cholesterol, Risk Ratio (good to total), and Triglycerides.</li>
<li>Complete Blood Count (CBC&rsquo;s): Used as a broad screening test to check for such disorders as anemia, infection, and many other diseases. It is actually a panel of tests that examines different parts of the blood.</li>
<li>Fluids and Electrolytes: Includes Chloride, Potassium, Sodium, and Carbon Dioxide.</li>
<li>Thyroid w/TSH: Includes T-3 Uptake, Total T4, (Free thyroxine index)T7, and TSH.</li>
<li>Liver: Includes Albumin, Alkaline Phosphatase, Alanine Transaminase (ALT or SGPT), Aspartate Transaminase (AST or SGOT), Total Bilirubin, Total Protein, LDH, Total Globulin, Albumin/Globulin Ratio, and GGT.</li>
<li>Kidney: Includes Blood Urea Nitrogen (BUN), Creatinine, BUN/Creatinine Ratio, eGFR, and Uric Acid.</li>
<li>Glucose (Diabetes);</li>
<li>Mineral and Bone: Total Iron, Calcium, and Phosphorus.</li>
</ul>
<p><strong>Fibrinogen, Quantitive:</strong>
Fibrinogen is used to detect suspected bleeding disorders or abnormal blood clotting. Fibrinogen is often significantly increased in conditions involving tissue damage, infection, or inflammation. Increased levels may be seen in smokers, during pregnancy, and in women taking oral contraceptives. Fibrinogen levels can be diminished in advanced liver disease.</p>
<p><strong>C-Reactive Protein, hs (CRP, hs):</strong>
CRP, hs is a critical component of the immune system and can be predictive of future risk of heart attack, stroke, sudden cardiac death, and the development of peripheral arterial disease. Individuals with elevated levels of CRP have a risk about 2 to 3 times higher than the risk of those with low levels.</p>
<p><strong>Homocysteine:</strong>
Homocysteine is an amino acid that plays a role in destroying the lining of your artery walls, promoting the formation of blood clots, and also accelerates the buildup of scar tissue. High levels may increase the chance of heart disease and stroke, especially if you have other risk factors such as diabetes, high blood pressure, obesity, smoking, or family history.</p>
<p><strong>Hemoglobin A1c:</strong>
This non-fasting test, also known as A1c, HbA1c, Glycohemoglobin, or Glycated hemoglobin, indicates how well you have controlled your diabetes over the last few months. Even though you may have some very high or very low blood glucose values, Hemoglobin A1C will give you a picture of the average amount of glucose in your blood over that time period. While the Hemoglobin A1C is the standard tool to determine blood sugar control for patients with diabetes, it is not a substitute for daily, routine blood glucose testing.</p>
<p><strong>DHEA-s:</strong>
DHEA-S serves as a building block for making the male sex hormone testosterone and the female sex hormone estrogen. DHEA-s concentrations peak after puberty and then the levels tend to decline with age. In women, too much DHEA-s can lead to excessive hair growth or male body characteristics as well as adrenal tumors, cancers, and adrenal hyperplasia. Under production can be an indication of Addison’s disease or adrenal hypoplasia.</p>
<p><strong>Total Testosterone:</strong>
Testosterone is a hormone that causes male characteristics. The blood level is used by men to investigate abnormal sexual development and sexual dysfunction. Small amounts are produced in women&rsquo;s ovaries and levels are tested to evaluate virilization.</p>
<p><strong>Testosterone, Free:</strong>
Testosterone, Free is the free flowing testosterone that is not bound within the body and only accounts for about 2% of all testosterone. The free flowing testosterone is unencumbered in the charging of testosterone related systems, the brain, muscles, blood and sex drive, while two-thirds of bound testosterone is connected the SHGB (Sex Hormone Binding Globulin) and the other third to albumin. Low free testosterone means testosterone related systems are not getting the necessary charge. When testosterone free decreases the SHGB increases, this can inhibit the way in which testosterone is distributed to bodily systems.</p>
<p><strong>Estradiol:</strong>
Estradiol, also known as E2, is the most active of the estrogens. For women, it is important to look at the relationship between estradiol and progesterone in evaluating menopausal symptoms such as hot flashes, mood disorders, and aging skin. It is also used for monitoring pregnancy.</p>
<p>In both men and women, low levels of estradiol can be associated with osteoporosis.</p>
<p><strong>PSA:</strong>
The prostate specific antigen (PSA) is a protein made only in the prostate gland. PSA is produced by normal, abnormal and cancerous prostatic tissue. The PSA blood test is an accurate measure of this amount. The theory is that cancer causes more of the protein to be made and leaked into the blood than normal prostate tissue, so PSA is now used for assisting in the diagnosis and monitoring of prostatic carcinoma.</p>
<p>Best of all, the cost of tests are covered by my insurance company since my policy does provide for preventative health care.</p>
<p><strong>Diet and Exercise:</strong></p>
<p>As for exercise, my routine is heavily focused on Escalation Density Training (EDT) and I am only now starting to incorporate Yoga into my schedule. I plan to dedicate an entire post to EDT in the very near future so will not discuss it now.</p>]]></content:encoded><category>wellness</category></item><item><title>Parallel and Distributed System Design, Part 2</title><link>https://michaelprimeaux.com/en/posts/2012-09-08-parallel-and-distributed-system-design-part-2/</link><pubDate>Sat, 08 Sep 2012 00:06:00 +0000</pubDate><author>michael@michaelprimeaux.com (Michael Primeaux)</author><guid>https://michaelprimeaux.com/en/posts/2012-09-08-parallel-and-distributed-system-design-part-2/</guid><description>The map is not the territory. &amp;ndash; Alfred Korzybsky in Science and Sanity, 1933
This is the second post in a series where I&amp;rsquo;ll discuss various aspects of parallel and distributed system design. I&amp;rsquo;d like to provide a brief introduction to taxonomy (or classification of data) and eventual consistency as these building blocks are fundamental to parallel and distributed system design.</description><content:encoded><![CDATA[<blockquote><p>The map is not the territory. &ndash; Alfred Korzybsky in Science and Sanity, 1933</p>
</blockquote>
<p>This is the second post in a 
<a href="/posts/2012-08-05-parallel-and-distributed-system-design-part-1/">series</a>
 where I&rsquo;ll discuss various aspects of parallel and distributed system design.  I&rsquo;d like to provide a brief introduction to taxonomy (or classification of data) and eventual consistency as these building blocks are fundamental to parallel and distributed system design.</p>
<p>Extending my thoughts from a 
<a href="/posts/2007-06-03-information-modeling/">post I made some time ago</a>
, in computer science and information modeling, an ontology formally represents knowledge as a set of concepts within a domain, and the relationships among those concepts. It can be used to reason about the entities within that domain and may be used to describe the domain.  Why do we need to know this? Because all parallel and distributed systems require data to operate and, in turn, operate on data.</p>
<h2 id="semantic-ontologies" class="heading">Semantic Ontologies
    <a class="heading__anchor" href="#semantic-ontologies" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h2>
<p>A semantic ontology, or ontology, is a formal explicit description of concepts in a domain of discourse, properties of each concept describing various features and attributes of the concept, and restrictions on properties. An ontology together with a set of individual instances of classes [or objects] constitutes a knowledge base. In reality, there is a very fine line where the ontology ends and the knowledge base begins but let&rsquo;s put that aside for a moment.</p>
<p>An implementation of conceptual ontologies is the Semantic Web [
<a href="http://www.w3.org/standards/semanticweb/" class="link-external" rel="noopener noreferrer" target="_blank">URI
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
]. Simply put, the Semantic Web is the representation of data on the web in which information is given well-defined meaning—“to be a universal medium for the exchange of data”.</p>
<p>The principal technologies of the Semantic Web fit into a set of layered specifications called the 
<a href="http://www.w3.org/RDF/" class="link-external" rel="noopener noreferrer" target="_blank">Resource Description Framework
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 (RDF). The current components of that framework are the RDF Core Model, the RDF Vocabulary Description Language and the Web Ontology Language (
<a href="http://www.w3.org/2007/OWL/wiki/OWL_Working_Group" class="link-external" rel="noopener noreferrer" target="_blank">OWL
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
).  OWL is a descriptive layer built on top of RDF used to model classes, properties, and objects. These languages all build on the foundation of URIs, XML, and XML namespaces.</p>
<p>Classes are the focus of most semantic ontologies. Outlined in most ontology research are the following observations:</p>
<ul>
<li>There is no one correct way to model a domain— there are always viable alternatives. The best solution almost always depends on the application that you have in mind and the extensions that you anticipate.</li>
<li>Ontology development is necessarily an iterative process.</li>
<li>Concepts in the ontology should be close to objects (physical or logical) and relationships in your domain of interest. These are most likely to be nouns (objects) or verbs (relationships) in sentences that describe your domain.</li>
</ul>
<p>Solution domains require, at times, different classifications. Regardless of which classification the solution domain requires, the following rules and considerations have proven effective in designing an efficient information model:</p>
<ul>
<li>Effectively understand the information.</li>
<li>Describe it unambiguously.</li>
<li>Enforce structure and style guidelines.</li>
<li>Allow for efficient storage and retrieval of information.</li>
<li>Keep network communication to a minimum. Don’t over engineer.</li>
</ul>
<p>I cannot overstate the need to understand your information model but always with an understanding of your delivery time frames. All too many times, we are caught up in the perfect model only in the end to take shortcuts to satisfy deadlines. The solution is acceptance and understanding that change is an integral part of any information model.  Temporal and transient taxonomies may be an integral part of your solution domain. Semantic ontologies may be created at runtime to address a special-purpose need where the need itself is transient in nature. For example, in order to fulfill a set of calculations with a high time and computational complexity rating a transient taxonomy might need to be created to provide global access to intermediate calculation results.  This is all too common in financial simulation.</p>
<p>Not surprising is that classes are the focus of most ontologies. So with that, let&rsquo;s move on to a more usual and enjoyable example of a semantic ontology: wine. Wine is a potable liquid produced by at least one maker of type winery, and is made from at least one type of grape. For example, a class of <strong>Wine</strong> represents all wines. Specific wines are instances of this class. The Bordeaux wine in the glass in front of you while you read this post is an instance of the class of Bordeaux wine. A class can have subclasses that represent concepts that are more specific than the superclass. For example, we can divide the class of all wines into red, white, and rose wines. Alternatively, we can divide a class of all wines into sparkling and non-sparkling wines.</p>
<p>We can further describe properties of classes and instances: Chateau Lafite Rothschild Pauillac wine has a full body; it is produced by the Chateau Lafite Rothschild winery. We can have two properties describing the wine, the property <strong>body</strong> with the value <strong>full</strong> and the property <strong>maker</strong> with the value <strong>Chateau Lafite Rothschild</strong> winery. At the class level, we can say that instances of the class <em>Wine</em> will have properties describing their flavor, body, sugar level, the maker of the wine and so on.</p>
<p>All instances of the class Wine, and its subclass Pauillac, have a property <strong>maker</strong> the value of which is an instance of the class Winery. All instances of the class Winery have a property <strong>produces</strong> that refers to all the wines (instances of the class Wine and its subclasses) that the winery produces. The entire example OWL ontology derived for <strong>Wine</strong> can be found 
<a href="http://www.w3.org/TR/owl-guide/wine.rdf" class="link-external" rel="noopener noreferrer" target="_blank">here
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
. I am of course a huge fan.</p>
<p>The strength of your application requires you to understand the data on which it operates—unambiguosly. Though perfection is not key, it is second to paramount. Once you fully understand your information model, then you are able to understand eventual consistency for your application. And with this in mind, let&rsquo;s discuss eventual consistency.</p>
<h2 id="eventual-consistency" class="heading">Eventual Consistency
    <a class="heading__anchor" href="#eventual-consistency" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h2>
<p>Eventual consistency is one of the consistency models used in the domain of parallel programming. It means that given a sufficiently long period of time over which no changes are sent, all updates can be expected to propagate eventually through the system and all the replicas will be consistent. I will remind you from a 
<a href="/posts/2012-08-05-parallel-and-distributed-system-design-part-1/">previous blog entry</a>
 there is no way to guarantee complete knowledge of the current or future state of a distributed system, because knowledge of state changes must be propagated and propagation takes time, during which more state changes may occur. This is an axiom of distributed computing. So how can we begin to reconcile eventual consistency with this axiom? Well, we don&rsquo;t really [
<a href="http://queue.acm.org/detail.cfm?id=1466448" class="link-external" rel="noopener noreferrer" target="_blank">URI
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
].  We design for loose coupling. We design for tolerance. We design for symmetry of algorithms.</p>
<p>At a high level, most mission- and safety-critical distributed applications 
<a href="http://www.ietf.org/rfc/rfc2119.txt" class="link-external" rel="noopener noreferrer" target="_blank">SHOULD
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 strive to achieve these high-level technical requirements:</p>
<ul>
<li>Provide high availability read and write access to information.</li>
<li>Minimize network communication.</li>
<li>Provide a highly available and fault tolerant system that can support an annual uptime guarantee of 99.999 percent , which is equal to 5.256 minutes of annual unscheduled downtime.</li>
<li>Provide instrumentation to aid implementers and customers in their hardware sizing estimates.  Scalability 
<a href="http://www.ietf.org/rfc/rfc2119.txt" class="link-external" rel="noopener noreferrer" target="_blank">MUST
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 be measurable.</li>
<li>Devise a software architecture that scales up by a factor of 10^6. That is, an application&rsquo;s storage and processing capacity can automatically grow by a factor of a million, doing jobs faster 10^6x speed up or doing 10^6 larger jobs in the same time 10^6 scale up, just by adding more resources.</li>
<li>Provide for conflict resolution. Common implementations in this area leverage 
<a href="http://en.wikipedia.org/wiki/Lamport_timestamps" class="link-external" rel="noopener noreferrer" target="_blank">Lamport timestamps
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 and 
<a href="http://en.wikipedia.org/wiki/Vector_clock" class="link-external" rel="noopener noreferrer" target="_blank">vector clocks
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
.</li>
<li>Provide for transient node failure.</li>
</ul>
<p>While the goal is to devise a software architecture that scales up without limits, there has to be some kind of limit: billions of dollars, or giga watts, or just space. So, the more realistic goal is to be able to scale from one node to a million nodes all working on the same problem or same set of problems.</p>
<p>While fundamentally a 
<a href="http://en.wikipedia.org/wiki/Distributed_hash_table" class="link-external" rel="noopener noreferrer" target="_blank">Distributed Hash Table (DHT)
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 is <em>generally</em> well suited for specific classes of decentralized distributed systems, it is certainly not well suited for all. For example, a DHT is well suited for problems where a highly reliable network between nodes is usual. But a DHT is not <em>necessarily</em> well suited for problem domains where frequent node joins and leaves are the norm.  That said, DHTs have been used for <em>routing</em> in many Peer-to-Peer (P2P) implementations [
<a href="/blog/2007/06/04/peer-to-peer-p2p/">URI</a>
]. Even some of the more well known NoSQL implementations leverage DHTs.</p>
<p>But as I mentioned, DHTs are not necessarily well suited for all implementations. When we designed the core replication algorithms for the Microsoft Active Directory (AD) service, a DHT was not chosen. Not only did we want to account for 
<a href="http://en.wikipedia.org/wiki/Byzantine_fault_tolerance" class="link-external" rel="noopener noreferrer" target="_blank">Byzantine
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 failures but we also needed to account for replica failures that lasted for long periods of time (30+ days).  AD subscribes to eventual consistency. Roughly speaking, the replication model of AD is <em>multi-master loose consistency with convergence (eventual consistency)</em>.    In this model, the directory can have many replicas; a replication system propagates changes made at any given replica to all other replicas. The replicas are not guaranteed to be consistent with each other at any particular time (&ldquo;loose consistency&rdquo;), because changes can be applied to any replica at any time (&ldquo;multi-master&rdquo;). If the system is allowed to reach a steady state, in which no new updates are occurring and all previous updates have been completely replicated, all replicas are guaranteed to converge on the same set of values (&ldquo;convergence or eventual consistency&rdquo;).</p>
<p>In addition to the technical requirements listed earlier in this post, we imposed the following requirements on the design of AD replication:</p>
<ul>
<li>To adapt to customer networks, provide flexibility in replication topology including choice of transports.</li>
<li>Provide a fully asynchronous and highly scalable architecture.</li>
<li>Minimize network communication in terms of size and round-trips, support encryption of data, and support transitive (store/forward) transportation of data.</li>
<li>Work well over high-latency communication links.</li>
<li>Operate correctly when encountering changes to the distinguished name (DN) of an object and to discriminate between a deleted object and a new object with the same DN. In other words, we replicate information based on object&rsquo;s universally unique identifier (
<a href="http://en.wikipedia.org/wiki/Universally_unique_identifier" class="link-external" rel="noopener noreferrer" target="_blank">UUID
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
) and not based on DN.</li>
<li>Automatic system topology generation. The system automatically creates (and destroys) &ldquo;short cut&rdquo; replication links between nodes in order to maintain a specific number of hops between any two points.</li>
</ul>
<p>Active Directory uses a state-based approach to replication. This approach is easier to appreciate in contrast with an alternative, log-based replication. In a typical log-based system each master keeps a log of the updates that it originated. The goal of each master is to communicate its log to every other replica. Once a log arrives at a replica, the replica applies the log, bringing its state more up to date.</p>
<p>In state-based replication each master applies updates, both originating and replicated, to its replica as they arrive. As such, replication is not driven from logs stored with the source replica but from current state of the source replica. This state includes information for resolving conflicts (also needed in the log-based approach) and information to avoid sending the full replica on each replication cycle (inherent in the log-based approach.) A state-based approach uses a single mechanism for incremental and full sync, and performs fewer database updates since repeated or conflicting updates to an attribute are collapsed into a single state. The resulting design has several stability-enhancing properties, such as:</p>
<ul>
<li>No matter how long two replication partners have been out of communication, they can always build upon any previous replication they have accomplished. They never have to start over from scratch because somebody&rsquo;s log &ldquo;wrapped around.&rdquo;</li>
<li>If a replica has a &ldquo;hot spot&rdquo; attribute that&rsquo;s being updated frequently for some reason (perhaps a bug in an application or an implementation similar to a performance counter), only the value that&rsquo;s current at the time of replication is sent to a replication partner. Some designs send the full history of all intermediate values thereby multiplying the problem.</li>
<li>The very same mechanism is used to initialize a new replica as is used for bringing a replica up to date with recent changes. Some other designs require two mechanisms.</li>
<li>AD has a simple and robust solution to the &ldquo;time went backwards due to restore from backup&rdquo; problem (also called the &ldquo;back sync&rdquo; problem) that plagues some other systems.</li>
<li>In a replication relationship the destination (i.e. the replica being updated) takes all responsibility for keeping track of how up to date it is. The source (i.e. the replica supplying the updates) takes no responsibility. This design choice avoids a lot of complexity and potential sources of failure; some other systems don&rsquo;t work this way.</li>
<li>In a replication relationship the destination always &ldquo;pulls&rdquo; changes from the source. The source may notify the destination &ldquo;now would be a good time to pull,&rdquo; but if the notification is lost (e.g. because the destination is overloaded or down) the result is longer replication latency, not incorrectness.</li>
<li>When two replicas establish a new replication relationship, that relationship is established in an incremental fashion, so not much work is lost should one replica go down before the relationship becomes complete.</li>
</ul>
<h2 id="impact-on-distributed-applications" class="heading">Impact on Distributed Applications
    <a class="heading__anchor" href="#impact-on-distributed-applications" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h2>
<p>A multi-master distributed system induces several problems on applications.</p>
<ul>
<li><strong>Version Skew</strong>. Version skew occurs when applications read the same object(s) from different replicas before a change has replicated.  Applications reading the remote replica see the unchanged object.  Version skew is an issue when a given application or set of applications use the information in the directory to interoperate.</li>
<li><strong>Partial Updates</strong>. Partial Update occurs when applications read the same set of objects from different replicas while replication is in progress.  Applications at the remote replica see some of the changes but not all.  Note that there is a small window in which partial update can affect an application: the application must start reading objects while inbound replication is in progress, after one or more of the related, changed objects have been received but before all have been received. The time between the updates at the source replica directly affects the size of this window—updates that occur close together in time will be replicated close together in time. Partial update is an issue when an application uses a related set of objects.</li>
<li><strong>Collisions</strong>. Collisions occur when the same properties of two or more replicas of a given object are changed during the same replication interval.  The replication process reconciles the collision; because of reconciliation a user or application may “see” a value other than the one they wrote. A simple example is user address information—if a user changes their mailing address at replica <strong>R-a</strong> and an administrator changes the same mailing address at replica <strong>R-b</strong>, the value ultimately propagated to (<strong>R-a</strong>, <strong>R-b</strong>), and all other replicas will be the value selected by the collision reconciliation mechanism. Collision resolution is an issue for applications that make assumptions about the internal consistency of objects or sets of objects.</li>
</ul>
<p>Though not in scope of this post, applications must accommodate replication latency.  The best way to accommodate replication latency is to design applications to minimize the effects—to tolerate latency.  The ideal distributed application is of course unaffected by replication latency induced state. Other applications must adopt an avoidance or detection strategy as a mechanism to tolerate replication latency.</p>
<p>Many NoSQL systems, such as MongoDB, employ a master/slave topology and so writes are accepted on a single node. Even the newer replica sets in MongoDB adhere to this model. Sharding (or partitioning), of course, is a key consideration in these types of systems. Sharding enables horizontal scaling across multiple nodes. A sharded MongoDB cluster performs automated leader election for the <em>primary</em> node.  Leader election in a ring is another topic in and of itself. So let&rsquo;s wrap this up&hellip;</p>
<h2 id="wrapping-it-all-up" class="heading">Wrapping it all up&hellip;
    <a class="heading__anchor" href="#wrapping-it-all-up" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h2>
<p>Regardless of the underlying durable storage technology, it is of paramount responsibility that you properly classify your information model, understand your consistency model, and develop your application to be highly resilient to failures. It is this latter point—being highly resilient to failures—that is not an easy task and that is precisely why I&rsquo;ll discuss fault tolerance and recovery in my next post.</p>]]></content:encoded><category>distributed systems</category><category>computing</category></item><item><title>Parallel and Distributed System Design, Part 1</title><link>https://michaelprimeaux.com/en/posts/2012-08-05-parallel-and-distributed-system-design-part-1/</link><pubDate>Sun, 05 Aug 2012 00:06:00 +0000</pubDate><author>michael@michaelprimeaux.com (Michael Primeaux)</author><guid>https://michaelprimeaux.com/en/posts/2012-08-05-parallel-and-distributed-system-design-part-1/</guid><description>…since my intention is to write something useful for anyone who understands it, it seemed more suitable to me to search after the effectual truth of the matter, rather than its imagined one. &amp;ndash; Niccolo Machiavelli in The Prince, 1532</description><content:encoded><![CDATA[<blockquote><p>…since my intention is to write something useful for anyone who understands it, it seemed more suitable to me to search after the effectual truth of the matter, rather than its imagined one. &ndash; Niccolo Machiavelli in The Prince, 1532</p>
</blockquote>
<p>While conducting a bit of research on scalability and efficiently storing 
<a href="http://en.wikipedia.org/wiki/Petabyte" class="link-external" rel="noopener noreferrer" target="_blank">large amounts
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 of information, I ran across an 
<a href="http://cacm.acm.org/magazines/2011/6/108666-if-you-have-too-much-data-then-good-enough-is-good-enough/abstract" class="link-external" rel="noopener noreferrer" target="_blank">abstract
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 in the Communications of the ACM written by a friend and former colleague Pat Helland. Pat and I worked at Microsoft together during the late 90s. Our paths naturally crossed given his core research in high performance transaction systems (
<a href="http://www.hpts.ws/" class="link-external" rel="noopener noreferrer" target="_blank">HPTS
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
) and my core work in parallel and distributed systems. Pat recently moved back to San Francisco after 15 years with Microsoft [
<a href="http://blogs.msdn.com/b/pathelland/archive/2011/09/30/leaving-microsoft-and-moving-to-san-francisco.aspx" class="link-external" rel="noopener noreferrer" target="_blank">URI
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
]. For the two years prior to leaving, Pat worked on 
<a href="http://blogs.msdn.com/b/seliot/archive/2010/11/05/cosmos-petabytes-perfectly-processed-perfunctorily.aspx" class="link-external" rel="noopener noreferrer" target="_blank">Cosmos
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
, some of the plumbing for 
<a href="http://www.bing.com" class="link-external" rel="noopener noreferrer" target="_blank">Bing
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
.  It stores hundreds of petabytes of data on tens of thousands of computers.</p>
<p>The 
<a href="http://cacm.acm.org/magazines/2011/6/108666-if-you-have-too-much-data-then-good-enough-is-good-enough/abstract" class="link-external" rel="noopener noreferrer" target="_blank">paper
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
, &ldquo;If You Have Too Much Data, then &lsquo;Good Enough&rsquo; Is Good Enough&rdquo;, is brilliantly written. Pat has always been a wonderful and capable writer with an ability to reduce complex problems into a simple presentation. Similar to his clear and concise description of application models using concepts known as &ldquo;fiefdoms&rdquo; and &ldquo;emissaries&rdquo; in 2002 [
<a href="http://www.pcmag.com/article2/0,2817,31952,00.asp" class="link-external" rel="noopener noreferrer" target="_blank">URI
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
] [
<a href="http://msdn.microsoft.com/en-us/magazine/cc164125.aspx" class="link-external" rel="noopener noreferrer" target="_blank">URI
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
], Pat identifies a world where many of our classic SQL database principles are being eroded by combining too much data each with disparate characteristics.</p>
<p>The non-relational storage technology (a.k.a. &ldquo;NoSQL&rdquo;) movement has of course given rise to the likes of 
<a href="http://www.mongodb.org" class="link-external" rel="noopener noreferrer" target="_blank">MongoDB
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
, 
<a href="http://couchdb.apache.org" class="link-external" rel="noopener noreferrer" target="_blank">CouchDB
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
, and 
<a href="http://redis.io" class="link-external" rel="noopener noreferrer" target="_blank">Redis
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
. Each of these NoSQL technologies have their own unique advantage so judicious evaluation is a 
<a href="http://www.ietf.org/rfc/rfc2119.txt" class="link-external" rel="noopener noreferrer" target="_blank">MUST
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
. The vast amounts of information we process each day in turn has forced us to consider alternate ways to process this information else risk not being able to translate this data into actionable information. Applied technologies such as 
<a href="http://hadoop.apache.org" class="link-external" rel="noopener noreferrer" target="_blank">Hadoop
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 and 
<a href="http://hadoop.apache.org/mapreduce/" class="link-external" rel="noopener noreferrer" target="_blank">MapReduce
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 are fundamental to processing &ldquo;big data&rdquo;. We often employ practices and technologies to enable timely dissemination, such as data analytics, business performance management, data warehousing, dashboards and key performance indicators (KPIs). Regardless of what we choose, the fundamentals of how we react to this vast amount of information must be swift, decisive, and&ndash;more importantly&ndash;accurate in today&rsquo;s global economy.  Being capable of pivoting is essential.</p>
<p><strong>Mobile + Cloud</strong></p>
<p>Mobile and cloud technologies are a winning distributed system solution for many problem domains. But let&rsquo;s not forget this combination is a distributed system. When designing and implementing distributed systems and the data models on which a distributed system operates, organization is indeed paramount; and so is synchronization. For safety- and mission-critical applications, high availability has always been a paramount concern and recent experience with large Internet sites has underscored the need for availability in that domain as well.  Traditional approaches to the problem have made three implicit assumptions:</p>
<ol>
<li>Failure rates of hardware and software are low and improving.</li>
<li>Systems can be modeled for reliability analysis and their failure modes can be predicted.</li>
<li>Human error during maintenance is not a major source of failures.</li>
</ol>
<p>The result is an emphasis on failure avoidance as the path to high availability.  These assumptions are in many cases based on incorrect perceptions of today&rsquo;s environment, and that renewed emphasis should be given to failure recovery.  Even the most highly tested systems occasionally exhibit &ldquo;
<a href="http://en.wikipedia.org/wiki/Uncertainty_principle" class="link-external" rel="noopener noreferrer" target="_blank">Heisenbugs
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
&rdquo;  and suffer from transient or permanent hardware failure and software aging, and human error has empirically been found to account for a nontrivial fraction of catastrophic failures.  The most successful systems have been those that can recover from these unexpected errors because they were designed for recovery.</p>

<blockquote><p>If a problem has no solution, it may not be a problem, but a fact—not to be solved, but to be coped with over time. &ndash; Shimon Peres, 1923</p>
</blockquote>
<p>There is no way to guarantee complete knowledge of the current or future state of a distributed system, because knowledge of state changes must be propagated and propagation takes time, during which more state changes may occur.  This is an axiom of distributed computing.</p>
<p>Tightly coupled systems deal with uncertainty by attempting to eliminate it.  This is done through constraints on updates, requiring all nodes or some majority of nodes to be available before updates can be performed; using distributed locking schemes or single mastering for critical resources, constraining all nodes to be well connected, or some combination of these techniques. “Majority” often involves weighted voting schemes; so “big” nodes can be more influential than “small” nodes. The more tightly coupled the computing nodes in a distributed system are, the lower the scaling limit.</p>
<p>Loosely coupled systems deal with uncertainty by tolerating it. A loosely coupled system allows participating nodes to have differing views of the overall system state and provides algorithms for resolving conflicts.</p>
<p>My choice for parallel and distributed system design is loosely coupled because:</p>
<ol>
<li>Customers  require a highly distributed solution in which parts of the infrastructure can be spread across the internal and public networks and administered locally.</li>
<li>Large customers need to grow in capacity to many millions of transactions per day or to hundreds or thousands of nodes, or both.</li>
<li>Many networks provide only intermittent connectivity to some locations, for example remote oil drilling platforms and ships at sea, so the system 
<a href="http://www.ietf.org/rfc/rfc2119.txt" class="link-external" rel="noopener noreferrer" target="_blank">MUST
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 be tolerant of partly connected or disconnected operation.</li>
</ol>
<p>Tightly coupled solutions are unsuitable for parallel and distributed system design because of the requirements for scalability to a very large numbers of nodes and disconnected operation. The loosely coupled model satisfies all of the above requirements.</p>
<p>I’d like to quickly point out an observation regarding tolerance as it relates to most Internet-aware software. As the World Wide Web Consortium (
<a href="http://www.w3.org" class="link-external" rel="noopener noreferrer" target="_blank">W3C
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
) points out with respect to tolerance, the principle of tolerance does not blunt the need for a perfectly clear specification which draws a precise distinction between conformance and non-conformance. The principle of tolerance is no excuse for a product which contravenes a standard. Naturally, the aphorism &ldquo;any problem in computer science can be solved with another level of indirection&rdquo; still rings true but to a varying degree. The quantification of that degree is a difficult balance to achieve as it involves many variables with the most notable, in my opinion, being scalability, flexibility, and reliability.</p>
<p>I plan to discuss the merits of loose coupling in the larger fabric of parallel and distributed system design more concretely over the next several posts.</p>]]></content:encoded><category>distributed systems</category><category>computing</category></item><item><title>Apple WWDC 2012</title><link>https://michaelprimeaux.com/en/posts/2012-04-29-apple-wwdc-2012/</link><pubDate>Tue, 29 May 2012 00:06:00 +0000</pubDate><author>michael@michaelprimeaux.com (Michael Primeaux)</author><guid>https://michaelprimeaux.com/en/posts/2012-04-29-apple-wwdc-2012/</guid><description/><content:encoded><![CDATA[<p>I’ve attended the 
<a href="https://developer.apple.com/wwdc/" class="link-external" rel="noopener noreferrer" target="_blank">Apple WWDC
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 for the past five years and, of course, look forward to this year’s event, which sold out in less than two hours. I am fortunate to have a ticket! Two years ago, the WWDC sold out in approximately two weeks; last year it sold out in approximately 10 hours. What an amazing trend.</p>
<p>Apple did enact a very important 
<a href="https://developer.apple.com/wwdc/tickets/" class="link-external" rel="noopener noreferrer" target="_blank">change
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 this year. All WWDC tickets (including activation codes) are non-transferable. The new rules are certainly worth reading.</p>
<p>I suspect we’ll likely get a preview at iOS 6 and of course the latest developments with OS X Mountain Lion. That said, I don’t expect we’ll see an unveiling of Apple’s latest iPhone but I remain hopeful. Regardless, I’m sure the technical content and overall event will not disappoint.</p>
<p>I look forward to seeing you there.</p>]]></content:encoded><category>apple</category><category>wwdc</category></item><item><title>Universal Frameworks for iOS</title><link>https://michaelprimeaux.com/en/posts/2011-10-30-universal-frameworks-for-ios/</link><pubDate>Sun, 30 Oct 2011 00:06:00 +0000</pubDate><author>michael@michaelprimeaux.com (Michael Primeaux)</author><guid>https://michaelprimeaux.com/en/posts/2011-10-30-universal-frameworks-for-ios/</guid><description>As of the time of this writing, Xcode does not offer a framework project to for Cocoa Touch (only Cocoa). Apple’s primary reasons behind this decision are security, performance, and memory footprint. As such Xcode limits iOS developers to the Static Library project type. Static libraries are quite cumbersome to work with since we must make compile-time decisions when working with the iOS Simulator or an iOS device. The iOS simulator on Mac OS X uses the i386 architecture whereas the iOS devices use either armv6 (opens in a new window) or armv7 (opens in a new window) .</description><content:encoded><![CDATA[<p>As of the time of this writing, Xcode does not offer a framework project to for Cocoa Touch (only Cocoa). Apple’s primary reasons behind this decision are security, performance, and memory footprint.  As such Xcode limits iOS developers to the Static Library project type. Static libraries are quite cumbersome to work with since we must make compile-time decisions when working with the iOS Simulator or an iOS device. The iOS simulator on Mac OS X uses the i386 architecture whereas the iOS devices use either 
<a href="http://en.wikipedia.org/wiki/ARM_architecture" class="link-external" rel="noopener noreferrer" target="_blank">armv6
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 or 
<a href="http://en.wikipedia.org/wiki/ARM_architecture" class="link-external" rel="noopener noreferrer" target="_blank">armv7
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
.</p>
<p>Additionally, iOS 5 introduces a new compile-time memory management feature known as 
<a href="http://clang.llvm.org/docs/AutomaticReferenceCounting.html" class="link-external" rel="noopener noreferrer" target="_blank">Automatic Reference Counting (ARC)
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
. The abridged version is you will never need to type retain or release again, which dramatically simplifies the development process while reducing crashes and memory leaks. The compiler has a complete understanding of your objects, and releases each object the instant it is no longer used, so apps execute much faster, with predictable, smooth performance. However, it’ll take the community some time to refactor various open source libraries to support ARC. Therefore, we have a much larger need today than ever before to move these source files into static libraries that are compiled with ARC disabled so we can compile our primary applications with ARC enabled.</p>
<p>Alternatively, if you are including files that don’t yet support ARC in a project that is ARC enabled, you can set the -fno-objc-arc compiler flag for each of these files. To do this in Xcode, go to your active target and select the “Build Phases” tab. In the “Compiler Flags” column, set -fno-objc-arc for each of the source files. Of course, this can be a very laborious process.</p>
<p>Apple defines a 
<a href="http://developer.apple.com/library/mac/#documentation/DeveloperTools/Conceptual/DynamicLibraries/100-Articles/OverviewOfDynamicLibraries.html" class="link-external" rel="noopener noreferrer" target="_blank">framework
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 as a bundle (a structured directory) that contains a dynamic shared library along with associated resources, such as nib files, image files, and header files. When you develop an application, your project links to one or more frameworks. For example, iOS application projects link by default to the Foundation, UIKit, and Core Graphics frameworks. Your code accesses the capabilities of a framework through the application programming interface (API), which is published by the framework through its header files. Because the library is dynamically shared, multiple applications can access the framework code and resources simultaneously. The system loads the code and resources of a framework into memory, as needed, and shares the one copy of a resource among all applications. A universal (or multi-architecture) file is nothing more than an application bundle.</p>
<p>As I mentioned above, iOS does not support dynamic shared libraries but using 
<a href="http://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/lipo.1.html" class="link-external" rel="noopener noreferrer" target="_blank">lipo
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 (a tool which comes with 
<a href="http://developer.apple.com/devcenter/ios" class="link-external" rel="noopener noreferrer" target="_blank">iOS SDK
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
) we are able to merge several static libraries into a single static library. By using lipo, we are able to create a static library that supports all architectures (armv6, armv7, and i386) packaged as a universal framework. Here’s how.</p>
<p>Within Xcode, either create a new iOS project or open an existing iOS project. If you do decide to create a new project then feel free to choose any application template you prefer. Which one you choose is irrelevant. Add a “Cocoa Bundle” target (not Cocoa Touch Bundle). Select the newly created bundle target in the left navigation panel, select the “Build Settings” tab and modify the following 
<a href="http://developer.apple.com/library/mac/#documentation/DeveloperTools/Reference/XcodeBuildSettingRef/0-Introduction/introduction.html#//apple_ref/doc/uid/TP40003931-CH1-SW1" class="link-external" rel="noopener noreferrer" target="_blank">settings
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 as required:</p>
<ul>
<li><strong>Architectures</strong> (ARCHS): <em>Standard (armv6 armv7 armv7s)</em>. In Xcode 4.2, use the value of $(ARCHS_STANDARD_32_BIT). If you wish to compile for older devices then add a new line with a value of armv6. Please see 
<a href="https://devforums.apple.com/message/536368#536368" class="link-external" rel="noopener noreferrer" target="_blank">this
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 Apple Developer forum post for more details.</li>
<li><strong>Base SDK</strong> (SDKROOT). <em>Latest iOS (iOS X.X)</em>.</li>
<li><strong>Build Active Architecture Only</strong> (ONLY_ACTIVE_ARCH). <em>No</em>. This allows us to compile for armv6 and armv7.</li>
<li><strong>Valid Architecture</strong> (VALID_ARCHS): <em>Standard (armv6 armv7 armv7s)</em>. In Xcode 4.2 and greater, use the value of $(ARCHS_STANDARD_32_BIT). If you wish to compile for older devices then add a new line with a value of armv6.</li>
<li><strong>Dead Code Stripping</strong> (DEAD_CODE_STRIPPING): <em>No</em></li>
<li><strong>Link With Standard Libraries</strong> (LINK_WITH_STANDARD_LIBRARIES): <em>No</em></li>
<li><strong>Mach-O Type</strong> (MACH_O_TYPE): <em>Relocatable Object File</em>. This is the most important change. Here, we instruct the compiler to treat the Bundle as a relocatable file, by doing this, we can turn it into a framework with the wrapper setting.</li>
<li><strong>Wrapper Extension</strong> (WRAPPER_EXTENSION). <em>framework</em>. Here we change the Bundle to a Framework. To Xcode, frameworks is just a folder with the extension .framework, which has inside one or more compiled binary sources, resources and some folders, a folder, usually called Headers, contains all the public headers.</li>
<li><strong>Generate Debug Symbols</strong> (GCC_GENERATE_DEBUGGING_SYMBOLS): <em>No</em>.</li>
<li><strong>Generate Position-Dependent Code</strong> (GCC_DYNAMIC_NO_PIC): <em>No</em></li>
<li><strong>Targeted Device Family</strong> (TARGETED_DEVICE_FAMILY). <em>iPhone/iPad</em>.</li>
</ul>
<p>Here are the steps&hellip;</p>
<ul>
<li>With the bundle target still in focus, select the “Info” tab and ensure the “Bundle OS Type code” is equal to FMWK.</li>
<li>Add any source code and resources to the bundle. With the bundle target selected, click the “Build Phase” tab. At the bottom, press the “Add Phase” button and then “Add Copy Headers“.</li>
<li>Open the newly created “Copy Headers” section and separate your public headers from private or project headers.</li>
<li>Open the “Compile Source” section and add any .m, .c, .mm, .cpp and any other compilable source file. If your framework contains any non-compilable files such as images, sounds, and other resources, you can add them to the “Copy Bundle Resources” section.</li>
</ul>
<p>You can access any non-compilable resources by using NSBundle.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-objc" data-lang="objc"><span class="line"><span class="cl"><span class="p">[[</span><span class="n">NSBundle</span> <span class="n">mainBundle</span><span class="p">]</span> <span class="nl">pathForResource</span><span class="p">:</span><span class="s">@&#34;MyFramework.framework/Resources/FileName&#34;</span> <span class="nl">ofType</span><span class="p">:</span><span class="s">@&#34;fileExtension&#34;</span><span class="p">];</span>
</span></span></code></pre></div><p>Next we’ll create a new Aggregate Target. As mentioned earlier, to join both architectures products into one, we must to use lipo.</p>
<ul>
<li>Add a new target by pressing the “Add Target” button.</li>
<li>Under the Cocoa Touch section, select the “Other” subcategory and then choose the “Aggregate” target. The “Product Name” is arbitrary.</li>
<li>Add a new “Run Script” phase under this newly created target. Copy and paste the following script into the “Run Script” phase.</li>
</ul>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl"><span class="c1"># The framework name and version</span>
</span></span><span class="line"><span class="cl"><span class="nv">X_FRAMEWORK_NAME</span><span class="o">=</span>CoreFramework
</span></span><span class="line"><span class="cl"><span class="nv">X_FRAMEWORK_VERSION</span><span class="o">=</span>A
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># This folder contains the final output of the framework.</span>
</span></span><span class="line"><span class="cl"><span class="nv">X_INSTALL_DIR</span><span class="o">=</span><span class="si">${</span><span class="nv">SRCROOT</span><span class="si">}</span>/Products/<span class="si">${</span><span class="nv">X_FRAMEWORK_NAME</span><span class="si">}</span>.framework
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># This working directory will be deleted after completion.</span>
</span></span><span class="line"><span class="cl"><span class="nv">X_WORKING_DIR</span><span class="o">=</span>build
</span></span><span class="line"><span class="cl"><span class="nv">X_DEVICE_DIR</span><span class="o">=</span><span class="si">${</span><span class="nv">X_WORKING_DIR</span><span class="si">}</span>/<span class="si">${</span><span class="nv">CONFIGURATION</span><span class="si">}</span>-iphoneos/<span class="si">${</span><span class="nv">X_FRAMEWORK_NAME</span><span class="si">}</span>.framework
</span></span><span class="line"><span class="cl"><span class="nv">X_SIMULATOR_DIR</span><span class="o">=</span><span class="si">${</span><span class="nv">X_WORKING_DIR</span><span class="si">}</span>/<span class="si">${</span><span class="nv">CONFIGURATION</span><span class="si">}</span>-iphonesimulator/<span class="si">${</span><span class="nv">X_FRAMEWORK_NAME</span><span class="si">}</span>.framework
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;******************************************************&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;X_DEVICE_DIR = </span><span class="si">${</span><span class="nv">X_DEVICE_DIR</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;X_SIMULATOR_DIR = </span><span class="si">${</span><span class="nv">X_SIMULATOR_DIR</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;******************************************************&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;SYMROOT = </span><span class="si">${</span><span class="nv">SYMROOT</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;OBJROOT = </span><span class="si">${</span><span class="nv">OBJROOT</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;PROJECT_DIR = </span><span class="si">${</span><span class="nv">PROJECT_DIR</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;CONFIGURATION_BUILD_DIR = </span><span class="si">${</span><span class="nv">CONFIGURATION_BUILD_DIR</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;CONFIGURATION = </span><span class="si">${</span><span class="nv">CONFIGURATION</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;CONFIGURATION_TEMP_DIR = </span><span class="si">${</span><span class="nv">CONFIGURATION_TEMP_DIR</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;DERIVED_FILE_DIR = </span><span class="si">${</span><span class="nv">DERIVED_FILE_DIR</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;BUILD_PRODUCTS_DIR = </span><span class="si">${</span><span class="nv">BUILT_PRODUCTS_DIR</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;BUILD_DIR = </span><span class="si">${</span><span class="nv">BUILD_DIR</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;TARGET_TEMP_DIR = </span><span class="si">${</span><span class="nv">TARGET_TEMP_DIR</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;PROJECT_TEMP_DIR = </span><span class="si">${</span><span class="nv">PROJECT_TEMP_DIR</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;PRODUCT_NAME = </span><span class="si">${</span><span class="nv">PRODUCT_NAME</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;******************************************************&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Build both simulator and device architectures.</span>
</span></span><span class="line"><span class="cl">xcodebuild clean
</span></span><span class="line"><span class="cl">xcodebuild -configuration <span class="si">${</span><span class="nv">CONFIGURATION</span><span class="si">}</span> -target <span class="s2">&#34;</span><span class="si">${</span><span class="nv">X_FRAMEWORK_NAME</span><span class="si">}</span><span class="s2">&#34;</span> -sdk iphoneos -SYMROOT<span class="o">=</span><span class="si">${</span><span class="nv">SYMROOT</span><span class="si">}</span> -OBJROOT<span class="o">=</span><span class="si">${</span><span class="nv">OBJROOT</span><span class="si">}</span>
</span></span><span class="line"><span class="cl">xcodebuild -configuration <span class="si">${</span><span class="nv">CONFIGURATION</span><span class="si">}</span> -target <span class="s2">&#34;</span><span class="si">${</span><span class="nv">X_FRAMEWORK_NAME</span><span class="si">}</span><span class="s2">&#34;</span> -sdk iphonesimulator -SYMROOT<span class="o">=</span><span class="si">${</span><span class="nv">SYMROOT</span><span class="si">}</span> -OBJROOT<span class="o">=</span><span class="si">${</span><span class="nv">OBJROOT</span><span class="si">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Clean the oldest.</span>
</span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="o">[</span> -d <span class="s2">&#34;</span><span class="si">${</span><span class="nv">X_INSTALL_DIR</span><span class="si">}</span><span class="s2">&#34;</span> <span class="o">]</span>
</span></span><span class="line"><span class="cl"><span class="k">then</span>
</span></span><span class="line"><span class="cl">rm -rf <span class="s2">&#34;</span><span class="si">${</span><span class="nv">X_INSTALL_DIR</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">fi</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Recreate the folder structure for the final product binaries.</span>
</span></span><span class="line"><span class="cl">mkdir -p <span class="s2">&#34;</span><span class="si">${</span><span class="nv">X_INSTALL_DIR</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">mkdir -p <span class="s2">&#34;</span><span class="si">${</span><span class="nv">X_INSTALL_DIR</span><span class="si">}</span><span class="s2">/Versions&#34;</span>
</span></span><span class="line"><span class="cl">mkdir -p <span class="s2">&#34;</span><span class="si">${</span><span class="nv">X_INSTALL_DIR</span><span class="si">}</span><span class="s2">/Versions/</span><span class="si">${</span><span class="nv">X_FRAMEWORK_VERSION</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">mkdir -p <span class="s2">&#34;</span><span class="si">${</span><span class="nv">X_INSTALL_DIR</span><span class="si">}</span><span class="s2">/Versions/</span><span class="si">${</span><span class="nv">X_FRAMEWORK_VERSION</span><span class="si">}</span><span class="s2">/Resources&#34;</span>
</span></span><span class="line"><span class="cl">mkdir -p <span class="s2">&#34;</span><span class="si">${</span><span class="nv">X_INSTALL_DIR</span><span class="si">}</span><span class="s2">/Versions/</span><span class="si">${</span><span class="nv">X_FRAMEWORK_VERSION</span><span class="si">}</span><span class="s2">/Headers&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Create the required symbolic links. Please note the paths MUST relative, </span>
</span></span><span class="line"><span class="cl"><span class="c1"># otherwise the symbolic links will be invalid when the folder is copied/moved.</span>
</span></span><span class="line"><span class="cl">ln -s <span class="s2">&#34;</span><span class="si">${</span><span class="nv">X_FRAMEWORK_VERSION</span><span class="si">}</span><span class="s2">&#34;</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">X_INSTALL_DIR</span><span class="si">}</span><span class="s2">/Versions/Current&#34;</span>
</span></span><span class="line"><span class="cl">ln -s <span class="s2">&#34;Versions/Current/Headers&#34;</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">X_INSTALL_DIR</span><span class="si">}</span><span class="s2">/Headers&#34;</span>
</span></span><span class="line"><span class="cl">ln -s <span class="s2">&#34;Versions/Current/Resources&#34;</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">X_INSTALL_DIR</span><span class="si">}</span><span class="s2">/Resources&#34;</span>
</span></span><span class="line"><span class="cl">ln -s <span class="s2">&#34;Versions/Current/</span><span class="si">${</span><span class="nv">X_FRAMEWORK_NAME</span><span class="si">}</span><span class="s2">&#34;</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">X_INSTALL_DIR</span><span class="si">}</span><span class="s2">/</span><span class="si">${</span><span class="nv">X_FRAMEWORK_NAME</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Copy the headers and resources files to the final product folder.</span>
</span></span><span class="line"><span class="cl">cp -R <span class="s2">&#34;</span><span class="si">${</span><span class="nv">X_DEVICE_DIR</span><span class="si">}</span><span class="s2">/Headers/&#34;</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">X_INSTALL_DIR</span><span class="si">}</span><span class="s2">/Versions/</span><span class="si">${</span><span class="nv">X_FRAMEWORK_VERSION</span><span class="si">}</span><span class="s2">/Headers/&#34;</span>
</span></span><span class="line"><span class="cl">cp -R <span class="s2">&#34;</span><span class="si">${</span><span class="nv">X_DEVICE_DIR</span><span class="si">}</span><span class="s2">/&#34;</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">X_INSTALL_DIR</span><span class="si">}</span><span class="s2">/Versions/</span><span class="si">${</span><span class="nv">X_FRAMEWORK_VERSION</span><span class="si">}</span><span class="s2">/Resources/&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Remove artifacts from the resources folder.</span>
</span></span><span class="line"><span class="cl">rm -r <span class="s2">&#34;</span><span class="si">${</span><span class="nv">X_INSTALL_DIR</span><span class="si">}</span><span class="s2">/Versions/</span><span class="si">${</span><span class="nv">X_FRAMEWORK_VERSION</span><span class="si">}</span><span class="s2">/Resources/Headers&#34;</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">X_INSTALL_DIR</span><span class="si">}</span><span class="s2">/Versions/</span><span class="si">${</span><span class="nv">X_FRAMEWORK_VERSION</span><span class="si">}</span><span class="s2">/Resources/</span><span class="si">${</span><span class="nv">X_FRAMEWORK_NAME</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Use lipo to merge both binary files (i386 + armv6/armv7) into one universal files.</span>
</span></span><span class="line"><span class="cl">lipo -create <span class="s2">&#34;</span><span class="si">${</span><span class="nv">X_DEVICE_DIR</span><span class="si">}</span><span class="s2">/</span><span class="si">${</span><span class="nv">X_FRAMEWORK_NAME</span><span class="si">}</span><span class="s2">&#34;</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">X_SIMULATOR_DIR</span><span class="si">}</span><span class="s2">/</span><span class="si">${</span><span class="nv">X_FRAMEWORK_NAME</span><span class="si">}</span><span class="s2">&#34;</span> -output <span class="s2">&#34;</span><span class="si">${</span><span class="nv">X_INSTALL_DIR</span><span class="si">}</span><span class="s2">/Versions/</span><span class="si">${</span><span class="nv">X_FRAMEWORK_VERSION</span><span class="si">}</span><span class="s2">/</span><span class="si">${</span><span class="nv">X_FRAMEWORK_NAME</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Remove the working directory</span>
</span></span><span class="line"><span class="cl">rm -r <span class="s2">&#34;</span><span class="si">${</span><span class="nv">X_WORKING_DIR</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span></code></pre></div><p>You’ll need to modify the first non-comment line in the script to be equal to the product name of your framework bundle target.</p>
<p>Now build the Aggregate target. It does not matter which architecture you select to build (iOS Device or Simulator) since the script creates a working folder, compiles the framework target twice (once for the iOS device and once for the iOS Simulator) and generates the output to a folder named “Products” located in the $(SRCROOT) root folder</p>
<p>If you previously upgraded from Xcode 3.x to 4.2, then your existing (SYMROOT) value will very likely cause the above script to fail. The failure is caused because the script expects your (SYMROOT) value to be set to the new Xcode 4 value of “build”, which refers to a relative path to $(SRCROOT). Unfortunately, you are not able to modify this setting in Xcode 4 due to an already reported bug. To work around this bug, close Xcode and simply delete the existing SYMROOT key and value from your com.apple.dt.Xcode.plist file, which is located in ~/Library/Preferences/.</p>
<p>Isn’t it about time for the WWDC to be here again?</p>]]></content:encoded><category>software engineering</category><category>apple</category></item><item><title>Stop the line so the line never stops.</title><link>https://michaelprimeaux.com/en/posts/2011-09-26-stop-the-line-so-the-line-never-stops/</link><pubDate>Mon, 26 Sep 2011 00:06:00 +0000</pubDate><author>michael@michaelprimeaux.com (Michael Primeaux)</author><guid>https://michaelprimeaux.com/en/posts/2011-09-26-stop-the-line-so-the-line-never-stops/</guid><description/><content:encoded><![CDATA[<p>I recently read 
<a href="http://www.amazon.com/Lean-Startup-Entrepreneurs-Continuous-Innovation/dp/0307887898" class="link-external" rel="noopener noreferrer" target="_blank">The Lean Startup
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 and a corresponding 
<a href="http://techcrunch.com/2011/09/25/founder-stories-eric-ries-lean-startups-stop-the-line-so-the-line/" class="link-external" rel="noopener noreferrer" target="_blank">interview
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 by 
<a href="http://www.crunchbase.com/person/chris-dixon" class="link-external" rel="noopener noreferrer" target="_blank">Chris Dixon
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 (
<a href="http://twitter.com/#!/cdixon" class="link-external" rel="noopener noreferrer" target="_blank">@cdixon
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
) at 
<a href="http://www.crunchbase.com/" class="link-external" rel="noopener noreferrer" target="_blank">CrunchBase
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 with the author, 
<a href="http://www.crunchbase.com/person/eric-ries" class="link-external" rel="noopener noreferrer" target="_blank">Eric Ries
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 (
<a href="http://twitter.com/#!/ericries" class="link-external" rel="noopener noreferrer" target="_blank">@ericries
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
).  Ries tells Dixon one of the phrases Toyota uses on the production line is “stop the line so that the line never stops.” It means “if you want to be able to sustainably have high productivity you have to stop as soon as you have a quality problem and remove it because quality problems pile up and compound… eventually you can grind your whole development organization to a halt.”</p>
<p>One of the more interesting concepts (to me anyway) is the notion of continuous deployment, which is a natural extension of 
<a href="http://en.wikipedia.org/wiki/Continuous_integration" class="link-external" rel="noopener noreferrer" target="_blank">Continuous Integration
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
. Continuously integrate (commit early and often). On commit automatically run all tests. If the tests pass deploy to the cluster. If the deploy succeeds, repeat.</p>
<p>The book is really quite eye-opening and offers a different way of thinking about not only the process of software engineering (by noting a slightly modified version of the 
<a href="http://en.wikipedia.org/wiki/Agile_software_development" class="link-external" rel="noopener noreferrer" target="_blank">Agile
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 development methodology) but the impact of a change to revenue by ignoring 
<a href="http://techcrunch.com/2011/07/30/vanity-metrics" class="link-external" rel="noopener noreferrer" target="_blank">vanity metrics
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
.</p>
<p>I highly recommend this book for anyone who wants to create something new.</p>]]></content:encoded><category>software engineering</category></item><item><title>Efficient Memory Usage in iOS</title><link>https://michaelprimeaux.com/en/posts/2011-06-19-efficient-memory-usage-in-ios/</link><pubDate>Sun, 19 Jun 2011 00:06:00 +0000</pubDate><author>michael@michaelprimeaux.com (Michael Primeaux)</author><guid>https://michaelprimeaux.com/en/posts/2011-06-19-efficient-memory-usage-in-ios/</guid><description>I wrote a post some time back on the value of singletons in a garbage collected language as an important component of scalability. The majority of my work these days targets Apple iOS (opens in a new window) devices and so a reduced memory footprint and overall memory management is not only fundamental but paramount. The use of singleton objects and an effective caching strategy are simple patterns to get you started.</description><content:encoded><![CDATA[<p>I wrote a 
<a href="/blog/2011/05/11/a-word-on-elegance/">post</a>
 some time back on the value of singletons in a garbage collected language as an important component of scalability. The majority of my work these days targets Apple 
<a href="http://en.wikipedia.org/wiki/IOS_%28Apple%29" class="link-external" rel="noopener noreferrer" target="_blank">iOS
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 devices and so a reduced memory footprint and overall memory management is not only fundamental but paramount. The use of singleton objects and an effective caching strategy are simple patterns to get you started.</p>
<p>I suggest reading Apple’s 
<a href="http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Multithreading" class="link-external" rel="noopener noreferrer" target="_blank">Thread Programming Guide
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 as a prerequisite, which also covers some of the basic concepts behind Blocks and 
<a href="http://developer.apple.com/library/mac/#featuredarticles/BlocksGCD/_index.html" class="link-external" rel="noopener noreferrer" target="_blank">Grand Central Dispatch (GCD)
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
.</p>
<h2 id="singletons" class="heading">Singletons
    <a class="heading__anchor" href="#singletons" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h2>
<p>For purposes of this discussion, a singleton is a class that only allows a single instance of itself to be created within an operating system process.</p>
<p>Apple’s 
<a href="http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaObjects/CocoaObjects.html%23//apple_ref/doc/uid/TP40002974-CH4-SW32" class="link-external" rel="noopener noreferrer" target="_blank">documentation
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 on creating a singleton recommends a pattern that works for most iOS applications but is not thread-safe. Beginning with iOS 2.0 and prior to iOS 4.1, one of the most widely used methods to introduce a thread-safe singleton was through the use of the 
<a href="http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Multithreading/ThreadSafety/ThreadSafety.html#//apple_ref/doc/uid/10000057i-CH8-SW3" class="link-external" rel="noopener noreferrer" target="_blank">@synchronized
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 directive.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-objc" data-lang="objc"><span class="line"><span class="cl"><span class="p">+</span> <span class="p">(</span><span class="n">MyClass</span><span class="o">*</span><span class="p">)</span> <span class="nf">instance</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">static</span> <span class="n">MyClass</span> <span class="o">*</span><span class="n">gInstance</span> <span class="o">=</span> <span class="nb">nil</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">@synchronized</span><span class="p">(</span><span class="nb">self</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span><span class="p">(</span><span class="nb">nil</span> <span class="o">==</span> <span class="n">gInstance</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">gInstance</span> <span class="o">=</span> <span class="p">[[</span><span class="n">MyClass</span> <span class="n">alloc</span><span class="p">]</span> <span class="n">init</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="p">(</span><span class="n">gInstance</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>There are a few inefficiencies with this approach because not only generates a recursive mutex lock but also introduces an exception handler. Specifically, Apple’s documentation indicates that as a precautionary measure, the @synchronized block implicitly adds an exception handler to the protected code. This handler automatically releases the mutex in the event that an exception is thrown. This means that in order to use the @synchronized directive, you must also enable Objective-C exception handling in your code. If you do not want the additional overhead caused by the implicit exception handler, you should consider using the lock classes.</p>
<p>At the time of this writing, the @synchronized directive turns into this basic pseudo-code:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-objc" data-lang="objc"><span class="line"><span class="cl"><span class="kt">id</span> <span class="n">_eval_once</span> <span class="o">=</span> <span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="n">objc_sync_enter</span><span class="p">(</span> <span class="n">_eval_once</span> <span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="k">@try</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="cm">/* code goes here */</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="k">@finally</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">objc_sync_exit</span><span class="p">(</span> <span class="n">_eval_once</span> <span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>For implementation details see: 
<a href="http://www.opensource.apple.com/source/objc4/objc4-437.1/runtime/objc-sync.m" class="link-external" rel="noopener noreferrer" target="_blank">http://www.opensource.apple.com/source/objc4/objc4-437.1/runtime/objc-sync.m
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
</p>
<p>Much of Apple’s sample code prior to iOS 4.0 use this approach. There is a technically more efficient and lock-free approach for applications that target operating systems earlier than Mac OS X version 10.5 or iOS 4.0.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-objc" data-lang="objc"><span class="line"><span class="cl"><span class="p">+</span> <span class="p">(</span><span class="n">MyClass</span><span class="o">*</span><span class="p">)</span> <span class="nf">gInstance</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">static</span> <span class="kt">void</span> <span class="o">*</span> <span class="k">volatile</span> <span class="n">gInstance</span> <span class="o">=</span> <span class="nb">nil</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">while</span> <span class="p">(</span><span class="o">!</span><span class="n">gInstance</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">MyClass</span> <span class="o">*</span><span class="n">temp</span> <span class="o">=</span> <span class="p">[</span><span class="n">MyClass</span> <span class="p">[</span><span class="n">alloc</span><span class="p">]</span> <span class="n">init</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">OSAtomicCompareAndSwapPtrBarrier</span><span class="p">(</span><span class="mh">0x0</span><span class="p">,</span> <span class="n">temp</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">gInstance</span><span class="p">))</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="p">[</span><span class="n">temp</span> <span class="k">release</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="p">(</span><span class="n">gInstance</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>You can read more about preferred versions of the atomic and synchronization operations 
<a href="http://developer.apple.com/library/mac/#documentation/DriversKernelHardware/Reference/libkern_ref/OSAtomic_h/index.html" class="link-external" rel="noopener noreferrer" target="_blank">here
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
.</p>
<p>For applications that target operating systems equal to or greater than Mac OS X 10.6 or iOS 4.0, the recommended singleton pattern uses dispatch_once, which relies on components of Grand Central Dispatch (GCD).</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-objc" data-lang="objc"><span class="line"><span class="cl"><span class="p">+</span> <span class="p">(</span><span class="n">MyClass</span> <span class="o">*</span><span class="p">)</span> <span class="nf">instance</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">static</span> <span class="n">MyClass</span><span class="o">*</span> <span class="n">gInstance</span> <span class="o">=</span> <span class="nb">nil</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">static</span> <span class="n">dispatch_once_t</span> <span class="n">pred</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"> 
</span></span><span class="line"><span class="cl">    <span class="n">dispatch_once</span><span class="p">(</span><span class="o">&amp;</span><span class="n">pred</span><span class="p">,</span> <span class="o">^</span><span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">gInstance</span> <span class="o">=</span> <span class="p">[[</span><span class="n">MyClass</span> <span class="n">alloc</span><span class="p">]</span> <span class="n">init</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">    <span class="p">});</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="p">(</span><span class="n">gInstance</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>It should go without saying but I’ll do so for completeness. All instance-level methods of classes that implement a singleton pattern 
<a href="http://www.ietf.org/rfc/rfc2119.txt" class="link-external" rel="noopener noreferrer" target="_blank">MUST
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 be thread-safe.</p>
<h2 id="nscache" class="heading">NSCache
    <a class="heading__anchor" href="#nscache" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h2>
<p>I suspect this class remains relatively unused by most iOS developers. 
<a href="http://developer.apple.com/library/ios/#documentation/Cocoa/Reference/NSCache_Class/Reference/Reference.html" class="link-external" rel="noopener noreferrer" target="_blank">NSCache
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 is essentially a container that it stores key-value pairs but unfortunately does so without an O(1) time complexity (like that of 
<a href="http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSMutableDictionary_Class/Reference/Reference.html" class="link-external" rel="noopener noreferrer" target="_blank">NSMutableDictionary
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
) but does automatically evicts objects from its store when the ‘cost’ (a heuristic that of course involves memory pressure) of the cache rises above a configurable threshold.</p>
<p>Per Apple’s documentation, NSCache objects differ from other mutable collections in a few ways:</p>
<ul>
<li>The NSCache class incorporates various auto-removal policies, which ensure that it does not use too much of the system’s memory. The system automatically carries out these policies if memory is needed by other applications. When invoked, these policies remove some items from the cache, minimizing its memory footprint.</li>
<li>You can add, remove, and query items in the cache from different threads without having to lock the cache yourself.</li>
<li>Retrieving something from an NSCache object returns an autoreleased result.</li>
<li>Unlike an NSMutableDictionary object, a cache does not copy the key objects that are put into it.These features are necessary for the NSCache class, as the cache may decide to automatically mutate itself asynchronously behind the scenes if it is called to free up memory.</li>
</ul>
<p>Though not required, NSCache works in conjunction with objects that implement the 
<a href="http://developer.apple.com/library/mac/documentation/cocoa/reference/NSDiscardableContent_Protocol/Reference/Reference.html#//apple_ref/occ/intf/NSDiscardableContent" class="link-external" rel="noopener noreferrer" target="_blank">NSDiscardableContent
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 protocol in that the 
<a href="http://developer.apple.com/library/mac/documentation/cocoa/reference/NSDiscardableContent_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/NSDiscardableContent/discardContentIfPossible" class="link-external" rel="noopener noreferrer" target="_blank">discardContentIfPossible
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 method is called when an object is removed.</p>
<p>The two most widely used caching strategies are proactive and reactive loading.</p>
<ol>
<li><strong>Proactive Cache Loading</strong>. A proactive cache loading strategy attempts to retrieve all required state when a process or application starts and cache it for the lifetime of the process or application. A decision to use a proactive cache loading strategy is generally done so in conjunction with either asynchronous pull loading based on expected not actual usage of the information being cached or notification-based loading whereby an application’s services are notified when cached state changes.</li>
<li><strong>Reactive Cache Loading</strong>. A reactive cache loading strategy retrieves data as it is requested by the application and caches it for future requests. A decision to use a reactive cache loading strategy is generally done so in conjunction with synchronous pull loading since the pattern is relatively easy to test and implement.</li>
</ol>
<p>Regardless of the selected caching strategy, determining a cache expiration policy is is key for most applications. There are a plethora of expiration policy patterns but the majority of them fall into the following general categories:</p>
<ul>
<li><strong>Time-based</strong>. Cached information is invalidated based on relative (sliding window) or absolute time periods.</li>
<li><strong>Notification-based</strong>. Cached information is invalidated based on instructions from a source.</li>
<li><strong>Counter-based</strong>. Cached information is invalidated based on a reference counts.</li>
</ul>
<p>Regardless of the expiration policy, scavenging based on memory pressure and other heuristics are key to a proper cache design and symmetry of that design is a key component in any distributed algorithm.</p>
<p>For most applications, a reactive cache loading strategy with a synchronous pull model is the most appropriate option. NSCache does evict objects based on memory pressure and so I strongly recommend you implement the NSDiscardableContent protocol for any objects you plan to store in NSCache. NSDiscardableContent is a simple counter-based pattern. For information stored in NSCache that represents NSData objects, Apple provides the 
<a href="http://developer.apple.com/library/mac/documentation/cocoa/reference/NSPurgeableData_Class/Reference/Reference.html#//apple_ref/occ/cl/NSPurgeableData" class="link-external" rel="noopener noreferrer" target="_blank">NSPurgeableData
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 class. NSPurgeable data inherits from NSMutableData and is available in iOS 4.0 and Mac OS X 10.6 and later. A description of how to use this class can be found be reading 
<a href="http://developer.apple.com/library/mac/#technotes/CachingPurgeableMemory/Introduction/Introduction.html" class="link-external" rel="noopener noreferrer" target="_blank">Caching and Purgeable Memory
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
.</p>
<p>I’d like to make one last point. Please be careful not to over-engineer your caching strategy but be elegant about your design.</p>]]></content:encoded><category>software engineering</category><category>apple</category></item><item><title>Apple WWDC 2011</title><link>https://michaelprimeaux.com/en/posts/2011-06-08-apple-wwdc-2011/</link><pubDate>Wed, 08 Jun 2011 00:06:00 +0000</pubDate><author>michael@michaelprimeaux.com (Michael Primeaux)</author><guid>https://michaelprimeaux.com/en/posts/2011-06-08-apple-wwdc-2011/</guid><description>I’ve attended the Apple WWDC (opens in a new window) for the past 4 years and it’s been nothing short of exciting each year. This year, event sold out in 10 hours and so I am fortunate to have a spot. In contrast to last year, the event sold out in approxiately 14 days. Steve Jobs delivered a very interesting keynote speech (opens in a new window) with features that in my opinion ensure Apple will continue to stay a few years ahead of all other mobile companies. It’s amazing to think how far we’ve come since my first 4 Macs, which were the Apple II (opens in a new window) , IIc (opens in a new window) , IIe (opens in a new window) , and IIGS (opens in a new window) . Ahhh…and let us not forget other microcomputers such as the Amiga (opens in a new window) , Commodore 64 (opens in a new window) , and the earlier TRS-80 (opens in a new window) (also known as the “trash 80″). The TRS-80 was in fact technically my first personal computer.</description><content:encoded><![CDATA[<p>I’ve attended the 
<a href="http://developer.apple.com/wwdc/" class="link-external" rel="noopener noreferrer" target="_blank">Apple WWDC
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 for the past 4 years and it’s been nothing short of exciting each year. This year, event sold out in 10 hours and so I am fortunate to have a spot. In contrast to last year, the event sold out in approxiately 14 days. Steve Jobs delivered a very interesting 
<a href="http://events.apple.com.edgesuite.net/11piubpwiqubf06/event/" class="link-external" rel="noopener noreferrer" target="_blank">keynote speech
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 with features that in my opinion ensure Apple will continue to stay a few years ahead of all other mobile companies. It’s amazing to think how far we’ve come since my first 4 Macs, which were the 
<a href="http://en.wikipedia.org/wiki/Apple_II" class="link-external" rel="noopener noreferrer" target="_blank">Apple II
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
, 
<a href="http://en.wikipedia.org/wiki/Apple_IIc" class="link-external" rel="noopener noreferrer" target="_blank">IIc
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
, 
<a href="http://en.wikipedia.org/wiki/Apple_IIe" class="link-external" rel="noopener noreferrer" target="_blank">IIe
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
, and 
<a href="http://en.wikipedia.org/wiki/Apple_IIGS" class="link-external" rel="noopener noreferrer" target="_blank">IIGS
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
. Ahhh…and let us not forget other microcomputers such as the 
<a href="http://en.wikipedia.org/wiki/Amiga" class="link-external" rel="noopener noreferrer" target="_blank">Amiga
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
, 
<a href="http://en.wikipedia.org/wiki/Commodore_64" class="link-external" rel="noopener noreferrer" target="_blank">Commodore 64
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
, and the earlier 
<a href="http://en.wikipedia.org/wiki/TRS-80" class="link-external" rel="noopener noreferrer" target="_blank">TRS-80
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 (also known as the “trash 80″).  The TRS-80 was in fact technically my first personal computer.</p>
<p>Here are a few very interesting statistics at the time of this writing:</p>
<ul>
<li>There are over 225 million iOS devices worldwide.</li>
<li>Apple represents a 48% share of the tablet and mobile market.</li>
<li>25 million iPads have been sold to date.</li>
<li>There are 425,000 applications in the App Store with 90,000 of those applications specifically designed to run on the iPad.</li>
<li>The App Store has enjoyed over 14 billion downloads</li>
<li>Apple has 225 million credit card accounts.</li>
<li>Apple has shipped 54 million Macs and growing, which is a 28% growth over last year. To contrast this, PC growth is at a negative 1% growth over the same year.</li>
<li>73% of the Macs shipped today are notebooks</li>
</ul>
<p>These statistics are astounding.  I am of course not at liberty to discuss any information not made public by Apple regarding the upcoming technologies but it is sufficed to say Mac OS X Lion + 
<a href="http://www.apple.com/icloud/" class="link-external" rel="noopener noreferrer" target="_blank">iCloud
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 + 
<a href="http://www.apple.com/ios/ios5/" class="link-external" rel="noopener noreferrer" target="_blank">iOS 5
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 represents another leap in market share for Apple and a set of very useful features for consumers.</p>
]]></content:encoded><category>apple</category></item><item><title>A Word on Elegance</title><link>https://michaelprimeaux.com/en/posts/2011-05-11-a-word-on-elegance/</link><pubDate>Wed, 11 May 2011 00:06:00 +0000</pubDate><author>michael@michaelprimeaux.com (Michael Primeaux)</author><guid>https://michaelprimeaux.com/en/posts/2011-05-11-a-word-on-elegance/</guid><description>What do I mean by elegance? Most software engineers equate elegance to efficiency. Still some equate elegance to robustness. Others choose correctness. All are variables in the equation of elegance. Many other variables exist and all are important.
Make no mistake, software is art. Some artists prefer oil on canvas as their medium. Others choose water color. As software design engineers (SDEs), we have chosen 1s and 0s to communicate our creative visions. Elegance must exist at each step in the engineering process and not only as an afterthought in the development phase. Elegance is the responsibility of each and every participant with accountability functioning as the enforcement point. Without accountability, chaos reigns. Accountability starts within.</description><content:encoded><![CDATA[<p>What do I mean by elegance? Most software engineers equate elegance to efficiency. Still some equate elegance to robustness. Others choose correctness. All are variables in the equation of elegance. Many other variables exist and all are important.</p>
<p>Make no mistake, software is art. Some artists prefer oil on canvas as their medium. Others choose water color. As software design engineers (SDEs), we have chosen 1s and 0s to communicate our creative visions. Elegance must exist at each step in the engineering process and not only as an afterthought in the development phase. Elegance is the responsibility of each and every participant with accountability functioning as the enforcement point. Without accountability, chaos reigns. Accountability starts within.</p>
<p>Many software engineers find themselves searching for or memorizing patterns that “work” to shortly find themselves bulimically spewing the results onto their canvas. What happened to the elegance of originality? It’s far too easy to become a GP (“Google programmer”). Why? Because creativity and originality aren’t as convenient as letting others do the work, which leads to chaos and hard-to-maintain code; especially, when you’re not the original developer.</p>
<p>Stay with me; we’re only scratching the surface. Do you remember the last time you really evaluated the usability of your consumer API surface? Did your evaluation begin in the design phase? Start with a high-level view of the scenarios. Then oscillate between architectural design and the scenario-based consumer API surface. Do not think about technical design until you’re satisfied with the consumer API surface and the architectural design. Keep in mind; it’s certainly acceptable to refactor your architectural design and consumer API based on the technical design.</p>
<p>An apparent and even larger obstacle I’ve noticed lately is the inability for an SDE to make the jump from procedure (function)-oriented design concepts to that of object-oriented design while keeping an eye to efficiency in terms computational complexity and network round-trips. The devil is in the details. In my opinion, one can’t be an effective architect without being an even more effective SDE; period. The implementation details do change the architecture.</p>
<p>In general, people tend to migrate toward what makes them feel good. Rework doesn’t feel good; no one enjoys it. But, if that was true—if you truly don’t enjoy rework—then why would you not elegantly architect, design, and develop your code initially? Why do you make more work for yourself? Elegance as a foundational element is difficult. More often than not, SDEs take the easy way out because they equate efficiency to speed of completion. I’m not advocating “analysis paralysis” but instead a balanced design. Deadlines must be met. Deadlines should not be met at the expense of elegance.</p>
<p>It’s your canvas.</p>
]]></content:encoded><category>computing</category><category>software engineering</category></item><item><title>Fabric of a Distributed System</title><link>https://michaelprimeaux.com/en/posts/2010-12-02-fabric-of-a-distributed-system/</link><pubDate>Thu, 02 Dec 2010 00:06:00 +0000</pubDate><author>michael@michaelprimeaux.com (Michael Primeaux)</author><guid>https://michaelprimeaux.com/en/posts/2010-12-02-fabric-of-a-distributed-system/</guid><description>” It has been said that art is a collaboration between God and the artist, which works best when the artist contributes as little as possible; so too with designing distributed systems ” –André Gide
Try to imagine the strategic direction of distributed computing frameworks. Just for a moment transition into a state where you think of nothing and yet listen to everything. What key technologies (disruptive or otherwise) have we experienced over recent years?</description><content:encoded><![CDATA[<blockquote><p>” It has been said that art is a collaboration between God and the artist, which works best when the artist contributes as little as possible; so too with designing distributed systems ” –André Gide</p>
</blockquote>
<p>Try to imagine the strategic direction of distributed computing frameworks. Just for a moment transition into a state where you think of nothing and yet listen to everything. What key technologies (disruptive or otherwise) have we experienced over recent years?</p>
<h1 id="notion-of-autonomous-computing" class="heading">Notion of Autonomous Computing
</h1>
<p>Arguably, one of the most well known papers on the subject of 
<a href="http://en.wikipedia.org/wiki/Autonomic_computing" class="link-external" rel="noopener noreferrer" target="_blank">autonomic computing
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 to be recently released is titled “Autonomic Computing: IBM’s Perspective on the State of Information Technology” [
<a href="http://www.research.ibm.com/autonomic" class="link-external" rel="noopener noreferrer" target="_blank">URI
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
]; authored by 
<a href="http://www.research.ibm.com/about/pmhorn.shtml" class="link-external" rel="noopener noreferrer" target="_blank">Paul Horn
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
, Senior Vice President of 
<a href="http://research.ibm.com/" class="link-external" rel="noopener noreferrer" target="_blank">IBM Research
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
. As outlined by Dr. Horn’s manifest, there are many challenges we face over the next decade within Information Technology.</p>
<p>Within the autonomic landscape, each system node must satisfy the following criteria:</p>
<ul>
<li>self-identification, self-knowing</li>
<li>self-(re)configuration</li>
<li>self-recovery (from perturbations)</li>
<li>self-protection (security)</li>
<li>self-learning (including from errors)</li>
<li>self-regulating (to open standards)</li>
<li>self-resource-allocation</li>
</ul>
<h1 id="notion-of-grid-computing" class="heading">Notion of Grid Computing
</h1>
<p>Wouldn’t it be nice to economically provide a highly available and fault tolerant system that can support an annual uptime guarantee of 99.999 percent—which equates to 5.256 minutes of annual unscheduled downtime—and that scales up by a factor of 106? That is, an application’s storage and processing capacity can automatically grow by a factor of a million, doing jobs faster (106x speed up) or doing 106 larger jobs in the same time (106x scale up), just by adding more resources. Stay focused.</p>
<p>The concept of Grid (or Utility) computing was coined in the mid 1990s and is best defined—to quote 
<a href="http://www.globus.org/alliance/publications/papers/anatomy.pdf" class="link-external" rel="noopener noreferrer" target="_blank">The Anatomy of the Grid
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
—the real and specific problem that underlies the Grid concept is coordinated resource sharing and problem solving in dynamic, multi-institutional virtual organizations.</p>
<p>The 
<a href="http://www.gridforum.org/" class="link-external" rel="noopener noreferrer" target="_blank">Grid Global Forum (GGF
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
) has made great headway; so has OGSA (Open Grid Services Architecture). 
<a href="http://www.mpi-forum.org/" class="link-external" rel="noopener noreferrer" target="_blank">Message Passing Interface (MPI)
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 is widely accepted. Microsoft entered the 
<a href="http://en.wikipedia.org/wiki/High_Performance_Computing" class="link-external" rel="noopener noreferrer" target="_blank">HPC
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 game with the 
<a href="http://www.microsoft.com/windowsserver2003/ccs/default.mspx" class="link-external" rel="noopener noreferrer" target="_blank">Microsoft Compute Cluster Server
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
, which I installed many months ago and is now consuming most of my free time.</p>
<h1 id="notion-of-adaptive-autonomous-agents" class="heading">Notion of Adaptive Autonomous Agents
</h1>
<p>An agent is a system that tries to fulfill a set of goals of goals in a complex, dynamic environment. An agent it situated in the environment; it can sense the environment through its sensors and act upon the environment using its actuators. An agent’s goal can take many different forms: they can be “end goals”, or particular states the agent tries to achieve; they can be selective reinforcement or reward that the agent attempts to maximize; they can be internal needs or motivations that the agent has to keep within certain viability zones and so on. An agent is called autonomous if it operates completely autonomously, i.e. if it decides itself how to relate its sensor data to motor commands in such a way that its goals are attended to successfully. An agent it said to be adaptive, if it is able to improve over time, i.e. if the agent becomes better at achieving its goals with experience.</p>
<p>The study of Adaptive Autonomous Agents is grounded in two important insights, which serve as “guiding principles” for most of the current research performed:</p>
<ul>
<li>Looking at complete systems changes the problems often in a favorable way.</li>
<li>Interaction dynamics can lead to emergent complexity.</li>
</ul>
<p>Essentially, an agent is viewed as a set of competence modules (often called behaviors). These modules are responsible for a particular small task-oriented competence. Each of the modules is directly connected to its relevant sensors and actuators. Modules interface to one another via extremely simple messages rather than a common representation of beliefs, and so on. The communication between modules is almost never of a “broadcast” nature, but happens rather on a point-to-point (or one-to-one) bases. Typically, the messages consist of activation energy, or simple suppression and inhibition signals, or simple tokens in a restricted language. In addition to communication via simple messages, modules also communicate “via the environment”. One module may change some aspect of the environment, which will trigger another module, etc.</p>
<h1 id="notion-of-the-semantic-web" class="heading">Notion of the Semantic Web
</h1>
<p>Simply put, the 
<a href="http://www.w3.org/2001/sw/" class="link-external" rel="noopener noreferrer" target="_blank">Semantic Web
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 is the representation of data on the web in which information is given well-defined meaning—“to be a universal medium for the exchange of data”.</p>
<p>The principal technologies of the Semantic Web fit into a set of layered specifications called the 
<a href="http://www.w3.org/RDF/" class="link-external" rel="noopener noreferrer" target="_blank">Resource Description Framework (RDF)
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
. The current components of that framework are the RDF Core Model, the RDF Vocabulary Description Language and the Web Ontology Language, which all build on the foundation of URIs, XML, and XML namespaces.</p>
<p>The most interesting of these languages is the 
<a href="http://www.w3.org/2004/OWL/" class="link-external" rel="noopener noreferrer" target="_blank">Web Ontology Language (OWL)
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
, which is a descriptive layer built on top of RDF used to model classes, properties, and objects.</p>
<p>Ontology is also a term borrowed from philosophy that refers to the science of describing the kinds of entities in the world and how they are related. Stated another way, an ontology defines the terms used to describe and represent an area of knowledge.</p>
<h1 id="notion-of-service-oriented-architecture" class="heading">Notion of Service-Oriented Architecture
</h1>
<p>I think everyone has been beaten of the head with the “SOA stick”, which is why you won’t feel a thing; keep reading.</p>
<p>In computing, the term Service-Oriented Architecture (SOA) expresses a software architectural concept that defines the use of services to support the requirements of software users. In a SOA environment, nodes on a network make resources available to other participants in the network as independent services that the participants access in a standardized way. Most definitions of SOA identify the use of Web services (i.e. using SOAP or REST) in its implementation. 
<a href="http://www.intertwingly.net/stories/2002/07/20/restSoap.html" class="link-external" rel="noopener noreferrer" target="_blank">Here
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 and 
<a href="http://www.prescod.net/rest/rest_vs_soap_overview/" class="link-external" rel="noopener noreferrer" target="_blank">here
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 are two links worth reading. However, one can implement SOA using any service-based technology.</p>
<p>The WS* specifications have gained wide adoption but other advances are needed.</p>
<p>One last point as related to service orientation; I caution everyone to not forget about the elegance in design of class libraries as they are the underpinnings of every SOA. Design for the in-process consumer first with an eye to areas of the API surface that might benefit from hosting within an SOA.</p>
<p>Other advances…</p>
<p>There are many others such as advances in peer-to-peer algorithms, discrete-event simulation and the event horizon, social networking, recovery-oriented systems, storage and machine virtualization, 
<a href="http://en.wikipedia.org/wiki/Bio_informatics" class="link-external" rel="noopener noreferrer" target="_blank">bioinformatics
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
, 
<a href="http://en.wikipedia.org/wiki/Biotechnology" class="link-external" rel="noopener noreferrer" target="_blank">biotechnology
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
, and 
<a href="http://en.wikipedia.org/wiki/Quantum_computing" class="link-external" rel="noopener noreferrer" target="_blank">quantum computing
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 to name but a few. In my mind, the two most important questions to answer are which of these variables are of significant weighting in the equation of strategic direction and which are “noise”?  I certainly have my opinion…but then again, you know what those are like.</p>
<p>Most readers and programmers have little patience to read discussions of this length. However, the length (at least to me) seems disproportionate to the importance of the topic. There is so much more to say and even more to ponder. But, before you run off to save the world let me leave you with one additional thought:</p>

<blockquote><p>“The map is not the territory.”
Alfred Korzybsky
Science and Sanity, 1933</p>
</blockquote>]]></content:encoded><category>computing</category><category>distributed systems</category></item><item><title>MethodImplOptions.Synchronized</title><link>https://michaelprimeaux.com/en/posts/2008-01-09-methodimploptions-dot-synchronized/</link><pubDate>Wed, 09 Jan 2008 00:06:00 +0000</pubDate><author>michael@michaelprimeaux.com (Michael Primeaux)</author><guid>https://michaelprimeaux.com/en/posts/2008-01-09-methodimploptions-dot-synchronized/</guid><description>Recent discussions with colleagues regarding use of MethodImplOptions.Synchronized (opens in a new window) prompted me to discuss its implications.
Let’s begin with formal documentation. The MethodImplOptions.Synchronized option “specifies that the method can be executed by only one thread at a time. Static methods lock on the type, while instance methods lock on the instance. Only one thread can execute in any of the instance functions and only one thread can execute in any of a class’s static functions”.</description><content:encoded><![CDATA[<p>Recent discussions with colleagues regarding use of 
<a href="http://msdn2.microsoft.com/en-us/library/system.runtime.compilerservices.methodimploptions%28VS.71%29.aspx" class="link-external" rel="noopener noreferrer" target="_blank">MethodImplOptions.Synchronized
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 prompted me to discuss its implications.</p>
<p>Let’s begin with formal documentation. The MethodImplOptions.Synchronized option “specifies that the method can be executed by only one thread at a time. Static methods lock on the type, while instance methods lock on the instance. Only one thread can execute in any of the instance functions and only one thread can execute in any of a class’s static functions”.</p>
<p>I’d like to focus on the statement “static methods lock on the type”. Microsoft strongly discourages locking on any public types, or on instances you do not control. This means the common constructs lock(this), lock(typeof(SomeType)), and lock(“myLock”) violate this guideline. If you’re not yet familiar with the reason behind this guideline then please read 
<a href="http://www.bluebytesoftware.com/blog/default.aspx" class="link-external" rel="noopener noreferrer" target="_blank">Joe Duffy’s
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 blog entry titled “
<a href="http://www.bluebytesoftware.com/blog/2005/09/29/RudeUnloadsAndOrphanedLocks.aspx" class="link-external" rel="noopener noreferrer" target="_blank">Rude unloads and orphaned locks
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
“. To provide additional support for Joe’s comments, the formal documentation for MethodImplOptions states “Locking on the instance or on the type, as with the Synchronized flag, is not recommended for public types because code other than your own can take locks on public types and instances. This might cause deadlocks or other synchronization problems.”</p>
<p>To be explicit, the lock(typeof(MyClass)) semantic is exactly what MethodImplOptions.Synchronized implements when adorned on static methods . The lock in this case is across all 
<a href="http://msdn2.microsoft.com/en-us/library/system.appdomain.aspx" class="link-external" rel="noopener noreferrer" target="_blank">AppDomains
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 in the same operating system process. Consider the following code, which if executed from multiple AppDomains would result in a conflict.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="n">ManualResetEvent</span> <span class="n">e1</span><span class="p">=</span> <span class="k">new</span> <span class="n">ManualResetEvent</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="k">lock</span> <span class="p">(</span><span class="k">typeof</span><span class="p">(</span><span class="kt">object</span><span class="p">))</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">AppDomain</span> <span class="n">domain</span> <span class="p">=</span> <span class="n">AppDomain</span><span class="p">.</span><span class="n">CreateDomain</span><span class="p">(</span><span class="s">&#34;MyDomain&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">domain</span><span class="p">.</span><span class="n">DoCallBack</span><span class="p">(</span><span class="k">delegate</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">ThreadPool</span><span class="p">.</span><span class="n">QueueUserWorkItem</span><span class="p">(</span><span class="k">delegate</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">ManualResetEvent</span> <span class="n">e2</span><span class="p">=</span> <span class="k">new</span> <span class="n">ManualResetEvent</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="k">lock</span> <span class="p">(</span><span class="k">typeof</span><span class="p">(</span><span class="kt">object</span><span class="p">))</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="n">e2</span><span class="p">.</span><span class="n">Set</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="p">});</span>
</span></span><span class="line"><span class="cl">    <span class="p">});</span>
</span></span><span class="line"><span class="cl"> 
</span></span><span class="line"><span class="cl">    <span class="n">e1</span><span class="p">.</span><span class="n">WaitOne</span><span class="p">();</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>As a result, you should shy away from using MethodImplOptions.Synchronized for the same reasons you wouldn’t use lock(this) or lock(typeof(SomeClass)).</p>
<p>Additionally, the MethodImplOptions.Synchronized option favors neither readers nor writers. Use of a low-locking technique such as a 
<a href="http://en.wikipedia.org/wiki/Spinlock" class="link-external" rel="noopener noreferrer" target="_blank">spinlock
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 or the intrinsic 
<a href="http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim.aspx" class="link-external" rel="noopener noreferrer" target="_blank">ReaderWriterLockSlim
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 and 
<a href="http://msdn.microsoft.com/en-us/library/system.threading.monitor.aspx" class="link-external" rel="noopener noreferrer" target="_blank">Monitor
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 classes will perform and scale much better on both single-core and multi-core (CPU) hardware.</p>
<p>The above points are important for several reasons:</p>
<ol>
<li>The scope of a lock is very relevant if a goal of your code is reuse. As a framework writer is it your responsibility to ensure consumers writing applications with differing scalability thresholds and concurrency rates are equally favored; the solution should either work for all consumers or offer options for each category of consumer.</li>
<li>If you’re writing code that is to be used in systems where efficient use of system resources (CPU and memory) is paramount then it is your responsibility to provide an implementation that meets this fundamental goal.</li>
<li>If you’re executing under the Microsoft SQL Server CLR host and your code takes too long to execute then SQL will force an AppDomain unload, which means (as a specific example), that a finally block wishing to execute Monitor.Exit won’t even be run. As Joe indicates, until you’ve created 4,294,967,295 threads such that the Thread IDs wrap around and the old ID gets assigned to a new thread, and that thread spuriously decides to Exit the Monitor without acquiring it first, your system is going to be locked up for a bit. In other words, deadlocked.</li>
<li>The MethodImplAttribute can only be used to adorn (you guessed it) methods.</li>
</ol>
<p>So how much of a difference can a low-locking technique really make? That obviously depends on the technique. I wrote a parallelized program (using the 
<a href="http://www.distributethis.com/post/2007/12/Microsoft-Parallel-Extensions-to-NET-Framework-35.aspx" class="link-external" rel="noopener noreferrer" target="_blank">Microsoft Parallel Extensions for .NET 3.5
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
) that tests synchronization using MethodImplOptions.Synchronized, Monitor, Interlocked, ReaderWriterLockSlim, and a spin-lock. For those interested, I’ve included my spin-lock implementation to the bottom of this article.</p>
<p><strong>Result Set 1: Write-only access:</strong></p>
<ul>
<li>Monitor executed 10,000,000 iterations in 13,372,540 (ticks), which is 747 iterations per tick.</li>
<li>Interlocked executed 10,000,000 iterations in 18,767,746 (ticks), which is 532 iterations per tick.</li>
<li>ReaderWriterLockSlim executed 10,000,000 iterations in 18,908,171 (ticks), which is 528 iterations per tick.</li>
<li>MethodImpl executed 10,000,000 iterations in 22,724,176 (ticks), which is 440 iterations per tick.</li>
<li>SpinLock executed 10,000,000 iterations in 17,713,122 (ticks), which is 564 iterations per tick.</li>
</ul>
<p><strong>Result Set 2: Read/write access with an equal read and write frequency:</strong></p>
<ul>
<li>Monitor executed 10,000,000 iterations in 23,701,864 (ticks), which is 421 executions iterations per tick.</li>
<li>Interlocked executed 10,000,000 iterations in 19,864,150 (ticks), which is 503 iterations per tick.</li>
<li>ReaderWriterLockSlim executed 10,000,000 iterations in 33,751,562 (ticks), which is 296 iterations per tick.</li>
<li>MethodImpl executed 10,000,000 iterations in 43,442,379 (ticks), which is 230 iterations per tick.</li>
<li>SpinLock executed 10,000,000 iterations in 20,713,905 (ticks), which is 482 iterations per tick.</li>
</ul>
<p><strong>Result Sets 3: Read-only access:</strong></p>
<ul>
<li>Monitor executed 10,000,000 iterations in 13,810,171 (ticks), which is 724 iterations per tick.</li>
<li>Interlocked executed 10,000,000 iterations in 17,628,526 (ticks), which is 567 iterations per tick.</li>
<li>ReaderWriterLockSlim executed 10,000,000 iterations in 20,326,949 (ticks), which is 491 iterations per tick.</li>
<li>MethodImpl executed 10,000,000 iterations in 34,891,919 (ticks), which is 286 iterations per tick.</li>
<li>SpinLock executed 10,000,000 iterations in 7,046,085 (ticks), which is 1,419 iterations per tick.</li>
</ul>
<p>The results are not surprising. Use of the MethodImplOptions.Synchronized option on static methods resulted in a lower concurrency rate. If you require thread synchronization for static methods then I strongly recommend you consider an alternate synchronization technique.</p>
<p>The full source code can be found 
<a href="/files/SpinLock.zip">here</a>
.</p>]]></content:encoded><category>computing</category><category>software engineering</category></item><item><title>Singletons in C#</title><link>https://michaelprimeaux.com/en/posts/2007-12-13-singletons-in-c-sharp/</link><pubDate>Thu, 13 Dec 2007 00:06:00 +0000</pubDate><author>michael@michaelprimeaux.com (Michael Primeaux)</author><guid>https://michaelprimeaux.com/en/posts/2007-12-13-singletons-in-c-sharp/</guid><description>In many ways software engineering strives to strike a balance between testability, scalability (and performance), execution logic and symmetry (in the case of distributed algorithms), and semantics (easily understood and usable) while remaining efficient in the use of system resources. In my opinion, these major variables are all of equal weighting; these define the elegance of a particular design.
For this discussion, I’d like to focus on two of the variables: testability and efficient use of system resources.</description><content:encoded><![CDATA[<p>In many ways software engineering strives to strike a balance between testability, scalability (and performance), execution logic and symmetry (in the case of distributed algorithms), and semantics (easily understood and usable) while remaining efficient in the use of system resources. In my opinion, these major variables are all of equal weighting; these define the 
<a href="/blog/2011/05/11/a-word-on-elegance/">elegance</a>
 of a particular design.</p>
<p>For this discussion, I’d like to focus on two of the variables: testability and efficient use of system resources.</p>
<h3 id="garbage-collection" class="heading">Garbage Collection
    <a class="heading__anchor" href="#garbage-collection" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h3>
<p>As a prerequisite, I recommend you read 
<a href="http://msdn2.microsoft.com/en-us/library/ms973837.aspx" class="link-external" rel="noopener noreferrer" target="_blank">this article
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 on how garbage collection works at a high-level in the Microsoft .NET Framework. If you 
<a href="http://en.wikipedia.org/wiki/Attention-Deficit_Hyperactivity_Disorder" class="link-external" rel="noopener noreferrer" target="_blank">don’t have time
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 to read the article then do take time to read the next paragraph.</p>
<p>The following is a good idea what sorts of things we should try to avoid to get the best performance out of the garbage collector:</p>
<ul>
<li>Too many allocations.</li>
<li>Too-large allocation.</li>
<li>Too many pointers.</li>
<li>Too many roots.</li>
<li>Too many object writes.</li>
<li>Too many Almost-Long-Life objects.</li>
<li>If you implement IDisposable then suppress finalization to reduce costs.</li>
</ul>
<h3 id="dependency-injection-di" class="heading">Dependency Injection (DI)
    <a class="heading__anchor" href="#dependency-injection-di" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h3>
<p>A foundational pattern in xUnit testing is 
<a href="http://en.wikipedia.org/wiki/Dependency_injection" class="link-external" rel="noopener noreferrer" target="_blank">Dependency Injection (DI)
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
, which is a form of 
<a href="http://martinfowler.com/articles/injection.html" class="link-external" rel="noopener noreferrer" target="_blank">Inversion of Control (IoC)
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
. Specifically, DI is a programming technique where the implementation of one class is actually performed partially by another. Inversion of Control is where a program gives up control of its own execution and simply responds to requests made of it. In the same way, a class using dependency injection gives up control over some of its implementation and lets the injected class do the work.</p>
<p>Three types of DI exist; constructor injection, property injection, and method call injection. Constructor injection is a pattern whereby dependencies are “injected” into an object during construction. Whereas, property injection uses set operations [on properties] to inject dependencies, which obviously occurs after construction. Method call injection simply uses method calls to inject dependencies.</p>
<p>Several libraries exist in each category. For example, the 
<a href="http://www.castleproject.org/container/index.html" class="link-external" rel="noopener noreferrer" target="_blank">Castle Project
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 and 
<a href="http://www.codeplex.com/ObjectBuilder" class="link-external" rel="noopener noreferrer" target="_blank">ObjectBuilder
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 both provide supports for constructor and property injection. As a side note, the 
<a href="http://www.codeplex.com/entlib/" class="link-external" rel="noopener noreferrer" target="_blank">Microsoft Enterprise Library
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 uses ObjectBuilder internally as its DI container framework. 
<a href="http://www.codeplex.com/unity" class="link-external" rel="noopener noreferrer" target="_blank">Unity
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 is Microsoft’s latest offering from the Pattern’s &amp; Practices team. Unity offers property, constructor, and method call injection.</p>
<h3 id="static-classes" class="heading">Static Classes
    <a class="heading__anchor" href="#static-classes" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h3>
<p>A 
<a href="http://msdn2.microsoft.com/en-us/library/79b3xss3%28VS.80%29.aspx" class="link-external" rel="noopener noreferrer" target="_blank">static class
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 does not have any instance-level members (including constructors) and is defined by the 
<a href="http://msdn2.microsoft.com/en-us/library/98f28cdx%28VS.80%29.aspx" class="link-external" rel="noopener noreferrer" target="_blank">static modifier
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
. The compiler in turn marks a static class as sealed and automatically creates a private constructor.</p>
<p>The main features of a static class are:</p>
<ul>
<li>They only contain static members.</li>
<li>They cannot be instantiated.</li>
<li>They are sealed.</li>
<li>They cannot contain 
<a href="http://msdn2.microsoft.com/en-us/library/k6sa6h87%28VS.80%29.aspx" class="link-external" rel="noopener noreferrer" target="_blank">Instance Constructors
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
.</li>
</ul>
<p>Inherently in the context of unit (and integration) testing, static classes are not recommended due to the difficulty in implementing a thread-safe property injector DI pattern and being unable to use constructor DI. However, the advantage of a properly written static class is there’s only one object instance per 
<a href="http://msdn2.microsoft.com/en-us/library/system.appdomain.aspx" class="link-external" rel="noopener noreferrer" target="_blank">AppDomain
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
, which can be very efficient on the GC (see the Too Many Object Writes section of the previously referenced 
<a href="http://msdn2.microsoft.com/en-us/library/ms973837.aspx" class="link-external" rel="noopener noreferrer" target="_blank">article
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
).</p>
<p>This is a very important and annoying impedance that exists between the use of a constructor DI pattern and efficient use (and preservation) of system resources (in this case CPU and memory). We want to be testable and mindful of system resources.</p>
<h3 id="singletons" class="heading">Singletons
    <a class="heading__anchor" href="#singletons" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h3>
<p>For purposes of this discussion, a singleton is a class that only allows a single instance of itself to be created within an AppDomain. The following are recommended singleton patterns.</p>
<p>Sidebar: 
<a href="http://msdn.microsoft.com/msdnmag/issues/05/10/MemoryModels/default.aspx" class="link-external" rel="noopener noreferrer" target="_blank">Understand the Impact of Low-Lock Techniques in Multithreaded Apps
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
</p>
<p><strong>Pattern 1: Niladic Constructor</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">class</span> <span class="nc">MySingleton</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">private</span> <span class="kd">static</span> <span class="k">readonly</span> <span class="n">MySingleton</span> <span class="n">_instance</span> <span class="p">=</span> <span class="k">new</span> <span class="n">MySingleton</span><span class="p">();</span>
</span></span><span class="line"><span class="cl"> 
</span></span><span class="line"><span class="cl">    <span class="kd">private</span> <span class="n">MySingleton</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"> 
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kd">static</span> <span class="n">MySingleton</span> <span class="n">Instance</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">get</span> <span class="p">{</span> <span class="k">return</span> <span class="n">_instance</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p><strong>Pattern 2: Niladic Constructor (Full Lazy Initialization)</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">class</span> <span class="nc">MySingleton</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">class</span> <span class="nc">Nested</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="c1">//</span>
</span></span><span class="line"><span class="cl">        <span class="c1">// Explicit static constructor to tell C# compiler not to mark</span>
</span></span><span class="line"><span class="cl">        <span class="c1">// type as BeforeFieldInit</span>
</span></span><span class="line"><span class="cl">        <span class="c1">//</span>
</span></span><span class="line"><span class="cl">        <span class="kd">static</span> <span class="n">Nested</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl"> 
</span></span><span class="line"><span class="cl">        <span class="kd">internal</span> <span class="kd">static</span> <span class="k">readonly</span> <span class="n">MySingleton</span> <span class="n">Instance</span> <span class="p">=</span> <span class="k">new</span> <span class="n">MySingleton</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"> 
</span></span><span class="line"><span class="cl">    <span class="kd">private</span> <span class="n">MySingleton</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"> 
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kd">static</span> <span class="n">MySingleton</span> <span class="n">Instance</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">get</span> <span class="p">{</span> <span class="k">return</span> <span class="n">Nested</span><span class="p">.</span><span class="n">Instance</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Note, the following alternate method results in identical MSIL…</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">class</span> <span class="nc">MySingleton</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">static</span> <span class="k">class</span> <span class="nc">Nested</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="kd">internal</span> <span class="kd">static</span> <span class="k">readonly</span> <span class="n">MySingleton</span> <span class="n">Instance</span> <span class="p">=</span> <span class="k">new</span> <span class="n">MySingleton</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"> 
</span></span><span class="line"><span class="cl">    <span class="kd">private</span> <span class="n">MySingleton</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"> 
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kd">static</span> <span class="n">MySingleton</span> <span class="n">Instance</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">get</span> <span class="p">{</span> <span class="k">return</span> <span class="n">Nested</span><span class="p">.</span><span class="n">Instance</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>A rather dated but still applicable discussion regarding the use of the double-check lock pattern written by 
<a href="http://blogs.msdn.com/vancem/" class="link-external" rel="noopener noreferrer" target="_blank">Vance Morrison
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 can be found 
<a href="http://discuss.develop.com/archives/wa.exe?A2=ind0203B&amp;L=DOTNET&amp;P=R375" class="link-external" rel="noopener noreferrer" target="_blank">here
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 and provides insight into subtle nuances of the Microsoft .NET Framework memory model implementation. I’ve attached a PDF version of the discussion to this entry (at the bottom) in case the archive disappears.</p>
<p>Singleton<T></p>
<p>So back to the question at hand, which is how do I ensure my production code is testable and uses system resources efficiently as possible? I offer the Singleton<T> class, which is defined as…</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="kd">sealed</span> <span class="k">class</span> <span class="nc">Singleton</span> <span class="k">where</span> <span class="n">T</span> <span class="p">:</span> <span class="k">new</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">private</span> <span class="kd">static</span> <span class="k">readonly</span> <span class="n">T</span> <span class="n">_instance</span> <span class="p">=</span> <span class="k">new</span> <span class="n">T</span><span class="p">();</span>
</span></span><span class="line"><span class="cl"> 
</span></span><span class="line"><span class="cl">    <span class="kd">private</span> <span class="n">Singleton</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"> 
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kd">static</span> <span class="n">T</span> <span class="n">Instance</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">get</span> <span class="p">{</span> <span class="k">return</span> <span class="n">_instance</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>With the Singleton<T> class, we’re now able to use the following syntax in production code…</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">class</span> <span class="nc">CustomerManager</span> <span class="p">:</span> <span class="n">BusinessLogicComponent</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">private</span> <span class="n">ICustomerRepository</span> <span class="n">_repository</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"> 
</span></span><span class="line"><span class="cl">    <span class="c1">//</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// This constructor is required by the Singleton generic class.</span>
</span></span><span class="line"><span class="cl">    <span class="c1">//</span>
</span></span><span class="line"><span class="cl"><span class="na">    [EditorBrowsable(EditorBrowsableState.Never)]</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="n">CustomerManager</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">        <span class="p">:</span> <span class="k">this</span><span class="p">(</span><span class="n">Singleton</span><span class="p">.</span><span class="n">Instance</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"> 
</span></span><span class="line"><span class="cl">    <span class="c1">//</span>
</span></span><span class="line"><span class="cl">    <span class="c1">//  This constructor is to be used only by test projects.</span>
</span></span><span class="line"><span class="cl">    <span class="c1">//</span>
</span></span><span class="line"><span class="cl"><span class="na">    [EditorBrowsable(EditorBrowsableState.Never)]</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="n">CustomerProcessor</span><span class="p">(</span><span class="n">ICustomerRepository</span> <span class="n">repository</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">_repository</span> <span class="p">=</span> <span class="n">repository</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"> 
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="k">void</span> <span class="n">Add</span><span class="p">(</span><span class="n">Customer</span> <span class="n">customer</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">_repository</span><span class="p">.</span><span class="n">Add</span><span class="p">(</span><span class="n">customer</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>…and the following syntax from test projects.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="na">[Test]</span>
</span></span><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">void</span> <span class="n">Customer_Add_Succeeds</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="c1">//</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// Create a mock customer repository and inject it into the business</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// logic component (manager).</span>
</span></span><span class="line"><span class="cl">    <span class="c1">//</span>
</span></span><span class="line"><span class="cl">    <span class="n">ICustomerRepository</span> <span class="n">repository</span> <span class="p">=</span> <span class="k">new</span> <span class="n">MockCustomerRepository</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="n">CustomerManager</span> <span class="n">manager</span> <span class="p">=</span> <span class="k">new</span> <span class="n">CustomerManager</span><span class="p">(</span><span class="n">repository</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> 
</span></span><span class="line"><span class="cl">    <span class="c1">//</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// Perform remaining test operations.</span>
</span></span><span class="line"><span class="cl">    <span class="c1">//</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Consumers of the CustomerManager business logic class in production simply use the Singleton<T> class just as the CustomerManager does with the CustomerRepository class in its niladic constructor.</p>
<p>A final note on thread-safety. The singleton pattern does require all instance level methods to be thread-safe.</p>
<h3 id="conclusion" class="heading">Conclusion
    <a class="heading__anchor" href="#conclusion" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h3>
<p>The Singleton<T> class provides an implementation pattern to balance between two important variables in any design; that of testability and efficient use of system resources. I encourage you to experiment.</p>
<p>
<a href="/files/Garbage-Collector-Basics-and-Performance-Hints.zip">Garbage Collector Basics and Performance Hints.zip</a>
</p>]]></content:encoded><category>computing</category><category>software engineering</category></item><item><title>Tribute to Honor Jim Gray</title><link>https://michaelprimeaux.com/en/posts/2007-11-23-tribute-to-honor-jim-gray/</link><pubDate>Fri, 23 Nov 2007 00:06:00 +0000</pubDate><author>michael@michaelprimeaux.com (Michael Primeaux)</author><guid>https://michaelprimeaux.com/en/posts/2007-11-23-tribute-to-honor-jim-gray/</guid><description>A dear friend and former colleague (opens in a new window) notified me of an upcoming event for Jim. From Werner Vogels‘ (opens in a new window) site:</description><content:encoded><![CDATA[<p>A 
<a href="http://blogs.msdn.com/pathelland/" class="link-external" rel="noopener noreferrer" target="_blank">dear friend and former colleague
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 notified me of an upcoming event for Jim. From 
<a href="http://www.allthingsdistributed.com/" class="link-external" rel="noopener noreferrer" target="_blank">Werner Vogels‘
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 site:</p>
<p>On May 31 2008 a tribute will be held at UC Berkeley to honor 
<a href="http://research.microsoft.com/%7EGray/" class="link-external" rel="noopener noreferrer" target="_blank">Jim Gray
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
, who went 
<a href="http://www.allthingsdistributed.com/2007/01/jim_gray_missing_at_sea.html" class="link-external" rel="noopener noreferrer" target="_blank">missing
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 during a solo sailing trip in January of this year. Although Jim is listed as missing, and will be until 2011, a Tribute be held to honor him before too much time has passed. There are two parts to this event:</p>
<p>The morning event, which will be in a very large hall, is open and public; the technical session, which is in a smaller hall, and for which you need to register. More details at the 
<a href="http://www.eecs.berkeley.edu/IPRO/JimGrayTribute/" class="link-external" rel="noopener noreferrer" target="_blank">Tribute website
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
.</p>
<p>I expect to attend.</p>
]]></content:encoded><category>transaction processing</category></item><item><title>Fiefdoms: Cause and Effect</title><link>https://michaelprimeaux.com/en/posts/2007-06-04-fiefdoms-cause-and-effect/</link><pubDate>Mon, 04 Jun 2007 00:06:00 +0000</pubDate><author>michael@michaelprimeaux.com (Michael Primeaux)</author><guid>https://michaelprimeaux.com/en/posts/2007-06-04-fiefdoms-cause-and-effect/</guid><description>I ran across a very good book titled The Fiefdom Syndrome (opens in a new window) , which discusses the cause and effect of fiefdoms (opens in a new window) .</description><content:encoded><![CDATA[<p>I ran across a very good book titled 
<a href="http://www.amazon.com/Fiefdom-Syndrome-Undermine-Companies-Overcome/dp/0385510683/ref=pd_bbs_sr_1?ie=UTF8&amp;s=books&amp;qid=1197511435&amp;sr=8-1" class="link-external" rel="noopener noreferrer" target="_blank">The Fiefdom Syndrome
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
, which discusses the cause and effect of 
<a href="http://en.wikipedia.org/wiki/Fiefdom" class="link-external" rel="noopener noreferrer" target="_blank">fiefdoms
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
.</p>
<p>“The fiefdom syndrome stems from the inclination of managers and employees to become fixated on their own activities, their own careers, their own territory or turf to the detriment of those around them.</p>
<p>People who create fiefdoms can become dangerously insular, losing perspective on what is happening in the world outside their own control. They also lose their ability to act consistently on behalf of the greater good, or in a way that enhances the effectiveness of the larger organization. They often resist new situations and change.</p>
<p>People who create fiefdoms tend to hoard resources. They are determined to do things their own way, often duplicating or complicating what should be streamlined throughout the company, leading to runaway costs, increased bureaucracy and slower response times.</p>
<p>Organizations infected with fiefdoms tend to kill off or stifle individual creativity, leading to what I call the ‘freeze factor’: when organizations become frozen or stuck in place, letting competitors pass them by.”</p>
]]></content:encoded><category>business</category></item><item><title>Peer-to-Peer (P2P)</title><link>https://michaelprimeaux.com/en/posts/2007-06-04-peer-to-peer-p2p/</link><pubDate>Mon, 04 Jun 2007 00:06:00 +0000</pubDate><author>michael@michaelprimeaux.com (Michael Primeaux)</author><guid>https://michaelprimeaux.com/en/posts/2007-06-04-peer-to-peer-p2p/</guid><description>“In a forest a tree will fade; from a forest a tree is made.” –Unknown
Over the past several years I’ve focused on application of P2P algorithms for the commercial space. Anyway, I thought I’d share some of my thoughts and tertiary research.
First, what is Peer-To-Peer (P2P)? P2P [ URI (opens in a new window) ] is a decentralized, fault tolerant, self-organizing system architecture comprised of many unreliable and heterogeneous nodes operating in a functionally symmetric manner—frequent joins and leaves are the norm. P2P is not a client / server architecture. P2P is a paradigm shift from coordination to cooperation, from centralization to decentralization, and from control to incentives.</description><content:encoded><![CDATA[<blockquote><p>“In a forest a tree will fade; from a forest a tree is made.”
–Unknown</p>
</blockquote>
<p>Over the past several years I’ve focused on application of P2P algorithms for the commercial space. Anyway, I thought I’d share some of my thoughts and tertiary research.</p>
<p>First, what is Peer-To-Peer (P2P)?  P2P [
<a href="http://en.wikipedia.org/wiki/Peer-to-peer" class="link-external" rel="noopener noreferrer" target="_blank">URI
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
] is a decentralized, fault tolerant, self-organizing system architecture comprised of many unreliable and heterogeneous nodes operating in a functionally symmetric manner—frequent joins and leaves are the norm. P2P is not a client / server architecture. P2P is a paradigm shift from coordination to cooperation, from centralization to decentralization, and from control to incentives.</p>
<h2 id="algorithms" class="heading">Algorithms
    <a class="heading__anchor" href="#algorithms" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h2>
<p>To my knowledge, the Plaxton mesh (1997) was the earliest known proposal for a scalable P2P network. One major problem with a Plaxton mesh is its static—there is no concept of node arrival, departure, or failure. Essentially, nodes act as routers, clients, and servers simultaneously. A Plaxton mesh routes a message to the nodes whose name is numerically closest to the destination.</p>
<p>From 2001 through 2003, P2P algorithms such as 
<a href="http://www.pdos.lcs.mit.edu/chord/" class="link-external" rel="noopener noreferrer" target="_blank">Chord
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
, CAN, 
<a href="http://freepastry.rice.edu/" class="link-external" rel="noopener noreferrer" target="_blank">Pastry
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
, Tapestry, Viceroy, P-Grid, 
<a href="http://en.wikipedia.org/wiki/Kademlia" class="link-external" rel="noopener noreferrer" target="_blank">Kademlia
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
, Koorde, SkipGraph, and SkipNet appeared.</p>
<h2 id="applications" class="heading">Applications
    <a class="heading__anchor" href="#applications" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h2>
<p>
<a href="http://www.napster.com" class="link-external" rel="noopener noreferrer" target="_blank">Napster
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 was one of the first P2P applications that appeared in 1999—though it’s not really a P2P network. With Napster, a single central server kept the directory of nodes and objects, which made is essentially a large file catalog—the discovery and routing algorithms are not P2P.</p>
<p>
<a href="http://en.wikipedia.org/wiki/Gnutella" class="link-external" rel="noopener noreferrer" target="_blank">Gnutella
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 first appeared in 2000 and then again in 2002. Though a pure P2P application, Gnutella generated far too much search traffic with a [broadcast-based] O(n) complexity—not very scalable.</p>
<p>
<a href="http://en.wikipedia.org/wiki/EDonkey_network" class="link-external" rel="noopener noreferrer" target="_blank">eDonkey
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 appeared in 2001 and presented a slight architectural improvement over Napster in that no single centralized server held the file catalog. Nevertheless, eDonkey was not a pure P2P application since it relied on status node structures.</p>
<p>
<a href="http://www.kazaa.com" class="link-external" rel="noopener noreferrer" target="_blank">Kazaa
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 also appeared in late 2001 but I haven’t studied its architecture at all. I listed it here for completeness.</p>
<p>
<a href="http://www.gnutella2.com/" class="link-external" rel="noopener noreferrer" target="_blank">Gnutella-2
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 and 
<a href="http://www.bittorrent.com" class="link-external" rel="noopener noreferrer" target="_blank">BitTorrent
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 were the P2P applications of 2002.  In 2003, 
<a href="http://www.skype.com" class="link-external" rel="noopener noreferrer" target="_blank">Skype
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
, Steam, and 
<a href="http://sharewareconnection.com/proxyshare-ps3-filesharing.htm" class="link-external" rel="noopener noreferrer" target="_blank">PS3
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 appeared.</p>
<h2 id="architecture" class="heading">Architecture
    <a class="heading__anchor" href="#architecture" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h2>
<p>Common characteristics of P2P architectures are:</p>
<ul>
<li>No central servers.</li>
<li>High level of scalability. Discovery and routing is O(log(n)). Routing table size is also O(log(n)).</li>
<li>Highly resilient.</li>
<li>Dynamic adaptability to node arrival, departure and failure.</li>
</ul>
<p>Because of these characteristics, P2P architectures offer challenges in many areas. The most visible of the challenges facing designers of P2P routing algorithms are:</p>
<ul>
<li><strong>Scalability</strong>. Scalability is a measure of how a system performs when the number of nodes and/or number of messages on the network grows.</li>
<li><strong>Computational Complexity</strong>. Computational complexity is the measure of the order of steps required for a packet to travel from one host to another in a worst case scenario.</li>
<li><strong>Anonymity</strong>. Anonymity is not a requirement of most P2P networks, however if a network is to be designed to provide anonymity then this is a problem that must be solved at the routing level.</li>
</ul>
<h3 id="topology" class="heading">Topology
    <a class="heading__anchor" href="#topology" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h3>
<p>A P2P infrastructure is best described as an overlay network—usually on top of an IP network.  In many ways, you can think of P2P as an application-level router providing services that underlying layers do not (i.e. IP multicast).  Generally speaking, P2P architectures employ one of the following topological structural designs:</p>
<ul>
<li>Centralized (Napster)</li>
<li>Decentralized
<ul>
<li>Unstructured (Gnutella)</li>
<li>Structured (Chord)</li>
</ul>
</li>
<li>Hierarchical (Multicast Backbone (MBone))</li>
<li>Hybrid (eDonkey)</li>
</ul>
<p>Different P2P algorithms employ different topological structures. For example, Chord employs a ring topology whereas Kademlia employs a tree and CAN a hypercube.</p>
<h2 id="routing" class="heading">Routing
    <a class="heading__anchor" href="#routing" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h2>
<p>Different topologies require different algorithm tactics and strategies. Routing within P2P architectures are very problematic.</p>
<p>Within P2P architectures, algorithms such as flooding, replication and caching, random walkers and probabilistic algorithms, super-peers, Time to Live (TTL), epidemic and gossip protocols, propagation, and dampening algorithms are widely used. These algorithms work well depending on the size of the P2P network. For example, 
<a href="http://www9.limewire.com/developer/gnutella_protocol_0.4.pdf" class="link-external" rel="noopener noreferrer" target="_blank">flooding
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 is more suited for a small to medium size networks but it has been shown that the cost of searching on a Gnutella style network increases super-linearly as the number of nodes increases.</p>
<h3 id="distributed-hash-tables-dht" class="heading">Distributed Hash Tables (DHT)
    <a class="heading__anchor" href="#distributed-hash-tables-dht" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h3>
<p>
<a href="http://en.wikipedia.org/wiki/Distributed_hash_table" class="link-external" rel="noopener noreferrer" target="_blank">DHTs
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 are a class of decentralized distributed systems that partition ownership of a set of keys among participating nodes, and can efficiently route messages to the unique owner of any given key. A hash function (such as SHA-1) accepts a variable length string of bytes and returns a one-way hash. The physical nodes are the hash buckets. Chord is a good example of a DHT algorithm.</p>
<p>Incidentally, in general DHT algorithms will always beat flooding algorithms in the area of routing.</p>
<p>One advantage of the Chord DHT algorithm is that it guarantees receipt of a reply with log(n) time, which is a far better guarantee in terms of computational and time complexity than that offered by flooding techniques.  That said, the Kademlia DHT algorithm does offer advantages over Chord depending on application requirements.</p>
<p>However, DHTs are not without problem:</p>
<ul>
<li>Routing state maintenance algorithms generate overhead.</li>
<li>They do not work well when lots of nodes join and leave frequently (churn).</li>
<li>Their structured topology and routing algorithms make them frail and vulnerable to security attacks.</li>
<li>Network locality problem: Nodes numerically-close are not topologically-close.</li>
</ul>
<p>Strategies do exist to address these problems. Regardless, structured DHT algorithms provide the most interesting P2P infrastructures.</p>
<h3 id="semantic-routing" class="heading">Semantic Routing
    <a class="heading__anchor" href="#semantic-routing" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h3>
<p>This is a relatively new area of routing as related to P2P infrastructures. Semantic Routing is a method of routing which is more focused on the nature of the query to be routed than the network topology. Essentially, semantic routing improves on traditional routing by prioritizing nodes which have been previously good at providing information about the types of content referred to by the query.</p>
<p>Semantic routing differs fundamentally from other routing techniques because prospective nodes are selected because of another node’s confidence in their ability to respond correctly to a given query irrespective of their position within the network. 
<a href="http://www.neurogrid.net/php/whitepaper.php" class="link-external" rel="noopener noreferrer" target="_blank">Neurogrid
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 and 
<a href="http://portal.acm.org/citation.cfm?id=988759" class="link-external" rel="noopener noreferrer" target="_blank">Remindin
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 are of the most interesting semantic routing systems with the Remindin system incorporating a semantic routing algorithm developed with the intention of mimicking social networks.</p>
<h3 id="summary" class="heading">Summary
    <a class="heading__anchor" href="#summary" tabindex="-1" aria-hidden="true"
        title="Link to this section">
<svg class="icon icon--hash" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M5 9h14M5 15h14M10 3.5 8 20.5M16 3.5l-2 17"/>
</svg>
</a>
</h3>
<p>Overall, the most interesting of the DHT algorithms are 
<a href="http://en.wikipedia.org/wiki/Chord_project" class="link-external" rel="noopener noreferrer" target="_blank">Chord
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
, 
<a href="http://en.wikipedia.org/wiki/Kademlia" class="link-external" rel="noopener noreferrer" target="_blank">Kademlia
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
, and 
<a href="http://research.microsoft.com/research/pubs/view.aspx?type=Technical%20Report&amp;id=798" class="link-external" rel="noopener noreferrer" target="_blank">XRing
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
.  I hope to release .NET implementations of all three of these algorithms (and a few variations) in the near future. You’ll find them here.</p>]]></content:encoded><category>computing</category></item><item><title>Information Modeling</title><link>https://michaelprimeaux.com/en/posts/2007-06-03-information-modeling/</link><pubDate>Sun, 03 Jun 2007 00:06:00 +0000</pubDate><author>michael@michaelprimeaux.com (Michael Primeaux)</author><guid>https://michaelprimeaux.com/en/posts/2007-06-03-information-modeling/</guid><description>When defining an information model, should one favor an abstract or concrete design? The short answer is neither.
Generally speaking, the life of any distributed system directly relates to its level of entropy. Furthermore, the level of entropy in a system directly relates to the system’s computational complexity. When designing applications to solve business problems, information storage and retrieval is one of the more important foundational design points. If the information schema is designed without efficiency, scalability, and flexibility in mind then not only will the system perform poorly but it will not meet the requirements imposed by future business demands.</description><content:encoded><![CDATA[<p>When defining an information model, should one favor an abstract or concrete design? The short answer is neither.</p>
<p>Generally speaking, the life of any distributed system directly relates to its level of entropy. Furthermore, the level of entropy in a system directly relates to the system’s computational complexity. When designing applications to solve business problems, information storage and retrieval is one of the more important foundational design points. If the information schema is designed without efficiency, scalability, and flexibility in mind then not only will the system perform poorly but it will not meet the requirements imposed by future business demands.</p>
<p>At either end of the spectrum, an information schema is categorized as either concrete or abstract—though there most certainly are varying degrees in between. Each design has advantages and disadvantages. A concrete design is easier to conceptualize and requires less complex algorithmic considerations. In most cases, a concrete design is far less flexible than that of an abstract design. A properly designed abstract information schema remains invariant in the face of change that would otherwise impose a relatively large amount of downtime for an equivalent concrete model.</p>
<p>Arguably, however, many abstract systems are indeed designed with concreteness in mind. By this I mean the system is designed to contain representations of concrete constructs. Why? It’s how humans think in every day life. If I ask you to describe yourself then you’re statistically more likely to forgo attributes such as “person” or “human” and instead provide attributes such as height and weight. The former attributes are more abstract (relatively speaking) than the latter attributes. However, both indeed describe a concrete construct: you.</p>
<p>I tend to favor abstract information models but then again, I spend the majority of my time in abstract problem domains. However, regardless of which classification the solution domain requires, the following rules and considerations have proven effective in designing an efficient information model:</p>
<ol>
<li>Effectively understand the information.</li>
<li>Describe it unambiguously.</li>
<li>Enforce structure and style guidelines.</li>
<li>Allow for efficient storage and retrieval of information.</li>
<li>Keep network communication to a minimum. Don’t over engineer.</li>
</ol>
<p>The last bullet (5) is delivered with a caveat. Over engineering is a very subjective quantification that takes time to perfect and is directly related to your complete understanding of the information (bullet 1). If bullet 1 suffers then so does bullet 5.</p>
<p>Usually, the questions are quick. It’s the answers that take the time.</p>
]]></content:encoded><category>computing</category></item><item><title>BitVault: a Highly Reliable Distributed Data Retention Platform</title><link>https://michaelprimeaux.com/en/posts/2007-05-02-bitvault-a-highly-reliable-distributed-data-retention-platform/</link><pubDate>Wed, 02 May 2007 00:06:00 +0000</pubDate><author>michael@michaelprimeaux.com (Michael Primeaux)</author><guid>https://michaelprimeaux.com/en/posts/2007-05-02-bitvault-a-highly-reliable-distributed-data-retention-platform/</guid><description> BitVault (opens in a new window) ( defined (opens in a new window) ) is a very interesting distributed data retention platform architecture from Microsoft Research. You can read the research paper here . Another interesting bit of news is an eWeek article (opens in a new window) documenting a Microsoft announcement of the productizing of BitVault.</description><content:encoded><![CDATA[<p>
<a href="http://research.microsoft.com/research/pubs/view.aspx?type=Technical%20Report&amp;id=1035" class="link-external" rel="noopener noreferrer" target="_blank">BitVault
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 (
<a href="http://en.wikipedia.org/wiki/BitVault" class="link-external" rel="noopener noreferrer" target="_blank">defined
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
) is a very interesting distributed data retention platform architecture from Microsoft Research. You can read the research paper 
<a href="/files/TR-2005-179.pdf">here</a>
.  Another interesting bit of news is an 
<a href="http://www.eweek.com/c/a/Windows/Microsoft-Readies-BitVault-SelfHealing-Data-Store/" class="link-external" rel="noopener noreferrer" target="_blank">eWeek article
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 documenting a Microsoft announcement of the productizing of BitVault.</p>
]]></content:encoded><category>computing</category></item><item><title>Update Sequence Numbers</title><link>https://michaelprimeaux.com/en/posts/1998-10-24-update-sequence-numbers/</link><pubDate>Sat, 24 Oct 1998 00:06:00 +0000</pubDate><author>michael@michaelprimeaux.com (Michael Primeaux)</author><guid>https://michaelprimeaux.com/en/posts/1998-10-24-update-sequence-numbers/</guid><description>A colleague and I discussed the value in using a 64 bit Update Sequence Number (USN) versus a 128 bit USN. Here are my thoughts assuming 64-bits.
To provide a bit of context, we were considering a solution space that incremented the USN value for each write operation for a specific set of protected data. The USN is 64 bits, and is advanced for each update on a given server. At 100 writes per second, the USN will roll over in 58,494,241,735 years (approximately).</description><content:encoded><![CDATA[<p>A colleague and I discussed the value in using a 64 bit Update Sequence Number (USN) versus a 128 bit USN. Here are my thoughts assuming 64-bits.</p>
<p>To provide a bit of context, we were considering a solution space that incremented the USN value for each write operation for a specific set of protected data. The USN is 64 bits, and is advanced for each update on a given server. At 100 writes per second, the USN will roll over in 58,494,241,735 years (approximately).</p>
<p>On a very busy server performing 10,000 writes per second it will roll over much sooner, in 584,942,417 years. Either way, the sun will burn out or go nova first, making USN’s moot (for this astronomical neighborhood anyway).</p>
<p>Just using 128 bits for USNs would give us a few more millennia breathing room. Now for the good news. In point of fact, since USN’s from different servers are never compared, all that is required is detecting rollover of the USN on a given server, for which algorithms are available. See 
<a href="http://www.ietf.org/rfc/rfc1982.txt?number=1982" class="link-external" rel="noopener noreferrer" target="_blank">RFC 1982
<svg class="icon icon--external" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
    stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
    <path d="M14 4h6v6M20 4l-8.5 8.5"/>
    <path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>
</svg>
<span class="visually-hidden"> (opens in a new window)</span>
</a>
 for a discussion.</p>
]]></content:encoded><category>computing</category></item></channel></rss>