Skip to content

Instantly share code, notes, and snippets.

View favila's full-sized avatar

Francis Avila favila

View GitHub Profile
@favila
favila / last-touched-tx.clj
Created February 27, 2018 23:41
datomic query to return the tx at which an entity or its components were last touched
(require '[datomic.api :as d])
(defn last-touched-tx
"Return the tx of the oldest assertion on `entity` or any of its components."
[db entity]
(or (d/q '[:find (max ?tx) .
:in $ % ?root
:where
(component-entities ?root ?ce)
(union ?root ?ce ?e)
[?e _ _ ?tx]]
@favila
favila / transit_uuid_reader.cljc
Created February 20, 2018 20:09
data readers to emit transit uuids in cljs with bits calculated at compile-time
(ns favila.transit-uuid-reader
"Use as a data reader for cljs-in-cljs or clj-for-cljs compilation to emit a
transit uuid type from a uuid string.
For clj-for-cljs compilation you must require this namespace at the top of
your cljs code somehow so that the emitted code can call
`transit-uuid-from-ints`"
#?(:clj (:import
(com.cognitect.transit types)
(goog.math Long))
@favila
favila / datomic-counter.clj
Created September 29, 2017 16:23
Demonstrate the creation and use of an auto-increment counter (with nonce) in datomic
(require '[datomic.api :as d])
(d/create-database "datomic:mem://counter-example")
;=> true
(def c (d/connect "datomic:mem://counter-example"))
;=> #'user/c
;; The essential features of creating and using an auto-increment counter in datomic:
;;
;; 1. A counter entity must store the current value and a nonce.
@favila
favila / spec-relation.clj
Last active September 1, 2017 17:04
Spec for a relation (tuple with named positions, optional trailing positions). Takes key + predicate pairs, and an optional final vector with key + predicate pairs. The predicates cannot be regexs. Returns a regex op that matches all values in sequence and returns a map of keys to the corresponding value, like s/cat. Unlike s/cat, values may onl…
(ns com.breezeehr.spec-utils
(:require [clojure.spec.alpha :as s]))
(s/def ::relation-arg-pair
(s/cat
:k (s/and keyword? #(not= % ::relation-tail))
:v #(not (s/regex? %))))
(defn- distinct-relation-keys? [{:keys [req opt]}]
(apply distinct? (concat (map :k req) (map :k opt))))
@favila
favila / unresponsive-immutant.clj
Created July 20, 2017 17:45
Minimum reproducible case where immutant connections seem to hang when using async/as-channel responses. This problem appears in immutant 2.1.7. The cause is not closing the InputStream from the request.
;;; immutant.web >= 2.1.7 will block subsequent requests on the same connection
;;; when using an async/as-channel response if the request body InputStream is
;;; not closed
;;; The essential difference seems to be the undertow dependency: 1.3.x
;;; does not care if the request is closed, but 1.4.x seems to care.
;;; Immutant 2.1.6 used undertow 1.3.x, but 2.1.7 switched to 1.4.x
;; leinigen Dependency: [[org.immutant/web "2.1.9"]]
@favila
favila / depth-first-path-comparator.clj
Created June 23, 2017 09:41
Comparator to sort path vectors (e.g. as used with get-in, assoc-in, update-in) in depth-first order instead of breath-first (which the standard comparator does)
(letfn [(cmp [^objects vec-b+maxi i a]
;; INVARIANT: vec-a is longer than or equal-len vec-b
;; INVARIANT: vec-a and vec-b are len >= 1
(let [vec-b (aget vec-b+maxi 0)
maxi (aget vec-b+maxi 1)
b (nth vec-b i)
diff (compare a b)]
(if (zero? diff)
(if (== i maxi)
(reduced vec-b+maxi)
@favila
favila / kafka-workbench.clj
Created May 2, 2017 18:20
code to fiddle with kafka behaviors
(ns kafka-workbench
(:require [franzy.clients.consumer.protocols :as c]
[franzy.clients.producer.protocols :as p]
[franzy.serialization.serializers :as serializers]
[franzy.serialization.deserializers :as deserializers]
[franzy.clients.consumer.client :as consumer]
[franzy.clients.producer.client :as producer]))
(def kafka-brokers [])
@favila
favila / drpcclient-example.clj
Created April 26, 2017 18:47
How to use DRPCClient in Java in storm 1.0.3 (at least)
;; Documentation on the storm site http://storm.apache.org/releases/1.0.3/Distributed-RPC.html
;; has an example that constructs DRPCClient in a way that is out-of-date.
;; And all the example code uses the LocalDRPCClient, so there's no docs on how to construct this object.
;; The problem is the new first parameter to the DRPCClient constructors. This should be the storm config map,
;; the same one topologies get and the one configured via storm.yaml. Ideally it is the identical map, but
;; if you are running the DRPCClient on a different process you may not have access to it.
;; Below is the minimum you need to get started on a not-very-customized storm cluster
@favila
favila / component-reachable.clj
Created April 17, 2017 15:21
Datomic rule to get all datoms for an entity and for all entities reachable via forward is-component attributes
'[[(component-reachable [?se] ?e ?a ?v ?tx)
[(identity ?se) ?e]
[?e ?a ?v ?tx]]
[(component-reachable [?se] ?e ?a ?v ?tx)
[?se ?sa ?sv ?tx]
[?sa :db/isComponent true]
[?sa :db/valueType ?type]
[?type :db/ident :db.type/ref]
(component-reachable ?sv ?e ?a ?v ?tx)]]
@favila
favila / str-test.cljs
Created April 6, 2017 20:32
Test different str implementations for cljs. Code used for this jsperf (which no longer runs due to DropBox): https://jsperf.com/cljs-core-str-possibilities
(ns str-test
(:import goog.string.StringBuffer))
(defn ^:export str-tostr
([x] (if (nil? x)
""
(.toString x)))
([x & ys]
(loop [sb (StringBuffer. (str-tostr x)) more ys]
(if more