This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-11-02
Channels
- # announcements (11)
- # aws (2)
- # babashka (42)
- # beginners (26)
- # calva (17)
- # cider (1)
- # clara (2)
- # clj-kondo (44)
- # clojars (30)
- # clojure (43)
- # clojure-australia (6)
- # clojure-europe (29)
- # clojure-gamedev (4)
- # clojure-greece (1)
- # clojure-nl (4)
- # clojure-spec (4)
- # clojure-uk (6)
- # clojurescript (28)
- # cursive (16)
- # data-science (1)
- # datahike (4)
- # datomic (26)
- # emacs (6)
- # events (3)
- # fulcro (11)
- # graalvm (7)
- # holy-lambda (118)
- # java (9)
- # jobs (1)
- # leiningen (3)
- # lsp (21)
- # luminus (2)
- # malli (13)
- # membrane-term (1)
- # music (1)
- # nrepl (3)
- # off-topic (38)
- # pedestal (2)
- # polylith (39)
- # re-frame (33)
- # reagent (7)
- # releases (1)
- # remote-jobs (4)
- # rewrite-clj (28)
- # ring (21)
- # sql (2)
- # tools-deps (23)
- # vim (4)
- # xtdb (15)
Never used carmine before? What questions regarding Carmine you do have?
current solution is use another HL lambda inside the VPC and invoke it from the outer lambda
Wait. Hmm. As I understand you have a Lambda that is in VPC (probably private one) and you would like to call the service that is publicly available?
If yes you would need NAT Gateway for that.
turns out I don’t. a lambda outside a VPC can call a lambda inside a VPC without NAT.
If that's the case it will cost you additional 30$.
I mean for NAT Gateway.
Why does the Redis is not in the VPC?
Ok got it. So you would need the NAT for those lambdas that connect to outer world. Otherwise putting all the lambdas in VPC is a good idea.
It will certainly not cost more
So you have a native lambdas that call native lambda to get the cache :D
some extra code because it’s Carmine api inside VPC and transit (or nippy) when sent to outside
Yeah cool. However there might be a case your cache will be called to frequently, so expect some cold starts there.
I’ve got a custom pinger that reduces cold starts. only scale up cold starts happen now
Doesn't the reserved concurrency work the same? Asking, because I'm curious
yes but it’s $40/month per lambda version. I use many versions so that adds up pretty quick. instead I track recent use of versions and keep those alive with a HL lambda
hmmm: Carmine isn’t well suited to HL. It’s a macro at it’s core https://github.com/ptaoussanis/carmine#connections
Why you think it would not work?
Macro expands during compilation then plain java classes are compiled
Btw are you using other runtimes/languages for Lambda as well? Or only HL and Native?
because the connection spec i.e. hostname is not known at compile time. it’s in the lambda env
I suppose I could hardcode a lookup for all the hostnames so it is known at compile time and not use env vars
I already tested interop with the Jedis lib so I can fallback to https://github.com/tolitius/obiwan
And? I mean. It doesn't matter. Macro expands at compile time
plus I don’t need/want a connection pool in a Lambda env. it’s effectively single threaded so only 1 connection required
I could be of course mistaken. Anyway to the last one I agree. You don't want a pool in AWS Lambda
yeah: env values in HL context are runtime. thus can’t use them to control the connection pool
But envs are also readable without the ctx
System/getenv to the rescue
You can create a connection on init step 🙂 Or you can initialize the connection in Lambda if you really want, but do it only once in an atom?
But yeah. System/getenv is probably what you do want
Yes you can. Actually envs are there, since it's easier to provide native-agent-payloads that way, or in general test the lambdas.
But yeah. HL afterwards is all about Java/Clojure 😄
Fatal error: java.lang.NullPointerException: null
at com.oracle.svm.agent.tracing.TraceFileWriter.printValue(TraceFileWriter.java:103)
at com.oracle.svm.agent.tracing.TraceFileWriter.printArray(TraceFileWriter.java:92)
at com.oracle.svm.agent.tracing.TraceFileWriter.traceEntry(TraceFileWriter.java:68)
at com.oracle.svm.agent.tracing.core.Tracer.traceCall(Tracer.java:117)
at com.oracle.svm.agent.BreakpointInterceptor.traceBreakpoint(BreakpointInterceptor.java:150)
at com.oracle.svm.agent.BreakpointInterceptor.handleGetMethod(BreakpointInterceptor.java:332)
at com.oracle.svm.agent.BreakpointInterceptor.getDeclaredMethod(BreakpointInterceptor.java:311)
at com.oracle.svm.agent.BreakpointInterceptor.onBreakpoint(BreakpointInterceptor.java:957)
at com.oracle.svm.jni.nativeapi.JNIFunctionPointerTypes$GetMethodIDFunctionPointer.invoke(JNIFunctionPointerTypes.java:-1)
at com.oracle.svm.agent.JniCallInterceptor.getStaticMethodID(JniCallInterceptor.java:163)
What GraalVM version?
Yeah, but what image builder
Yeah. But still you should upgrade 😄 I really mean it. There are new images with GraalVM native-image with various variants.
0.6.2 is a way better release. Very close to how stable I want HL to be.
But yeah. Starting from 0.5.0 I promised myself to do as little breaking changes as it's only possible
Also 0.6.2 doesn't puts all the artifacts in local directory (which means your CI will see a speedup)
I’ve been meaning to ask about upgrading. My hope is that it will use less mem for native:executable?
It should both use less memory, compile faster, and also produce smaller artifact. Btw don't you want to use the local agent for CI? That way you would benefit from ARM64. Much better cold starts, faster compile time, better price per 1M invocation.
Yeah. You can generate a new project and just compare the changes or follow the migration guide: https://fierycod.github.io/holy-lambda/#/migration-guide
Yeah totally got your point 🙂
Wish you the same 🙂 In case of any issues you know where to find me. All the best!
Any idea how to deal with this error:
Exception in agent-context: #error {
:cause No implementation of method: :-get-info of protocol: #'cognitect.aws.client/ClientSPI found for class: clojure.lang.Delay
I am trying to access secrets from aws ssm using aws-api from cognitect.
I am running the latest holy-lambda, 0.6.2. This works using the babashka aws-api pod, but gives that error when I try to compile native.
(def ssm (delay (aws/client {:api :ssm
:region "us-west-2"})))
that normally means you haven’t captured enough using agent/in-context or using sample requests
I only have this 1 call in the agent context and the lambda function. I have to get the pass word from ssm to do my actual work.
(def ssm (delay (aws/client {:api :ssm
:region "us-west-2"})))
(defn TestAPI
"Test DDI API"
[{:keys [event ctx] :as request}]
(let [ddipass (aws/invoke @ssm {:op :GetParameter
:request {:Name "ddi-api-password"
:withDecryption true}})]
(hr/json {:event event
:ddipass ddipass})))
(h/entrypoint [#'TestAPI])
(agent/in-context
(let [ddipass (aws/invoke ssm {:op :GetParameter
:request {:Name "ddi-api-password"
:WithDecryption true}})]
(println (pprint ddipass))))
personally I find it easier to build a mock for aws api requests and use that in conf handling.
often it’s easier to have a mocked aws call in an agent/in-context call than a real call. it still uses all the classes and conf catches it all
I will try your example. Could you paste the entire namespace, and your deps.edn?
Anyway I can second what @U0510KXTU said. Using official AWS SDK V2 has numerous benefits over cognitect AWS api: • you can mock your functions • X-ray is there • Works better with graalVM native-image • The performance is better • Artifact is smaller I will probably work on making a lite version of AWS Cognitect API that is both faster and GraalVM native-image friendly for clj-easy organization, but this will take a while.
@UAB2NMK25 You have a typo in your example.
(agent/in-context
(let [ddipass (aws/invoke ssm {:op :GetParameter
:request {:Name "ddi-api-password"
:WithDecryption true}})]
(println (pprint ddipass))))
You have to reference the ssm @ssm
bb hl:native:conf
calls a regular JVM Java with tracing, therefore if it fails you have 99% chance it's issue with you code.
Deps.edn
{:deps {org.clojure/clojure {:mvn/version "1.10.3"}
io.github.FieryCod/holy-lambda {:mvn/version "0.6.2"}
com.github.clj-easy/graal-build-time {:mvn/version "0.1.4"}
com.cognitect.aws/api {:mvn/version "0.8.524"}
com.cognitect.aws/endpoints {:mvn/version "1.1.12.93"}
com.cognitect.aws/ssm {:mvn/version "814.2.1008.0"}}
:paths ["src" "resources"]
:aliases {:uberjar {:replace-deps {com.github.seancorfield/depstar {:mvn/version "2.1.303"}}
:exec-fn hf.depstar/uberjar
:exec-args {:aot ["example.core"]
:main-class "example.core"
:jar ".holy-lambda/build/output.jar"
:jvm-opts ["-Dclojure.compiler.direct-linking=true"
"-Dclojure.spec.skip-macros=true"]}}}}
core.cljc
(ns example.core
(:gen-class)
(:require
[cognitect.aws.http.cognitect]
[cognitect.aws.protocols.query]
[cognitect.aws.protocols.json]
[cognitect.aws.protocols.common]
[cognitect.aws.protocols.rest]
[cognitect.aws.protocols.rest-xml]
[cognitect.aws.client.api :as aws]
[fierycod.holy-lambda.response :as hr]
[fierycod.holy-lambda.agent :as agent]
[fierycod.holy-lambda.core :as h]))
(def ssm (delay (aws/client {:api :ssm
:region "eu-central-1"})))
(defn ExampleLambda
[{:keys [event ctx] :as request}]
(let [ddipass (aws/invoke @ssm {:op :GetParameter
:request {:Name "ddi-api-password"
:withDecryption true}})]
(hr/json {:event event
:ddipass ddipass})))
(h/entrypoint [#'ExampleLambda])
(agent/in-context
(let [ddipass (aws/invoke @ssm {:op :GetParameter
:request {:Name "ddi-api-password"
:WithDecryption true}})]
(println ddipass)
;; (println (pprint ddipass))
))
This works for hl:native:conf but fails for hl:native:executable with: jdk.xml.internal.SecuritySupport was unintentionally initialized at build time.
So initialize jdk.xml.internal at build time.
—initialize-at-build-time=jdk.xml.internal @UAB2NMK25
Sorry I'm newish to this whole thing, where do I do that? Is that an option I add to the bb command?
Put it in :native-image-args in bb.edn
There will be an additional error as far as I can remember
I will document the common ways of dealing with native-image errors. https://fierycod.github.io/holy-lambda/#/native-backend
Ok got further it wants some apache libs now. How to add multiple libraries to --initialize-at-build-time? comma seperated list? A whole new --initialize line?
You can do both
Congrats. ;)
You’re very close to getting it working.
Error: Image build request failed with exit status 137
com.oracle.svm.driver.NativeImage$NativeImageError: Image build request failed with exit status 137
at com.oracle.svm.driver.NativeImage.showError(NativeImage.java:1762)
at com.oracle.svm.driver.NativeImage.build(NativeImage.java:1473)
at com.oracle.svm.driver.NativeImage.performBuild(NativeImage.java:1434)
at com.oracle.svm.driver.NativeImage.main(NativeImage.java:1421)
In the past the errors have kinda given me a pointer, but that one is just flat, no pointer to a file to get more details.
Not enough memory
At least 6gb. But if you wanna be safe increase to 8gb
You’re very welcome