This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-06-07
Channels
- # beginners (142)
- # boot (18)
- # cider (39)
- # cljs-dev (2)
- # cljsrn (11)
- # clojars (8)
- # clojure (51)
- # clojure-brasil (3)
- # clojure-italy (22)
- # clojure-losangeles (2)
- # clojure-nl (20)
- # clojure-nlp (2)
- # clojure-russia (4)
- # clojure-serbia (2)
- # clojure-spec (90)
- # clojure-uk (147)
- # clojurescript (116)
- # data-science (10)
- # datomic (189)
- # devcards (31)
- # duct (6)
- # emacs (12)
- # fulcro (16)
- # graphql (36)
- # juxt (1)
- # off-topic (5)
- # om (11)
- # overtone (2)
- # pedestal (4)
- # perun (1)
- # portkey (17)
- # reagent (6)
- # reitit (3)
- # shadow-cljs (57)
- # spacemacs (45)
- # specter (8)
- # tools-deps (46)
has anyone tested AWS App-Sync using an Ion Lambda? i.e. graphql api for Ion without any code
if its like ring, :protocol
should be something like “The protocol the request was made with, e.g. “HTTP/1.1".” and :scheme
is :http or :https
@chris.blom thanks! You are right, :protocol
should be like Ring
Ok, it was not immediately clear to me what ion is about: My understanding now is that: - its an application server integrated with datomic - has build in tooling based on deps.edn to deploy based on git revisions - it integrates with AWS Lambda and API Gateway to handle http requests, in a mostly ring compatible way Its not clear to me what “deploying your code to a running Datomic cluster” entails: - What exactly runs on Lambda, and what runs on the datomic cluster? - What are the limitations of running code in a datomic cluster? Can I access the local disk and other AWS services? - How does the autoscaling work? - Is it possible to develop and test ions locally? - Can I run some sort of test environment for CI testing?
The picture at https://docs.datomic.com/cloud/ions/ions.html might help
Essentially all of your code is running on the d cluster. Being there you can access all the aws services. For storage, I think you’d use aws storage services, not disk. Stu or Rich can probably answer some of the others better than I can but generally the answers will be to use the aws functionality for autoscaling, ci, etc.
ok, so the Lambda functions for an Ion are just glue to interface with the outside world, and delegate the actual work to the Datomic cluster?
Client API now supports :server-type :ion
, which connects remotely when you dev on your laptop, but connects in memory when you deploy the same code to Datomic: https://docs-gateway-dev2-952644531.us-east-1.elb.amazonaws.com:8181/cloud/ions/ions-reference.html#server-type-ion
stu, the transaction producing functions will run on whatever node in datomic cluster, right? But the final transactions are still directed to the node acting as transactor? (so essentially, it’s like the peer model)
@andrewhr the tx fns run where the txes do. There isn't a dedicated transactor per se as with on prem
but you will be able to have independent clusters running app/query code and handling txes
I remember something about “avoiding contention”, but in retrospect doesn’t make too much sense giving ddb could probably just autoscale in response. Maybe this image make me a little confused https://docs.datomic.com/cloud/whatis/architecture.html#production-topology
as far as I understand (together with you previous explanation), query groups aka “extra clusters” will tunnel their transactions thought the primary tx group
or when do you say “extra clusters” you’re really meaning “one set of storage resources” + “multiple sets of primary compute resources”?
@steveb8n I gave a talk last month at Serverless Chicago about using Datomic Cloud with AppSync, you may expect some kind of preliminary blog post or code sample extending that talk to Ions like …today?
I am finding it very difficult to focus on my day-job work right now, knowing that I could be spinning up a Cloud instance in my personal account and exploring getting AppSync to run, looking at modeling what $day-job
does with the txn report queue in Ions callbacks, etc. etc. so …I don’t think it will be too long before I have a trip report re: AppSync ready for people to read hehe
Agreed, lots of people will be interested to know the graphql options using API Gateway on top of Ions.
best would be App Sync subscriptions support. Somehow I doubt that’s possible. What do you think?
- What exactly runs on Lambda,
a generic proxy. We call it 'Ultimate, the lambda'
- and what runs on the datomic cluster?
everything
- What are the limitations of running code in a datomic cluster? Can I access the local disk and other AWS services?
AWS services sure. It is *your* instance, running in *your* VPC. That said, local disk, probably not a great idea.
- How does the autoscaling work?
You can trigger autoscaling of the cluster on any of various metrics we or AWS produce.
- Is it possible to develop and test ions locally?
As Stu said, sure! The db API you'll see in the ion is the same as the client sync API, and the :ion server type dynamically loads the right back end.
- Can I run some sort of test environment for CI testing?
Yes. You can run a solo instance that is a target of the same application, deploying early revs to it and tested revs to prod.
I suppose if everything runs in the cluster, then there's no way to restrict certain functions to certain operations, as you can do with Lambdas?
We had some bad experiences with AWS lambda in the past: 1. It has a global queue per account (our solution: never use AWS lambda for anything of high throughput as it will block other tasks unexpectedly). 2. AWS requires node updates sometimes (one time within 3 months from launch). @richhickey Are these issues taken into account? Is the ultimate lambda free of these concerns? Thank you.
@dominicm There are distinct instances of ultimate the lambda and each is an independent AWS Lambda and proxies to a particular fn on a particular Datomic compute group. From there you have all the ordinary wiring up of Lambdas available, to particular events etc.
@jeroenvandijk AWS has improved #1 with per-Lambda concurrency reservations/limits (which we expose as a knob). Not sure I understand 2 - lambda's internal nodes?
@richhickey Thank you, interesting. Regarding 2 sorry i meant the node.js runtime (assuming you use this, but might apply to jvm runtime too). We were forced to upgrade the node.js runtime and didn't have a choice to leave it as is (like how you can choose to stick with an old AMI version)
@jeroenvandijk we care very little about the lambda runtime as we're not doing much there, and your ion code does not run there so cares not at all
I guess you might occasionally have to roll for things like that
Ok understood. Thank you. I guess it could have been more like a one time occurrence.
One other thing I noticed in the architecture of Datomic Cloud (https://docs.datomic.com/cloud/whatis/architecture.html) is that the storage of record is S3 and Dynamodb is used as transaction log. Is it possible to clean up the transaction log every now and then and rely on S3 for older data in order to save data costs? (With a self-hosted Datomic setup we have a big dynamodb table and this would be a potential cost saver)
@jeroenvandijk yes, getting the log into S3 is an optimization we intend to implement
@jeroenvandijk for many use cases, Cloud is already cheaper than On-Prem with DDB just because indexing doesn’t have to hit DDB
@stuarthalloway Nice 🙂 TBH we have been really abusing Datomic for things that is advised against. We have also reached the 10 billion datom limit times 4.. Is this something that Cloud is also addressing?
In practice how are classpath functions most commonly invoked? [:find (pull ?f [:db/id *]) :where [(partial contrib.datomic/datomic-entity-successors $) ?succ] [(loom.alg-generic/bf-traverse ?succ :db/ident) [?f ...]]] vs (->> (loom.alg-generic/bf-traverse (partial contrib.datomic/datomic-entity-successors $) :db/ident) (d/pull-many $ [:db/id *])) The first has constraints on the complexity of the clojure form, but is more structured
@jeroenvandijk out of curiosity, how are you abusing it?
@U06DQC6MA Biggest abuse is that we are using it as a timeseries database basically. This is causing (too) many transactions and a huge dynamodb size. Another less serious abuse it that we are storing relative big string blobs in Datomic
Are :cookies
supported in the return map? https://docs.datomic.com/cloud/ions/ions-reference.html#web-code
is there a way I can pull attributes that are not :db/valueType :db.type/ref
?
without knowing what their names are in advance ?
Can you query schema and use that to decide the pull
that's what I'm trying to do, but I can't see how to use the variable from the :where to inform the pull
i did not think of that
You can also go wild with subqueries in this fashion http://www.hyperfiddle.net/:cookbook.recipe!datomic-subquery/
also, is there a way in the pull to use a wildcard with a recursion limit ?
I tried {* 2}
but doesn't return anything
i dont know the answer to that sorry
Also, is there a story for web apps that have real-time requirements (i.e. Web sockets or SSE)? I don't believe AWS API Gateway has built-in support for either of those.
when i try to clj -Spom the deps.edn in the guide of ion i get
Caused by: org.eclipse.aether.resolution.ArtifactResolutionException: Could not transfer artifact com.datomic:ion:pom:0.9.7 from/to datomic-cloud (): Access Denied (Service: Amazon S3; Status Code: 403; Error Code: AccessDenied; Request ID: 82E950FAE7704579; S3 Extended Request ID: Su8rZMB9c+Z65RQbBwA8K1mxjVkjX0JU5NJRpbrT6k2/rRN8ubyMA3SJO9TucAlKFVf0fQUVZ3w=)
deps.edn
{:paths ["src" "resources"]
:deps {com.datomic/client-cloud {:mvn/version "0.8.50"}
com.datomic/ion {:mvn/version "0.9.7"}
org.clojure/data.json {:mvn/version "0.2.6"}
org.clojure/clojure {:mvn/version "1.9.0"}}
:mvn/repos {"datomic-cloud" {:url ""}}
:aliases
{:dev {:extra-deps {com.datomic/ion-dev {:mvn/version "0.9.160"}}}}}
what am i doing wrong?@kenny right, API gateway has no websockets/sse
@gabriele.carrettoni do other things (like clj -Spath
) work?
➜ datomic clj -Spath
Error building classpath. Failed to read artifact descriptor for com.datomic:ion:jar:0.9.7
org.eclipse.aether.resolution.ArtifactDescriptorException: Failed to read artifact descriptor for com.datomic:ion:jar:0.9.7
at org.apache.maven.repository.internal.DefaultArtifactDescriptorReader.loadPom(DefaultArtifactDescriptorReader.java:276)
at org.apache.maven.repository.internal.DefaultArtifactDescriptorReader.readArtifactDescriptor(DefaultArtifactDescriptorReader.java:192)
at org.eclipse.aether.internal.impl.DefaultRepositorySystem.readArtifactDescriptor(DefaultRepositorySystem.java:253)
at clojure.tools.deps.alpha.extensions.maven$eval668$fn__670.invoke(maven.clj:77)
@alexmillerI don’t have any issues doing that on my own box, not sure why you’d see that
I assume you’re not proxied or anything
@alexmiller i was inside the work vpn, just tried outside of it and i get the same error
@alexmiller maybe it's picking something from my .aws/credentials? :thinking_face:
can you try with com.datomic/client-cloud {:mvn/version “0.8.52”} instead ?
I think prior is a bug in the ion-starter deps.edn, but it’s not this problem
aws s3 cp
- does that work for you?
Hi @gabriele.carrettoni can you confirm you have list-buckets with your AWS creds?
aws s3api list-buckets --query "Buckets[].Name"
and i believe the repo is public so it shouldn't matter if i have or not the permissions :thinking_face:
We updated ion-starter to reflect the latest client. Could you pull the last commit to give you com.datomic/client-cloud {:mvn/version “0.8.54”}?
same Could not transfer artifact com.datomic:ion:pom:0.9.7 from/to datomic-cloud (<s3://datomic-releases-1fc2183a/maven/releases>): Access Denied (Service: Amazon S3; Status Code: 403; Error Code: AccessDenied; Request ID: 9BF4D9EDB140DB3B; S3 Extended Request ID: KDJi+KjUHOXfcCf0EoU9DSk5V4iP0HxFAUxqj14QFHEwN1rQ5D8qzDOdmCsantCEKzeG+6ydacE=)
@gabriele.carrettoni I can repro the problem locally, but only when running with no AWS creds at all
i.e. if I use any random creds from any account things seem to work
@stuarthalloway on my pc i got it working, i'll try again tomorrow at work to try to understand where the problem is, now i get this error
[ERROR] Failed to execute goal on project ion-starter: Could not resolve dependencies for project ion-starter:ion-starter:jar:0.1.0: Failed to collect dependencies at com.datomic:client-cloud:jar:0.8.54 -> com.datomic:client:jar:0.8.59 -> com.datomic:client-impl-shared:jar:0.8.40: Failed to read artifact descriptor for com.datomic:client-impl-shared:jar:0.8.40: Could not transfer artifact com.datomic:client-impl-shared:pom:0.8.40 from/to datomic-cloud (): Cannot access with type default using the available connector factories: BasicRepositoryConnectorFactory: Cannot access using the registered transporter factories: WagonTransporterFactory: java.util.NoSuchElementException
the plot thickens
I guess I’d start looking for other environmental variables - default AWS creds, repository settings in ~/.m2/settings.xml, etc. But I’m not sure what in any of those would actually cause a problem.
the fact that the s3 call works makes me think it’s not the aws creds
I think my question got lost 🙂 Are :cookies
supported in the return map for web code? https://docs.datomic.com/cloud/ions/ions-reference.html#web-code
hi @kenny ! in my experience :cookies
are derived from the :headers
and added by middleware, e.g. https://github.com/ring-clojure/ring/blob/master/ring-core/src/ring/middleware/cookies.clj. I believe that should work fine here.
Right. I guess my question should be rephrased - what subset of the Ring spec is supported?
At minimum the keys listed at https://docs.datomic.com/cloud/ions/ions-reference.html#web-code. That map is open and can/will get more stuff over time.
@gabriele.carrettoni I was able to repro it by monkeying with my aws creds, we will check into this
@kenny yes, it's part of Datomic
@kenny nope, part of the value prop is getting maximum leverage and agility.
@lockdown- no, some ions are just used by txes and queries, not behind lambdas
@richhickey your customers aren’t worried about vendor lock-in?
Application Load Balancer (ALB) supports Websockets and lately it got a feature to delegate authentication (https://aws.amazon.com/blogs/aws/built-in-authentication-in-alb/). Do you see possibility to front Ions with ALB?
@richhickey k, cool, just want to use ions for tx functions for now with solo and app code running on a ec2 node
Thinking that API Gateway is public (might change in future though), ALB could be exposed internally only, to allow say access from corporate network only
@kenny lockin has to be balanced with other objectives. If it dominates ones thinking you'll never maximize your leverage of the platforms. I can't say what's most important for anyone, but there are tradeoffs. We are supporting the 'leverage AWS' strategy. Lots of people succeeding there while others worry and don't ship.
@richhickey Does ion auto scaling apps essentially supersede the client model? Meaning there is no datomic client in play? Just a client-like local api
@dustingetz right, client-free apps totally possible
Idiomatic, right?
well, there's zero reason for clients inside ions, but you may have legacy architecture that dictates use of clients. They're not deprecated or anything
I think many apps can be written as ions
and of course you can mix and match
Are there technical reasons for no entity API or is it just historical at this point, and is the ion "local client api" equivalent in power to the entity api
@dustingetz there are semantic differences with client (vs peer) that yield 'no entity'. The 'local' API of ions matches the client API so people can do local REPL dev and testing (against cloud). So semantically, it's compatible with 'over wires'. That said, the perf of the same API in local mode within ions trounces clients.
but keeping wire semantics means if you need to make an architectural shift that requires moving some parts to clients you're not screwed
thus 'client' is the only API of cloud, ion or out
@lockdown- right, no wires, same process
Remote client requesting query for Ion cluster [:find (pull ?f [:db/id *]) :where [(partial contrib.datomic/datomic-entity-successors $) ?succ] [(loom.alg-generic/bf-traverse ?succ :db/ident) [?f ...]]] Ion application local query (->> (loom.alg-generic/bf-traverse (partial contrib.datomic/datomic-entity-successors $) :db/ident) (d/pull-many $ [:db/id *]))
if I am an Ion app, I can do both, is the former considered idiomatic? Because it is equivalent and works over wires
the former has the overhead of the network, which of the two you use depends on your needs/architecture
@dustingetz the portability of the former seems like a flexibility win, but you may not care
@richhickey I like the former but that
thats a pretty wild "partial" in there
you would consider that idiomatic? Im ok with that if you are
idioms take time to develop
these are some brand new power tools, would hate to pour concrete advice 🙂
To what extent is it reasonable to query other data stores (e.g a remote SQL or ElasticSearch server) from ions?
@val_waeselynck you can do anything as long as you give the datomic cluster node's role the necessary permissions
The ion will autoscale though and the foreign store will not
you'd need a queue
your instances, your VPC
@dustingetz not everyone scales or needs to
but in any case the important point is, as @richhickey said, it is your instances, use them as you will
@richhickey thanks, it may be a good idea to make that obvious in the docs - it helps assess the power / limitations, especially since we've been accustomed to "be careful of the code Datomic runs for you" with tx fns
This is very exciting - it seems to give you the getting started experience of Firebase or Lambda with the scalability of advanced hand-rolled systems
@val_waeselynck that still applies, you can hold up your txes
Sure, but from what I understand it's fine for reading and for preparing writes - that part is important but not obvious imho
If I write to a durable kv store from a transactor fn and it takes 1ms to return, will this in practice slow down transactor throughput? Or are transactions processed in parallel up until the dynamo conditional put which i understand to be batched
it's going to be serial
Oh I see, because if there is a cas in the same tx, that needs a dbval
because e.g. tx fns can query and expect to see prior txes
yes, stuff like that
but remember you will likely be initiating your txes from ions, so there's another opportunity there for coordinated (if not transactional) work
I dont understand that, can you give me another hint
put in elasticsearch, transact
means it might be in elasticsearch but tx fails, but not holding up txes
Oh ok, so if the other store supported two phase commit that might work too
or whatever, cleanup on tx fail
you are likely retrying
thanks
the point is, you will be in your VPC, running in a role, able to do cool things
@lockdown- a) ease, b) not having to run in lambda execution container, c) running in db context vs making a client call, d) speed
the important value prop is API Gateway. Putting a lambda behind it is just one option (hint)
@richhickey Since it is our instance, why is eval blacklisted in :where clause evaluation
Or is/could that be different in Ion
there is an :accept list in ion, put stuff there to allow it
clojure.core/eval was excluded from cloud for security?
security of your own jars or something
nothing will run not on the list
i.e. nothing will be an entry point in tx/query/lambda
pants on by default
people inadvertently expose clients, query etc
Oh, ok makes sense
trying to push
{:command-failed "{:op :push}",
:causes
({:message
"You must either specify a uname or deploy from clean git commit",
:class IllegalArgumentException})}
what does it mean? :thinking_face:it seems push won't work if there are untracked files, adding them to .gitignore did the trick
or you can add a :uname key to the op
@alexmiller may i suggest to update https://docs.datomic.com/cloud/ions/ions-tutorial.html#sec-5-4 changing the curl call from
curl https://$(obfuscated-name).
to
curl https://$(obfuscated-name). -d ':hat'
because calling the first gives Expected a request body keyword naming a type
hi @kenny ! in my experience :cookies
are derived from the :headers
and added by middleware, e.g. https://github.com/ring-clojure/ring/blob/master/ring-core/src/ring/middleware/cookies.clj. I believe that should work fine here.
At minimum the keys listed at https://docs.datomic.com/cloud/ions/ions-reference.html#web-code. That map is open and can/will get more stuff over time.
How are people dealing with schema changes in development mode. I’m using conformity, but there is this problem: When I’m developing I might be “fiddling” with some bit of schema. I’d like to put it in a migration, but as soon as I do that it is “fixed” in the database, and I have to “hand unroll” it if I change my mind. It seems: 1. make an “up”/“down” function to use during dev, and drop the “up” one into the migrations only once it is stable. 2. It occurs to me that if you were to look up the tx time of the “up”, you could “undo” all of the changes that had been made since that time (which could be your automatic “down”…`d/as-of` to get the old values for the things the history could tell you have changed since then) Given those two, seems you could just add something like a “SNAPSHOT” versioning in conformity that would automate that on startup in dev mode (e.g. undo everything that has happened since the earliest SNAPSHOT was conformed, then re-conform). Anyone aware of existing code for doing that, or an alternative that is as convenient? Otherwise, we’re probably going to write it.
using forked connections to develop the migration, and transact it to actual db when finished
i’ve even used it to test migrations in production, by connecting to the production db, forking the conn, and running the migrations and app with the forked conn