urn:clojang-lfe-io:feed2018-07-19 00:28:43The Clojang BlogFollowup: New Versions of Clojang Agent and API Published on Clojars2018-07-19 00:28:43oubiwannurn:clojang-lfe-io:feed:post:Followup: New Versions of Clojang Agent and API Published on Clojars<p>As with the <a href='/archives/2018-07/17-191932/new-versions-of-jinterface-and-jiface-published-on-clojars.html'>post from the other day</a>, tonight (this morning) has seen the two other core Clojang libraries get updates. The agent lib in particular is a cause for celebration, since there's been an out-standing issue with failing builds for the past year (a dep with AOT'ed classes was the primary suspect; unlike the vanilla class-not-found-due-to AOT'ed JAR file collisions, this one was particulaly nasty/unusual ... hadn't seen anything like it before). That issue is now closed and builds are successful again.</p><p>The agent is the means by which a JVM process can emulate the behaviour of an Erlang/OTP process (with regard to its messaging inbox, node name assignment, and other defaults set up automatically, keeping thigs simple for the developer).</p><p>The long-awaited fix allowed me to pump out the following agent releases:</p><ul><li><a href='https://clojars.org/clojang/agent/versions/0.4.0'>agent 0.4.0</a> for Erlang 19.2 and 19.3 (uses JInterface 1.7.1)</li><li><a href='https://clojars.org/clojang/agent/versions/0.5.0'>agent 0.5.0</a> for Erlang 20.3 (uses JInterface 1.8.1)</li><li><a href='https://clojars.org/clojang/agent/versions/0.6.0'>agent 0.6.0</a> for Erlang 21.0 (uses JInterface 1.9)</li></ul><p>And then the clojang API releases that depended upon the different agent versions:</p><ul><li><a href='https://clojars.org/clojang/clojang/versions/0.4.0'>clojang 0.4.0</a> for Erlang 19.2 and 19.3 (uses JInterface 1.7.1)</li><li><a href='https://clojars.org/clojang/clojang/versions/0.5.0'>clojang 0.5.0</a> for Erlang 20.3 (uses JInterface 1.8.1)</li><li><a href='https://clojars.org/clojang/clojang/versions/0.6.0'>clojang 0.6.0</a> for Erlang 21.0 (uses JInterface 1.9)</li></ul><p>Still coming up ...</p><ul><li>Port more Erlang/Java examples to LFE/Clojure</li><li>Demonstrate use with the Clojure Component library</li><li>Demonstrate managing throw-away JVM instances from Erlang/LFE, managed via JMX</li></ul>New Versions of JInterface and jiface Published on Clojars2018-07-17 19:19:32oubiwannurn:clojang-lfe-io:feed:post:New Versions of JInterface and jiface Published on Clojars<p>Since the last updates to the Clojure libraries, Erlang has had several major releases. Today, I was able to catch up and publish the following:</p><ul><li><a href='https://clojars.org/clojang/erlang-jinterface/versions/1.8.1'>JInterface 1.8.1</a> for Erlang 20.3 (ERTS 9.3)</li><li><a href='https://clojars.org/clojang/erlang-jinterface/versions/1.9'>JInterface 1.9</a> for Erlang 21.0 (ERTS 10)</li></ul><p>These are now available on Clojars.</p><p>Also now on Clojars are the following low-level Clojure API releases:</p><ul><li><a href='https://clojars.org/clojang/jiface/versions/0.4.0'>jiface 0.4.0</a> for Erlang 19.2 and 19.3 (uses JInterface 1.7.1)</li><li><a href='https://clojars.org/clojang/jiface/versions/0.5.0'>jiface 0.5.0</a> for Erlang 20.3 (uses JInterface 1.8.1)</li><li><a href='https://clojars.org/clojang/jiface/versions/0.6.0-SNAPSHOT'>jiface 0.6.0-SNAPSHOT</a> for Erlang 21.0 (uses JInterface 1.9)</li></ul><p>Coming up:</p><ul><li>Similar updates for the JVM agent and the hi-level API (clojang-proper)</li><li>Port more Erlang/Java examples to LFE/Clojure</li><li>Demonstrate use with the Clojure Component library</li><li>Demonstrate managing throw-away JVM instances from Erlang/LFE, managed via JMX</li></ul>New Clojang Blog2017-03-16 00:47:34oubiwannurn:clojang-lfe-io:feed:post:New Clojang Blog<p>After a few weeks of hacking and furtive hosting of alpha code and alpha-er content, I think the blog's ready to have more eyeballs on it. It's mostly a vehicle for sharing Clojang project code snippets, clarifying documentation (and then using that to go update the docs!), provide updates on version releases, and maybe even share the occasional experiment. Though it should be fairly low-volume and low-impact, it seemed like a nice way increase the contact area for curious developers who have to (or want to!) straddle the two very different worlds of the JVM (Clojure in particular) and BEAM.</p><p>I might not ever have created a dedicated blog for Clojang, but there's been a growing interest among fellow LFErs and BEAMers in general, as well as from curious Clojurians. After the 5th or 6th recent conversation, it was time to do something. One comment in particular, that I should create a <code>STATUS.md</code> file in the one or more repos really motivated me to do something about a Clojang blog.</p><p>For the archivally inclined, the following notes may be of interest. I've been able to reconstruct the older posts from old notes, repositories, and emails, but the furthest back I could find was work I was doing on <a href='https://github.com/Elzor'>Maxim Molchanov</a>'s <a href='https://github.com/Elzor/erlang-clojure-node'>erlang-clojure-node</a> repository. There was work done earlier, but I can't find it anywhere, since I don't think any of that got committed. However, it wasn't any time before the end of 2013, so I didn't lose much :-)</p><p>There was also some forking I did of <a href='https://github.com/awetzel'>Arnaud Wetzel</a>'s <a href='https://github.com/awetzel/clojure-erlastic'>clojure-erlastic</a> repository, but which has since been deleted from Github since that was abandoned and a completely different tack was chosen. I do have an older repo of that on disk somewhere, so if anyone's interested, I can push it up to a Clojang attic ...</p><p>Anyway, all this is to say that most of the important stuff has been preserved and the interesting bits are now either in the various <a href='http://github.com/clojang'>Clojang</a> repos or they've been published on the blog.</p><p>One last thing: comments are on the way ... but they will be a bit unusual: each blog post that has comments enabled will link to a dedicated ticket on Github <i class="fa fa-github"></i></p>Clojang Mail List & Slack Channel2017-03-12 21:25:49oubiwannurn:clojang-lfe-io:feed:post:Clojang Mail List & Slack Channel<h2>Mail List</h2><p>A mail list for Clojang has been created and is availble for user subscriptions here:</p><ul><li><a href='https://groups.google.com/forum/#!forum/clojang'>https://groups.google.com/forum/#!forum/clojang</a></li></ul><p>Once subscribed, you may send emails to the list via clojang@googlegroups.com.</p><h2>Slack</h2><p>Additionally, a Slack channel has been set up at <a href='http://clojang.slack.com'>clojang.slack.com</a>. However, you need an invite in order to join the rooms. If you would like to participate in Clojang development or usage discussions, send a direct message to <a href='http://twitter.com/clojang'>@Clojang</a> (requires mutual follow) or open a <a href='https://github.com/clojang/slack/issues/new'>Slack invitation request ticket</a>.</p>Clojang is on Twitter2017-03-04 20:19:18oubiwannurn:clojang-lfe-io:feed:post:Clojang is on Twitter<p>The Clojang project now has a <a href='https://twitter.com/clojang'>Twitter account</a> :-)</p>Progress Towards the Next Releases2017-03-01 23:52:10oubiwannurn:clojang-lfe-io:feed:post:Progress Towards the Next Releases<p>An enormous amount of work has been going on in Clojang-land lately – enough so that a new release is imminent. The work in jiface and clojang is being driven almost entirely by the long-awaited rewrite of <a href='lfecljapp'>lfecljapp</a>.</p><p>The tickets have all been organized into a release, epics, features, tasks, etc., and are linked from this one ticket here:</p><ul><li><a href='https://github.com/clojang/lfecljapp/issues/20'>isuse #20 - Release 0.4.0</a></li></ul>Clojang, JInterface, & core.async2017-02-24 01:42:24oubiwannurn:clojang-lfe-io:feed:post:Clojang, JInterface, & core.async<p>The discussion on Slack the other day kicked off with a question about how messages are consumed in Clojang (and thus jiface and JInterface), and whether, in Clojure code, one could use <code>core.async</code> to do this.</p><p>We'll take a very quick deep (while at the same time superficial) dive into this, but then answer some broader questions to provide a better context for JInterface and the projects built upon it.</p><h2>Receiving Messages</h2><p>If you are using the <code>clojang</code> library, receiving messages is as simple as the following (assuming you've followed the best practice of adding the Clojang <code>agent</code> dependency in your <code>project.clj</code> file and set the <code>:java-agents</code> option):</p><pre><code class="cl">(require '[clojang.core :refer [receive]]
(receive)
</code></pre><p>At which point, your code blocks until a message is received. When a message comes in, <code>clojang</code> will automatically convert the Java-OTP hybrid types to Clojure types; when you reply, the conversion will take place in the other direction.</p><p>A fuller examples is viewable here:</p><ul><li><a href='https://github.com/clojang/lfecljapp/blob/master/src/clj/cljnode/server.clj'>https://github.com/clojang/lfecljapp/blob/master/src/clj/cljnode/server.clj</a></li></ul><p>Under the hood (in the <code>clojang</code> library), a default OTP node and associated mbox are being used (using the Clojure-idiomatic library <code>jiface</code>). Under <em>that</em> hood, Erlang's JInterface Java library is using threads, sockets, and custom queues to handle in-coming and out-going messages.</p><p>In other words, not a lot of room for <code>core.async</code>, unfortunately.</p><p>However, there's a <em>little</em> bit of room :-)</p><h2>Command & Convenience Channels</h2><p>One way I use <code>core.async</code> in Clojang applications is to facilitate communications between Clojure functions (i.e., a Clojang server and client, both written in Clojure).</p><p>Here's a Clojure server that takes a <code>core.async</code> channel as an argument:</p><pre><code class="clj">(defn run
[cmd-chan]
(log/info "Starting Clojure node with nodename ="
(System/getProperty "node.sname"))
(let [init-state 0]
(loop [png-count init-state]
(match (receive)
[:register caller]
(do
(log/infof "Got :register request from %s ..." caller)
(mbox/link (self) caller)
(! caller :linked)
(recur png-count))
[:ping caller]
(do
(log/infof "Got :ping request from %s ..." caller)
(! caller :pong)
(recur (inc png-count)))
[:get-ping-count caller]
(do
(log/infof "Got :get-ping-count request from %s ..." caller)
(! caller png-count)
(recur png-count))
[:stop caller]
(do
(log/warnf "Got :stop request from %s ..." caller)
(! caller :stopping)
:stopped)
[:shutdown caller]
(do
(log/warnf "Got :shutdown request from %s ..." caller)
(! caller :shutting-down)
(async/>! cmd-chan :shutdown))
[_ caller]
(do
(log/error "Bad message received: unknown command")
(! caller [:error :unknown-command])
(recur png-count))
[_]
(do
(log/error "Bad message received: improperly formatted")
(recur png-count))))))
</code></pre><p>In this particular case, it doesn't do too much: it simply sends a message back to the calling code when the server has been asked to shutdown. (Note that the <code>:shutdown</code> clause is sending two types of messages: first an OTP message reply is sent back to the calling OTP node – which could be either another OTP Clojure node or a BEAM node – and then a <code>core.async</code> message is pushed onto the channel that was passed to the server function. In the case where this code was copied from, that channel was started by the function that called <code>(run)</code>.)</p><p>That's a really simple (and not strictly necessary) example of a command channel use case for <code>core.async</code> in a Clojang app. Here's another case:</p><pre><code class="clj">(defn otp-bridge
"This function creates the following in order to facilitate core.async
communications with the Clojure OTP server:
1. A dedicated mbox for the OTP bridge (what receives messages from the
OTP server)
2. The pid for the dedicated mbox
3. A core.async channel for sending messages to the OTP server."
[]
(let [bridge-mbox (mbox/add :otpbrige)
bridge-pid (mbox/get-pid bridge-mbox)
bridge-chan (async/chan)]
(async/go-loop []
(when-let [value (async/<! bridge-chan)]
(! [value bridge-pid]))
(recur))
{:mbox bridge-mbox
:pid bridge-pid
:channel bridge-chan}))
</code></pre><p>As the docstring above says, this function uses <code>core.async</code> to provide a wrapper for OTP communications with a Clojang server. Interesting and kind of fun, but not really tapping into the power of <code>core.async</code>.</p><h2>Zhang</h2><p>There is an experimental project for exploring ways in which Clojure/OTP applications could maximize <code>core.async</code> while communicating with nodes, services, and full distributed systems in the BEAM world:</p><ul><li><a href='/archives/2016-02/13-121526/zhang.html'>Zhang</a> (blog post/project announcement)</li><li><a href='http://github.com/clojang/zhang'>zhang on github</a></li></ul><p>Those two links provide some good introductory material, so I won't duplicate that here. Note, however, than while the <code>jiface</code> and <code>clojang</code> libs are stabilizing, little effort is being applied to <code>zhang</code>. As such, there's not much to the project currently.</p>clojang & agent v0.3.0 Released2017-01-17 19:48:58oubiwannurn:clojang-lfe-io:feed:post:clojang & agent v0.3.0 Released<p>The new releases are available here:</p><ul><li><a href='https://github.com/clojang/clojang/releases/tag/0.3.0'>clojang</a>.</li><li><a href='https://github.com/clojang/agent/releases/tag/0.3.0'>agent</a>.</li></ul><p>Enjoy!</p>jiface & clojang-agent v0.1.0 Released2016-04-30 21:43:38oubiwannurn:clojang-lfe-io:feed:post:jiface & clojang-agent v0.1.0 Released<p>The new releases are available here:</p><ul><li><a href='https://github.com/clojang/jiface/releases/tag/0.1.0'>jiface</a></li><li><a href='https://github.com/clojang/agent/releases/tag/0.1.0'>agent</a></li></ul><p>Enjoy!</p>clojang v0.1.0 Released2016-02-15 02:04:57oubiwannurn:clojang-lfe-io:feed:post:clojang v0.1.0 Released<p>After two months of intense development, the first (alpha) release of clojang is out!</p><p>Available <a href='https://github.com/clojang/clojang/releases/tag/0.1.0'>here</a>.</p><p>Enjoy!</p>Zhang2016-02-13 12:15:26oubiwannurn:clojang-lfe-io:feed:post:Zhang<p>Today <a href='http://github.com/clojang'>yet another Clojang project</a> was created:</p><ul><li><a href='http://github.com/clojang/zhang'>zhang</a></li></ul><p>From the project's README, here is a (partial) list of desired features:</p><ul><li>the ability to quickly create and destroy processes, nodes, and mboxes</li><li>ensure the safe "crashing" of a process</li><li>very fast message-passing between processes</li><li>the ability support very large numbers of processes</li><li>shared nothing</li><li>low-overhead function-level mailboxes</li><li>ordered message queues</li><li>timeouts</li><li>pattern matching (<code>core.match</code>) and selective <code>receive</code></li><li>process registration hooks (in order to support arbitrary publishing mechanisms)</li></ul><p>A great deal of work (and time in production deployments) has gone into Erlang's JInterface Java package. Using it in Clojure has been such a pain, however, that two projects were created to mitigate two major issues around that (Clojure idioms and sane OTP defaults). Even with these libraries under active development, their ultimate goals (and areas of focus) are beyond the scope of addressing the JInterface internals of threads, sockets, and queues. As such, zhang was created to find a good solution for replacing those bits with <code>core.async</code>.</p><p>The project is experimental in nature and will likely be developed only very slowly, especially while <a href='https://github.com/clojang/jiface'>jiface</a> and <a href='https://github.com/clojang/clojang'>clojang</a> are in development. Once those projects hit a level of stability, though, I expect to be spending more time on the interesting problems to be solved in zhang.</p><p>Additionally, I expect that zhang, jiface, and clojang will end up sharing a certain amount of code. Only once jiface and clojang stabilize will it become clear what common bits for zhang can be split out into supporting library projects. I expect that one of these will be the type conversions developed in clojang (i.e., there will likely eventually be a clojang/types library and corresponding repo).</p><p>Since zhang aims to be messaging and deployment agnostic, there could also be a set of message implementation libraries created – the first of which would be the default: OTP process messaging. However, there's no reason other message formats couldn't be implemented or integrated. This would allow zhang (and thus Clojang in general) to transcend the current domain of OTP messaging and take fault-tolerant, soft real-time programming into other areas of the Clojure ecosystem.</p><p>On a fun side note, the zhang project takes it's name from <a href='https://en.wikipedia.org/wiki/Zhang_Heng'>Zhang Heng</a>, who approximated pi early in the first millennium (Han Dynasty). This is an obscure pun, since the Erlang process model could be, in some ways, interpreted as an approximation of the <a href='https://en.wikipedia.org/wiki/%CE%A0-calculus'>process calculus</a>. In addition to being a mathematician, Zhang Heng was also a poet, astronomer, and engineer – a wonderful patron for a software project :-)</p>Announcing jiface, clojang, & a Clojure OTP agent2016-01-19 18:42:24oubiwannurn:clojang-lfe-io:feed:post:Announcing jiface, clojang, & a Clojure OTP agent<p>After all the hacking on the Clojure/LFE/Erlang code – a prototype version of Clojang – it has become clear that Clojang really needs to be split into projects with separate concerns. Firstly, there needs to be a dedicated project for two very distinct aspects of this mini-ecosystem:</p><ul><li>There should be a low-level Clojure wrapper around JInterface (having to write OTP-interop code using Clojure's Java interop makes for unbelievably ugly code ...). This library should have no opinions about anything, instead simply providing a minimally Clojure-idiomatic wrapper around JInterface.</li><li>In addition, there needs to be a mid-level API that wrapps jiface and allows one to use even more idiomatic Clojure (and perhaps some LFE-isms, too). This library can have the luxury of being opinionated about how things should be done, including default nodes, mboxes, etc., as well as automatic conversion of Erlang/OTP types.</li></ul><p>Finally, there is a bit of functionality that can be broken out into another project, usable by clojang and other higher-level libs that would benefit from some basic OTP conveniences: a <a href='http://github.com/clojang/agent'>Clojure/Java agent</a> that helps set up a default OTP node in Clojure applications.</p><p>The home for these projects is here:</p><ul><li><a href='http://github.com/clojang'>githb.com/clojang</a></li></ul><p>Or, individually:</p><ul><li><a href='http://github.com/clojang/jiface'>githb.com/clojang/jiface</a></li><li><a href='http://github.com/clojang/clojang'>githb.com/clojang/clojang</a></li><li><a href='http://github.com/clojang/agent'>githb.com/clojang/agent</a></li></ul><p>The work started last year on <a href='https://github.com/awetzel/clojure-erlastic'>a fork of Arnaud Wetzel'a code</a>, while interesting at first, doesn't really provide a general and open-ended solution that's needed for larger-scale applications. As such, the new version of clojang – as well as its other new sister projects – represents a completely fresh start with no shared code history. This should leave things maximally flexible.</p>lfecljapp v0.3.0 Release2015-09-19 20:20:40oubiwannurn:clojang-lfe-io:feed:post:lfecljapp v0.3.0 Release<p>The project that kicked this whole thing off just got a series of updates. In fact, it got enough of them to warrant a new release. However, this will likely be the last significant update for a while, since I'm going to spend any time I have for this work on core libraries of jiface and clojang.</p><p>Hopefully, the next release of lfecljapp will be using released versions of jiface, clojang, and the agent.</p><p>Stay tuned ...</p>Clojang2015-09-13 23:19:09oubiwannurn:clojang-lfe-io:feed:post:Clojang<p>After the initial work with Erlang, LFE, Clojure, and JInterface last year, I've been pursuing other options of simplifying BEAM development (LFE in particular) in conjunction with JVM apps (Clojure, really). I recently came across the work of <a href='https://github.com/awetzel'>Arnaud Wetzel</a> in his <a href='https://github.com/awetzel/clojure-erlastic'>clojure-erlastic</a> project.</p><p>This looks promising enough to fork and experiment with, so I've done just that. However, since I plan on doing much more than what clojure-erlastic provides, I've changed the name of the forked repo to "clojang" :-)</p>A New Project2014-05-11 22:55:55oubiwannurn:clojang-lfe-io:feed:post:A New Project<p>I've been hacking on LFE/Clojure code lately, based on the work that <a href='https://github.com/Elzor'>Maxim Molchanov</a> has done in his <a href='https://github.com/Elzor/erlang-clojure-node'>Erlang/Clojure repo</a>. This could end up being a great deal of fun :-)</p><p>Here's a quick sample of his Erlang supervisor for a Clojure node:</p><pre><code class="erlang">-module(clojurenode_sup).
-behaviour(supervisor).
%% API
-export([start_link/0]).
%% Supervisor callbacks
-export([init/1]).
%% Helper macro for declaring children of supervisor
-define(CHILD(I, Type), {I, {I, start_link, []}, permanent, 5000, Type, [I]}).
%% ===================================================================
%% API functions
%% ===================================================================
start_link() ->
supervisor:start_link({local, ?MODULE}, ?MODULE, []).
%% ===================================================================
%% Supervisor callbacks
%% ===================================================================
init([]) ->
{ok, { {one_for_one, 5, 10}, [?CHILD(clj_controller, worker)]} }.
</code></pre><p>Note sure if the work I'm doing with LFE and Clojure will go anywhere yet, but even if it doesn't, it's a ton of fun :-)</p>