alandipert / enduro

Durable Atoms in Clojure
114 stars 5 forks source link

S3 backed atom #6

Open martinklepsch opened 8 years ago

martinklepsch commented 8 years ago
(ns open-company-auth.store
  (:require [alandipert.enduro :as end]
            [amazonica.aws.s3 :as s3]
            [clojure.java.io :as io]
            [clojure.edn :as edn]))

(defn- get-value [creds bucket key]
  (-> (s3/get-object creds bucket key) :input-stream slurp edn/read-string))

(defn- store-value [creds bucket key value]
  (time
   (let [str-val (pr-str value)]
     (s3/put-object creds bucket key
                    (io/input-stream (.getBytes str-val))
                    {:content-length (count str-val)}))))

(deftype S3Backend [creds bucket key]
  end/IDurableBackend
  (-commit! [this value]
    (store-value creds bucket key value))
  (-remove! [this]
    (s3/delete-object creds bucket key)))

(defn s3-atom
  #=(end/with-options-doc "Creates and returns a S3-backed atom.
  If the location denoted by the combination of bucket and key exists,
  it is read and becomes the initial value.
  Otherwise, the initial value is init and the bucket denoted by table-name is updated.")
  [init aws-creds bucket key & opts]
  (end/atom*
   (or (and (s3/does-object-exist aws-creds bucket key)
            (get-value aws-creds bucket key))
       (do
         (store-value aws-creds bucket key init)
         init))
   (S3Backend. aws-creds bucket key)
   (apply hash-map opts)))

Thanks for enduro @alandipert, good fun. Implemented an S3 backed atom as above, thought I'd let you know, maybe it's an interesting thing to add to the docs or just for other people stopping by here :)

mikegirkin commented 8 years ago

@martinklepsch Thank you for this, exactly what I needed. I think you should consider putting this as a separate lib, or creating an opensource repo with this