Fork me on GitHub
#lumo
<
2017-11-30
>
johnjelinek16:11:51

is there a good way to eval some cljs from node with lumo?

johnjelinek16:11:01

I don't see it documented in the repo

johnjelinek16:11:31

I'd like to run a bootstrap start script that calls a commonJS exported method and passes it to a cljs function that is transpiled as it's called rather than built up-front

johnjelinek16:11:11

pseudocode:

import * as lumo from 'lumo-cljs'
const cljs-handler = require('src/cljs-handler/core.cljs')

exports.handler = (event, context, callback) => lumo.eval(cljs-handler(event, context, callback));

hlolli16:11:56

@johnjelinek this is not possible, what you could do is just spawn lumo from node

var lumoProcess = spawn(process.cwd() + '/node_modules/lumo-cljs/bin/lumo',
                        			['-e', 'insert code here', '-m', 'or run a script with main', 'or without a main like (load-file ...)']);
// get the return values
lumoProcess.stdout.on('data', (data) => {
    console.log(`${data}`);
});

lumoProcess.stderr.on('data', (data) => {
    console.log(`${data}`);
});

johnjelinek16:11:01

would this be a good feature?

johnjelinek16:11:43

For me, I'd like to cut down transpile time and I haven't been able to figure out how to call transpiled output with :optimizations :none

johnjelinek16:11:13

since I'm deploying code on the backend -- I don't have any need to bundle and minify and what-not

hlolli16:11:27

have yout tried adding :^export to your function you want to call from js-land?

johnjelinek16:11:41

ya -- but even then, I have to do this:

const cljs-handler = ('./out/main.js')

exports.handler = (event, context, callback) => cljs-handler.cljs-handler.core.handler(event, context, callback);

johnjelinek16:11:00

because the stuff from Google Closure doesn't export to CommonJS format

johnjelinek17:11:41

I thought maybe I could do :optimizations :none and then in my bootstrap file:

require('out/goog/base')
const cljs-handler = ('./out/main')
...
but then it complains about not finding goog in the global namespace

johnjelinek17:11:41

so -- I pushed this example last night: https://github.com/johnjelinek/cljs-lambda It would be nice to not have to run npm run build before being able to npm start

bhurlow20:11:50

@johnjelinek my two cents on your two questions ;):

bhurlow20:11:43

1. requiring lumo from a standard js project sort of mitigates the value prop of lumo, in that case you may prefer to simply import the bootstrapped cljs library ala https://github.com/nasser/clojurescript-npm

johnjelinek20:11:54

>Status > >Very early. Do not use for anything critical. Contributions welcome! ☝️ doesn't make me feel too warm n' fuzzy

johnjelinek20:11:49

also, I don't see how it mitigates the value prop of lumo -- is the alternative to take a dep on Java?

bhurlow22:11:57

Hi John! so regarding the ‘status’ warning there, that code base is really just a small shim around the bootstrap clojurescript compiler aka cljs.js which is actually pretty stable 🙂 The bootstrapped compiler is still very young so you could say the whole project is a ‘not for production’ status though I’ve been running plenty of cljs code and I find the compiler output relatively robust

bhurlow22:11:49

and for the second comment, what I mean to say is that the value proposition of lumo is really about pre-loading the bootstrapped cljs repl into the v8 snapshot for a fast ‘native like’ experience. Requiring lumo as a library doesn’t make use of much of what separates lumo from just simply using the cljs compiler. The alternative would be simply to use the compiler (which is just js anyway) from node.js, imo that makes more sense in than including, for example, the lumo repl implementation. Hope I’m understanding your use case properly 👍

johnjelinek23:11:25

oh, is there an official nodejs implementation of a cljs compiler? I thought that's what lumo was for

bhurlow01:12:54

No there is not an official nodejs compiler, instead clojure can generate clojurescript code that includes the compiler in the resulting javascript. This is what they call ‘self-hosted’ or ‘bootstrapped’ and basically the clojurescript compiler is available to all javascript targets as a essentially a library

bhurlow01:12:47

That code can be run with node.js. But it can also run on other js platforms like Rhino, JavascriptCore (MacOS), browsers

bhurlow01:12:05

It’s all very inception

johnjelinek16:12:02

ya, but that requires a dependency on Java -- I don't want to take that dependency -- so I'm using lumo to fulfill that dependency instead

bhurlow20:11:20

2. re usage of cljs in AWS lambda, my company has been including static binaries into our lambda releases with the help of (https://github.com/apex/up), we are simply popping the lumo linux binary in there instead of building lambda compatible js. So far this has been really awesome as we’re not bound to their older js runtimes

johnjelinek20:11:58

@bhurlow: do you have any examples of this? This is what I had in mind for one of my upcoming steps.

johnjelinek20:11:52

how do you bootstrap the static binary? I suppose you follow a convention of up?

bhurlow22:11:57

I’m sure it’s possible without using up, but up takes care of this pretty nicely. Take a look here: https://github.com/apex/up-examples/tree/master/oss/node-8

bhurlow22:11:17

namely this:

bhurlow22:11:20

"proxy": {
    "command": "./node-v8.4.0-linux-x64/bin/node app.js"
  },

bhurlow22:11:54

^ so for a lumo project, that’d look something like ./lumo-1.8-linux script.cljs

bhurlow22:11:35

that’s how up is able to support non-official runtimes in lambda such as Go or Crystal

johnjelinek23:11:44

ok, so I'm looking at up a bit more -- it appears like it encourages you to develop services instead of microservices -- where you're serving static content and the whole backend in a single lambda deployment -- is that correct?

johnjelinek23:11:16

does up just kill the HTTP server after a 200 response is delivered?

johnjelinek23:11:15

also -- how does up handle services that aren't meant to be triggered by API Gateway?

bhurlow14:12:17

Yea, up is a bit of an unconventional use for lambda. Traditionally the lambda idea was to have a small function that exits after the first request, but up instead opts to leave a server running inside the lambda vm for its lifecycle

bhurlow14:12:51

its a bit counter-intuitive but it works pretty well

bhurlow14:12:24

So up does NOT kill the HTTP server after a 200, it leaves it running until lambda kills that vm and/or starts another instance

bhurlow14:12:58

that means that every so ofter there’s a slower request which is triggering a ‘cold boot’, but subsequent requests would hit the already running server

bhurlow14:12:36

As far as non gateway services, up is designed for web services, there are some other tools for worker style lambda routines

richiardiandrea20:11:42

@bhurlow can you expand on 2? I am interested. At the moment I am using serverless-cljs-plugin in order to compile down to JS with lumo

bhurlow22:11:32

@richiardiandrea sure, so there’s sort of a popular emerging pattern with lambda which is to include your own linux binary, could be golang, jvm, whatever you want and shell exec that inside of the lambda boot. TJ has done a great job wrapping that with apex and up (two comparable projects)

bhurlow22:11:04

This relates to lumo because to run cljs code in the lambda environment, all you have to do is include the lumo linux binary in the lambda zip file and configure lamba to execute that instead of their supplied js runtime. Takes a bit of shimming around but this allows you to run pretty much whatever you’d like to in the serverless VM, including CLJS

bhurlow22:11:28

Because lumo is optimized for fast startup, its a pretty good experience

bhurlow22:11:37

have heard of people using https://github.com/indigo-dc/udocker to run docker containers, which would be another path for running lumo

richiardiandrea23:11:54

@bhurlow but fast startup will always be lower than compiled JS right? I know there might be other benefits about running Cljs script given the lumo repl, but lumo has macro and stuff that make it slower.

johnjelinek23:11:44

I bet if you did some benchmarks, the difference would be negligible

richiardiandrea23:11:39

lumo caches macro dependencies using transit so the lambda should read these files outside the handlers or you are going to pay this cost all the time

richiardiandrea23:11:06

it is optimizable of course, but something to be aware of, even if you have -K in place

bhurlow00:12:49

@richiardiandrea true, good thing to note

richiardiandrea23:11:49

yeah well the advantage would be to run node 9.2.0