Skip to content

Instantly share code, notes, and snippets.

;; Copyright © 2016, JUXT LTD.
(ns edge.web-server
(:require
[bidi.bidi :refer [tag]]
[bidi.vhosts :refer [make-handler vhosts-model]]
[clojure.tools.logging :refer :all]
[com.stuartsierra.component :refer [Lifecycle using]]
[clojure.java.io :as io]
[edge.sources :refer [source-routes]]

Excellent advices

Whatever you're building, releases should consist of a single artifact. A .jar or .war or docker container or AMI or whatever it is, it should be self-contained, and reproducible. Your process should not resolve or download dependencies at runtime. https://rasterize.io/blog/clojure-the-good-parts.html

DDD in Clojure

(query (-> 7 time/days time/ago) (time/now))
-Xms128m
-Xmx750m
-XX:ReservedCodeCacheSize=240m
-XX:+UseConcMarkSweepGC
-XX:SoftRefLRUPolicyMSPerMB=50
-ea
-Dsun.io.useCanonCaches=false
-Djava.net.preferIPv4Stack=true
-XX:+HeapDumpOnOutOfMemoryError
-XX:-OmitStackTraceInFastThrow

Yada

the devil is in the details, and the details include charsets, languages, encodings, parameters, q values, vary headers, options, error handling and renegotiation, etag per representation, If-None-Match, reactive negotiation, 406, 300 ... it's labyrithine. If anybody has ever implemented content negotiation in Clojure (fully) outside of Liberator and yada and lived to tell the tale I'd love to hear about it. https://m.reddit.com/r/Clojure/comments/4pb0la/concerns_with_ring/

Etags

Note also that different representations generate different ETag values. The entity tag is a way of managing a cache of representations, not a cache of resources

http://coop.apps.knpuniversity.com/token
?client_id=Your+Client+Name
&client_secret=abcdefg
&grant_type=client_credentials
$request = $http->post('/token', null, array(
'client_id' => 'Brent\'s Lazy CRON Job',
'client_secret' => 'a2e7f02def711095f83f2fb04ecbc0d3',
'grant_type' => 'client_credentials',

Reactor - Reactive Programming

https://spring.io/blog/2016/03/11/reactor-core-2-5-becomes-a-unified-reactive-foundation-on-java-8

Stream est un type qui est fait pour gérer des flux (comme Flux et Observable) mais c’est fait pour traiter des flux quand il n’y a aucune latence (quand tout est en mémoire par ex). Mais quand il y a de la latence (dès qu’il y a de l’IO), alors Stream c’est mort car il utilise un Thread pool commun. (confirmé par Brian Goetz)

CompletableFuture est un vrai type non bloquant (avec Callback pour traiter le résultat). Mais pas pratique pour gérer des multitudes d’éléments. On a juste CompletableFuture<List>.

ReactiveStream est une spec vers laquelle tout le monde migre et implémente.

# i'd like to have this printed out, using nested zip data structures:
# john eats roasted pizza
# mary eats raw vegetables
# john eats tender chicken
# But there's an error at line 'for f, c in fc:' saying: ValueError: too many values to unpack
people = ["john", "mary", "doug"]
food = ["pizza", "vegetables", "chicken"]
cooked = ["roasted", "raw", "tender"]
food_cooked = zip(food, cooked)
people_food_cooked = zip(people, food_cooked)