<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>chewbranca.com</title>
    <description>Food, tech, and things not related to either of those.</description>
    <link>http://chewbranca.com/</link>
    <atom:link href="http://chewbranca.com/feed.xml" rel="self" type="application/rss+xml" />
    
      <item>
        <title>Lisp Game Jam - Day one update 01</title>
        <description>&lt;p&gt;I’m very excited to be diving into the &lt;a href=&quot;https://itch.io/jam/lisp-game-jam-2018&quot;&gt;2018 Lisp Game
Jam&lt;/a&gt;! My plan is to make a
Diablo-esque pvp deathmatch game! I stumbled upon the awesome open
source &lt;a href=&quot;https://github.com/clintbellanger/flare-game&quot;&gt;Flare Game&lt;/a&gt; that
is a single player action RPG inspired by Diablo. What really
intrigued me about the game is all of the artwork.&lt;/p&gt;

&lt;p&gt;I haven’t had great luck finding open source isometric game art,
especially with a variety of characters and animations, so when I
found all of the open source artwork in Flare Game, I started dancing
and getting ideas for this game. The Flare Game repo itself that I
linked to above is actually just the game assets, containing the
artwork, animation definitions, maps, map tiles, sounds, etc, and the
engine is in the &lt;a href=&quot;https://github.com/clintbellanger/flare-engine&quot;&gt;Flare
Engine&lt;/a&gt; repo. This is
perfect for me, because I’m rolling my own engine on top of &lt;a href=&quot;http://love2d.org/&quot;&gt;Love
2D&lt;/a&gt; using Lua, so I just need the art assets.&lt;/p&gt;

&lt;p&gt;I’ve built a library around the Flare Game assets, called
&lt;a href=&quot;https://github.com/chewbranca/lfg&quot;&gt;LFG&lt;/a&gt;, short for Lua Flare
Game. The idea with this library is to take care of parsing the
various animation definitions and making usable characters out of the
sprite sheets.&lt;/p&gt;

&lt;p&gt;What does that actually mean? Well, let’s take a look. A sprite sheet
is a series of animation frames combined into a single image that you
then load in your game engine to render. So for instance, I’ve taken
a sprite sheet from Flare Game like this minotaur sprite sheet:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/flare-game/minotaur.png&quot; alt=&quot;Minotaur Sprite Sheet&quot; /&gt;&lt;/p&gt;

&lt;p&gt;and using LFG I’ve turned it into animations like:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/lfg_minotaur.gif&quot; alt=&quot;Minotaur Animation&quot; /&gt;&lt;/p&gt;

&lt;p&gt;and that’s based on Flare Game’s animation definition for the &lt;a href=&quot;https://github.com/clintbellanger/flare-game/blob/master/art_src/animation_defs/characters/minotaur.txt&quot;&gt;Minotaur
Animation&lt;/a&gt;
which looks like:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;#image=

render_size=128,128
render_offset=64,96

[stance]
position=0
frames=8
duration=1600ms
type=looped

[run]
position=8
frames=8
duration=533ms
type=looped

[swing]
position=16
frames=8
duration=1066ms
type=play_once
...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Those animation definition files give you the information to know what
frames correspond to a particular animation, and then the 8 rows of
the sprite sheet correspond to the 8 cardinal directions. So to make
an animation, you figure out which cardinal direction the player is
facing, select the appropriate row, and then select the appropriate
sprite tiles for the desired animation. Then you divide the animation
duration by the number of frames in the animation, and you play each
frame for that long to animate the character.&lt;/p&gt;

&lt;p&gt;The idea of the LFG library is to provide a simple library interface
around these Flare Game assets, so you can do things like &lt;code class=&quot;highlighter-rouge&quot;&gt;local
minotaur = lfg.get_character(&quot;Minotaur&quot;)&lt;/code&gt; and have the full set of
animations at your disposal. The LFG library also takes care of player
controls, movement, circling strafing, and it has rudimentary
projectiles and collision detection in place. I’m in the process of
adding networking support to it as well. In general, LFG’s goal is to
make it easy to build Love 2D games using the wonderful assets from
Flare Game.&lt;/p&gt;

&lt;h2 id=&quot;lisp-game-jam-2018&quot;&gt;Lisp Game Jam 2018&lt;/h2&gt;

&lt;p&gt;So how does this all fit together for the Lisp Game Jam? Well, like I
said, I’m going to build a Diabo-esque pvp deathmatch game using the
Flare Game assets! This is the first video game I’ve ever made, so
I’ve been having a blast diving in and researching how to build games
and how game engines work and game networking and all that fun
stuff. It’s been a bit tortuous not being able to actually start on
the game itself until today, but it took a chunk of work to get LFG to
where it provides higher level abstractions around the Flare Game
assets so you can just grab the different characters and use them in
your game. A handful of the Flare Game character mobs are currently
supported, for instance:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/lfg_rand_mobs.gif&quot; alt=&quot;Random Mobs&quot; /&gt;&lt;/p&gt;

&lt;p&gt;“But I thought you said this is a &lt;em&gt;Lisp&lt;/em&gt; game jam? Lua ain’t a Lisp.”
Correct! That’s where the awesome &lt;a href=&quot;https://github.com/bakpakin/fennel&quot;&gt;Fennel
Lang&lt;/a&gt; comes in! Fennel is a
lightweight Lisp that compiles down to Lua code with minimal
overhead. So my plan for the game jam is to make a new Love 2D based
game that is written in Fennel, and uses LFG to provide the characters
and game world! The entire point of this game is for pvp deathmatch,
so getting networking in place quickly is a priority for today. I’m
going to focus on LAN only game play, because low latency internet
based gaming is serious undertaking. Maybe in version 2 :D&lt;/p&gt;

&lt;p&gt;My plan is to post updates to this blog as development progresses so
folks can see it come together. Happy hacking!&lt;/p&gt;
</description>
        <pubDate>Fri, 20 Apr 2018 09:35:51 +0000</pubDate>
        <link>http://chewbranca.com/lisp-game-jam/2018/04/20/lgj-day-one-01/</link>
        <guid isPermaLink="true">http://chewbranca.com/lisp-game-jam/2018/04/20/lgj-day-one-01/</guid>
      </item>
    
      <item>
        <title>Does this thing still work?</title>
        <description>&lt;p&gt;Is the mic on? Does this thing still work? It sure has been a while
since I’ve updated this site. Truth be told, I don’t really care for
the current technology I’m using to power this site. I’ve got a
handful of grand ambitions on what I want a personal “homepage” to be,
but they all require a considerable chunk of development time, which I
haven’t invested in yet. As a result, I typically don’t bother
updating this site, but the net result of that is that it stays
stagnant and I don’t create new content. Well, I’ve decided to take a
different approach and just start generating the content and be
accepting that this isn’t quite what I want it to be, but I can always
fix it later. I mean hey, 301 redirects are a thing, I can migrate
this content to a new site later. So here goes my attempt at
resurrecting chewbranca.com in 2018!&lt;/p&gt;
</description>
        <pubDate>Fri, 20 Apr 2018 09:35:51 +0000</pubDate>
        <link>http://chewbranca.com/general/2018/04/20/does-this-thing-still-work/</link>
        <guid isPermaLink="true">http://chewbranca.com/general/2018/04/20/does-this-thing-still-work/</guid>
      </item>
    
      <item>
        <title>Rewriting the CouchDB HTTP layer</title>
        <description>&lt;p&gt;With the light at the end of tunnel on the BigCouch merge, I thought
it was time to get the conversation going on cleaning up the current
HTTP stack duality. We’ve got a good opportunity to do some major
cleanup, remove duplication, and really start more clearly separating
the various components of CouchDB.&lt;/p&gt;

&lt;h2 id=&quot;primary-objectives&quot;&gt;Primary objectives&lt;/h2&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;* Consolidate down to one HTTP layer
* Isolate HTTP functionality
* Separate HTTP server from HTTP resources
* Easy plugin integration
* Build clustered/local API
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;consolidate-down-to-one-http-layer&quot;&gt;Consolidate down to one HTTP layer&lt;/h3&gt;

&lt;p&gt;We currently have two HTTP layers, &lt;code class=&quot;highlighter-rouge&quot;&gt;couch_httpd&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;chttpd&lt;/code&gt;. This
was a useful construct when BigCouch was a separate application where
isolating the clustered layer from the local layer was necessary, and
quite useful.&lt;/p&gt;

&lt;p&gt;This is no longer the case, and we can significantly reduce code
duplication by consolidating down to one http layer. There are a
number of places in the two apps where the code is nearly identical,
except one calls out to &lt;code class=&quot;highlighter-rouge&quot;&gt;fabric&lt;/code&gt; and the other calls out for
&lt;code class=&quot;highlighter-rouge&quot;&gt;couch_*&lt;/code&gt;. For instance, compare &lt;code class=&quot;highlighter-rouge&quot;&gt;couch_httpd_db:couch_doc_open/4&lt;/code&gt; [1]
with &lt;code class=&quot;highlighter-rouge&quot;&gt;chttpd_db:couch_doc_open/4&lt;/code&gt; [2]. These are completely identical
aside from whether it goes through the clustered layer, &lt;code class=&quot;highlighter-rouge&quot;&gt;fabric&lt;/code&gt;, or
through the local layer &lt;code class=&quot;highlighter-rouge&quot;&gt;couch_db&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;There are plenty of other places with similar duplication. This is
obviously ripe with opportunity to refactor and introduce some higher
level abstractions to make the HTTP layer function independently of the
document/database level APIs.&lt;/p&gt;

&lt;h3 id=&quot;isolate-http-functionality&quot;&gt;Isolate HTTP functionality&lt;/h3&gt;

&lt;p&gt;I don’t think &lt;code class=&quot;highlighter-rouge&quot;&gt;couch_doc_open/4&lt;/code&gt; has any business existing in
the HTTP layer, we should move all non HTTP logic out. IMO the HTTP
layer should only concern itself with:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;1. Receiving the HTTP requests
2. Extracting out the request data into a standard data structure
3. Dispatch requests to the appropriate internal APIs
4. Forward the response
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Anything that doesn’t fit into those four steps should be ripped out
and moved elsewhere. For instance, the primary logic for determining the
database redundancy and shard values is done in &lt;code class=&quot;highlighter-rouge&quot;&gt;chttpd_db&lt;/code&gt; [3]. I
would greatly prefer to see this logic in a database API.&lt;/p&gt;

&lt;p&gt;The more we can isolate HTTP logic from database logic the
better. Once they are fully decoupled, then the HTTP layer is merely
one particular client interface on top of the core database. We also
get all the benefits of isolation for testing and what not.&lt;/p&gt;

&lt;p&gt;Along these lines, I think we greatly overuse the #http{} record for
passing around request data, and instead you extract the body, and
then combine all of the user supplied headers and query string params
into a standard options list. This we can we completely separate
making database requests from the representation of the client
request.&lt;/p&gt;

&lt;h3 id=&quot;separate-http-server-from-http-resources&quot;&gt;Separate HTTP server from HTTP resources.&lt;/h3&gt;

&lt;p&gt;I think everything I’ve said so far is pretty clear cut in terms of
it’s &lt;em&gt;the&lt;/em&gt; logical thing to do, but separating the HTTP server from
the HTTP endpoints is less clearly defined. However, we do have
precedence for this and there are a number of solid benefits.&lt;/p&gt;

&lt;p&gt;First, let me explain what I mean here. There are two pieces to an
HTTP stack, first there’s the core HTTP engine that handles receiving
and responding to requests and other things along those lines, and
second there’s the places where you supply your business logic and
figure what content to send to the user.&lt;/p&gt;

&lt;p&gt;CouchDB has a handful of places using this aproach, where instead of
defining all the logic in the HTTP stack directly, we have auxilary
modules defined within the appropriate applications that specify how
any HTTP requests for that application are handled. A good clean
example of this approach is &lt;code class=&quot;highlighter-rouge&quot;&gt;couch_mrview_http&lt;/code&gt; [4].&lt;/p&gt;

&lt;h3 id=&quot;easy-plugin-integration&quot;&gt;Easy plugin integration&lt;/h3&gt;

&lt;p&gt;One big advantage of the above separation of HTTP resources is that it
provides a standard way of plugins hooking in new HTTP endpoints. The
more we can treat the “core” CouchDB applications as plugins, the more
easily it is to isolate and replace various parts of the stack.&lt;/p&gt;

&lt;h3 id=&quot;build-clusteredlocal-api&quot;&gt;Build clustered/local API&lt;/h3&gt;

&lt;p&gt;The above example of &lt;code class=&quot;highlighter-rouge&quot;&gt;couch_doc_open/4&lt;/code&gt; is a clear cut case where
we want to abstract the process of loading a document. Not all places
are as easily abstractable, but this is a great example of why I think
we should have a standard API on top of clustered and local layers,
where deciding which to use is based on a local/clustered flag, or
some other heuristic.&lt;/p&gt;

&lt;p&gt;I’ve been toying around with the idea of making a request object of
some sort, is something like &lt;code class=&quot;highlighter-rouge&quot;&gt;couch_req:make(ReqBody, ReqOptions)&lt;/code&gt;
that you can then pass to &lt;code class=&quot;highlighter-rouge&quot;&gt;couch_doc_api&lt;/code&gt; or some such, but I don’t
have any strong opinions on this.&lt;/p&gt;

&lt;h2 id=&quot;where-ive-gotten-so-far-chttpd2-a-proof-of-concept&quot;&gt;Where I’ve gotten so far: chttpd2, a proof of concept&lt;/h2&gt;

&lt;p&gt;I’ve hacked out an experimental WebMachine [5] based rewrite of the
HTTP stack called &lt;code class=&quot;highlighter-rouge&quot;&gt;chttpd2&lt;/code&gt; [6]. This PoC follows the same ideas I’ve
outlined above, so I’ll run back through the previous outlined items
and explain how &lt;code class=&quot;highlighter-rouge&quot;&gt;chttpd2&lt;/code&gt; handles it.&lt;/p&gt;

&lt;h3 id=&quot;consolidate-down-to-one-http-layer-1&quot;&gt;Consolidate down to one HTTP layer&lt;/h3&gt;

&lt;p&gt;Right now I’m not doing anything special here, I still think building
an API layer that handles deciding whether to make a clustered or
local request is the proper approach, so I’ve not included any logic
in the HTTP stack for doing so.&lt;/p&gt;

&lt;h3 id=&quot;isolate-http-functionality-1&quot;&gt;Isolate HTTP functionality&lt;/h3&gt;

&lt;p&gt;I’ve got a solid separation of functionality in &lt;code class=&quot;highlighter-rouge&quot;&gt;chttpd2&lt;/code&gt;. If you
notice the current codebase in [6], there is zero logic for actually
handling any particular CouchDB requests. Rather those are self
contained within the appropriate sub applications. I’ve started this
for &lt;code class=&quot;highlighter-rouge&quot;&gt;couchdb-couch&lt;/code&gt; [7] and &lt;code class=&quot;highlighter-rouge&quot;&gt;couchdb-config&lt;/code&gt; [8]. Here’s a simple
example of the new welcome resource [9].&lt;/p&gt;

&lt;p&gt;As you can see, there is zero database logic in the welcome request
module. In fact, I started moving all the random logic in the current
HTTP layer to a temporary module I’m calling &lt;code class=&quot;highlighter-rouge&quot;&gt;couch_api&lt;/code&gt; [10]. As you
can see from that module, it removes all the logic that was previously
nested in &lt;code class=&quot;highlighter-rouge&quot;&gt;couch_httpd_misc_handlers&lt;/code&gt; [11]. More complicated examples
for creating a database and viewing database info are in [12], and an
all dbs example is in [13]. Also I’ve done similar things for
&lt;code class=&quot;highlighter-rouge&quot;&gt;couchdb-couch&lt;/code&gt; as mentioned above in [8].&lt;/p&gt;

&lt;h3 id=&quot;easy-plugin-integration-1&quot;&gt;Easy plugin integration&lt;/h3&gt;

&lt;p&gt;As I mentioned above, by making it easy to plugin in new HTTP
endpoints, we also make it easier for plugins to do the same. On that
front I’ve made it so each application can optionally declare a
&lt;code class=&quot;highlighter-rouge&quot;&gt;couch_dispatch&lt;/code&gt; function describing what endpoints it can handle, and
then &lt;code class=&quot;highlighter-rouge&quot;&gt;chttpd2&lt;/code&gt; will go and find all of those to figure out how to
dispatch requests [14]. And for example, here’s how the
&lt;code class=&quot;highlighter-rouge&quot;&gt;couchdb-couch&lt;/code&gt; endpoints are declared [15].&lt;/p&gt;

&lt;h3 id=&quot;build-clusteredlocal-api-1&quot;&gt;Build clustered/local API&lt;/h3&gt;

&lt;p&gt;I have not started on this front, and have only built these endpoints
for interacting with the clustered layer for simplicity as this is
just a proof of concept I hacked together. However, as I mentioned
above I’ve started moving all the logic out of the HTTP layer into
more appropriate places. I’ve made similar changes to &lt;code class=&quot;highlighter-rouge&quot;&gt;couch-config&lt;/code&gt;
by moving all of the logic from [16] into the &lt;code class=&quot;highlighter-rouge&quot;&gt;couch-config&lt;/code&gt;
application itself.&lt;/p&gt;

&lt;h3 id=&quot;why-webmachine&quot;&gt;Why WebMachine?&lt;/h3&gt;

&lt;p&gt;I find WebMachine [5] to be one of the more interesting HTTP stacks for
building webapps. In particular I like how they have a specific flow
chart [17] and coordinate point corresponds to a particular definition
of the &lt;code class=&quot;highlighter-rouge&quot;&gt;webmachine_decision_core:decision/1&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;That said I think Cowboy [19] has more momentum and might be a better
long term project to tie ourselves too.&lt;/p&gt;

&lt;p&gt;Also, if we decide to go the WebMachine route, we’ll need to
restructure a fair bit of the current HTTP layer, making a number of
breaking changes. I’m a strong -1 for coercing WebMachine into the
current haphazard CouchDB API. WebMachine is very opinionated on how
you structure your API (for good reason!) and I think going against
that is a mistake.&lt;/p&gt;

&lt;p&gt;So if we wanted to just do a drop in replacement of the current
CouchDB API, then Cowboy is the way to go. Although one of these days
we should clean up the HTTP API.&lt;/p&gt;

&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;I hope this can start a good discussion on a game plan for the HTTP
layer. Like I said, this is a proof of concept that I hacked out, so
I’m not attached to the code or the use of WebMachine, but I do think
it’s a good representation of the ideas outlined above.&lt;/p&gt;

&lt;p&gt;Looking forward to hearing your thoughts and comments!&lt;/p&gt;

&lt;h4 id=&quot;footnotes&quot;&gt;Footnotes&lt;/h4&gt;

&lt;p&gt;[1] https://github.com/apache/couchdb-couch/blob/master/src/couch_httpd_db.erl#L805-L823&lt;/p&gt;

&lt;p&gt;[2] https://github.com/apache/couchdb-chttpd/blob/master/src/chttpd_db.erl#L886-L904&lt;/p&gt;

&lt;p&gt;[3] https://github.com/apache/couchdb-chttpd/blob/master/src/chttpd_db.erl#L203-L205&lt;/p&gt;

&lt;p&gt;[4] https://github.com/apache/couchdb-couch-mrview/blob/master/src/couch_mrview_http.erl&lt;/p&gt;

&lt;p&gt;[5] https://github.com/basho/webmachine&lt;/p&gt;

&lt;p&gt;[6] https://github.com/chewbranca/chttpd2/tree/initial-branch&lt;/p&gt;

&lt;p&gt;[7] https://github.com/apache/couchdb-couch/tree/2073-feature-webmachine-http-engine&lt;/p&gt;

&lt;p&gt;[8] https://github.com/apache/couchdb-config/tree/2073-feature-webmachine-http-engine&lt;/p&gt;

&lt;p&gt;[9] https://github.com/apache/couchdb-couch/blob/2073-feature-webmachine-http-engine/src/couch_httpr_welcome.erl&lt;/p&gt;

&lt;p&gt;[10]
https://github.com/apache/couchdb-couch/blob/2073-feature-webmachine-http-engine/src/couch_api.erl&lt;/p&gt;

&lt;p&gt;[11] https://github.com/apache/couchdb-couch/blob/master/src/couch_httpd_misc_handlers.erl#L32-L45&lt;/p&gt;

&lt;p&gt;[12] https://github.com/apache/couchdb-couch/blob/2073-feature-webmachine-http-engine/src/couch_httpr_db.erl&lt;/p&gt;

&lt;p&gt;[13] https://github.com/apache/couchdb-couch/blob/2073-feature-webmachine-http-engine/src/couch_httpr_dbs.erl&lt;/p&gt;

&lt;p&gt;[14] https://github.com/chewbranca/chttpd2/blob/initial-branch/src/chttpd2_config.erl#L26-L33&lt;/p&gt;

&lt;p&gt;[15] https://github.com/apache/couchdb-couch/blob/2073-feature-webmachine-http-engine/src/couch.erl#L68-L73&lt;/p&gt;

&lt;p&gt;[16] https://github.com/apache/couchdb-couch/blob/master/src/couch_httpd_misc_handlers.erl#L155-L249&lt;/p&gt;

&lt;p&gt;[17] https://raw.githubusercontent.com/basho/webmachine/develop/docs/http-headers-status-v3.png&lt;/p&gt;

&lt;p&gt;[18] https://github.com/basho/webmachine/blob/develop/src/webmachine_decision_core.erl#L158-L595&lt;/p&gt;

&lt;p&gt;[19] https://github.com/ninenines/cowboy&lt;/p&gt;
</description>
        <pubDate>Sun, 17 Aug 2014 10:19:23 +0000</pubDate>
        <link>http://chewbranca.com/tech/2014/08/17/rewriting-the-couchdb-http-layer/</link>
        <guid isPermaLink="true">http://chewbranca.com/tech/2014/08/17/rewriting-the-couchdb-http-layer/</guid>
      </item>
    
      <item>
        <title>On the Viability of Erlang Releases and CouchDB</title>
        <description>&lt;p&gt;There has been some discussion on what versions of Erlang CouchDB
should support, and what versions of Erlang are detrimental to
use. Sadly there were some pretty substantial problems in the R15 line
and even parts of R16 that are landmines for CouchDB. This post will
describe the current state of things and make some potential
recommendations on approach.&lt;/p&gt;

&lt;h2 id=&quot;scheduler-collapse&quot;&gt;Scheduler Collapse&lt;/h2&gt;

&lt;p&gt;It was discovered by Basho that R15* and R16B are susceptible to
scheduler collapse. There’s quite a bit of discussion and
information in several threads [1] [2] [3] [4] [5].&lt;/p&gt;

&lt;p&gt;So what is scheduler collapse? Erlang schedulers can be put to sleep
when there is not sufficient work to occupy all schedulers, which
saves on CPU and power consumption. When the schedulers that are still
running go through enough reductions to pass the work balancing
threshold, they can trigger a rebalance of work that will wake up
sleeping schedulers. The other mechanism for sharing scheduler load is
work stealing. A scheduler that does not have any work to do can
steal work from other schedulers. However a scheduler that has gone
to sleep cannot steal work, it has to be woken up separately.&lt;/p&gt;

&lt;p&gt;Now the real problem of scheduler collapse occurs when you take
sleeping schedulers and long running NIFs and BIFs that do not report
an appropriate amount of reductions. When you have NIFs and BIFs that
don’t report an appropriate amount of reductions, you can get into a
situation where a long running function call will only show up as
taking one reduction, and never hit the work balance threshold,
causing that scheduler to be blocked during the operation and no
additional schedulers getting woken up.&lt;/p&gt;

&lt;p&gt;I keep mentioning “NIFs and BIFs” because it’s important to note that
it is &lt;em&gt;not&lt;/em&gt; just user defined NIFs that are problematic, but also a
number of Erlang BIFs that don’t properly report reductions.
Particularly relevant to CouchDB are the BIFs &lt;code class=&quot;highlighter-rouge&quot;&gt;term_to_binary&lt;/code&gt; and
&lt;code class=&quot;highlighter-rouge&quot;&gt;binary_to_term&lt;/code&gt; which do &lt;em&gt;not&lt;/em&gt; behave properly, and each report a
single reduction count, regardless of the size of the value passed to
them. Given that every write CouchDB makes goes through
&lt;code class=&quot;highlighter-rouge&quot;&gt;term_to_binary&lt;/code&gt;, this is definitely not good.&lt;/p&gt;

&lt;p&gt;This problem is systemic to all versions of R15 and R16B. In R16B01,
two changes were made to alleviate the problem. First, in &lt;code class=&quot;highlighter-rouge&quot;&gt;OTP-11163&lt;/code&gt;
&lt;code class=&quot;highlighter-rouge&quot;&gt;term_to_binary&lt;/code&gt; now uses an appropriate amount of reductions and will
yield back to the scheduler. The second important change was the
introduction of the &lt;code class=&quot;highlighter-rouge&quot;&gt;+sfwi&lt;/code&gt; (Scheduler Forced Wakeup Interval) flag
[6] which allows you to specify a time interval for a new watchdog
process to check scheduler run queues and wake up sleeping schedulers
if need be. These two changes help significantly, although from what I
understand, they do not fully eliminate scheduler collapse.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;NOTE&lt;/em&gt;: the &lt;code class=&quot;highlighter-rouge&quot;&gt;+sfwi&lt;/code&gt; is &lt;em&gt;not&lt;/em&gt; enabled by default, you must specify a
greater than zero time interval to enable this. &lt;em&gt;WE NEED TO ENABLE
THIS SETTING.&lt;/em&gt; We should figure out a way to conditionally add this
to vm.args or some such.&lt;/p&gt;

&lt;p&gt;On a side note, Basho runs R15B01 because they backported the &lt;code class=&quot;highlighter-rouge&quot;&gt;+sfwi&lt;/code&gt;
feature to R15B01 [7] [8]. They recommend running with &lt;code class=&quot;highlighter-rouge&quot;&gt;+sfwi 500&lt;/code&gt; for
a 500ms interval. It might be worth testing out different values, but
500 seems like a good starting point. For Riak 2.0, they will be
building against R16B03-1 and 17.0 as their set of patches to R16B02
landed in R16B03-1 [9] [10].&lt;/p&gt;

&lt;h2 id=&quot;r16b01-and-the-breaking-of-monitors&quot;&gt;R16B01 and the breaking of monitors&lt;/h2&gt;

&lt;p&gt;So R16B01 sorted out the scheduler collapse issues, but unfortunately
it also broke monitors, which immediately disqualifies this release as
something we should recommend to users. The issues was fixed in
&lt;code class=&quot;highlighter-rouge&quot;&gt;OTP-11225&lt;/code&gt; in R16B02.&lt;/p&gt;

&lt;h2 id=&quot;r16b02-and-r16b03&quot;&gt;R16B02 and R16B03*&lt;/h2&gt;

&lt;p&gt;I don’t know of any catastrophic problems on the order of those
described above in either of these releases. Basho fixed a number of
unrelated bugs in R16B02 [9] [10] that have since landed in R16B03-1,
which indicates we should probably prefer R16B03-1 over R16B02. R16B03
is also disqualified because it broke SSL and &lt;code class=&quot;highlighter-rouge&quot;&gt;erl_syntax&lt;/code&gt;, resulting
in the patched R16B03-1.&lt;/p&gt;

&lt;h2 id=&quot;r14&quot;&gt;R14&lt;/h2&gt;

&lt;p&gt;R14B01, R14B03, and R14B04 are known good stable releases of Erlang,
and in my opinion the only known stable releases &amp;gt; R13 that don’t
present issues for CouchDB (I think R16B02/R16B03-1 are too new to
declare stable yet). As for R14B02, there are some bad &lt;code class=&quot;highlighter-rouge&quot;&gt;ets&lt;/code&gt; issues
with that release.&lt;/p&gt;

&lt;p&gt;It’s worth pointing out that there are two known bugs in R14B01, as
Robert Newson explains:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;There are two bugs in R14B01 that we do encounter, however. 1) Another
32/64 bit oops causes the vm to attempt to allocate huge amounts of
ram (terabytes, or more) if it ever tries to allocate more than 2gib
of ram at once. When this happens, the vm dies and is restarted. It’s
annoying, but infrequent. 2) Sometimes when closing a file, the
underlying file descriptor is *not* closed, though the erlang process
exits. This is rare but still quite annoying.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;erlang-170&quot;&gt;Erlang 17.0&lt;/h2&gt;

&lt;p&gt;The 17.0 release brings in a number of interesting changes to help the
scheduler collapse situation. &lt;code class=&quot;highlighter-rouge&quot;&gt;OTP-11648&lt;/code&gt; improves reduction cost and
yielding of &lt;code class=&quot;highlighter-rouge&quot;&gt;term_to_binary&lt;/code&gt;. It also utilizes &lt;code class=&quot;highlighter-rouge&quot;&gt;OTP-11388&lt;/code&gt; which
allows for NIFs and BIFs to have more control over when and how they
are garbage collected (we should do some investigation on the
usefulness of this for NIFs like Jiffy).&lt;/p&gt;

&lt;p&gt;The 17.0 release also updates &lt;code class=&quot;highlighter-rouge&quot;&gt;binary_to_term&lt;/code&gt; in &lt;code class=&quot;highlighter-rouge&quot;&gt;OTP-11535&lt;/code&gt; to
behave properly with reductions and yielding similar to
&lt;code class=&quot;highlighter-rouge&quot;&gt;term_to_binary&lt;/code&gt;. This marks the 17.0 release as an important one for
CouchDB as now &lt;code class=&quot;highlighter-rouge&quot;&gt;term_to_binary&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;binary_to_term&lt;/code&gt; both behave
properly.&lt;/p&gt;

&lt;h2 id=&quot;dirty-schedulers&quot;&gt;Dirty Schedulers&lt;/h2&gt;

&lt;p&gt;One other interesting item introduced in the 17.0 release is the
concept of dirty schedulers [12] [13]. This is an experimental feature
providing CPU and I/O schedulers specifically for NIFs that are known
to take longer that 1ms to run. In general, we want to make sure the
NIFs we use will yield and report reductions properly, but for
situations where that isn’t feasible, we may want to look into using
dirty schedulers down the road when it’s a non experimental feature.&lt;/p&gt;

&lt;h2 id=&quot;recommendations-for-couchdb&quot;&gt;Recommendations for CouchDB&lt;/h2&gt;

&lt;p&gt;In my opinion we need to take the Erlang release issues more seriously
than we currently do and provide strong recommendations to users on
what versions of Erlang we support. I suggest we loosely take an
approach similar to Debian, and make three recommendations:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;OldStable: [R14B01, R14B03, R14B04 (NOTE: &lt;em&gt;not&lt;/em&gt; R14B02)]&lt;/li&gt;
  &lt;li&gt;Unstable: [R16B03-1 recommended, R16B02 acceptable]&lt;/li&gt;
  &lt;li&gt;Experimental: [17.0]&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’m not suggesting permanently having three Erlang releases
recommended like this, but it currently seems appropriate. I think
long term we should target 17.x as our preferred Erlang release, and
then make a CouchDB 3.0 release that is backwards incompatible with
anything less than 17.0 so that we can switch over to using maps.&lt;/p&gt;

&lt;p&gt;The narrowness of the acceptable releases list is going to cause some
problems. Debian Wheezy runs R15B01, which as established above, is
not good to run with unless you have the &lt;code class=&quot;highlighter-rouge&quot;&gt;+sfwi&lt;/code&gt; patch, and I’m sure
there are many other distros running R15 and R16B or R16B01. I think
it would be useful to users to have a set of packages with a proper
Erlang CouchDB release allowing us to bless specific versions of
Erlang and bundle it together, but I know this idea goes against the
recent change in stance on working with distributions, and I don’t
know the ASF stance on this issue well enough to comment on the
legality of it. That said, it does seem like the logical approach
until we get a range of stable releases spread out through the
distros.&lt;/p&gt;

&lt;h2 id=&quot;work-to-be-done&quot;&gt;Work to be done&lt;/h2&gt;

&lt;p&gt;We need to make sure that all NIFs we use that could potentially take
longer than 1ms to run properly yield and report reductions. For
Jiffy, there is already a good start on this work [11]. We’ll want to
look into what needs to be done for the rest of the NIFs.&lt;/p&gt;

&lt;h2 id=&quot;wrapping-up&quot;&gt;Wrapping up&lt;/h2&gt;

&lt;p&gt;There’s quite a bit of information here, and plenty more in the
footnotes, so I hope this gives a good overview of the current state
of Erlang releases and helps us to make informed decisions on what
approach to take with Erlang releases.&lt;/p&gt;

&lt;h3 id=&quot;footnotes&quot;&gt;Footnotes&lt;/h3&gt;

&lt;p&gt;[1] &lt;a href=&quot;http://comments.gmane.org/gmane.comp.lang.erlang.bugs/3564&quot;&gt;http://comments.gmane.org/gmane.comp.lang.erlang.bugs/3564&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[2] &lt;a href=&quot;http://erlang.org/pipermail/erlang-questions/2013-April/073490.html&quot;&gt;http://erlang.org/pipermail/erlang-questions/2013-April/073490.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[3] &lt;a href=&quot;http://erlang.org/pipermail/erlang-questions/2012-October/069503.html&quot;&gt;http://erlang.org/pipermail/erlang-questions/2012-October/069503.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[4] &lt;a href=&quot;http://erlang.org/pipermail/erlang-questions/2012-October/069585.html&quot;&gt;http://erlang.org/pipermail/erlang-questions/2012-October/069585.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[5] &lt;a href=&quot;http://permalink.gmane.org/gmane.comp.lang.erlang.bugs/3573&quot;&gt;http://permalink.gmane.org/gmane.comp.lang.erlang.bugs/3573&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[6] &lt;a href=&quot;http://erlang.org/pipermail/erlang-patches/2013-June/004109.html&quot;&gt;http://erlang.org/pipermail/erlang-patches/2013-June/004109.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[7] &lt;a href=&quot;https://gist.github.com/evanmcc/a599f4c6374338ed672e&quot;&gt;https://gist.github.com/evanmcc/a599f4c6374338ed672e&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[8] &lt;a href=&quot;http://data.story.lu/2013/06/23/riak-1-3-2-released&quot;&gt;http://data.story.lu/2013/06/23/riak-1-3-2-released&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[9] &lt;a href=&quot;https://github.com/basho/otp/compare/erlang:maint...OTP_R16B02_basho4&quot;&gt;https://github.com/basho/otp/compare/erlang:maint…OTP_R16B02_basho4&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[10] &lt;a href=&quot;https://groups.google.com/forum/#!topic/nosql-databases/XpFKVeUBdn0&quot;&gt;https://groups.google.com/forum/#!topic/nosql-databases/XpFKVeUBdn0&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[11] &lt;a href=&quot;https://github.com/davisp/jiffy/pull/49&quot;&gt;https://github.com/davisp/jiffy/pull/49&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[12] &lt;a href=&quot;https://github.com/erlang/otp/commit/c1c03ae4ee50e58b7669ea88ec4d29c6b2b67c7b&quot;&gt;https://github.com/erlang/otp/commit/c1c03ae4ee50e58b7669ea88ec4d29c6b2b67c7b&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[13] &lt;a href=&quot;http://www.erlang.org/doc/man/erl_nif.html#dirty_nifs&quot;&gt;http://www.erlang.org/doc/man/erl_nif.html#dirty_nifs&lt;/a&gt;&lt;/p&gt;
</description>
        <pubDate>Wed, 07 May 2014 20:17:51 +0000</pubDate>
        <link>http://chewbranca.com/tech/2014/05/07/on-the-viability-of-erlang-releases-and-couchdb/</link>
        <guid isPermaLink="true">http://chewbranca.com/tech/2014/05/07/on-the-viability-of-erlang-releases-and-couchdb/</guid>
      </item>
    
      <item>
        <title>Emacs + EDTS + (big)CouchDB... a journey</title>
        <description>&lt;p&gt;If you use Emacs to write Erlang, you might have heard of
&lt;a href=&quot;https://github.com/tjarvstrand/edts&quot;&gt;EDTS&lt;/a&gt;. It’s a recent Erlang
development suite for Emacs, and it has some impressive features, but
it can be a beast to get setup and working properly with CouchDB and
the BigCouch merge branch.&lt;/p&gt;

&lt;p&gt;Current CouchDB master’s folder hierarchy is non standard for Erlang
applications, and as a result it does not work well with EDTS. There
is work being done in the BigCouch merge branch and the RCouch merge
branch to restructure things in a standard OTP compliant
hierarchy. This guide is for Emacs + EDTS + the
&lt;a href=&quot;https://github.com/apache/couchdb/tree/1843-feature-bigcouch&quot;&gt;BigCouch merge branch&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you just want to load a vanilla VM with no running applications,
then just follow the standard EDTS config, but that’s boring. This
guide will get you setup connecting Emacs/EDTS to your local BigCouch
dev cluster, and provides all the nice EDTS features like automatic
code reloading in the running VM, Emacs repl with tab completion and
documentation, show callers and everything else in EDTS.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;WARNING&lt;/em&gt; this is quite a hack, and involves a number of changes and
 updates. I hope that by writing this up I’ll get some feedback on how
 to do things cleaner, but it works, and that’s the important part ;-)&lt;/p&gt;

&lt;h2 id=&quot;steps&quot;&gt;Steps&lt;/h2&gt;

&lt;p&gt;We’ll need to update the EDTS start script, make an .edts config file,
and use a hacked together function for spinning up the repl.&lt;/p&gt;

&lt;p&gt;Also worth noting is that this setup expects you to manually run
&lt;code class=&quot;highlighter-rouge&quot;&gt;./rel/boot_dev_cluster.sh&lt;/code&gt; in the BigCouch branch to spin up the
VM. If you forget to do that, EDTS will spin up a VM for you and then
when you try to boot the dev cluster you’ll get errors from trying to
run multiple Erlang VMs with the same name.&lt;/p&gt;

&lt;h3 id=&quot;update-edts-start-script&quot;&gt;Update EDTS start script&lt;/h3&gt;

&lt;p&gt;We need to update the base EDTS VM start script to use &lt;code class=&quot;highlighter-rouge&quot;&gt;-name&lt;/code&gt; instead
of &lt;code class=&quot;highlighter-rouge&quot;&gt;-sname&lt;/code&gt; so that it can talk to the CouchDB nodes. I also like to
add &lt;code class=&quot;highlighter-rouge&quot;&gt;-hidden&lt;/code&gt; so that th EDTS VM doesn’t show up in the list of nodes
in the three node dev cluster. Here’s my diff to the &lt;a href=&quot;https://github.com/tjarvstrand/edts/blob/master/start&quot;&gt;start script&lt;/a&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-diff&quot; data-lang=&quot;diff&quot;&gt;&lt;span class=&quot;gh&quot;&gt;diff --git a/start b/start
index de68605..c744e72 100755
&lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;--- a/start
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+++ b/start
&lt;/span&gt;&lt;span class=&quot;gu&quot;&gt;@@ -27,8 +27,9 @@ PLUGIN_DIR=$EDTS_HOME/plugins
&lt;/span&gt;
cd $EDTS_HOME
exec $ERL \
&lt;span class=&quot;gd&quot;&gt;-    -sname edts \
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+    -name edts@127.0.0.1 \
&lt;/span&gt;     -edts project_data_dir &quot;\&quot;$PROJDIR\&quot;&quot; \
     -edts plugin_dir &quot;\&quot;$PLUGIN_DIR\&quot;&quot; \
     -pa $EDTS_HOME/{lib,plugins}/*/ebin \
&lt;span class=&quot;gd&quot;&gt;-    -s edts_app
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+    -s edts_app \
+    -hidden&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;add-a-edts-config&quot;&gt;Add a .edts config&lt;/h3&gt;

&lt;p&gt;EDTS works by having a .edts config in the top level of your
project. We need to let the config know where to find all the
projects, and we also need to specify the name of the VM. It’s
important that the name matches the name of the local dev cluster node
you want to connect to, as EDTS will connect to the existing VM we
start with the dev script, rather than starting a new VM. This way any
changes you make will be immediately reflected in the running VM,
allowing you to curl again or work in remsh without having to manually
reload the modules or dev server. Here’s my config, it’s pretty
simple:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-common-lisp&quot; data-lang=&quot;common-lisp&quot;&gt;&lt;span class=&quot;ss&quot;&gt;:name&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;dev1&quot;&lt;/span&gt;
&lt;span class=&quot;ss&quot;&gt;:lib-dirs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;src&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Now when you open a &lt;code class=&quot;highlighter-rouge&quot;&gt;.erl&lt;/code&gt; file within the CouchDB source folder, EDTS
will start and then you will connect to the running dev server. At
this point you’ll be able to save files and have them loaded in the
VM, but you won’t have a repl available to you. For some reason EDTS
does not start a repl for nodes in remsh’s into.&lt;/p&gt;

&lt;h3 id=&quot;opening-an-inferior-erlang-remsh&quot;&gt;Opening an inferior Erlang remsh&lt;/h3&gt;

&lt;p&gt;I cobbled together a little function to spin up an inferior Erlang
shell and remsh into the dev cluster. This works, and let’s you
interact with the running VM, but you lose out on all the niceties of
the EDTS shell, like tab completion and inline documentation
boxes.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-common-lisp&quot; data-lang=&quot;common-lisp&quot;&gt;&lt;span class=&quot;c1&quot;&gt;;; adapted from: https://github.com/adbl/tools-emacs/blob/master/david.emacs&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;defun&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;erlang-shell-connect-to-node&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;interactive&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;MNode name to connect to: &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let*&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;inferior-erlang-machine-options&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;-hidden&quot;&lt;/span&gt;
                &lt;span class=&quot;s&quot;&gt;&quot;-name&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;emacs-remsh-%s&quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;s&quot;&gt;&quot;-remsh&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;%s@127.0.0.1&quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;erlang-shell-display&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;hacking-together-an-edts-remsh&quot;&gt;Hacking together an EDTS remsh&lt;/h3&gt;

&lt;p&gt;I decided I really wanted to have the proper EDTS repl, so I dove in
and hacked one out today. I updated
&lt;a href=&quot;https://github.com/tjarvstrand/edts/blob/master/elisp/edts/edts-shell.el&quot;&gt;edts-shell.el&lt;/a&gt;
with a new hardcoded function to connect to dev1 through a remsh. It’s
ugly, hardcoded, and it even throws an error at you when you run it,
but it works!&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-common-lisp&quot; data-lang=&quot;common-lisp&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;defun&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;edts-shell-dev1&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;&amp;amp;optional&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;pwd&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;switch-to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;&quot;Start an interactive erlang shell.&quot;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;interactive&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;edts-ensure-server-started&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;buffer-name&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;*dev1-shell&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;node-name&lt;/span&gt;   &lt;span class=&quot;s&quot;&gt;&quot;dev1@127.0.0.1&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;;; (command     (list &quot;erl&quot; &quot;-name dev1-remsh -hidden -remsh&quot; node-name))&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;command&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;/Users/russell/src/dotfiles/emacs.d/plugins/edts/start_dev1&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;root&lt;/span&gt;        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;expand-file-name&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;pwd&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;default-directory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;buffer&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;edts-shell-make-comint-buffer&lt;/span&gt;
                   &lt;span class=&quot;nv&quot;&gt;buffer-name&lt;/span&gt;
                   &lt;span class=&quot;nv&quot;&gt;node-name&lt;/span&gt;
                   &lt;span class=&quot;nv&quot;&gt;root&lt;/span&gt;
                   &lt;span class=&quot;nv&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;edts-init-node-when-ready&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;node-name&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;node-name&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;root&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;switch-to&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;switch-to-buffer&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
      &lt;span class=&quot;nv&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;I was having trouble properly passing the Erlang VM command line
options, so I switched to using a little shell script to start the
VM. Ideally the commented out command declaration should do the trick,
but I was having issues with it. Here’s my start_dev1 script:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;#/usr/bin/env bash&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;exec&lt;/span&gt; /usr/local/bin/erl &lt;span class=&quot;nt&quot;&gt;-name&lt;/span&gt; dev1-remsh &lt;span class=&quot;nt&quot;&gt;-hidden&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-remsh&lt;/span&gt; dev1@127.0.0.1&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Hopefully someone has a cleaner approach for this, but it works for
now.&lt;/p&gt;

&lt;h2 id=&quot;results&quot;&gt;Results&lt;/h2&gt;

&lt;p&gt;With this in place I’ve got a solid Emacs + EDTS dev environment for
hacking on (big)CouchDB. If you have any feedback or suggestions,
please don’t be shy as this is definitely a work in progress and I see
it as an minimal working version, not a finished configuration. I
would also like to better understand interacting with running VMs with
EDTS, it seems to be designed with the assumption you’re working
locally with a VM started by EDTS, not a running environment. I’m
curious if the author of EDTS has any suggestions on better approach
here.&lt;/p&gt;

&lt;h2 id=&quot;gotchas&quot;&gt;Gotchas&lt;/h2&gt;

&lt;p&gt;Some random things to keep in mind.&lt;/p&gt;

&lt;h3 id=&quot;single-node-interaction-only&quot;&gt;Single node interaction only&lt;/h3&gt;

&lt;p&gt;Right now you connect to an individual node, in this case dev1. The
local dev cluster spins up dev2 and dev3 as well, but this does not
connect to those nodes, and does not load code with &lt;code class=&quot;highlighter-rouge&quot;&gt;nl&lt;/code&gt; to upgrade
all nodes with your modifications. I would like to fix this to at
least do an &lt;code class=&quot;highlighter-rouge&quot;&gt;nl&lt;/code&gt;. You’ll occasionally run into whacky behavior on the
dev cluster, just restart it and run &lt;code class=&quot;highlighter-rouge&quot;&gt;M-x edts-project-node-init&lt;/code&gt; to
reconnect.&lt;/p&gt;

&lt;h3 id=&quot;disconnected-from-dev1-vm&quot;&gt;Disconnected from dev1 VM&lt;/h3&gt;

&lt;p&gt;If you restart the dev server, you’ll lose the connection from EDTS
and will get an error when it tries to push your changes. I just do
&lt;code class=&quot;highlighter-rouge&quot;&gt;M-x edts-project-node-init&lt;/code&gt; to get back up and running.&lt;/p&gt;

&lt;h3 id=&quot;show-source-under-cursor-doesnt-go-into-erlangotp-source&quot;&gt;Show source under cursor doesn’t go into Erlang/OTP source&lt;/h3&gt;

&lt;p&gt;I was having issues following code into the full OTP source, and I
tracked this down to the compile info stored in the beams pointing to
a directory that did not exist on my system. I’m not sure what
happened there, I was using erlbrew but ended up going back to erln8
and now I can follow code down into the Erlang/OTP source.&lt;/p&gt;

&lt;h3 id=&quot;built-in-manual&quot;&gt;Built in manual&lt;/h3&gt;

&lt;p&gt;Don’t forget to generate the manual with &lt;code class=&quot;highlighter-rouge&quot;&gt;M-x edts-man-setup RET&lt;/code&gt; so
you can go directly to the man pages inside emacs and also get inline
function docs, very handy!&lt;/p&gt;
</description>
        <pubDate>Fri, 14 Mar 2014 21:05:46 +0000</pubDate>
        <link>http://chewbranca.com/tech/2014/03/14/emacs-edts-couchdb-a-journey/</link>
        <guid isPermaLink="true">http://chewbranca.com/tech/2014/03/14/emacs-edts-couchdb-a-journey/</guid>
      </item>
    
  </channel>
</rss>
