; FILE:         sequence_generator.clj
; PROJECT:      Micro-Manager
; SUBSYSTEM:    mmstudio acquisition engine
; ----------------------------------------------------------------------------
; AUTHOR:       Arthur Edelstein, arthuredelstein@gmail.com, Dec 14, 2010
;               Adapted from the acq eng by Nenad Amodaj and Nico Stuurman
; COPYRIGHT:    University of California, San Francisco, 2006-2011
; LICENSE:      This file is distributed under the BSD license.
;               License text is included with the source distribution.
;               This file is distributed in the hope that it will be useful,
;               but WITHOUT ANY WARRANTY; without even the implied warranty
;               of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
;               IN NO EVENT SHALL THE COPYRIGHT OWNER OR
;               CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
;               INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES.

(ns org.micromanager.sequence-generator
  (:use [org.micromanager.mm :only [get-default-devices select-values-match?]]))

(defstruct channel :name :exposure :z-offset :use-z-stack :skip-frames)

(defstruct stage-position :stage-device :axes)

(defstruct acq-settings :frames :positions :channels :slices :slices-first
  :time-first :keep-shutter-open-slices :keep-shutter-open-channels
  :use-autofocus :autofocus-skip :relative-slices :exposure :interval-ms)

(defn pairs [x]
  (partition 2 1 (lazy-cat x (list nil))))

(defn pairs-back [x]
  (partition 2 1 (lazy-cat (list nil) x)))

(defn if-assoc [pred m k v]
  (if pred (assoc m k v) m))

(defn make-dimensions [settings]
  (let [{:keys [slices channels frames positions
                slices-first time-first]} settings
        a [[slices :slice :slice-index] [channels :channel :channel-index]]
        a (if slices-first a (reverse a))
        b [[frames :frame :frame-index] [positions :position :position-index]]
        b (if time-first b (reverse b))]
    (concat a b)))

(defn nest-loop [events dim-vals dim dim-index-kw]
  (if (and dim-vals (pos? (count dim-vals)))
    (for [i (range (count dim-vals)) event events]
      (assoc event
        dim-index-kw i
        dim (nth dim-vals i)))
    (map #(assoc % dim-index-kw 0) events)))

(defn create-loops [dimensions]
  (reduce #(apply (partial nest-loop %1) %2) [{:task :snap}] dimensions))

(defn make-main-loops [settings]
  (create-loops (make-dimensions settings)))

(defn build-event [settings event]
  (assoc event
    :z-drive (:focus (get-default-devices))
    :exposure (if (:channel event)
                (get-in event [:channel :exposure])
                (:default-exposure settings))
    :relative-z (:relative-slices settings)))

(defn process-skip-z-stack [events slices]
  (if (pos? (count slices))
    (let [middle-slice (nth slices (int (/ (count slices) 2)))]
      (filter
        #(or
           (nil? (% :channel))
           (-> % :channel :use-z-stack)
           (= middle-slice (% :slice)))
        events))
    events))

(defn manage-shutter [events keep-shutter-open-channels keep-shutter-open-slices]
  (for [[e1 e2] (pairs events)]
    (assoc e1 :close-shutter
      (if e2 (or
               (and
                 (not keep-shutter-open-channels)
                 (not= (e1 :channel) (e2 :channel)))
               (and
                 (not keep-shutter-open-slices)
                 (not= (e1 :slice) (e2 :slice)))
               (not= (e1 :frame-index) (e2 :frame-index))
               (not= (e1 :position-index) (e2 :position-index)))
        true))))

(defn process-channel-skip-frames [events]
  (filter
    #(or
       (nil? (% :channel))
       (-> % :channel :skip-frames zero?)
       (zero? (mod (% :frame) (-> % :channel :skip-frames inc))))
    events))

(defn process-use-autofocus [events use-autofocus autofocus-skip]
  (for [[e1 e2] (pairs-back events)]
    (assoc e2 :autofocus
      (and use-autofocus
        (or (not e1)
          (and (zero? (mod (e2 :frame-index) (inc autofocus-skip)))
               (or (not= (:position-index e1) (:position-index e2))
                   (not= (:frame-index e1) (:frame-index e2)))))))))

(defn process-wait-time [events interval-ms]
  (cons
    (assoc (first events) :wait-time-ms 0)
    (for [[e1 e2] (pairs events) :when e2]
      (if-assoc (not= (:frame-index e1) (:frame-index e2))
        e2 :wait-time-ms interval-ms))))

(defn burst-valid [e1 e2]
  (println e2)
  (and
    (#(or (nil? %) (>= (:exposure e2) %)) (:wait-time-ms e2))
    (select-values-match? e1 e2 [:exposure :position :slice :channel])
    (not (:autofocus e2))))

(defn make-bursts [events]
  (let [e1 (first events)
        ne (next events)
        [run later] (split-with #(burst-valid e1 %) ne)]
    (when e1
      (if (not (empty? run))
        (lazy-cat (list (assoc e1 :task :init-burst
                                  :burst-length (inc (count run))))
                (map #(assoc % :task :collect-burst) run)
                (make-bursts later))
        (lazy-cat (list e1) (make-bursts later))))))

(defn add-next-task-tags [events]
  (for [p (pairs events)]
    (assoc (first p) :next-frame-index (get (second p) :frame-index))))

(defn selectively-update-tag [events event-template key update-fn]
  (let [ks (keys event-template)]
    (for [event events]
      (if (select-values-match? event event-template ks)
        (update-in event [key] update-fn)
        event))))

(defn selectively-append-runnable [events event-template runnable]
  (selectively-update-tag events event-template :runnables
                          #(conj (vec %) runnable)))

(defn attach-runnables [events runnable-list]
  (if (pos? (count runnable-list))
    (recur (apply selectively-append-runnable events (first runnable-list))
           (next runnable-list))
    events))

(defn generate-acq-sequence [settings runnables]
  (let [{:keys [slices keep-shutter-open-channels keep-shutter-open-slices
                use-autofocus autofocus-skip interval-ms relative-slices
                runnable-list]} settings]
    (-> (make-main-loops settings)
      (#(map (partial build-event settings) %))
      (process-skip-z-stack slices)
      (manage-shutter keep-shutter-open-channels keep-shutter-open-slices)
      (process-channel-skip-frames)
      (process-use-autofocus use-autofocus autofocus-skip)
      (process-wait-time interval-ms)
      (attach-runnables runnables)
      (make-bursts)
      (add-next-task-tags))))

; Testing:

(def my-channels
  [(struct channel "Cy3" 100 0 true 0)
   (struct channel "Cy5"  50 0 false 0)
   (struct channel "DAPI" 50 0 true 0)])

(def default-settings
  (struct-map acq-settings
    :frames (range 10) :positions [{:name "a" :x 1 :y 2} {:name "b" :x 4 :y 5}]
    :channels my-channels :slices (range 5)
    :slices-first true :time-first true
    :keep-shutter-open-slices false :keep-shutter-open-channels true
    :use-autofocus true :autofocus-skip 3 :relative-slices true :exposure 100
    :interval-ms 1000))

(def test-settings
  (struct-map acq-settings
    :frames (range 10) :positions [{:name "a" :x 1 :y 2} {:name "b" :x 4 :y 5}]
    :channels my-channels :slices (range 5)
    :slices-first true :time-first true
    :keep-shutter-open-slices false :keep-shutter-open-channels true
    :use-autofocus true :autofocus-skip 3 :relative-slices true :exposure 100
    :interval-ms 100))

(def null-settings
  (struct-map acq-settings
    :frames (range 96)
    :positions (range 1536)
    :channels [(struct channel "Cy3" 100 0 true 0)
               (struct channel "Cy5"  50 0 true 0)]
    :slices (range 5)
    :slices-first true :time-first false
    :keep-shutter-open-slices false :keep-shutter-open-channels true
    :use-autofocus true :autofocus-skip 3 :relative-slices true :exposure 100
    :interval-ms 100))

;(def result (generate-acq-sequence null-settings))

;(count result)

; FILE:         sequence_generator.clj
; PROJECT:      Micro-Manager
; SUBSYSTEM:    mmstudio acquisition engine
; ----------------------------------------------------------------------------
; AUTHOR:       Arthur Edelstein, arthuredelstein@gmail.com, Dec 14, 2010
;               Adapted from the acq eng by Nenad Amodaj and Nico Stuurman
; COPYRIGHT:    University of California, San Francisco, 2006-2011
; LICENSE:      This file is distributed under the BSD license.
;               License text is included with the source distribution.
;               This file is distributed in the hope that it will be useful,
;               but WITHOUT ANY WARRANTY; without even the implied warranty
;               of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
;               IN NO EVENT SHALL THE COPYRIGHT OWNER OR
;               CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
;               INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES.

(ns org.micromanager.sequence-generator
  (:use [org.micromanager.mm :only [get-default-devices select-values-match?]]))

(defstruct channel :name :exposure :z-offset :use-z-stack :skip-frames)

(defstruct stage-position :stage-device :axes)

(defstruct acq-settings :frames :positions :channels :slices :slices-first
  :time-first :keep-shutter-open-slices :keep-shutter-open-channels
  :use-autofocus :autofocus-skip :relative-slices :exposure :interval-ms)

(defn pairs [x]
  (partition 2 1 (lazy-cat x (list nil))))

(defn pairs-back [x]
  (partition 2 1 (lazy-cat (list nil) x)))

(defn if-assoc [pred m k v]
  (if pred (assoc m k v) m))

(defn make-dimensions [settings]
  (let [{:keys [slices channels frames positions
                slices-first time-first]} settings
        a [[slices :slice :slice-index] [channels :channel :channel-index]]
        a (if slices-first a (reverse a))
        b [[frames :frame :frame-index] [positions :position :position-index]]
        b (if time-first b (reverse b))]
    (concat a b)))

(defn nest-loop [events dim-vals dim dim-index-kw]
  (if (and dim-vals (pos? (count dim-vals)))
    (for [i (range (count dim-vals)) event events]
      (assoc event
        dim-index-kw i
        dim (nth dim-vals i)))
    (map #(assoc % dim-index-kw 0) events)))

(defn create-loops [dimensions]
  (reduce #(apply (partial nest-loop %1) %2) [{:task :snap}] dimensions))

(defn make-main-loops [settings]
  (create-loops (make-dimensions settings)))

(defn build-event [settings event]
  (assoc event
    :z-drive (:focus (get-default-devices))
    :exposure (if (:channel event)
                (get-in event [:channel :exposure])
                (:default-exposure settings))
    :relative-z (:relative-slices settings)))

(defn process-skip-z-stack [events slices]
  (if (pos? (count slices))
    (let [middle-slice (nth slices (int (/ (count slices) 2)))]
      (filter
        #(or
           (nil? (% :channel))
           (-> % :channel :use-z-stack)
           (= middle-slice (% :slice)))
        events))
    events))

(defn manage-shutter [events keep-shutter-open-channels keep-shutter-open-slices]
  (for [[e1 e2] (pairs events)]
    (assoc e1 :close-shutter
      (if e2 (or
               (and
                 (not keep-shutter-open-channels)
                 (not= (e1 :channel) (e2 :channel)))
               (and
                 (not keep-shutter-open-slices)
                 (not= (e1 :slice) (e2 :slice)))
               (not= (e1 :frame-index) (e2 :frame-index))
               (not= (e1 :position-index) (e2 :position-index)))
        true))))

(defn process-channel-skip-frames [events]
  (filter
    #(or
       (nil? (% :channel))
       (-> % :channel :skip-frames zero?)
       (zero? (mod (% :frame) (-> % :channel :skip-frames inc))))
    events))

(defn process-use-autofocus [events use-autofocus autofocus-skip]
  (for [[e1 e2] (pairs-back events)]
    (assoc e2 :autofocus
      (and use-autofocus
        (or (not e1)
          (and (zero? (mod (e2 :frame-index) (inc autofocus-skip)))
               (or (not= (:position-index e1) (:position-index e2))
                   (not= (:frame-index e1) (:frame-index e2)))))))))

(defn process-wait-time [events interval-ms]
  (cons
    (assoc (first events) :wait-time-ms 0)
    (for [[e1 e2] (pairs events) :when e2]
      (if-assoc (not= (:frame-index e1) (:frame-index e2))
        e2 :wait-time-ms interval-ms))))

(defn burst-valid [e1 e2]
  (and
    (#(or (nil? %) (>= (:exposure e2) %)) (:wait-time-ms e2))
    (select-values-match? e1 e2 [:exposure :position :slice :channel])
    (not (:autofocus e2))))

(defn make-bursts [events]
  (let [e1 (first events)
        ne (next events)
        [run later] (split-with #(burst-valid e1 %) ne)]
    (when e1
      (if (not (empty? run))
        (lazy-cat (list (assoc e1 :task :init-burst
                                  :burst-length (inc (count run))))
                (map #(assoc % :task :collect-burst) run)
                (make-bursts later))
        (lazy-cat (list e1) (make-bursts later))))))

(defn add-next-task-tags [events]
  (for [p (pairs events)]
    (assoc (first p) :next-frame-index (get (second p) :frame-index))))

(defn selectively-update-tag [events event-template key update-fn]
  (let [ks (keys event-template)]
    (for [event events]
      (if (select-values-match? event event-template ks)
        (update-in event [key] update-fn)
        event))))

(defn selectively-append-runnable [events event-template runnable]
  (selectively-update-tag events event-template :runnables
                          #(conj (vec %) runnable)))

(defn attach-runnables [events runnable-list]
  (if (pos? (count runnable-list))
    (recur (apply selectively-append-runnable events (first runnable-list))
           (next runnable-list))
    events))

(defn generate-acq-sequence [settings runnables]
  (let [{:keys [slices keep-shutter-open-channels keep-shutter-open-slices
                use-autofocus autofocus-skip interval-ms relative-slices
                runnable-list]} settings]
    (-> (make-main-loops settings)
      (#(map (partial build-event settings) %))
      (process-skip-z-stack slices)
      (manage-shutter keep-shutter-open-channels keep-shutter-open-slices)
      (process-channel-skip-frames)
      (process-use-autofocus use-autofocus autofocus-skip)
      (process-wait-time interval-ms)
      (attach-runnables runnables)
      (make-bursts)
      (add-next-task-tags))))

; Testing:

(def my-channels
  [(struct channel "Cy3" 100 0 true 0)
   (struct channel "Cy5"  50 0 false 0)
   (struct channel "DAPI" 50 0 true 0)])

(def default-settings
  (struct-map acq-settings
    :frames (range 10) :positions [{:name "a" :x 1 :y 2} {:name "b" :x 4 :y 5}]
    :channels my-channels :slices (range 5)
    :slices-first true :time-first true
    :keep-shutter-open-slices false :keep-shutter-open-channels true
    :use-autofocus true :autofocus-skip 3 :relative-slices true :exposure 100
    :interval-ms 1000))

(def test-settings
  (struct-map acq-settings
    :frames (range 10) :positions [{:name "a" :x 1 :y 2} {:name "b" :x 4 :y 5}]
    :channels my-channels :slices (range 5)
    :slices-first true :time-first true
    :keep-shutter-open-slices false :keep-shutter-open-channels true
    :use-autofocus true :autofocus-skip 3 :relative-slices true :exposure 100
    :interval-ms 100))

(def null-settings
  (struct-map acq-settings
    :frames (range 96)
    :positions (range 1536)
    :channels [(struct channel "Cy3" 100 0 true 0)
               (struct channel "Cy5"  50 0 true 0)]
    :slices (range 5)
    :slices-first true :time-first false
    :keep-shutter-open-slices false :keep-shutter-open-channels true
    :use-autofocus true :autofocus-skip 3 :relative-slices true :exposure 100
    :interval-ms 100))

;(def result (generate-acq-sequence null-settings))

;(count result)

remove debugging println

remove debugging println

git-svn-id: 03a8048b5ee8463be5048a3801110fb50f378627@6813 d0ab736e-dc22-4aeb-8dc9-08def0aa14fd


(ns incise.parsers.html-spec
  (:require [incise.parsers.html :refer :all]
            [incise.parsers.core :refer [map->Parse]]
            [clojure.java.io :refer [file resource]]
            [speclj.core :refer :all]))

(describe "File->Parse"
  (with short-md-file (file (resource "spec/short-sample.md")))
  (it "reads some stuff out of a file, yo"
    (should= (map->Parse {:title "My Short Page"
                          :layout :page
                          :date "2013-08-12"
                          :tags [:cool]
                          :category :blarg
                          :content "\n\nHey there!\n"
                          :extension :html}) (File->Parse identity @short-md-file))))

(run-specs)

(ns incise.parsers.html-spec
  (:require [incise.parsers.html :refer :all]
            [incise.parsers.core :refer [map->Parse]]
            [clojure.java.io :refer [file resource]]
            [speclj.core :refer :all]))

(describe "File->Parse"
  (with short-md-file (file (resource "spec/short-sample.md")))
  (it "reads some stuff out of a file, yo"
    (should= (map->Parse {:title "My Short Page"
                          :layout :page
                          :date "2013-08-12"
                          :tags [:cool]
                          :category :blarg
                          :content "\n\nHey there!\n"
                          :extension "/index.html"}) (File->Parse identity @short-md-file))))

(run-specs)

Fix html_spec extension.

Fix html_spec extension.


(ns cook.mesos.pool
  (:require [clojure.string :as str]
            [clojure.tools.logging :as log]
            [cook.config :as config]
            [datomic.api :as d])
  (:import [java.util UUID]))

(defn check-pool
  "Returns true if requesting-default-pool? and the entity does not have a pool
   or the entity has a pool named pool-name"
  ([ent entity->pool pool-name requesting-default-pool?]
   (let [pool (entity->pool ent)]
     (or (and (nil? pool)
              requesting-default-pool?)
         (= pool-name (:pool/name pool)))))
  ([source eid entity->pool pool-name requesting-default-pool?]
   (check-pool (d/entity source eid) entity->pool pool-name requesting-default-pool?)))

(def nil-pool (str (UUID/randomUUID)))

(defn check-pool-for-listing
  "Returns true if either the provided pool-name is the 'nil' pool, or if
  pool/check-pool returns true. This allows us to return jobs in all pools when the user
  does not specify a pool."
  ([entity entity->pool pool-name default-pool?]
   (or
     (= nil-pool pool-name)
     (cook.mesos.pool/check-pool entity entity->pool pool-name default-pool?)))
  ([source eid entity->pool pool-name default-pool?]
   (check-pool-for-listing (d/entity source eid) entity->pool pool-name default-pool?)))

(defn pool-name-or-default
  "Returns:
   - The given pool name if not-nil
   - The default pool name, if configured
   - A random UUID"
  [pool-name]
  (or pool-name (config/default-pool) (str (UUID/randomUUID))))

(defn default-pool?
  "Returns true if pool-name is equal to the default pool name"
  [pool-name]
  (= pool-name (config/default-pool)))

(defn requesting-default-pool?
  "Returns true if pool-name is nil or equal to the default pool name"
  [pool-name]
  (true? (or (nil? pool-name) (default-pool? pool-name))))

(defn all-pools
  "Returns a list of Datomic entities corresponding
  to all of the currently defined pools."
  [db]
  (map (partial d/entity db)
       (d/q '[:find [?e ...]
              :in $
              :where
              [?e :pool/name]]
            db)))

(defn accepts-submissions?
  "Returns true if the given pool can accept job submissions"
  [pool]
  (= :pool.state/active (:pool/state pool)))

(defn guard-invalid-default-pool
  "Throws if either of the following is true:
   - there are pools in the database, but no default pool is configured
   - there is no pool in the database matching the configured default"
  [db]
  (let [pools (all-pools db)
        default-pool-name (config/default-pool)]
    (log/info "Pools in the database:" pools ", default pool:" default-pool-name)
    (if default-pool-name
      (when-not (some #(= default-pool-name (:pool/name %)) pools)
        (throw (ex-info "There is no pool in the database matching the configured default pool"
                        {:pools pools :default-pool-name default-pool-name})))
      (when (-> pools count pos?)
        (throw (ex-info "There are pools in the database, but no default pool is configured"
                        {:pools pools}))))))

(ns cook.mesos.pool
  (:require [clojure.string :as str]
            [clojure.tools.logging :as log]
            [cook.config :as config]
            [datomic.api :as d])
  (:import [java.util UUID]))

(defn check-pool
  "Returns true if requesting-default-pool? and the entity does not have a pool
   or the entity has a pool named pool-name"
  ([ent entity->pool pool-name requesting-default-pool?]
   (let [pool (entity->pool ent)]
     (or (and (nil? pool)
              requesting-default-pool?)
         (= pool-name (:pool/name pool)))))
  ([source eid entity->pool pool-name requesting-default-pool?]
   (check-pool (d/entity source eid) entity->pool pool-name requesting-default-pool?)))

(def nil-pool (str (UUID/randomUUID)))

(defn check-pool-for-listing
  "Returns true if either the provided pool-name is the 'nil' pool, or if
  pool/check-pool returns true. This allows us to return jobs in all pools when the user
  does not specify a pool."
  ([entity entity->pool pool-name default-pool?]
   (or
     (= nil-pool pool-name)
     (cook.mesos.pool/check-pool entity entity->pool pool-name default-pool?)))
  ([source eid entity->pool pool-name default-pool?]
   (check-pool-for-listing (d/entity source eid) entity->pool pool-name default-pool?)))

(defn pool-name-or-default
  "Returns:
   - The given pool name if not-nil
   - The default pool name, if configured
   - `nil-pool`
   Returning `nil-pool` instead of `nil` allows this to be used as an argument to a datomic function
   or comparison operator"
  [pool-name]
  (or pool-name (config/default-pool) nil-pool))

(defn default-pool?
  "Returns true if pool-name is equal to the default pool name"
  [pool-name]
  (= pool-name (config/default-pool)))

(defn requesting-default-pool?
  "Returns true if pool-name is nil or equal to the default pool name"
  [pool-name]
  (true? (or (nil? pool-name) (default-pool? pool-name))))

(defn all-pools
  "Returns a list of Datomic entities corresponding
  to all of the currently defined pools."
  [db]
  (map (partial d/entity db)
       (d/q '[:find [?e ...]
              :in $
              :where
              [?e :pool/name]]
            db)))

(defn accepts-submissions?
  "Returns true if the given pool can accept job submissions"
  [pool]
  (= :pool.state/active (:pool/state pool)))

(defn guard-invalid-default-pool
  "Throws if either of the following is true:
   - there are pools in the database, but no default pool is configured
   - there is no pool in the database matching the configured default"
  [db]
  (let [pools (all-pools db)
        default-pool-name (config/default-pool)]
    (log/info "Pools in the database:" pools ", default pool:" default-pool-name)
    (if default-pool-name
      (when-not (some #(= default-pool-name (:pool/name %)) pools)
        (throw (ex-info "There is no pool in the database matching the configured default pool"
                        {:pools pools :default-pool-name default-pool-name})))
      (when (-> pools count pos?)
        (throw (ex-info "There are pools in the database, but no default pool is configured"
                        {:pools pools}))))))

Use `nil-pool` instead of a new random UUID (#919)


(defproject example "0.1.0-SNAPSHOT"
  :description "Simple example of using lein-jslint"
  :url "https://github.com/vbauer/lein-jslint"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}

  ; List of plugins
  :plugins [[lein-jslint "0.1.6"]]

  ; List of hooks
  ; It's used for running JSLint during compile phase
  :hooks [lein-jslint.plugin]

  ; JSLint configuration
  :jslint {:includes "resources/*.js"})

(defproject example "0.1.0-SNAPSHOT"
  :description "Simple example of using lein-jslint"
  :url "https://github.com/vbauer/lein-jslint"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}

  ; List of plugins
  :plugins [[lein-jslint "0.1.7"]]

  ; List of hooks
  ; It's used for running JSLint during compile phase
  :hooks [lein-jslint.plugin]

  ; JSLint configuration
  :jslint {:includes "resources/*.js"})

Update an example project

Update an example project


(import [java.util Properties])
(require '[clojure.java.io :as io])
(def propsfile "../../version.properties")
(def version (-> (doto (Properties.) (.load (io/input-stream propsfile)))
               (.getProperty "version")))

(defproject boot/worker version
  :aot :all
  :jar-exclusions [#"^clojure/core/"]
  :description  "Boot worker module–this is the worker pod for built-in tasks."
  :url          "https://github.com/boot-clj/boot"
  :scm          {:url "https://github.com/boot-clj/boot.git" :dir "../../"}
  :repositories [["clojars"  {:url "https://clojars.org/repo" :creds :gpg :sign-releases false}]]
  :license      {:name "Eclipse Public License"
                 :url "http://www.eclipse.org/legal/epl-v10.html"}
  :java-source-paths ["third_party/barbarywatchservice/src"]
  :javac-options ["-target" "1.7" "-source" "1.7"]
  :dependencies [[org.clojure/clojure         "1.6.0"  :scope "provided"]
                 [boot/base                   ~version :scope "provided"]
                 [boot/aether                 ~version]
                 ;; Suppress warnings from SLF4J via pomegranate via aether
                 [org.slf4j/slf4j-nop         "1.7.22"]
                 ;; see https://github.com/boot-clj/boot/issues/82
                 [net.cgrand/parsley          "0.9.3" :exclusions [org.clojure/clojure]]
                 [mvxcvi/puget                "1.0.1"]
                 [reply                       "0.4.3"]
                 [cheshire                    "5.6.0"]
                 [clj-jgit                    "0.8.0"]
                 [clj-yaml                    "0.4.0"]
                 [javazoom/jlayer             "1.0.1"]
                 [net.java.dev.jna/jna        "4.1.0"]
                 [alandipert/desiderata       "1.0.2"]
                 [org.clojure/data.xml        "0.0.8"]
                 [org.clojure/data.zip        "0.1.1"]
                 [org.clojure/tools.namespace "0.2.11"]])

(import [java.util Properties])
(require '[clojure.java.io :as io])
(def propsfile "../../version.properties")
(def version (-> (doto (Properties.) (.load (io/input-stream propsfile)))
               (.getProperty "version")))

(defproject boot/worker version
  :aot :all
  :jar-exclusions [#"^clojure/core/"]
  :description  "Boot worker module–this is the worker pod for built-in tasks."
  :url          "https://github.com/boot-clj/boot"
  :scm          {:url "https://github.com/boot-clj/boot.git" :dir "../../"}
  :repositories [["clojars"  {:url "https://clojars.org/repo" :creds :gpg :sign-releases false}]]
  :license      {:name "Eclipse Public License"
                 :url "http://www.eclipse.org/legal/epl-v10.html"}
  :java-source-paths ["third_party/barbarywatchservice/src"]
  :javac-options ["-target" "1.8" "-source" "1.8"]
  :dependencies [[org.clojure/clojure         "1.6.0"  :scope "provided"]
                 [boot/base                   ~version :scope "provided"]
                 [boot/aether                 ~version]
                 ;; Suppress warnings from SLF4J via pomegranate via aether
                 [org.slf4j/slf4j-nop         "1.7.22"]
                 ;; see https://github.com/boot-clj/boot/issues/82
                 [net.cgrand/parsley          "0.9.3" :exclusions [org.clojure/clojure]]
                 [mvxcvi/puget                "1.0.1"]
                 [reply                       "0.4.3"]
                 [cheshire                    "5.6.0"]
                 [clj-jgit                    "0.8.0"]
                 [clj-yaml                    "0.4.0"]
                 [javazoom/jlayer             "1.0.1"]
                 [net.java.dev.jna/jna        "4.1.0"]
                 [alandipert/desiderata       "1.0.2"]
                 [org.clojure/data.xml        "0.0.8"]
                 [org.clojure/data.zip        "0.1.1"]
                 [org.clojure/tools.namespace "0.2.11"]])

update java to 1.8

update java to 1.8


(ns tranjlator.master-view
  (:require [cljs.core.async :refer [<! >! put! timeout chan] :as a]
            [om.core :as om :include-macros true]
            [om.dom :as dom :include-macros true]
            [tranjlator.actions :refer [check-for-enter post-message clear-text
                                        text-entry]]
            [tranjlator.sockets :refer [make-socket]]
            [tranjlator.langs :refer [+langs+]]
            [tranjlator.messages :as m]
            [tranjlator.hashing :refer [hash hex-string]]
            [tranjlator.slash-commands :refer [command]])
  (:require-macros [cljs.core.async.macros :refer [go-loop go alt!]]))

(defn ping []
  (let [clip (.getElementById js/document "ping-sound")]
    (.play clip)))

(defn reading-language-change [e sender-ch app]
  (let [new-lang (.. e -target -value)
        old-lang (:reading-language @app)
        user-name (:user-name @app)]
    (when (not (= new-lang old-lang))
      (do
        (om/update! app :reading-language new-lang)
        (when-not (nil? old-lang)
          (put! sender-ch (m/->language-unsub user-name old-lang)))
        (when-not (nil? new-lang)
          (put! sender-ch (m/->language-sub user-name new-lang)))))))

(defn writing-language-change [e sender-ch app]
  (let [new-lang (.. e -target -value)]
    (om/update! app :writing-language new-lang)))

(defn send-message-click [sender-ch text owner app]
  (do
    (let [sha (-> text hash hex-string)]
      (post-message sender-ch
                    (assoc (command text)
                      :user-name (:user-name @app)
                      :language (keyword (:writing-language @app))
                      :original-sha sha
                      :content-sha sha)))
    (clear-text owner)))

(defn users-view [app owner]
  (reify
    om/IRender
    (render [this]
      (dom/div #js {:className "col-md-2"}
               (dom/div #js {:className "panel panel-info"}
                        (dom/div #js {:className "panel-heading"}
                                 (dom/h4 #js {:className "panel-title"}
                                         (dom/span #js {:className "glyphicon glyphicon-user"})
                                         " Users"))
                        (dom/div #js {:className "panel-body"}
                                 (apply dom/ul nil
                                        (map (fn [item] (dom/li nil item)) (sort app)))))))))

(defn format-chat [{:keys [user-name content]}]
  (str user-name ": " content ))

(defn original-view [app owner]
  (reify
    om/IRenderState
    (render-state [this state]
      (dom/div #js {:className "col-md-5"}
               (dom/div #js {:className "panel panel-primary"}
                        (dom/div #js {:className "panel-heading"}
                                 (dom/h4 #js {:className "panel-title"}
                                         (dom/span #js {:className "glyphicon glyphicon-globe"})
                                         " Original"))
                        (dom/div #js {:className "panel-body chat" :id "original-panel"}
                                 (apply dom/ul #js {:className "list-group"}
                                        (map (fn [item] (dom/li #js {:className "list-group-item"} (format-chat item)
                                                               (dom/span #js {:className "badge"} (name (:language item))))) app))))))
    om/IDidUpdate
    (did-update [_ _ _]
      (let [panel (.getElementById js/document "original-panel")]
        (set! (.-scrollTop panel) (.-scrollHeight panel))))))

(defn translated-view [app owner]
  (reify
    om/IRenderState
    (render-state [this state]
      (dom/div #js {:className "col-md-5"}
               (dom/div #js {:className "panel panel-primary"}
                        (dom/div #js {:className "panel-heading"}
                                 (dom/h4 #js {:className "panel-title"}
                                         (dom/span #js {:className "glyphicon glyphicon-home"})
                                         " Translated"))
                        (dom/div #js {:className "panel-body chat" :id "translated-panel"}
                                 (apply dom/ul #js {:className "list-group"}
                                        (map (fn [item] (dom/li #js {:className "list-group-item"} (format-chat item))) app))))))
    om/IDidUpdate
    (did-update [_ _ _]
      (let [panel (.getElementById js/document "translated-panel")]
        (set! (.-scrollTop panel) (.-scrollHeight panel)))))
  )
(defn master-view [app owner]
  (reify
    om/IWillMount
    (will-mount [_]
      (let [listener-ch (:listener-ch app)
            sender-ch (:sender-ch app)
            socket-ctrl (:socket-ctrl app)]
        (make-socket listener-ch sender-ch (:user-name app) socket-ctrl)
        (go (loop []
              (when-let [msg (<! listener-ch)]
                (let [topic (:topic msg)
                      lang (:reading-language @app)]
                  (cond
                   (= :original topic) (om/transact! app :original (fn [col] (conj col msg)))
                   (= :user-join topic) (om/transact! app :users (fn [col] (conj col (:user-name msg []))))
                   (= :user-part topic) (om/transact! app :users (fn [col] (remove (fn [x] (= x (:user-name msg))) col)))
                   (= (keyword lang) topic) (om/transact! app :translated (fn [col] (conj col msg)))
                   (= :ping topic) (when (= (:target msg) (:user-name @app)) (ping))
                   (= :error topic) (do (let [name (:user-name @app)]
                                          (put! socket-ctrl "Doh")
                                          (om/update! app :sender-ch (chan))
                                          (om/update! app :listener-ch (chan))
                                          (om/update! app :dissappointed-user name)
                                          (om/update! app :user-name nil)))
                   :default (println "RECVD:" msg "type: " (keys msg))))
                (recur))))))
    om/IDidMount
    (did-mount [_]
      (let [txtbox (.getElementById js/document "text-entry")
            msg (.getElementById js/document "timeout-alert")]
        (.focus txtbox)
        (go
         (<! (timeout (* 30 1000)))
         (set! (.-className msg) (+ (.-className msg) " hidden")))))

    om/IInitState
    (init-state [_]
      {:text ""})
    om/IRenderState
    (render-state [this {:keys [text] :as state}]
      (let [sender-ch (:sender-ch app)]
        (dom/div {:className "col-md-12"}
                 (dom/div #js {:className "row"}
                          (when-not (:reading-language app)
                            (dom/div #js {:className "alert alert-success"} "Select a language to view translated messages."))
                          (dom/div #js {:className "col-md-5 col-xs-offset-7"}
                                   (apply dom/select #js {:className "form-control"
                                                    :value (:reading-language app)
                                                          :onChange (fn [e] (reading-language-change e sender-ch app))}
                                          (map (fn [lang] (dom/option #js {:value (:code lang)} (:name lang))) (cons {:code nil :name ""} +langs+))))
                          (om/build users-view (:users app))
                          (om/build original-view (:original app))
                          (om/build translated-view (:translated app) {:init-state {:label " Translated"
                                                                                :glyph "glyphicon glyphicon-home"
                                                                                :show-language false}})
                          (dom/div #js {:className "col-md-12 table"}
                                   (dom/div #js {:className "col-md-3"}
                                            (apply dom/select #js {:className "form-control"
                                                             :value (:writing-language app)
                                                             :onChange (fn [e] (writing-language-change e sender-ch app))}
                                                        (map (fn [lang] (dom/option #js {:value (:code lang)} (:name lang))) +langs+)))
                                   (dom/div #js {:className "col-md-8"}
                                            (dom/input #js {:className "form-control" :type "text"
                                                            :value text :id "text-entry"
                                                            :onKeyUp (fn [e] (check-for-enter e owner state app send-message-click))
                                                            :onChange #(text-entry % owner state)}))
                                   (dom/div #js {:className "col-md-1"}
                                            (dom/button #js {:type "button" :className "btn btn-primary"
                                                             :onClick (fn [e] (send-message-click sender-ch text owner app))}
                                                        (dom/span #js {:className "glyphicon glyphicon-leaf"}) " Enter"))))
                 (dom/div #js {:className "row"}
                          (dom/div #js {:className "alert alert-warning" :id "timeout-alert"}
                                   "Want to type in a different language? Use the dropdown to tell us which one. Rather code? Use /clojure or @clojure to evaluate forms.")))))))

(ns tranjlator.master-view
  (:require [cljs.core.async :refer [<! >! put! timeout chan] :as a]
            [om.core :as om :include-macros true]
            [om.dom :as dom :include-macros true]
            [tranjlator.actions :refer [check-for-enter post-message clear-text
                                        text-entry]]
            [tranjlator.sockets :refer [make-socket]]
            [tranjlator.langs :refer [+langs+]]
            [tranjlator.messages :as m]
            [tranjlator.hashing :refer [hash hex-string]]
            [tranjlator.slash-commands :refer [command]])
  (:require-macros [cljs.core.async.macros :refer [go-loop go alt!]]))

(defn ping []
  (let [clip (.getElementById js/document "ping-sound")]
    (.play clip)))

(defn reading-language-change [e sender-ch app]
  (let [new-lang (.. e -target -value)
        old-lang (:reading-language @app)
        user-name (:user-name @app)]
    (when (not (= new-lang old-lang))
      (do
        (om/update! app :reading-language new-lang)
        (when-not (nil? old-lang)
          (put! sender-ch (m/->language-unsub user-name old-lang)))
        (when-not (nil? new-lang)
          (put! sender-ch (m/->language-sub user-name new-lang)))))))

(defn writing-language-change [e sender-ch app]
  (let [new-lang (.. e -target -value)]
    (om/update! app :writing-language new-lang)))

(defn send-message-click [sender-ch text owner app]
  (do
    (let [sha (-> text hash hex-string)]
      (post-message sender-ch
                    (assoc (command text)
                      :user-name (:user-name @app)
                      :language (keyword (:writing-language @app))
                      :original-sha sha
                      :content-sha sha)))
    (clear-text owner)))

(defn replacer [col key val new-val]
  (loop [src col acc []]
    (cond (empty? src) (conj acc new-val)
          (= (key (first src)) val) (concat acc [new-val] (rest src))
          :default (recur (rest src) (conj acc (first src))))))

(defn users-view [app owner]
  (reify
    om/IRender
    (render [this]
      (dom/div #js {:className "col-md-2"}
               (dom/div #js {:className "panel panel-info"}
                        (dom/div #js {:className "panel-heading"}
                                 (dom/h4 #js {:className "panel-title"}
                                         (dom/span #js {:className "glyphicon glyphicon-user"})
                                         " Users"))
                        (dom/div #js {:className "panel-body"}
                                 (apply dom/ul nil
                                        (map (fn [item] (dom/li nil item)) (sort app)))))))))

(defn format-chat [{:keys [user-name content]}]
  (str user-name ": " content ))

(defn original-view [app owner]
  (reify
    om/IRenderState
    (render-state [this state]
      (dom/div #js {:className "col-md-5"}
               (dom/div #js {:className "panel panel-primary"}
                        (dom/div #js {:className "panel-heading"}
                                 (dom/h4 #js {:className "panel-title"}
                                         (dom/span #js {:className "glyphicon glyphicon-globe"})
                                         " Original"))
                        (dom/div #js {:className "panel-body chat" :id "original-panel"}
                                 (apply dom/ul #js {:className "list-group"}
                                        (map (fn [item] (dom/li #js {:className "list-group-item"} (format-chat item)
                                                               (dom/span #js {:className "badge"} (name (:language item))))) app))))))
    om/IDidUpdate
    (did-update [_ _ _]
      (let [panel (.getElementById js/document "original-panel")]
        (set! (.-scrollTop panel) (.-scrollHeight panel))))))

(defn translated-view [app owner]
  (reify
    om/IRenderState
    (render-state [this state]
      (dom/div #js {:className "col-md-5"}
               (dom/div #js {:className "panel panel-primary"}
                        (dom/div #js {:className "panel-heading"}
                                 (dom/h4 #js {:className "panel-title"}
                                         (dom/span #js {:className "glyphicon glyphicon-home"})
                                         " Translated"))
                        (dom/div #js {:className "panel-body chat" :id "translated-panel"}
                                 (apply dom/ul #js {:className "list-group"}
                                        (map (fn [item] (dom/li #js {:className "list-group-item"} (format-chat item))) app))))))
    om/IDidUpdate
    (did-update [_ _ _]
      (let [panel (.getElementById js/document "translated-panel")]
        (set! (.-scrollTop panel) (.-scrollHeight panel)))))
  )
(defn master-view [app owner]
  (reify
    om/IWillMount
    (will-mount [_]
      (let [listener-ch (:listener-ch app)
            sender-ch (:sender-ch app)
            socket-ctrl (:socket-ctrl app)]
        (make-socket listener-ch sender-ch (:user-name app) socket-ctrl)
        (go (loop []
              (when-let [msg (<! listener-ch)]
                (let [topic (:topic msg)
                      lang (:reading-language @app)]
                  (cond
                   (= :original topic) (om/transact! app :original (fn [col] (conj col msg)))
                   (= :user-join topic) (om/transact! app :users (fn [col] (conj col (:user-name msg []))))
                   (= :user-part topic) (om/transact! app :users (fn [col] (remove (fn [x] (= x (:user-name msg))) col)))
                   (= (keyword lang) topic) (om/transact! app :translated (fn [col] (replacer col :original-sha (:original-sha msg) msg)))
                   (= :ping topic) (when (= (:target msg) (:user-name @app)) (ping))
                   (= :error topic) (do (let [name (:user-name @app)]
                                          (put! socket-ctrl "Doh")
                                          (om/update! app :sender-ch (chan))
                                          (om/update! app :listener-ch (chan))
                                          (om/update! app :dissappointed-user name)
                                          (om/update! app :user-name nil)))
                   :default (println "RECVD:" msg "type: " (keys msg))))
                (recur))))))
    om/IDidMount
    (did-mount [_]
      (let [txtbox (.getElementById js/document "text-entry")
            msg (.getElementById js/document "timeout-alert")]
        (.focus txtbox)
        (go
         (<! (timeout (* 30 1000)))
         (set! (.-className msg) (+ (.-className msg) " hidden")))))

    om/IInitState
    (init-state [_]
      {:text ""})
    om/IRenderState
    (render-state [this {:keys [text] :as state}]
      (let [sender-ch (:sender-ch app)]
        (dom/div {:className "col-md-12"}
                 (dom/div #js {:className "row"}
                          (when-not (:reading-language app)
                            (dom/div #js {:className "alert alert-success"} "Select a language to view translated messages."))
                          (dom/div #js {:className "col-md-5 col-xs-offset-7"}
                                   (apply dom/select #js {:className "form-control"
                                                    :value (:reading-language app)
                                                          :onChange (fn [e] (reading-language-change e sender-ch app))}
                                          (map (fn [lang] (dom/option #js {:value (:code lang)} (:name lang))) (cons {:code nil :name ""} +langs+))))
                          (om/build users-view (:users app))
                          (om/build original-view (:original app))
                          (om/build translated-view (:translated app) {:init-state {:label " Translated"
                                                                                :glyph "glyphicon glyphicon-home"
                                                                                :show-language false}})
                          (dom/div #js {:className "col-md-12 table"}
                                   (dom/div #js {:className "col-md-3"}
                                            (apply dom/select #js {:className "form-control"
                                                             :value (:writing-language app)
                                                             :onChange (fn [e] (writing-language-change e sender-ch app))}
                                                        (map (fn [lang] (dom/option #js {:value (:code lang)} (:name lang))) +langs+)))
                                   (dom/div #js {:className "col-md-8"}
                                            (dom/input #js {:className "form-control" :type "text"
                                                            :value text :id "text-entry"
                                                            :onKeyUp (fn [e] (check-for-enter e owner state app send-message-click))
                                                            :onChange #(text-entry % owner state)}))
                                   (dom/div #js {:className "col-md-1"}
                                            (dom/button #js {:type "button" :className "btn btn-primary"
                                                             :onClick (fn [e] (send-message-click sender-ch text owner app))}
                                                        (dom/span #js {:className "glyphicon glyphicon-leaf"}) " Enter"))))
                 (dom/div #js {:className "row"}
                          (dom/div #js {:className "alert alert-warning" :id "timeout-alert"}
                                   "Want to type in a different language? Use the dropdown to tell us which one. Rather code? Use /clojure or @clojure to evaluate forms.")))))))

Replace when you get a new translation

Replace when you get a new translation


(ns status-im.react-native.js-dependencies)

(def config                 (js/require "react-native-config"))
(def fs                     (js/require "react-native-fs"))
(def http-bridge            (js/require "react-native-http-bridge"))
(def keychain               (js/require "react-native-keychain"))
(def qr-code                (js/require "qrcode"))
(def react-native           (js/require "react-native"))
(def webview-bridge         (js/require "react-native-webview-bridge"))
(def webview                #js {:WebView #js {}})
(def EventEmmiter           #js {})
(def securerandom           (js/require "react-native-securerandom"))
(def secure-random          (.-generateSecureRandom securerandom))
(def fetch-polyfill         (js/require "react-native-fetch-polyfill"))
(def fetch                  (.-default fetch-polyfill))
(def i18n                   (js/require "i18n-js"))
(def react-native-languages (.-default (js/require "react-native-languages")))
(def desktop-linking        (.-DesktopLinking (.-NativeModules react-native)))
(def desktop-menu           (js/require "react-native-desktop-menu"))
(def desktop-config         (js/require "react-native-desktop-config"))
(def desktop-shortcuts      (js/require "react-native-desktop-shortcuts"))
(def react-native-firebase  #js {})
(def touchid                #js {})
(def camera                 #js {:default #js {:constants {:Aspect "Portrait"}}})
(def status-keycard         #js {:default #js {}})
(def dialogs                #js {})
(def dismiss-keyboard       #js {})
(def image-crop-picker      #js {})
(def image-resizer          #js {})
(def svg                    #js {})
(def snoopy                 #js {})
(def snoopy-filter          #js {})
(def snoopy-bars            #js {})
(def snoopy-buffer          #js {})
(def background-timer       #js {:setTimeout (fn [cb ms] (js/setTimeout cb ms))})
(def react-navigation       (js/require "react-navigation"))
(def react-native-navigation-twopane  (js/require "react-native-navigation-twopane"))
(def react-native-shake     #js {})
(def react-native-mail      #js {:mail (fn [])})

(ns status-im.react-native.js-dependencies)

(def config                 (js/require "react-native-config"))
(def fs                     (js/require "react-native-fs"))
(def http-bridge            (js/require "react-native-http-bridge"))
(def keychain               (js/require "react-native-keychain"))
(def qr-code                (js/require "qrcode"))
(def react-native           (js/require "react-native"))
(def webview-bridge         (js/require "react-native-webview-bridge"))
(def webview                #js {:WebView #js {}})
(def EventEmmiter           #js {})
(def securerandom           (js/require "react-native-securerandom"))
(def secure-random          (.-generateSecureRandom securerandom))
(def fetch-polyfill         (js/require "react-native-fetch-polyfill"))
(def fetch                  (.-default fetch-polyfill))
(def i18n                   (js/require "i18n-js"))
(def react-native-languages (.-default (js/require "react-native-languages")))
(def desktop-linking        (.-DesktopLinking (.-NativeModules react-native)))
(def desktop-menu           (js/require "react-native-desktop-menu"))
(def desktop-config         (js/require "react-native-desktop-config"))
(def desktop-shortcuts      (js/require "react-native-desktop-shortcuts"))
(def react-native-firebase  #js {})
(def touchid                #js {})
(def camera                 #js {:default #js {:constants {:Aspect "Portrait"}}})
(def status-keycard         #js {:default #js {}})
(def dialogs                #js {})
(def dismiss-keyboard       #js {})
(def image-crop-picker      #js {})
(def image-resizer          #js {})
(def svg                    #js {})
(def snoopy                 #js {})
(def snoopy-filter          #js {})
(def snoopy-bars            #js {})
(def snoopy-buffer          #js {})
(def background-timer       #js {:setTimeout (fn [cb ms] (js/setTimeout cb ms))})
(def react-navigation       (js/require "react-navigation"))
(def react-native-navigation-twopane  (js/require "react-native-navigation-twopane"))
(def react-native-shake     #js {})
(def net-info               #js {:default #js {}})
(def react-native-mail      #js {:mail (fn [])})

Fix missing net-info in Desktop js dependencies

Signed-off-by: Pedro Pombeiro <f8c34e1c5d363d76a4b9e8313641f62c1029c3e7@users.noreply.github.com>


(ns flux-challenge-reagent.sith-lords
    (:require [reagent.core :as r]
              [ajax.core :as ajax]
              [flux-challenge-reagent.util :as util]))

;; -------------------------
;; Constant parameters
(def darth-sidious-id 3616)

;; -------------------------
;; State
(defonce coll (r/atom nil))

;; -------------------------
;; Sith Lords list
(defn sith-lord-url [id]
  (str "http://localhost:3000/dark-jedis/" id))

(defn sith-lord-item [sith-lord]
  {:id (get sith-lord "id")
   :sith-lord sith-lord})

(defn sith-lord-request-item! [id]
  (if id
    (let [url (sith-lord-url id)]
      {:id id
       :request (ajax/GET url
                          :response-format :json
                          :handler handle-sith-lord-response!)})
    nil))

(defn request-sith-lord! [coll index id]
  (if (and (>= index 0) (< index (count coll)) id (nil? (get coll index)))
    (assoc coll index (sith-lord-request-item! id))
    coll))

(defn accept-sith-lord! [coll sith-lord]
  (let [sith-lord-id (get sith-lord "id")
        sith-lord-index (util/index-of (map :id coll) sith-lord-id)]
    (-> (vec coll)
        (assoc sith-lord-index (sith-lord-item sith-lord))
        (request-sith-lord! (inc sith-lord-index) (get-in sith-lord ["apprentice" "id"]))
        (request-sith-lord! (dec sith-lord-index) (get-in sith-lord ["master" "id"])))))

(defn handle-sith-lord-response! [sith-lord]
  (swap! coll accept-sith-lord! sith-lord))

(defn abort-request! [item]
  (if-let [request (:request item)]
    (ajax/abort request)))

(defn scroll-once! [coll direction]
  (case direction
    :up (let [first-sith-lord (-> coll first :sith-lord)
              master-id (get-in first-sith-lord ["master" "id"])
              master-request (sith-lord-request-item! master-id)]
          (abort-request! (peek coll))
          (into [master-request] (pop coll)))
    :down (let [last-sith-lord (-> coll last :sith-lord)
                apprentice-id (get-in last-sith-lord ["apprentice" "id"])
                apprentice-request (sith-lord-request-item! apprentice-id)]
            (abort-request! (nth coll 0))
            (conj (subvec coll 1) apprentice-request))))

(defn scroll! [n direction]
  (swap! coll (fn [coll]
                (reduce #(scroll-once! %1 direction) coll (range n)))))

(defn init! []
  (reset! coll (request-sith-lord! (vec (repeat 5 nil)) 0 darth-sidious-id)))

(ns flux-challenge-reagent.sith-lords
    (:require [reagent.core :as r]
              [ajax.core :as ajax]
              [flux-challenge-reagent.util :as util]))

(defonce coll (r/atom (vec (repeat 5 nil))))

(defn sith-lord-url [id]
  (str "http://localhost:3000/dark-jedis/" id))

(defn sith-lord-item [sith-lord]
  {:id (get sith-lord "id")
   :sith-lord sith-lord})

(defn sith-lord-request-item! [id]
  (if id
    (let [url (sith-lord-url id)]
      {:id id
       :request (ajax/GET url
                          :response-format :json
                          :handler handle-sith-lord-response!)})
    nil))

(defn request-sith-lord! [coll index id]
  (if (and (>= index 0) (< index (count coll)) id (nil? (get coll index)))
    (assoc coll index (sith-lord-request-item! id))
    coll))

(defn accept-sith-lord! [coll sith-lord]
  (let [sith-lord-id (get sith-lord "id")
        sith-lord-index (util/index-of (map :id coll) sith-lord-id)]
    (-> (vec coll)
        (assoc sith-lord-index (sith-lord-item sith-lord))
        (request-sith-lord! (inc sith-lord-index) (get-in sith-lord ["apprentice" "id"]))
        (request-sith-lord! (dec sith-lord-index) (get-in sith-lord ["master" "id"])))))

(defn handle-sith-lord-response! [sith-lord]
  (swap! coll accept-sith-lord! sith-lord))

(defn abort-request! [item]
  (if-let [request (:request item)]
    (ajax/abort request)))

(defn scroll-once! [coll direction]
  (case direction
    :up (let [first-sith-lord (-> coll first :sith-lord)
              master-id (get-in first-sith-lord ["master" "id"])
              master-request (sith-lord-request-item! master-id)]
          (abort-request! (peek coll))
          (into [master-request] (pop coll)))
    :down (let [last-sith-lord (-> coll last :sith-lord)
                apprentice-id (get-in last-sith-lord ["apprentice" "id"])
                apprentice-request (sith-lord-request-item! apprentice-id)]
            (abort-request! (nth coll 0))
            (conj (subvec coll 1) apprentice-request))))

(defn scroll! [n direction]
  (swap! coll (fn [coll]
                (reduce #(scroll-once! %1 direction) coll (range n)))))

(defn init! []
  (let [darth-sidious-id 3616]
    (swap! coll #(request-sith-lord! % 0 darth-sidious-id))))

Refactor sith-lords init!

Refactor sith-lords init!


(ns backtype.storm.zookeeper
  (:import [com.netflix.curator.retry RetryNTimes])
  (:import [com.netflix.curator.framework.api CuratorEvent CuratorEventType CuratorListener UnhandledErrorListener])
  (:import [com.netflix.curator.framework CuratorFramework CuratorFrameworkFactory])
  (:import [org.apache.zookeeper ZooKeeper Watcher KeeperException$NoNodeException
            ZooDefs ZooDefs$Ids CreateMode WatchedEvent Watcher$Event Watcher$Event$KeeperState
            Watcher$Event$EventType KeeperException$NodeExistsException])
  (:import [org.apache.zookeeper.data Stat])
  (:import [org.apache.zookeeper.server ZooKeeperServer NIOServerCnxn$Factory])
  (:import [java.net InetSocketAddress BindException])
  (:import [java.io File])
  (:import [backtype.storm.utils Utils])
  (:use [backtype.storm util log config]))

(def zk-keeper-states
  {Watcher$Event$KeeperState/Disconnected :disconnected
   Watcher$Event$KeeperState/SyncConnected :connected
   Watcher$Event$KeeperState/AuthFailed :auth-failed
   Watcher$Event$KeeperState/Expired :expired
  })

(def zk-event-types
  {Watcher$Event$EventType/None :none
   Watcher$Event$EventType/NodeCreated :node-created
   Watcher$Event$EventType/NodeDeleted :node-deleted
   Watcher$Event$EventType/NodeDataChanged :node-data-changed
   Watcher$Event$EventType/NodeChildrenChanged :node-children-changed
  })

(defn- default-watcher [state type path]
  (log-message "Zookeeper state update: " state type path))

(defnk mk-client [conf servers port :root "" :watcher default-watcher]
  (let [fk (Utils/newCurator conf servers port root)]
    (.. fk
        (getCuratorListenable)
        (addListener
         (reify CuratorListener
           (^void eventReceived [this ^CuratorFramework _fk ^CuratorEvent e]
             (when (= (.getType e) CuratorEventType/WATCHED)
               (let [^WatchedEvent event (.getWatchedEvent e)]
                 (watcher (zk-keeper-states (.getState event))
                          (zk-event-types (.getType event))
                          (.getPath event))))))))
    (.. fk
        (getUnhandledErrorListenable)
        (addListener
         (reify UnhandledErrorListener
           (unhandledError [this msg error]
             (if (or (exception-cause? InterruptedException error)
                     (exception-cause? java.nio.channels.ClosedByInterruptException error))
               (do (log-warn-error error "Zookeeper exception " msg)
                   (let [to-throw (InterruptedException.)]
                     (.initCause to-throw error)
                     (throw to-throw)
                     ))
               (do (log-error error "Unrecoverable Zookeeper error " msg)
                   (halt-process! 1 "Unrecoverable Zookeeper error")))
             ))))
    (.start fk)
    fk))

(def zk-create-modes
  {:ephemeral CreateMode/EPHEMERAL
   :persistent CreateMode/PERSISTENT})

(defn create-node
  ([^CuratorFramework zk ^String path ^bytes data mode]
    (.. zk (create) (withMode (zk-create-modes mode)) (withACL ZooDefs$Ids/OPEN_ACL_UNSAFE) (forPath (normalize-path path) data)))
  ([^CuratorFramework zk ^String path ^bytes data]
    (create-node zk path data :persistent)))

(defn exists-node? [^CuratorFramework zk ^String path watch?]
  ((complement nil?)
    (if watch?
       (.. zk (checkExists) (watched) (forPath (normalize-path path)))
       (.. zk (checkExists) (forPath (normalize-path path))))))

(defn delete-node [^CuratorFramework zk ^String path]
  (.. zk (delete) (forPath (normalize-path path))))

(defn mkdirs [^CuratorFramework zk ^String path]
  (let [path (normalize-path path)]
    (when-not (or (= path "/") (exists-node? zk path false))
      (mkdirs zk (parent-path path))
      (try-cause
        (create-node zk path (barr 7) :persistent)
        (catch KeeperException$NodeExistsException e
          ;; this can happen when multiple clients doing mkdir at same time
          ))
      )))

(defn get-data [^CuratorFramework zk ^String path watch?]
  (let [path (normalize-path path)]
    (try-cause
      (if (exists-node? zk path watch?)
        (if watch?
          (.. zk (getData) (watched) (forPath path))
          (.. zk (getData) (forPath path))))
    (catch KeeperException$NoNodeException e
      ;; this is fine b/c we still have a watch from the successful exists call
      nil ))))

(defn get-children [^CuratorFramework zk ^String path watch?]
  (if watch?
    (.. zk (getChildren) (watched) (forPath (normalize-path path)))
    (.. zk (getChildren) (forPath (normalize-path path)))))

(defn set-data [^CuratorFramework zk ^String path ^bytes data]
  (.. zk (setData) (forPath (normalize-path path) data)))

(defn exists [^CuratorFramework zk ^String path watch?]
  (exists-node? zk path watch?))

(defn delete-recursive [^CuratorFramework zk ^String path]
  (let [path (normalize-path path)]
    (when (exists-node? zk path false)
      (let [children (try-cause (get-children zk path false)
                                (catch KeeperException$NoNodeException e
                                  []
                                  ))]
        (doseq [c children]
          (delete-recursive zk (full-path path c)))
        (try-cause (delete-node zk path)
                   (catch KeeperException$NoNodeException e
                                  nil
                                  ))
        ))))

(defnk mk-inprocess-zookeeper [localdir :port nil]
  (let [localfile (File. localdir)
        zk (ZooKeeperServer. localfile localfile 2000)
        [retport factory] (loop [retport (if port port 2000)]
                            (if-let [factory-tmp (try-cause (NIOServerCnxn$Factory. (InetSocketAddress. retport))
                                              (catch BindException e
                                                (when (> (inc retport) (if port port 65535))
                                                  (throw (RuntimeException. "No port is available to launch an inprocess zookeeper.")))))]
                              [retport factory-tmp]
                              (recur (inc retport))))]
    (log-message "Starting inprocess zookeeper at port " retport " and dir " localdir)
    (.startup factory zk)
    [retport factory]
    ))

(defn shutdown-inprocess-zookeeper [handle]
  (.shutdown handle))

(ns backtype.storm.zookeeper
  (:import [com.netflix.curator.retry RetryNTimes])
  (:import [com.netflix.curator.framework.api CuratorEvent CuratorEventType CuratorListener UnhandledErrorListener])
  (:import [com.netflix.curator.framework CuratorFramework CuratorFrameworkFactory])
  (:import [org.apache.zookeeper ZooKeeper Watcher KeeperException$NoNodeException
            ZooDefs ZooDefs$Ids CreateMode WatchedEvent Watcher$Event Watcher$Event$KeeperState
            Watcher$Event$EventType KeeperException$NodeExistsException])
  (:import [org.apache.zookeeper.data Stat])
  (:import [org.apache.zookeeper.server ZooKeeperServer NIOServerCnxn$Factory])
  (:import [java.net InetSocketAddress BindException])
  (:import [java.io File])
  (:import [backtype.storm.utils Utils])
  (:use [backtype.storm util log config]))

(def zk-keeper-states
  {Watcher$Event$KeeperState/Disconnected :disconnected
   Watcher$Event$KeeperState/SyncConnected :connected
   Watcher$Event$KeeperState/AuthFailed :auth-failed
   Watcher$Event$KeeperState/Expired :expired
  })

(def zk-event-types
  {Watcher$Event$EventType/None :none
   Watcher$Event$EventType/NodeCreated :node-created
   Watcher$Event$EventType/NodeDeleted :node-deleted
   Watcher$Event$EventType/NodeDataChanged :node-data-changed
   Watcher$Event$EventType/NodeChildrenChanged :node-children-changed
  })

(defn- default-watcher [state type path]
  (log-message "Zookeeper state update: " state type path))

(defnk mk-client [conf servers port :root "" :watcher default-watcher]
  (let [fk (Utils/newCurator conf servers port root)]
    (.. fk
        (getCuratorListenable)
        (addListener
         (reify CuratorListener
           (^void eventReceived [this ^CuratorFramework _fk ^CuratorEvent e]
             (when (= (.getType e) CuratorEventType/WATCHED)
               (let [^WatchedEvent event (.getWatchedEvent e)]
                 (watcher (zk-keeper-states (.getState event))
                          (zk-event-types (.getType event))
                          (.getPath event))))))))
    (.. fk
        (getUnhandledErrorListenable)
        (addListener
         (reify UnhandledErrorListener
           (unhandledError [this msg error]
             (if (or (exception-cause? InterruptedException error)
                     (exception-cause? java.nio.channels.ClosedByInterruptException error))
               (do (log-warn-error error "Zookeeper exception " msg)
                   (let [to-throw (InterruptedException.)]
                     (.initCause to-throw error)
                     (throw to-throw)
                     ))
               (do (log-error error "Unrecoverable Zookeeper error " msg)
                   (halt-process! 1 "Unrecoverable Zookeeper error")))
             ))))
    (.start fk)
    fk))

(def zk-create-modes
  {:ephemeral CreateMode/EPHEMERAL
   :persistent CreateMode/PERSISTENT})

(defn create-node
  ([^CuratorFramework zk ^String path ^bytes data mode]
    (.. zk (create) (withMode (zk-create-modes mode)) (withACL ZooDefs$Ids/OPEN_ACL_UNSAFE) (forPath (normalize-path path) data)))
  ([^CuratorFramework zk ^String path ^bytes data]
    (create-node zk path data :persistent)))

(defn exists-node? [^CuratorFramework zk ^String path watch?]
  ((complement nil?)
    (if watch?
       (.. zk (checkExists) (watched) (forPath (normalize-path path)))
       (.. zk (checkExists) (forPath (normalize-path path))))))

(defnk delete-node [^CuratorFramework zk ^String path :force false]
  (try-cause  (.. zk (delete) (forPath (normalize-path path)))
    (catch KeeperException$NoNodeException e
      (when-not force (throw e))
      )))

(defn mkdirs [^CuratorFramework zk ^String path]
  (let [path (normalize-path path)]
    (when-not (or (= path "/") (exists-node? zk path false))
      (mkdirs zk (parent-path path))
      (try-cause
        (create-node zk path (barr 7) :persistent)
        (catch KeeperException$NodeExistsException e
          ;; this can happen when multiple clients doing mkdir at same time
          ))
      )))

(defn get-data [^CuratorFramework zk ^String path watch?]
  (let [path (normalize-path path)]
    (try-cause
      (if (exists-node? zk path watch?)
        (if watch?
          (.. zk (getData) (watched) (forPath path))
          (.. zk (getData) (forPath path))))
    (catch KeeperException$NoNodeException e
      ;; this is fine b/c we still have a watch from the successful exists call
      nil ))))

(defn get-children [^CuratorFramework zk ^String path watch?]
  (if watch?
    (.. zk (getChildren) (watched) (forPath (normalize-path path)))
    (.. zk (getChildren) (forPath (normalize-path path)))))

(defn set-data [^CuratorFramework zk ^String path ^bytes data]
  (.. zk (setData) (forPath (normalize-path path) data)))

(defn exists [^CuratorFramework zk ^String path watch?]
  (exists-node? zk path watch?))

(defn delete-recursive [^CuratorFramework zk ^String path]
  (let [path (normalize-path path)]
    (when (exists-node? zk path false)
      (let [children (try-cause (get-children zk path false)
                                (catch KeeperException$NoNodeException e
                                  []
                                  ))]
        (doseq [c children]
          (delete-recursive zk (full-path path c)))
        (delete-node zk path :force true)
        ))))

(defnk mk-inprocess-zookeeper [localdir :port nil]
  (let [localfile (File. localdir)
        zk (ZooKeeperServer. localfile localfile 2000)
        [retport factory] (loop [retport (if port port 2000)]
                            (if-let [factory-tmp (try-cause (NIOServerCnxn$Factory. (InetSocketAddress. retport))
                                              (catch BindException e
                                                (when (> (inc retport) (if port port 65535))
                                                  (throw (RuntimeException. "No port is available to launch an inprocess zookeeper.")))))]
                              [retport factory-tmp]
                              (recur (inc retport))))]
    (log-message "Starting inprocess zookeeper at port " retport " and dir " localdir)
    (.startup factory zk)
    [retport factory]
    ))

(defn shutdown-inprocess-zookeeper [handle]
  (.shutdown handle))

refactor delete-node in zk code

refactor delete-node in zk code


(ns parkour.io.transient
  (:require [pjstadig.scopes :as s]
            [parkour (conf :as conf) (fs :as fs)]
            [parkour.util :as util :refer [ignore-errors doto-let]]))

(defonce
  ^{:private true
    :doc "Process-wide run identifier for transient FS entries."}
  run-id
  (str (util/run-id) "-parkour-transient"))

(defn ^:private transient-root
  "Transient path root directory, as specified by `conf` if provided."
  ([] (transient-root (conf/ig)))
  ([conf]
     (or (conf/get conf "parkour.transient.dir")
         (fs/path (fs/temp-root conf) run-id))))

(defn transient-path
  "Return new unique transient path, which will be deleted on process exit or
when leaving the current resource scope.  If `p` is provided and not `nil`,
should be a path, and returned path will have the same path name.  If `conf` is
provided, it will be used to determine the transient path root directory."
  ([] (transient-path nil))
  ([p] (transient-path (conf/ig) p))
  ([conf p]
     (let [root (transient-root conf), fs (fs/path-fs conf root)
           tbase (fs/path root (name (gensym "t-")))
           tpath (cond-> tbase p (fs/path (-> p fs/path .getName)))]
       (.mkdirs fs root)
       (.deleteOnExit fs root)
       (when (bound? #'s/*resources*)
         (s/scoped! tbase #(ignore-errors (fs/path-delete fs %))))
       tpath)))

(ns parkour.io.transient
  (:require [pjstadig.scopes :as s]
            [parkour (conf :as conf) (fs :as fs)]
            [parkour.util :as util :refer [ignore-errors doto-let]])
  (:import [org.apache.hadoop.fs Path]))

(defonce
  ^{:private true
    :doc "Process-wide run identifier for transient FS entries."}
  run-id
  (str (util/run-id) "-parkour-transient"))

(defn ^:private transient-root
  "Transient path root directory, as specified by `conf` if provided."
  {:tag `Path}
  ([] (transient-root (conf/ig)))
  ([conf]
     (-> (or (conf/get conf "parkour.transient.dir")
             (fs/path (fs/temp-root conf) run-id))
         (fs/path))))

(defn transient-path
  "Return new unique transient path, which will be deleted on process exit or
when leaving the current resource scope.  If `p` is provided and not `nil`,
should be a path, and returned path will have the same path name.  If `conf` is
provided, it will be used to determine the transient path root directory."
  ([] (transient-path nil))
  ([p] (transient-path (conf/ig) p))
  ([conf p]
     (let [root (transient-root conf), fs (fs/path-fs conf root)
           tbase (fs/path root (name (gensym "t-")))
           tpath (cond-> tbase p (fs/path (-> p fs/path .getName)))]
       (.mkdirs fs root)
       (.deleteOnExit fs root)
       (when (bound? #'s/*resources*)
         (s/scoped! tbase #(ignore-errors (fs/path-delete fs %))))
       tpath)))

Handle the transient path root slightly more defensively.


(ns parkour.remote.basic
  {:private true}
  (:require [clojure.string :as str]
            [clojure.edn :as edn]
            [clojure.tools.logging :as log]
            [parkour (conf :as conf) (mapreduce :as mr) (wrapper :as w)])
  (:import [clojure.lang IFn$OOLL]
           [org.apache.hadoop.mapreduce MapContext]))

(defn require-readers
  "Require the namespaces of all `*data-readers*` vars."
  [] (doseq [[_ v] *data-readers*] (-> v .-ns ns-name require)))

(defn step-v-args
  ([conf key]
     (let [fqname (conf/get conf (str "parkour." key ".var"))
           [ns sym] (str/split fqname #"/" 2)
           ns (symbol (if-not (.startsWith ^String ns "#'") ns (subs ns 2)))
           v (do (require ns) (ns-resolve ns (symbol sym)))
           args (do (require-readers)
                    (some->> (conf/get conf (str "parkour." key ".args"))
                             (edn/read-string {:readers *data-readers*})))]
       [v args]))
  ([conf kind id]
     (step-v-args conf (str kind "." id))))

(defn raw?
  "True iff `v` is a raw task function-var."
  [v] (-> v meta ::mr/raw))

(defn task-transformer
  "Adapter for basic collection-transformation task."
  [f] (fn [context] (->> context w/unwrap (f context) (mr/sink context))))

(defn task-partitioner
  "Adapter for basic partitioning functions."
  [f]
  (if (instance? IFn$OOLL f)
    (fn ^long [key val ^long nparts]
      (let [key (w/unwrap key), val (w/unwrap val)]
        (.invokePrim ^IFn$OOLL f key val nparts)))
    (fn ^long [key val ^long nparts]
      (let [key (w/unwrap key), val (w/unwrap val)]
        (f key val nparts)))))

(defn task-fn
  "Return full task-function for function-var `v`, configuration `conf`, and
arguments `args`.  Wrap with `wrap`, unless `v` is a raw task function."
  [wrap v conf args] (cond-> (apply v conf args) (not (raw? v)) (wrap)))

(defn mapper-run
  [id context]
  (let [conf (doto (conf/ig context)
               (conf/assoc! "parkour.step" "map"))
        [v args] (step-v-args conf "mapper" id)
        split (.getInputSplit ^MapContext context)]
    (log/infof "mapper: split=%s, var=%s, args=%s"
               (pr-str split) (pr-str v) (pr-str args))
    (conf/with-default conf
      ((task-fn task-transformer v conf args) context))))

(defn reducer-run
  [id context]
  (let [step (conf/get context (str "parkour.reducer." id ".step"))
        conf (doto (conf/ig context)
               (conf/assoc! "parkour.step" step))
        [v args] (step-v-args conf "reducer" id)]
    (log/infof "reducer: var=%s, args=%s" (pr-str v) (pr-str args))
    (conf/with-default conf
      ((task-fn task-transformer v conf args) context))))

(defn partitioner-set-conf
  [conf]
  (let [[v args] (step-v-args conf "partitioner")]
    (log/infof "partitioner: var=%s, args=%s" (pr-str v) (pr-str args))
    (conf/with-default conf
      (task-fn task-partitioner v conf args))))

(ns parkour.remote.basic
  {:private true}
  (:require [clojure.string :as str]
            [clojure.edn :as edn]
            [clojure.tools.logging :as log]
            [parkour (conf :as conf) (mapreduce :as mr) (wrapper :as w)])
  (:import [clojure.lang IFn$OOLL Var]
           [org.apache.hadoop.mapreduce MapContext]))

(defn require-readers
  "Require the namespaces of all `*data-readers*` vars."
  [] (doseq [[_ ^Var v] *data-readers*] (-> v .-ns ns-name require)))

(defn step-v-args
  ([conf key]
     (let [fqname (conf/get conf (str "parkour." key ".var"))
           [ns sym] (str/split fqname #"/" 2)
           ns (symbol (if-not (.startsWith ^String ns "#'") ns (subs ns 2)))
           v (do (require ns) (ns-resolve ns (symbol sym)))
           args (do (require-readers)
                    (some->> (conf/get conf (str "parkour." key ".args"))
                             (edn/read-string {:readers *data-readers*})))]
       [v args]))
  ([conf kind id]
     (step-v-args conf (str kind "." id))))

(defn raw?
  "True iff `v` is a raw task function-var."
  [v] (-> v meta ::mr/raw))

(defn task-transformer
  "Adapter for basic collection-transformation task."
  [f] (fn [context] (->> context w/unwrap (f context) (mr/sink context))))

(defn task-partitioner
  "Adapter for basic partitioning functions."
  [f]
  (if (instance? IFn$OOLL f)
    (fn ^long [key val ^long nparts]
      (let [key (w/unwrap key), val (w/unwrap val)]
        (.invokePrim ^IFn$OOLL f key val nparts)))
    (fn ^long [key val ^long nparts]
      (let [key (w/unwrap key), val (w/unwrap val)]
        (f key val nparts)))))

(defn task-fn
  "Return full task-function for function-var `v`, configuration `conf`, and
arguments `args`.  Wrap with `wrap`, unless `v` is a raw task function."
  [wrap v conf args] (cond-> (apply v conf args) (not (raw? v)) (wrap)))

(defn mapper-run
  [id context]
  (let [conf (doto (conf/ig context)
               (conf/assoc! "parkour.step" "map"))
        [v args] (step-v-args conf "mapper" id)
        split (.getInputSplit ^MapContext context)]
    (log/infof "mapper: split=%s, var=%s, args=%s"
               (pr-str split) (pr-str v) (pr-str args))
    (conf/with-default conf
      ((task-fn task-transformer v conf args) context))))

(defn reducer-run
  [id context]
  (let [step (conf/get context (str "parkour.reducer." id ".step"))
        conf (doto (conf/ig context)
               (conf/assoc! "parkour.step" step))
        [v args] (step-v-args conf "reducer" id)]
    (log/infof "reducer: var=%s, args=%s" (pr-str v) (pr-str args))
    (conf/with-default conf
      ((task-fn task-transformer v conf args) context))))

(defn partitioner-set-conf
  [conf]
  (let [[v args] (step-v-args conf "partitioner")]
    (log/infof "partitioner: var=%s, args=%s" (pr-str v) (pr-str args))
    (conf/with-default conf
      (task-fn task-partitioner v conf args))))

Fix unnecessary reflection.

Fix unnecessary reflection.