nervous-systems / serverless-cljs-plugin

Serverless plugin for Clojurescript deployment w/ cljs-lambda
The Unlicense
74 stars 10 forks source link

Respect individually option #5

Open arichiardi opened 6 years ago

arichiardi commented 6 years ago

Hi there again,

opening this PR because I have two issues. One is major and a feature request. I have:

...
package:
  individually: true

JS code is zipped correctly so I have two lambdas. However the serverless-cljs-plugin just packages everything in a zip.

I saw the implementation and it is no handling it. That's ok, is there anything I need to know if I want to tackle this problem?

For instance, there is an index.js there, which is generated. What was the purpose of it?

Thanks a lot for your patience :smile:

PS.: I was able to create a zip with the lumo compiler but I am still finishing it off.

moea commented 6 years ago

index.js

With this example serverless.yml:

functions:
  abc:
    cljs: example.core/abc

cljs-lambda'll generate an index.js with a function called abc (from this template, or one like it, depending on the optimisation level - see the parent directory), which loads the relevant namespaces and invokes example.core/abc.

Knowing this, the serverless plugin updates the handler in your function's config so it's effectively:

functions:
  abc:
    handler: index.abc

This is because for a variety of reasons it's not practical to instruct the Lambda runtime to load a module of JS that's been directly compiled from cljs, so we have index.js to intermediate.

individually: true

I'm not averse to supporting this, but I'm not sure the effort is worth the reward. What would you hope to get out of it?

arichiardi commented 6 years ago

individually: true

I observed what serverless does and it basically just creates two equal zips - same handler.js (say):

-rw-rw-r-- 1 arichiardi arichiardi 15427638 Aug 18 01:58 bunyan-lambda-js.zip
-rw-rw-r-- 1 arichiardi arichiardi      361 Aug 18 01:58 cloudformation-template-create-stack.json
-rw-rw-r-- 1 arichiardi arichiardi     7719 Aug 18 01:59 cloudformation-template-update-stack.json
-rw-rw-r-- 1 arichiardi arichiardi 15427638 Aug 18 01:58 console-stamp-lambda-js.zip
-rw-rw-r-- 1 arichiardi arichiardi  9354994 Aug 18 01:59 logpoc.zip  <-- produce serverless-cljs-plugin
-rw-rw-r-- 1 arichiardi arichiardi    11418 Aug 18 01:59 serverless-state.json

So this might easy to do then, the only concern is when you have both index.js and handler.js...shall we merge the two?

moea commented 6 years ago

The name handler.js or index.js is arbitrary, it just has to correspond to the prefix of the handler values passed to aws, so it knows which module to load. With cljs-lambda, the contract is that the module is always called index.js.

While in your example it creates two identical zip files, there are almost certainly per-function options you can set (e.g. include/exclude) in your serverless.yml which would affect the contents of zip files, otherwise the feature would be completely useless.

I'm still not sure I understand the utility of making the change in the context of this plugin.

arichiardi commented 6 years ago

No sorry I have not explained my concern properly.

At the moment I have:

functions:
  bunyan-lambda-js:
    handler: logpoc.bunyanLambdaJs

  console-stamp-lambda-js:
    handler: logpoc.consoleStampLambdaJs

  bunyan-lambda-cljs:
    cljs: logpoc.core/bunyan-lambda

plugins:
  - serverless-cljs-plugin

So I have a handler.js and the generated index.js. I wonder if the plugin should merge the two, or append them. It does not seem to be confused when I deploy.

arichiardi commented 6 years ago

Sorry the discussion has derailed a bit, so I guess my question is whether I need to change something in order to have a mixed JS + cljs setup.

moea commented 6 years ago

I see, apologies for the misunderstanding. In theory bunyan-lambda-cljs will invoke the handler in index.js, and the other guys will invoke the handlers in handler.js, which is what you want. Something else may well break though, I haven't tried this. And it may work for simple setups, but break if you wanted to do some preprocessing on the js code, using babel, or whatever - I would personally have two different projects / serverless.yml files.

arichiardi commented 6 years ago

I was also wondering another thing about the famous index.js. If it were generated dynamically and not by the template, one could append things to whatever handler.js is there. This would require to parse serverless.yml probably, but I am sure it wouldn't be that complicated.

moea commented 6 years ago

How much more dynamic could the generation be? cljs-lambda avoids running any user code, it just invokes the compiler and builds a zip file. The inputs to the template are obtained by parsing serverless.yml.

The thing about appending to handler.js is a red herring - whatever problems may exist with having js and cljs live side-by-side in a single serverless.yml, they don't have anything to do with index.js vs handler.js. There is no requirement in serverless or lambda that there's a file called handler.js - you created a file called handler.js, possibly because you were working from an example which used handler.js. You could rename it to anything you wanted, as long as the handler keys in serverless.yml were updated from handler.xyz to new_name.xyz. You could even put each handler in a different top-level js module!

If you want this to work, please create a public github repository with a serverless.yml and some js + cljs functions, which doesn't do what you expect when you invoke them after deploying, and I will try to help you with it.

arichiardi commented 6 years ago

I guess you are right I am overengineering. -- Sent from my Android device with K-9 Mail. Please excuse my brevity.