google-cloud

Google Cloud Platform: Clojure + {GAE, GCE, anything else on Google Platform}
domparry 2017-01-19T05:44:47.000356Z

boy am I glad I found this #

domparry 2017-01-19T05:56:51.000357Z

Awesome repo! Thank you for doing this!

😊 1
nickbauman 2017-01-19T16:00:19.000358Z

Yeah we’re discussing it. It’s in my queue right now.

qqq 2017-01-19T16:15:24.000359Z

========== (summarizing a discussion with n@ickbauman) So as it turns out, it's possible to call "eval" in clojure code running on GAE. For example, you can take the standard lein new cljgae-template, change the :h3 to

[:pre (eval (read-string "(+ 40 2)"))] 
-- and it would work. This opens up the following really cool possibility: instead of doing a "lein ring uberwar + deploy" every time, it should be, in theory, sposible to: (1) up load some *.clj files to datastore / cloud storage (2) have the dev-appspot server, on every request, pull the *.clj files from datastore/storage, and eval it on the fly for the http handler This reduces the number of "lein ring uberwar + deploys" down to only (1) you have to add new server side dependencies and (2) when you are uploading the final AOT classes. There's some non-trivial engineering effort (atleast from my perspective) involved to get this to work. If you're good with getting eval to work with entire files (instead of simple "(+ 40 2)" expressions) or can contribute in other ways, please let @nickbauman [ author of cljgae-template] know Getting this to work may drastically increase all of our productivity via reducing deploy times.

❤️ 1
nickbauman 2017-01-19T16:16:39.000360Z

☝️ This is a big deal.

2017-01-19T17:30:47.000361Z

what problem is this addressing? repl-like development?

👍 1
2017-01-19T18:57:45.000362Z

Howdy folks. FYI: https://clojurians.slack.com/archives/boot/p1484852190009405

2017-01-19T19:02:41.000364Z

@nickbauman, @qqq: not sure what you’re planning to do with eval, but if you’re looking for REPL-like development please check out boot-gae before you put in too much work. It reloads changed clojure source on page refresh.

2017-01-19T19:04:21.000365Z

It differs from most approaches to Clojure on GAE in that it does not AOT compile the entire app, only the servlet and filter stubbs, and it generates all the XML config files from edn files. Also supports both servlet-based and service-based apps from the same codebase.

2017-01-19T19:06:54.000366Z

There’s quite a bit of documentation explaining the implementation techniques, so you might be able to use something similar for your leiningen code.

2017-01-19T20:39:01.000367Z

see also https://github.com/migae/datastore/blob/master/README.adoc. this is completely separate from boot-gae. haven't worked on it for many months, but looking over the docs, it seems to make sense. ;)

nickbauman 2017-01-19T22:06:49.000369Z

Yeah I haven’t been able to spend much time looking at that, @mobileink but it seems promising.

nickbauman 2017-01-19T22:07:38.000370Z

It’s a big problem with developing with clojure on appengine.

2017-01-19T22:10:22.000371Z

@nickbauman buleeeve me! i've been hacking at this for several years - tried leinengen, tried maven, tried gradle. with boot i believe i may be almost done with thw blasted thing!

2017-01-19T22:11:59.000372Z

i still have a warm corner of my heart reserved for leinengen, but boot is in an entirely different league.

nickbauman 2017-01-19T22:12:43.000373Z

🙇 I think it’s time for me to get more familiar with you work.

2017-01-19T22:13:21.000374Z

that would be nice - its lonely out here!

nickbauman 2017-01-19T22:14:05.000375Z

:highfive:

nickbauman 2017-01-19T22:14:20.000376Z

What’s going on with the flexible environment?

2017-01-19T22:15:30.000377Z

fwiw i'm totally in favor of a leinengen solution. just not sur how it works, since i haven't worked with it for quite a while. boot is very different

2017-01-19T22:16:46.000378Z

re: flexible env: no free tier, that's all. but it cant be that much different.

2017-01-19T22:18:18.000379Z

i'm just happy that i got service-based apps to work. i think; let's wait and see what happens when sb usescit in anger.

2017-01-19T22:22:40.000380Z

anyway, @nickbauman , don't want to rain on your parade, but i also hate to see people spending effort reinventing the wheel. not that my whell is the best wheel, but it's sufficiently unusual that i think it's worth your while to take look.

nickbauman 2017-01-19T22:23:26.000381Z

Yeah I’ve never looked at boot very closely.

nickbauman 2017-01-19T22:23:56.000383Z

If the parade needs raining on, please go ahead and rain.

nickbauman 2017-01-19T22:24:10.000384Z

The point is it will move all of us forward.

nickbauman 2017-01-19T22:24:13.000385Z

😉

2017-01-19T22:24:37.000386Z

i'll note also that i'm only talking about build/test/deploy stuff, not apis for GAE services like datasore. in principle that atuff should work with any build systwm.

2017-01-19T22:25:45.000387Z

i like your attitude! par for course with Clojure, i guess. :)

2017-01-19T22:27:14.000388Z

caveat: boot does have a learning curve. but the devs on the boot channel are unbelievable tesponsive and helpful.

2017-01-19T22:29:06.000389Z

re: flexible env: if anybody wants to pay me large sums of money to make it go i'm game!

nickbauman 2017-01-19T22:32:18.000390Z

lol

nickbauman 2017-01-19T22:32:22.000391Z

could happen

qqq 2017-01-19T22:59:26.000392Z

@mobilelink: [ all in context of boot-gae ] 1) what is servlet-based vs service-based approach 2) this entire time, I was under the impression that to update a gae app, we have ot deploy, and during deploy, we SEND AN ENTIRE NEW WAR -- from what you're saying it sounds like it's possible to UPDATE ONLY A PORTION OF THE APP INSTEAD OF SENDING A NEW WAR -- is this true? 3) does boot-gae requires flexible env, or does it also work on the standard env?

qqq 2017-01-19T22:59:42.000393Z

@mobileink : ^^^

qqq 2017-01-19T23:00:52.000394Z

Q3 answered from front page of docs: Note Currently only the Standard Environment is supported. The Flexible Environment is not supported. Okay, 2 questions left: @mobileink

2017-01-19T23:20:36.000395Z

@qqq q 1: see the doc, there are links to the ggogle docs. briefly, a "servlet app" is a standalone app. it can have multiple servlets, but calling from one servlet to another is complicated. a "service-based" app is an assembly of one or more servlet apps. they communicate by http requests. it's kinda hard to explian; best bet is to read the google docs.

qqq 2017-01-19T23:21:56.000396Z

@mobileink : q1, fair enough, will read the docs; q2 -- how are you doing these updates so effeiciency, are you only uploading 'part of the full proejct' very time?

2017-01-19T23:23:15.000397Z

@qqq: q2: you do not need to build, pkg, updste, restart, etc. every time you change your clojure source.

qqq 2017-01-19T23:24:23.000398Z

fighweel can recompile locally, but how do you update remote gae without build/pkg/upload/restart ?

2017-01-19T23:28:21.000399Z

read the doc for gen-class very carefully. the servelet container searches for a class file, loads it, and sends it a "service" message. the class file created by gen-class forwards that to the appropriately named clj fn, in the appropriate clj namespace. so we only need to aot-compile the stub that does the forwarding. boot-gae creates that class "invisibly".

2017-01-19T23:33:39.000400Z

@qqq what does " update remote gae" mean? boot-gae allows you to live update locally, using the dev server. deployment to prod is a whole 'nither matter.

qqq 2017-01-19T23:34:24.000401Z

updating locally via dev server I can do already via lein + figwheel

qqq 2017-01-19T23:34:36.000402Z

it's the "deploying to remote gae server" part that takes long right now 10-20 seconds

qqq 2017-01-19T23:34:50.000403Z

I'm tring to understand how migae cuts down the "deploy to remote gae server" time

2017-01-19T23:35:30.000404Z

you only need to restart the dev server if you need to add/remove servlets or filters

2017-01-19T23:37:13.000405Z

what is a "remote gae ssrver"? you mean the prod, in-the-cloud server?0

qqq 2017-01-19T23:38:34.000406Z

yes

qqq 2017-01-19T23:38:45.000407Z

"remote gae server" == I mean the gae server in the cloud

2017-01-19T23:38:56.000408Z

boot-gae makes it easy to develop gae stuff locally, with a quasi-REPL, that's all.

qqq 2017-01-19T23:38:57.000409Z

updating locally is not a problem, I just tell cider to replaod buffer, and BAM, I'm running new code

qqq 2017-01-19T23:39:10.000410Z

I can develop stuff locally without migae though too

qqq 2017-01-19T23:39:21.000411Z

the problem we're trying to solve is "how do we cut down on deploy time"

qqq 2017-01-19T23:39:48.000412Z

right now, deplying to remote cloud gae takes 10-20 seconds, we want to reduce that down to (1) upload a new *.clj file, and (2) have remote cloud gae take that clj and run it on the fly

2017-01-19T23:39:51.000413Z

how do yu so that? jeez, maybe i'vw been wasting my time. ;)

qqq 2017-01-19T23:40:42.000414Z

no no, I think the work you're doing is very interesting and I'm glad we're having this conversaion; I'm being exposed to lots of into I'm not used to; give me a few secs to describe my current work env

qqq 2017-01-19T23:42:56.000415Z

for deplying to cloud/gae:
  I type "sh deploy.sh", which then does:
    lein ring uberwar
    some other complicated stuff to put resources/xml files in right place
    runs app_cfg.sh update
    then I wait 10-20 seconds

to develop locally:
  1) I fire up "lein repl" (actually just cider-jack-in)
  2) I run four lines in repl, which then (a) starts up jetty/ring using the #' trick to update handlers and (b) starts up figwheel

  3) I edit some file, and I save. For cljs side, figwheel auto recompiles and updates the browser.
  4) If I'm editing server side code, I run cider-reload-buffer, which reloads the current buffer, and the #' trick causes the running jetty server to pick up the new handler
^^ taht's my entire dev setup

2017-01-19T23:43:47.000416Z

i'm very interested and terrified. if i find out i've spent many months figuring out the hard way to do sth everybody else already knew how to do... well, what else is new?

2017-01-19T23:46:42.000417Z

jetty server: are you running sth orher thsn the gae devserver? i started down this path years ago with appengine-magic, which did sth like that. boot-gae only ever uses the devserver

2017-01-19T23:47:47.000418Z

what is the #' trick?

qqq 2017-01-19T23:48:00.000419Z

@mobileink: 1) what you have done [and also what @nickbauman has done] is far bigger than what I did: both of you actually wrapped google service libraries all I have at the moment is that I got http://lambda-startup.com/developing-clojure-on-app-engine/ to work -- and I'm still reading gae/java docs

qqq 2017-01-19T23:49:01.000421Z

@mobileink : the #' trick see the comment by Tim in the above link:

Hi Oliver,
Great post, thanks for all the details.
Regarding reloading routes, the trick is to pass the var pointing to your handler to jetty.
(def handler (environment-decorator handler/app))
(run-jetty #’handler {:port myport :join? false})
basically, #' causes it to "use most recent binding of var", which means when you reload the buffer, the ring/jetty server will run the latest handler

qqq 2017-01-19T23:49:30.000422Z

it has to do with (1) #' using the var rather than the binding and (2) vars get auto dereferenced if they're in the place of a function call