lumo

:lumo: Standalone ClojureScript environment. Currently at version 1.9.0
johnjelinek 2017-11-30T16:42:51.000317Z

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

johnjelinek 2017-11-30T16:43:01.000623Z

I don't see it documented in the repo

johnjelinek 2017-11-30T16:44:31.000044Z

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

johnjelinek 2017-11-30T16:48:11.000106Z

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));

2017-11-30T16:51:56.000266Z

@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}`);
});

johnjelinek 2017-11-30T16:53:01.000056Z

would this be a good feature?

johnjelinek 2017-11-30T16:53:43.000022Z

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

johnjelinek 2017-11-30T16:54:13.000265Z

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

2017-11-30T16:54:27.000258Z

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

johnjelinek 2017-11-30T16:55:41.000150Z

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);

johnjelinek 2017-11-30T16:56:00.000354Z

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

johnjelinek 2017-11-30T17:32:41.000042Z

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

johnjelinek 2017-11-30T17:41:41.000332Z

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

johnjelinek 2017-11-30T17:42:56.000522Z

@hlolli: you can see my export here: https://github.com/johnjelinek/cljs-lambda/blob/master/src/cljs_lambda/core.cljs#L4

2017-11-30T20:01:50.000211Z

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

2017-11-30T20:02:43.000636Z

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

johnjelinek 2017-12-01T16:58:02.000515Z

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

2017-11-30T20:04:20.000229Z

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

2017-12-01T14:44:17.000308Z

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

2017-12-01T14:44:51.000051Z

its a bit counter-intuitive but it works pretty well

2017-12-01T14:45:24.000158Z

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

2017-12-01T14:45:58.000163Z

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

2017-12-01T14:46:36.000012Z

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

richiardiandrea 2017-11-30T20:30:42.000682Z

@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

johnjelinek 2017-11-30T20:46:58.000346Z

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

johnjelinek 2017-11-30T20:51:54.000036Z

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

johnjelinek 2017-11-30T20:52:49.000519Z

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

johnjelinek 2017-11-30T20:53:52.000576Z

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

2017-11-30T22:25:57.000405Z

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

2017-11-30T22:28:49.000104Z

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 👍

2017-11-30T22:30:32.000573Z

@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)

2017-11-30T22:32:04.000020Z

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

2017-11-30T22:32:28.000141Z

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

2017-11-30T22:33:37.000008Z

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

2017-11-30T22:34:57.000421Z

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

2017-11-30T22:35:17.000290Z

namely this:

2017-11-30T22:35:20.000172Z

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

2017-11-30T22:35:54.000041Z

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

2017-11-30T22:36:35.000125Z

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

richiardiandrea 2017-11-30T23:12:54.000031Z

@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.

richiardiandrea 2017-11-30T23:13:49.000397Z

yeah well the advantage would be to run node 9.2.0

johnjelinek 2017-11-30T23:21:44.000276Z

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

johnjelinek 2017-11-30T23:37:25.000637Z

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

johnjelinek 2017-11-30T23:38:44.000084Z

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?

johnjelinek 2017-11-30T23:39:16.000165Z

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

richiardiandrea 2017-11-30T23:41:39.000294Z

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

richiardiandrea 2017-11-30T23:42:06.000221Z

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

johnjelinek 2017-11-30T23:52:15.000085Z

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