(PDB-4504) Use batched inserts

(PDB-4504) Use batched inserts

Port of puppetlabs/puppetdb#3074 to partitioning work

--- src/puppetlabs/puppetdb/scf/migrate.clj
+++ src/puppetlabs/puppetdb/scf/migrate.clj
@@ -1596,48 +1596,51 @@
    "ALTER TABLE certnames SET ( autovacuum_vacuum_scale_factor=0.75 )"
    "ALTER TABLE reports   SET ( autovacuum_vacuum_scale_factor=0.01 )"))

-(defn reporting-partitioned-tables []
-  (jdbc/do-commands
-   "ALTER TABLE resource_events RENAME TO resource_events_premigrate"
-
-   "CREATE TABLE resource_events (
-      event_hash bytea NOT NULL PRIMARY KEY,
-      report_id bigint NOT NULL,
-      certname_id bigint NOT NULL,
-      status text NOT NULL,
-      \"timestamp\" timestamp with time zone NOT NULL,
-      resource_type text NOT NULL,
-      resource_title text NOT NULL,
-      property text,
-      new_value text,
-      old_value text,
-      message text,
-      file text DEFAULT NULL::character varying,
-      line integer,
-      name text,
-      containment_path text[],
-      containing_class text,
-      corrective_change boolean)"
-
-   "CREATE OR REPLACE FUNCTION resource_events_insert_trigger()
-   RETURNS TRIGGER AS $$
-   DECLARE
-     tablename varchar;
-   BEGIN
-     SELECT FORMAT('resource_events_%sZ',
-                   TO_CHAR(NEW.\"timestamp\" AT TIME ZONE 'UTC', 'YYYYMMDD')) INTO tablename;
-
-     EXECUTE 'INSERT INTO ' || tablename || ' SELECT ($1).*'
-     USING NEW;
-
-     RETURN NULL;
-   END;
-   $$
-   LANGUAGE plpgsql;"
-
-   "CREATE TRIGGER insert_resource_events_trigger
-   BEFORE INSERT ON resource_events
-   FOR EACH ROW EXECUTE PROCEDURE resource_events_insert_trigger();")
+(defn reporting-partitioned-tables
+  ([]
+   (reporting-partitioned-tables 1000))
+  ([batch-size]
+   (jdbc/do-commands
+    "ALTER TABLE resource_events RENAME TO resource_events_premigrate"
+
+    "CREATE TABLE resource_events (
+       event_hash bytea NOT NULL PRIMARY KEY,
+       report_id bigint NOT NULL,
+       certname_id bigint NOT NULL,
+       status text NOT NULL,
+       \"timestamp\" timestamp with time zone NOT NULL,
+       resource_type text NOT NULL,
+       resource_title text NOT NULL,
+       property text,
+       new_value text,
+       old_value text,
+       message text,
+       file text DEFAULT NULL::character varying,
+       line integer,
+       name text,
+       containment_path text[],
+       containing_class text,
+       corrective_change boolean)"
+
+    "CREATE OR REPLACE FUNCTION resource_events_insert_trigger()
+    RETURNS TRIGGER AS $$
+    DECLARE
+      tablename varchar;
+    BEGIN
+      SELECT FORMAT('resource_events_%sZ',
+                    TO_CHAR(NEW.\"timestamp\" AT TIME ZONE 'UTC', 'YYYYMMDD')) INTO tablename;
+
+      EXECUTE 'INSERT INTO ' || tablename || ' SELECT ($1).*'
+      USING NEW;
+
+      RETURN NULL;
+    END;
+    $$
+    LANGUAGE plpgsql;"
+
+    "CREATE TRIGGER insert_resource_events_trigger
+    BEFORE INSERT ON resource_events
+    FOR EACH ROW EXECUTE PROCEDURE resource_events_insert_trigger();")

   ;; create range of partitioned tables

@@ -1659,38 +1662,57 @@

   (let [event-count (-> "select count(*) from resource_events_premigrate"
                         jdbc/query-to-vec first :count)
-        last-logged (atom (.getTime (java.util.Date.)))]
+        last-logged (atom (.getTime (java.util.Date.)))
+        events-migrated (atom 0)]
    (jdbc/call-with-query-rows
     ["select
-       report_id, certname_id, status, \"timestamp\", resource_type, resource_title, property,
-       new_value, old_value, message, file, line, containment_path, containing_class, corrective_change
-     from resource_events_premigrate"]
-   (fn [rows]
-     (doseq [date (set (map #(-> ^Timestamp (:timestamp %)
-                                 (.toInstant)
-                                 (ZonedDateTime/ofInstant (ZoneId/of "UTC"))
-                                 (.truncatedTo (ChronoUnit/DAYS))) rows))]
-       (partitioning/create-resource-events-partition date))
-     (reduce (fn [hashes-seen [row i]]
-               (let [now (.getTime (java.util.Date.))]
-                 (when (> (- now @last-logged) 60000)
-                   (maplog :info
-                           {:migration 69 :at i :of event-count}
-                           #(trs "Migrated {0} of {1} events" (:at %) (:of %)))
-                   (reset! last-logged now)))
-               (conj hashes-seen
-                     (let [hash-str (hash/resource-event-identity-pkey row)]
-                       (when-not (hashes-seen hash-str)
-                         (jdbc/insert-multi! "resource_events"
-                                             (list (assoc row :event_hash
-                                                              (sutils/munge-hash-for-storage hash-str)))))
-                       hash-str)))
-             #{}
-             (map vector rows (range event-count))))))
+        report_id, certname_id, status, \"timestamp\", resource_type, resource_title, property,
+        new_value, old_value, message, file, line, containment_path, containing_class, corrective_change
+      from resource_events_premigrate"]
+    (fn [rows]
+      (let [old-cols [:report_id :certname_id :status :timestamp :resource_type
+                      :resource_title :property :new_value :old_value :message
+                      :file :line :containment_path :containing_class
+                      :corrective_change]
+            new-cols (into [:event_hash] old-cols)
+            update-row (apply juxt (comp sutils/munge-hash-for-storage
+                                         hash/resource-event-identity-pkey)
+                              old-cols)
+            ;; Retrieve event_hash string from PGobject produced by sutils
+            row->id (fn [row] (-> row first .getValue))
+            insert->hash (fn [batch]
+                           (when (seq batch)
+                             (jdbc/insert-multi! :resource_events
+                                                 new-cols
+                                                 batch))
+                           (let [now (.getTime (java.util.Date.))]
+                             (when (> (- now @last-logged) 60000)
+                               (maplog :info
+                                       {:migration 73 :at @events-migrated :of event-count}
+                                       #(trs "Migrated {0} of {1} events" (:at %) (:of %)))
+                               (reset! last-logged now)))
+                           ;; Return hashes for each row directly instead of
+                           ;; reading them back from the DB via the return
+                           ;; value of insert-multi!
+                           (map row->id batch))
+            dedupe-and-insert (fn [hashes-seen batch]
+                                (swap! events-migrated + (count batch))
+                                (->> batch
+                                     (map update-row)
+                                     ;; Remove any duplicates in current batch
+                                     (group-by row->id)
+                                     (map (comp first last))
+                                     ;; Remove any duplicates in previous batches
+                                     (filter #(-> % row->id hashes-seen nil?))
+                                     insert->hash
+                                     (reduce conj hashes-seen)))]
+        (reduce dedupe-and-insert
+                #{}
+                (partition batch-size batch-size [] rows))))))

   (jdbc/do-commands
    ;; Indexes are created on the individual partitions, not on the base table
-   "DROP TABLE resource_events_premigrate"))
+   "DROP TABLE resource_events_premigrate")))

 (def migrations
   "The available migrations, as a map from migration version to migration function."


(PDB-3600) time migration execution

(PDB-3600) time migration execution

Time migrations and log them to make testing/support awareness easier.

--- src/puppetlabs/puppetdb/scf/migrate.clj
+++ src/puppetlabs/puppetdb/scf/migrate.clj
@@ -59,7 +59,7 @@
             [puppetlabs.puppetdb.scf.storage-utils :as sutils]
             [clojure.set :refer :all]
             [puppetlabs.puppetdb.time :refer [to-timestamp]]
-            [clj-time.core :refer [now]]
+            [clj-time.core :refer [now interval in-millis]]
             [puppetlabs.puppetdb.jdbc :as jdbc :refer [query-to-vec]]
             [puppetlabs.puppetdb.config :as conf]
             [puppetlabs.i18n.core :refer [trs]]
@@ -1612,10 +1612,13 @@
       (let [tables-to-analyze (jdbc/with-db-transaction []
                                 (->> pending
                                      (map (fn [[version migration]]
+                                            (let [t0 (now)]
                                             (log/info (trs "Applying database migration version {0}" version))
                                             (sql-or-die (fn [] (let [result (migration)]
                                                                     (record-migration! version)
-                                                                    result)))))
+                                                                    result)))
+                                            (log/info (trs "Applied database migration version {0} in {1} ms"
+                                                           version (in-millis (interval t0 (now))))))))
                                      (filter map?)
                                      (map ::vacuum-analyze)
                                      (apply set/union small-tables)


Clear command.

Clear command.

--- src/mash_commander/nix/filesystem.cljs
+++ src/mash_commander/nix/filesystem.cljs
@@ -2,6 +2,7 @@
   (:require [clojure.string :as str]
             [mash-commander.state :as state]
             [mash-commander.trie :as trie]
+            [mash-commander.mode :as mode]
             [om.core :as om :include-macros true]))

 (defn fs-cursor []
@@ -23,6 +24,14 @@
       (om/transact! (fs-cursor) #(assoc % :cwd new-cwd))))
   nil)

+(defn clear []
+  (om/transact!
+   (state/lines)
+   #(as-> % c
+      (assoc-in c [:history] [])
+      (assoc-in c [:active] (mode/initial-line-state {:mode :nix}))))
+  nil)
+
 (defn init []
   (om/update!
    (fs-cursor)
@@ -37,7 +46,11 @@
                                   "cd" {:mod #{:x}
                                         :type :file
                                         :fn cd
-                                        :args [:file]}}}
+                                        :args [:file]}
+                                  "clear" {:mod #{:x}
+                                           :type :file
+                                           :fn clear
+                                           :args []}}}
                    "usr" {:mod #{:r}
                           :type :dir
                           :files {}}}}


fixed a couple bugs

fixed a couple bugs

--- src/strictly_specking/context_print.clj
+++ src/strictly_specking/context_print.clj
@@ -70,20 +70,21 @@

 (defn blank-space-trim [formatted-lines]
   (let [min-lead (min-blank-lead formatted-lines)]
-    (when (> min-lead 6)
+    (if (> min-lead 6)
       (let [subtract-lead (- min-lead 6)]
         (map (fn [[t l b]]
                [t l (if (string/blank? b)
                       b
                       (subs b subtract-lead))])
-             formatted-lines)))))
+             formatted-lines)))
+    formatted-lines))

 (defn format-line-numbers [formatted-lines]
   (let [max-char-length (+ 2 (count (str (max-line-number formatted-lines))))]
     (map
      (fn [[t l b]]
        [t
-        (if (#{:line :error-line} t)
+        (if (and (#{:line :error-line} t) (integer? l))
           (format (str "%" max-char-length "d ") l)
           (str (blanks (inc max-char-length))))
         b])
@@ -141,13 +142,15 @@
       blank-space-trim
       format-line-numbers
       color-lines
-      print-formatted-lines))
+      print-formatted-lines
+      ))

 #_(print-message-in-context-of-file "project.clj" 35 28 "here I am" )

 #_(-> (fetch-lines "project.clj")
       number-lines
       (insert-message 35 28 "here I am \nonce again \nonce again  \nonce again again")
+      (insert-missing-keys [:asdf :ASDFG] 35 28)
       (extract-range-from-center 35 10)
       blank-space-trim
       format-line-numbers


added a parser-state arg to parser hook function. added a hof arg to the parser to handle to computing of the value to be returned by the parser

--- src/paredit/parser.clj
+++ src/paredit/parser.clj
@@ -63,25 +63,29 @@
   [stop-offset]
   (fn stop-offset-based-parser-hook
   ; todo : later on, move offset+line+col+parents inside a proper deftyped type
-    [#^String text offset line col parents hook-state]
-    [(< offset stop-offset)
-    { :parents parents :offset offset :line line :col col }]))
+    [#^String text offset line col parents parser-state hook-state]
+    [(< offset stop-offset) nil]))
+
+(defn default-parser-result-maker
+  [#^String text offset line col parents parser-state hook-state]
+  { :parents parents :offset offset :line line :col col })

 (defn parse
 	"TODO: currently the parser assumes a well formed document ... Define a policy if the parser encounters and invalid text
 	 TODO: make the parser restartable at a given offset given a state ...
 	 TODO: make the parser fully incremental (via chunks of any possible size ...)"
-  ([#^String text] (parse text (make-stop-offset-based-parser-hook (.length text)) nil))
-  ([#^String text stop-offset] (parse text (make-stop-offset-based-parser-hook stop-offset) nil))
-	([#^String text parser-hook hook-state]
+  ([#^String text] (parse text (.length text)))
+  ([#^String text stop-offset] (parse text nil (make-stop-offset-based-parser-hook stop-offset) default-parser-result-maker))
+	([#^String text initial-hook-state parser-hook parser-result-maker]
 	  (loop [offset  (int 0)
 	         line    (int 0)
 	         col     (int 0)
 	         parents [{:type nil :offset 0 :line 0 :col 0}]
-	         hook-state hook-state]
-	      (let [[continue? hook-state] (parser-hook text offset line col parents hook-state)]
-  	      (if (or (not continue?) (>= offset (.length text)))
-  	        hook-state
+	         hook-state initial-hook-state]
+	      (let [parser-state (if (>= offset (.length text)) :eof :ok) ; TODO soon an additional :parser-error state !
+	            [continue? hook-state] (parser-hook text offset line col parents parser-state hook-state)]
+  	      (if (or (not continue?) (= :eof parser-state))
+  	        (parser-result-maker text offset line col parents parser-state hook-state)
   	        (let [c (.charAt text offset)] ; c: current char
   	          (condp = (-> parents peek :type)
   	            \"


Debugging code when problems with edit-buffer function

--- src/paredit/parser.clj
+++ src/paredit/parser.clj
@@ -339,6 +339,7 @@
     ))

 (defn edit-buffer [buffer offset len text]
+  ;(println (str "------- edit buffer:" " offset=" offset ", len=" len ", text='" text "'"))
   (let [text (or text "")]
     (if (= [0 -1] [offset len])
       (p/edit (p/incremental-buffer sexp) 0 0 text)


fine tuning

fine tuning

--- src/lights/my_show.clj
+++ src/lights/my_show.clj
@@ -558,11 +558,11 @@
         (oscillators/sawtooth-beat :beat-ratio :osc-beat-ratio :down? true) :min :lightness-min-general :max :lightness-max-front)]
     (ct/set-cue! (:cue-grid *show*) 2 2
       (cues/cue :color  (fn [_] (afterglow.effects/scene
-        "Sawtooth Back & Front 1"
+        "Sawtooth Back & Front"
           (afterglow.effects.color/color-effect
             "Back" (params/build-color-param :h :main-hue :s 100 :l light-param-back) (show/fixtures-named "back"))
           (afterglow.effects.color/color-effect
-            "Bass" (params/build-color-param :h :main-hue :s 100 :l light-param-front) (show/fixtures-named "front"))
+            "Front" (params/build-color-param :h :main-hue :s 100 :l light-param-front) (show/fixtures-named "front"))
       )))))

   (ct/set-cue! (:cue-grid *show*) 1 2


six event-monitor-timer print messages

six event-monitor-timer print messages

--- src/overtone/libs/event.clj
+++ src/overtone/libs/event.clj
@@ -164,9 +164,9 @@
      (loop [i seconds]
        (when (and @monitoring?* (pos? i))
          (println (str "Event monitor activated for "
-                       (- seconds i)
+                       i
                        " more second"
-                       (when (> (- seconds i) 1)
+                       (when (> i 1)
                          "s")))
          (Thread/sleep 1000)
          (recur (dec i))))


Added test for generator overrides.

Added test for generator overrides.

--- test/blutwurst/tuple_generator_test.clj
+++ test/blutwurst/tuple_generator_test.clj
@@ -78,3 +78,18 @@
      (is (= expected (retrieve-registered-generators)))
    ))
  ))
+
+(deftest generator-overrides
+ (testing "Generator override is used."
+   (with-redefs [blutwurst.tuple-generator/value-generation-strategies fixed-generators]
+    (let [spec {:column-generator-overrides (list {:column-pattern "^ID$" :generator-name "Random Decimal Generator"})
+                :number-of-rows 5}
+          tables '({
+                          :name "Destination"
+                          :schema "foo"
+                          :columns ({:name "Address1" :type "VARCHAR" :length 20 :nullable false}
+                                     {:name "ID" :type "INTEGER" :length 3 :nullable true})
+                          })]
+      (is (= `({:table ~(first tables) :tuples ~(repeat 5 {:Address1 "asdf" :ID 1.7})})
+              (generate-tuples-for-plan spec tables)))
+    ))))


tweak bb script

tweak bb script

--- bin/bb-test-runner.clj
+++ bin/bb-test-runner.clj
@@ -1,4 +1,4 @@
-#!/usr/bin/env bb --debug
+#!/usr/bin/env bb
 (ns bb-test-runner
   (:require [clojure.test :as t]
             [babashka.classpath :as cp]))


Update catacumba-prone dependency in the debugging example.

--- profiles.clj
+++ profiles.clj
@@ -73,7 +73,7 @@

  :debugging-example
  [:examples
-  {:dependencies [[funcool/catacumba-prone "0.3.0"]]
+  {:dependencies [[funcool/catacumba-prone "0.4.0"]]
    :source-paths ["examples/debugging/src"]
    :resource-paths ["examples/debugging/resources"]
    :main ^:skip-aot debugging.core}]


Bump lein deps

Bump lein deps

--- etc/lein/profiles.clj
+++ etc/lein/profiles.clj
@@ -1,10 +1,10 @@
 {:repl {:dependencies [^:displace [org.clojure/clojure "1.10.1"]
                        [com.cemerick/pomegranate "1.1.0"]
                        [lambdaisland/kaocha "0.0-554"]
-                       [org.clojure/tools.namespace "0.3.1"]]
+                       [nrepl "0.6.0"]
+                       [org.clojure/tools.namespace "0.3.2-SNAPSHOT"]]
         :repl-options {:color false}}
  :user {:dependencies [^:displace [org.clojure/clojure "1.10.1"]
-                       [cljfmt "0.6.4"]]
-        :plugins [[lein-cljfmt "0.6.4"]
-                  [lein-cloverage "1.1.1"]
+                       [cljfmt "0.6.6"]]
+        :plugins [[lein-cljfmt "0.6.6"]
                   [lein-ancient "0.6.15"]]}}


Rename arg to attr

Rename arg to attr

--- src/piper/template.clj
+++ src/piper/template.clj
@@ -51,12 +51,12 @@
               "
               tags             = (tag | close-tag | closed-tag | text)*
               close-tag        = <'</'> name <'>'>
-              closed-tag       = <'<'> name arg* <'/>'>
-              tag              = <'<'> name arg* <'>'>
-              arg              = arg-with-value | arg-no-value
-              arg-with-value   = name <'='> arg-value
-              arg-no-value     = name
-              arg-value        = <quote> #'[^\"]*' <quote>
+              closed-tag       = <'<'> name attr* <'/>'>
+              tag              = <'<'> name attr* <'>'>
+              attr              = attr-with-value | attr-no-value
+              attr-with-value   = name <'='> attr-value
+              attr-no-value     = name
+              attr-value        = <quote> #'[^\"]*' <quote>
               quote            = #'\"'
               name             = #'[a-zA-Z0-9!-]+'
               text             = #'[^<]*'
@@ -66,13 +66,13 @@

 (defrecord Fragment [src primary? async? fallback-src])

-(defun arg-to-string
+(defun attr-to-string
        ([{:name name :value nil}] name)
        ([{:name name :value value}] (str name "=\"" value "\"")))

-(defn args-to-string [args]
-  (->> args
-       (map (fn [arg] (arg-to-string arg)))
+(defn attrs-to-string [attrs]
+  (->> attrs
+       (map (fn [attr] (attr-to-string attr)))
        (str/join " ")))

 (defn add-leading-space [s]
@@ -80,8 +80,8 @@
     s
     (str " " s)))

-(def args [{:name "n1" :value "v1"} {:name "n3" :value nil} {:name "n2" :value "v2"}])
-(args-to-string args)
+(def attrs [{:name "n1" :value "v1"} {:name "n3" :value nil} {:name "n2" :value "v2"}])
+(attrs-to-string attrs)

 (comment
   (parser "<hello>")
@@ -90,27 +90,27 @@
   (parser "<hello>world >>> xx bb</hello>")
   (parser template)
   (parser template-1)
-  (let [nodes (tr/transform {:tags           (fun ([& rest] rest))
-                             :close-tag      (fun
-                                               ([[:name "fragment"]]
-                                                 nil)
-                                               ([[:name close-tag-name]]
-                                                 [:text (str "</" close-tag-name ">")]))
-                             :arg            (fn [arg] arg)
-                             :arg-with-value (fun ([[:name name] [:arg-value arg-value]] {:name  name
-                                                                                :value arg-value}))
-                             :arg-no-value   (fun ([[:name name]] {:name  name
-                                                                   :value nil}))
-                             :tag            (fun ([[:name "slot"] & args] {:slot (into {} args)})
-                                                  ([[:name "fragment"] & args] {:fragment (into {} args)})
-                                                  ([[:name tag-name] & args]
-                                                    [:text (str "<" tag-name (add-leading-space
-                                                                               (args-to-string args)) ">")]))
-                             :closed-tag     (fun ([[:name "slot"] & args] {:slot (into {} args)})
-                                                  ([[:name "fragment"] & args] {:fragment (into {} args)})
-                                                  ([[:name tag-name] & args]
-                                                    [:text (str "<" tag-name (add-leading-space
-                                                                               (args-to-string args)) "/>")]))
+  (let [nodes (tr/transform {:tags            (fun ([& rest] rest))
+                             :close-tag       (fun
+                                                ([[:name "fragment"]]
+                                                  nil)
+                                                ([[:name close-tag-name]]
+                                                  [:text (str "</" close-tag-name ">")]))
+                             :attr            (fn [attr] attr)
+                             :attr-with-value (fun ([[:name name] [:attr-value attr-value]] {:name  name
+                                                                                :value attr-value}))
+                             :attr-no-value   (fun ([[:name name]] {:name  name
+                                                                    :value nil}))
+                             :tag             (fun ([[:name "slot"] & attrs] {:slot (into {} attrs)})
+                                                   ([[:name "fragment"] & attrs] {:fragment (into {} attrs)})
+                                                   ([[:name tag-name] & attrs]
+                                                     [:text (str "<" tag-name (add-leading-space
+                                                                                (attrs-to-string attrs)) ">")]))
+                             :closed-tag      (fun ([[:name "slot"] & attrs] {:slot (into {} attrs)})
+                                                   ([[:name "fragment"] & attrs] {:fragment (into {} attrs)})
+                                                   ([[:name tag-name] & attrs]
+                                                     [:text (str "<" tag-name (add-leading-space
+                                                                                (attrs-to-string attrs)) "/>")]))
                              }
                             (parser template-1))]


Better names for entry API funtions.

Better names for entry API funtions.

--- src/oc/storage/api/entries.clj
+++ src/oc/storage/api/entries.clj
@@ -334,14 +334,14 @@

     (do (timbre/error "Failed updating entry:" entry-for) false)))

-(defn- update-entry-new [conn ctx entry-for action-type]
+(defn- update-user-visibility [conn ctx entry-for action-type]
   (timbre/info "Updating entry for:" entry-for)
   (if-let* [org (:existing-org ctx)
             board (:existing-board ctx)
             user (:user ctx)
             entry (:existing-entry ctx)
             updated-entry (:updated-entry ctx)
-            final-entry (entry-res/update-entry! conn (:uuid updated-entry) updated-entry user)]
+            final-entry (entry-res/update-entry-no-user! conn (:uuid updated-entry) updated-entry)]
     (let [notify-map* {:client-id (api-common/get-change-client-id ctx)}
           notify-map (cond
                       (= action-type :dismiss)
@@ -356,14 +356,14 @@

     (do (timbre/error "Failed updating entry:" entry-for) false)))

-(defn- update-entry-dismiss-all [conn ctx entry-for]
+(defn- update-user-visibility-dismiss-all [conn ctx entry-for]
   (timbre/info "Dismiss all entries for:" entry-for ". Dismissing" (count (:updated-entries ctx)) "entries:" (map :uuid (:updated-entries ctx)))
   (if-let* [org (:existing-org ctx)
             user (:user ctx)
             existing-entries (:existing-entries ctx)
             updated-entries (:updated-entries ctx)
             final-entries (map
-                            #(entry-res/update-entry! conn (:uuid %) % user)
+                            #(entry-res/update-entry-no-user! conn (:uuid %) %)
                             updated-entries)]
     (if (every? #(lib-schema/valid? common-res/Entry %) final-entries)
       (let [notify-map {:client-id (api-common/get-change-client-id ctx)
@@ -1023,7 +1023,7 @@

   ;; Actions
   :post! (fn [ctx]
-           (update-entry-dismiss-all conn ctx org-slug))
+           (update-user-visibility-dismiss-all conn ctx org-slug))

   :handle-unprocessable-entity (fn [ctx]
     (api-common/unprocessable-entity-response (:updated-entries ctx))))
@@ -1080,7 +1080,7 @@

   ;; Actions
   :post! (fn [ctx]
-           (update-entry-new conn ctx (s/join " " [org-slug board-slug entry-uuid]) action-type))
+           (update-user-visibility conn ctx (s/join " " [org-slug board-slug entry-uuid]) action-type))

   ;; Responses
   :handle-ok (fn [ctx] (entry-rep/render-entry (:existing-org ctx)


Fix video related keys for email trigger.

--- src/oc/storage/async/email.clj
+++ src/oc/storage/async/email.clj
@@ -24,8 +24,8 @@
    :headline schema/Str
    :body (schema/maybe schema/Str)
    :must-see (schema/maybe schema/Bool)
-   :video-id (schema/maybe lib-schema/NonBlankStr)
-   :video-image (schema/maybe lib-schema/NonBlankStr)
+   :video-id (schema/maybe lib-schema/Str)
+   :video-image (schema/maybe lib-schema/Str)
    :video-duration (schema/maybe schema/Str)
    :secure-uuid lib-schema/UniqueID
    :publisher lib-schema/Author


enforce reg-sub :<- syntax

enforce reg-sub :<- syntax

--- src/re_frame/subs.cljc
+++ src/re_frame/subs.cljc
@@ -183,14 +183,18 @@
                              f)

                          ;; one sugar pair
-                         2 (fn inp-fn
-                             ([_] (subscribe (second input-args)))
-                             ([_ _] (subscribe (second input-args))))
+                         2 (let [[label vec] input-args]
+                             (when-not (= :<- label)
+                               (console :error err-header "expected :<-, got:" label))
+                             (fn inp-fn
+                               ([_] (subscribe vec))
+                               ([_ _] (subscribe vec))))

                          ;; multiple sugar pairs
                          (let [pairs (partition 2 input-args)
+                               labels (map first pairs)
                                vecs  (map last pairs)]
-                           (when-not (every? vector? vecs)
+                           (when-not (and (every? #{:<-} labels) (every? vector? vecs))
                              (console :error err-header "expected pairs of :<- and vectors, got:" pairs))
                            (fn inp-fn
                              ([_] (map subscribe vecs))


Refactor code

Refactor code

- calculate subscription value within with-trace
- rename sub-value to value

--- src/re_frame/subs.cljc
+++ src/re_frame/subs.cljc
@@ -114,7 +114,7 @@
      (if-let [cached (cache-lookup query)]
        (do
          (trace/merge-trace! {:tags {:cached?  true
-                                     :sub-value (deref cached)
+                                     :value (deref cached)
                                      :reaction (reagent-id cached)}})
          cached)

@@ -125,7 +125,7 @@
            (do (trace/merge-trace! {:error true})
                (console :error (str "re-frame: no subscription handler registered for: \"" query-id "\". Returning a nil subscription.")))
            (let [sub-reaction (handler-fn app-db query)]
-             (do (trace/merge-trace! {:tags {:sub-value (deref sub-reaction)}})
+             (do (trace/merge-trace! {:tags {:value (deref sub-reaction)}})
                  (cache-and-return query [] sub-reaction))))))))

   ([query dynv]
@@ -305,13 +305,13 @@
                reaction-id   (atom nil)
                reaction      (make-reaction
                                (fn []
-                                 (let [sub-value (computation-fn (deref-input-signals subscriptions query-id) query-vec)]
-                                   (trace/with-trace {:operation (first-in-vector query-vec)
-                                                      :op-type   :sub/run
-                                                      :tags      {:sub-value  sub-value
-                                                                  :query-v    query-vec
-                                                                  :reaction   @reaction-id}}
-                                                     sub-value))))]
+                                 (trace/with-trace {:operation (first-in-vector query-vec)
+                                                    :op-type   :sub/run
+                                                    :tags      {:query-v    query-vec
+                                                                :reaction   @reaction-id}}
+                                                   (let [subscription (computation-fn (deref-input-signals subscriptions query-id) query-vec)]
+                                                     (trace/merge-trace! {:tags {:value subscription}})
+                                                     subscription))))]

            (reset! reaction-id (reagent-id reaction))
            reaction))
@@ -320,14 +320,14 @@
                reaction-id   (atom nil)
                reaction      (make-reaction
                                (fn []
-                                 (let [sub-value (computation-fn (deref-input-signals subscriptions query-id) query-vec dyn-vec)]
-                                   (trace/with-trace {:operation (first-in-vector query-vec)
-                                                      :op-type   :sub/run
-                                                      :tags      {:sub-value sub-value
-                                                                  :query-v   query-vec
-                                                                  :dyn-v     dyn-vec
-                                                                  :reaction  @reaction-id}}
-                                                     sub-value))))]
+                                 (trace/with-trace {:operation (first-in-vector query-vec)
+                                                    :op-type   :sub/run
+                                                    :tags      {:query-v   query-vec
+                                                                :dyn-v     dyn-vec
+                                                                :reaction  @reaction-id}}
+                                                   (let [subscription (computation-fn (deref-input-signals subscriptions query-id) query-vec dyn-vec)]
+                                                     (trace/merge-trace! {:tags {:value subscription}})
+                                                     subscription))))]

            (reset! reaction-id (reagent-id reaction))
            reaction))))))


Backoff on empty read of no recovery ledger

--- src/onyx/plugin/bookkeeper.clj
+++ src/onyx/plugin/bookkeeper.clj
@@ -70,24 +70,25 @@

 (def read-chunk-size 100)

-(defn read-ledger-entries! [client ^LedgerHandle ledger-handle last-acked max-id no-recovery? read-ch]
+(defn read-ledger-entries! [client ^LedgerHandle ledger-handle read-ch last-acked max-id no-recovery? backoff-period]
   (info "Starting BooKeeper input ledger reader at:" (inc last-acked))
   (let [ledger-id (.getId ledger-handle)]
-    (loop [;; only need to read this once unless recover mode
-           last-confirmed (.getLastAddConfirmed ledger-handle)
+    (loop [last-confirmed (.getLastAddConfirmed ledger-handle)
            start (inc last-acked)
            end (min last-confirmed max-id (+ start read-chunk-size))]
       (let [not-fully-read? (and (not (neg? last-confirmed))
                                  (< last-acked last-confirmed)
                                  (< start last-confirmed))]
-        (when not-fully-read?
-          (read-ledger-chunk! ledger-handle ledger-id read-ch start end))
+        (if not-fully-read?
+          (read-ledger-chunk! ledger-handle ledger-id read-ch start end)
+          (Thread/sleep backoff-period))
         (when (or not-fully-read?
                   (not (.isClosed client ledger-id)))
-          (let [last-confirmed (if no-recovery?
-                                 (.getLastAddConfirmed ledger-handle)
-                                 last-confirmed)]
-            (recur last-confirmed
+          (let [new-last-confirmed (if no-recovery?
+                                     ;; new confirmations may occur in recover mode
+                                     (.getLastAddConfirmed ledger-handle)
+                                     last-confirmed)]
+            (recur new-last-confirmed
                    (inc end)
                    (min last-confirmed max-id (+ (inc end) read-chunk-size)))))))))

@@ -107,7 +108,7 @@
         _ (check-completed task-map checkpointed)
         read-size (or (:bookkeeper/read-max-chunk-size task-map) 1000)
         batch-timeout (or (:onyx/batch-timeout task-map) (:onyx/batch-timeout defaults))
-        initial-backoff 1
+        backoff-period 10
         commit-loop-ch (start-commit-loop! commit-ch log checkpoint-key)
         ledgers-root-path (or (:bookkeeper/zookeeper-ledgers-root-path task-map)
                                (zk/ledgers-path (:onyx/id peer-opts)))
@@ -125,7 +126,7 @@
                       (try
                         (let [exit (loop [last-acked (:largest checkpointed)]
                                      ;if (first (alts!! [shutdown-ch] :default true))
-                                     (read-ledger-entries! client ledger-handle last-acked max-id no-recovery? read-ch)
+                                     (read-ledger-entries! client ledger-handle read-ch last-acked max-id no-recovery? backoff-period)
                                      :finished)]
                           (if-not (= exit :shutdown)
                             (>!! read-ch (t/input (java.util.UUID/randomUUID) :done))))


Fix typo.

Fix typo.

--- src/open_company/lib/email.clj
+++ src/open_company/lib/email.clj
@@ -25,7 +25,7 @@

 (defn send-trigger! [trigger]
   (timbre/info "Request to send msg to " c/aws-sqs-email-queue "\n" (dissoc trigger :snapshot))
-  (s/validate EmailTrigger trigger)
+  (schema/validate EmailTrigger trigger)
   (timbre/info "Sending")
   (sqs/send-message
    {:access-key c/aws-access-key-id


kill set functions that are unused

kill set functions that are unused

--- src/riemann/common.clj
+++ src/riemann/common.clj
@@ -172,22 +172,4 @@
 (defn member?
   "Is r present in seqable s?"
   [r s]
-  (some (fn [e] (= r e)) s))
-
-(defn subset?
-  "Are all elements of required present in seqable s?"
-  [required s]
-  (clojure.set/subset? (set required) (set s)))
-
-(defn overlap?
-  "Do a and b (any seqables) have any elements in common?"
-  [a b]
-  (some (fn [e]
-          (some (fn [r] (= e r)) a)) b))
-
-(defn disjoint?
-  "Do a and b (any seqables) have no elements in common?"
-  [a b]
-  (not-any? (fn [e]
-             (some (fn [r] (= e r)) a))
-           b))
+  (some (fn [e] (= r e)) s))


add checking functionality to ugens. Now the :check functions are honoured (but still need a lot of fleshing out)

--- src/overtone/sc/ugen/specs.clj
+++ src/overtone/sc/ugen/specs.clj
@@ -98,6 +98,23 @@
   "The default ugen init fn (used if an :init key is not present in the ugen
   metadata). Simply returns the args unchanged."
   [rate args spec] args)
+
+(defn- placebo-ugen-checker-fn
+  "The default ugen checker n (used if a :check key is not present in the ugen
+  metadata). Simply returns nil."
+  [rate num-outs args spec] nil)
+
+(defn- with-ugen-checker-fn
+  "Calls the checker fn. If checker fn returns a string, throws an exception
+  using the string as a message. Otherwise returns ugen unchanged."
+  [spec fun ugen]
+  (let [rate (:rate ugen)
+        args (:args ugen)
+        num-outs (:n-outputs ugen)
+        result (fun rate num-outs args spec)]
+    (if (string? result)
+      (throw (Exception. (str "Error in checker for ugen " (:name spec) ". " result)))
+      ugen)))

 (defn- check-arg-rates [spec ugen]
   (let [cur-rate (REVERSE-RATES (:rate ugen))
@@ -254,17 +271,21 @@
   If an init function is already present it will get called after doing the
   mapping and mode transformations."
   [spec]
-  (let [defaulter    (partial add-default-args spec)
-        mapper       (partial map-ugen-args spec)
-        init-fn      (if (contains? spec :init)
-                       (:init spec)
-                       placebo-ugen-init-fn)
-        initer       (partial with-ugen-metadata-init spec init-fn)
-        n-outputer   (partial with-num-outs-mode spec)
-        floater      (partial with-floated-args spec)
-        appender     (partial append-seq-args spec)
-        auto-rater   (partial auto-rate-setter spec)
-        rate-checker (partial check-arg-rates spec)]
+  (let [defaulter       (partial add-default-args spec)
+        mapper          (partial map-ugen-args spec)
+        init-fn         (if (contains? spec :init)
+                          (:init spec)
+                          placebo-ugen-init-fn)
+        initer          (partial with-ugen-metadata-init spec init-fn)
+        n-outputer      (partial with-num-outs-mode spec)
+        floater         (partial with-floated-args spec)
+        appender        (partial append-seq-args spec)
+        auto-rater      (partial auto-rate-setter spec)
+        rate-checker    (partial check-arg-rates spec)
+        checker-fn      (if (contains? spec :check)
+                          (:check spec)
+                          placebo-ugen-checker-fn)
+        bespoke-checker (partial with-ugen-checker-fn spec checker-fn)]

     (assoc spec :init

@@ -279,7 +300,8 @@
                  bus->id
                  appender
                  auto-rater
-                 rate-checker)))))
+                 rate-checker
+                 bespoke-checker)))))

 (defn- with-fn-names
   "Generates all the function names for this ugen and adds a :fn-names map


update @morganastra's pronouns

update @morganastra's pronouns

--- src/pronouns/pages.clj
+++ src/pronouns/pages.clj
@@ -69,7 +69,7 @@
     "Written by "
     (twitter-name "morganastra")
     ", whose "
-    [:a {:href "http://pronoun.is/ze/zir"} "pronoun.is/ze/zir"]
+    [:a {:href "http://pronoun.is/ze/zir?or=she"} "pronoun.is/ze/zir?or=she"]
     ". "
    "Visit the project on " [:a {:href "https://github.com/witch-house/pronoun.is"} "github!"]]]))


removed printlns

removed printlns

--- src/publisher/core.clj
+++ src/publisher/core.clj
@@ -34,8 +34,6 @@
       URLEncoder/encode))

 (defn disqus [path title]
-  (println "showing" (path-to-disqus-id path))
-
   (str "


correct duplicate name error in test

correct duplicate name error in test

--- test/clj_money/models/accounts_test.clj
+++ test/clj_money/models/accounts_test.clj
@@ -50,7 +50,9 @@
   (testing "Values are coerced into the correct types"
     (try
     (let [result (accounts/create storage-spec
-                                  (update-in attributes [:entity-id] str))]
+                                  (-> attributes
+                                      (update-in [:entity-id] str)
+                                      (assoc :name "Coerced")))]
       (is (number? (:id result))))
       (catch clojure.lang.ExceptionInfo e
         (pprint (ex-data e))


Improve layout

Improve layout

--- src/re_com/layout.cljs
+++ src/re_com/layout.cljs
@@ -38,7 +38,7 @@

 (def h-layout-args-desc
   [{:name :panel-1       :required true                 :type "hiccup"          :validate-fn string-or-hiccup? :description "markup to go in the left panel"}
-   {:name :panel-2       :required true                 :type "hiccup"         :validate-fn string-or-hiccup? :description "markup to go in the right panel"}
+   {:name :panel-2       :required true                 :type "hiccup"          :validate-fn string-or-hiccup? :description "markup to go in the right panel"}
    {:name :initial-split :required false :default 50    :type "double | string" :validate-fn number-or-string? :description "initial split percentage of the left panel. Can be double value or string (with/without percentage sign)"}
    {:name :splitter-size :required false :default "8px" :type "string"          :validate-fn string?           :description "thickness of the splitter"}
    {:name :margin        :required false :default "8px" :type "string"          :validate-fn string?           :description "thickness of the margin around the panels"}])


Tictactoe is done

Tictactoe is done

--- src/ulam/tictactoe.clj
+++ src/ulam/tictactoe.clj
@@ -1,5 +1,6 @@
 (ns ulam.tictactoe
   (require [ulam.core :as ulam]
+           [criterium.core :as crit]
            [clojure.math.numeric-tower :as math]))

 (defn init []
@@ -17,12 +18,11 @@
   (for [i (range 9)]
     (math/expt 2 i)))

-(defn pick-move [state]
+(defn valid-moves [state]
   (let [occupied (bit-or (:p1 state) (:p2 state))]
-    (rand-nth (keep identity (map-indexed (fn [i pos]
-                              (if (zero? (bit-and occupied pos))
-                                i))
-                            possible-moves)))))
+    (filter #(zero? (bit-and occupied %))
+                      possible-moves)))
+

 (def winning-positions
   [2r111000000                                              ;horizontals
@@ -40,19 +40,45 @@
                         (= winning-pos (bit-and board winning-pos)))
                       winning-positions)))

+
+(defn format-stats [stats]
+  (println "===============================")
+  (doseq [[move stats] (sort stats)]
+    (println move (format "%.5f" (try (double (/ (:total stats) (:n stats)))
+                                      (catch Exception e 0.0))))))
+
+(defn perform-move [state move]
+  (-> state
+      (update-in [(:active state)] #(bit-or % move))
+      (assoc :active (if (= :p1 (:active state)) :p2 :p1))))
+
+(perform-move (init) 2r000010000)
+
 (defn simulate [state]
+  (let [valids (valid-moves state)]
+    (loop [n 0
+           stats (into {}
+                  (for [move valids]
+                    [move {:total 0 :n 0}]))]
+      (if (= 1 (mod n 100000))
+        (format-stats stats))
+      (let [random-move (rand-nth valids)
+            result (simulate-step (perform-move state random-move))]
+        (recur (inc n)
+               (-> stats
+                   (update-in [random-move :n] inc)
+                   (update-in [random-move :total] #(+ % result))))))))

-  )

-(defn simulate-step [state player]
-  (println state)
+
+(defn simulate-step [state]
   (cond (check-win (:p1 state)) 1
         (check-win (:p2 state)) -1
         (= 2r111111111 (bit-or (:p1 state) (:p2 state))) 0
-        :else (let [random-move (pick-move state)
-                    bit (math/expt 2 random-move)]
-                (recur
-                 (update-in state [player] #(bit-or bit %))
-                 (if (= :p1 player) :p2 :p1)))))
+        :else (let [move (rand-nth (valid-moves state))]
+                (recur (perform-move state move)))))

-(simulate-step (init) :p1)
+(simulate (init))
+(simulate {:p1 2r000110100 :p2 2r101000000 :active :p2})
+
+(crit/quick-bench (simulate-step (init)))


Fix index pubsub in cores.

Fix index pubsub in cores.

The config wrapper for index pubsub used the *next* core's pubsub,
instead of the current core's. That pubsub is intentionally discarded in
favor of the current core's pubsub on transition, which meant the index
was forwarding events to an orphaned pubsub registry.

--- src/riemann/config.clj
+++ src/riemann/config.clj
@@ -154,11 +154,14 @@
 (defn index
   "Set the index used by this core. Returns the index."
   [& opts]
-  (let [index (apply riemann.index/index opts)
-        wrap  (fn [{:keys [pubsub] :as core}]
-                (assoc core :index (core/wrap-index index pubsub)))]
-    (locking core
-      (:index (swap! next-core wrap)))))
+  (locking core
+    (let [index (apply riemann.index/index opts)
+          ; Note that we need to wrap the *current* core's pubsub; the next
+          ; core's pubsub module will be discarded in favor of the current one
+          ; when core transition takes place.
+          wrapper (core/wrap-index index (:pubsub @core))]
+      (swap! next-core assoc :index wrapper)
+      wrapper)))

 (defn update-index
   "Updates the given index with all events received. Also publishes to the


seperating disk formate validation for both cases

--- src/vc/validations.clj
+++ src/vc/validations.clj
@@ -47,11 +47,11 @@
 (defvalidatorset common-allocation
     :pool [cv/str?]
     :hostsystem [cv/str? v/required]
-    :disk-format [v/required (v/member formats :message (<< "disk format must be either ~{formats}"))]
     :datacenter [cv/str? v/required]
   )

 (defvalidatorset vcenter-provider
+   [:allocation :disk-format] [v/required (v/member formats :message (<< "disk format must be either ~{formats}"))]
    :allocation common-allocation
    :machine machine-common
    :machine machine-networking
@@ -61,10 +61,16 @@
 (defn provider-validation [allocation machine]
   (validate! ::invalid-vm {:allocation allocation :machine machine} vcenter-provider))

+(def format-names (into #{} (map name (keys disk-format-types))))
+
+(defvalidatorset disk-format
+   :disk-format [v/required (v/member format-names :message (<< "disk format must be either ~{format-names}"))])
+
 (defn validate-entity
  "vcenter based system entity validation for persistence layer"
   [{:keys [machine vcenter] :as vc}]
    (validate! ::invalid-system vcenter common-allocation)
+   (validate! ::invalid-system vcenter disk-format)
    (validate! ::invalid-system machine machine-common)
    (validate! ::invalid-system machine machine-networking)
    (validate! ::invalid-system machine machine-entity)


Change color of the "Show" button, blue to green.

--- src/wlmmap/handler.clj
+++ src/wlmmap/handler.clj
@@ -271,9 +271,9 @@
        [:form
         (f/drop-down {:id "db"} "db" (db-options-localized lng))
         [:p
-         (e/link-to {:id "sm" :style "color:blue"} "#"
+         (e/link-to {:id "sm" :style "color:green"} "#"
                     (tower/t (keyword lng) trad :main/show))
-         (e/link-to {:id "stop" :style "color: red"} "#"
+         (e/link-to {:id "stop" :style "color:red"} "#"
                     (tower/t (keyword lng) trad :main/stop))
          (e/link-to {:id "showhere" :style "color:yellow"} "#" "....")]
         "</p>"


Fix bug in org response links.

Fix bug in org response links.

--- src/oc/storage/representations/org.clj
+++ src/oc/storage/representations/org.clj
@@ -45,16 +45,16 @@
                           (concat links [(activity-link org) (calendar-link org)])
                           links)
         full-links (if (= access-level :author)
-                      (concat links [(board-create-link org)
-                                     (partial-update-link org)
-                                     (add-author-link org)
-                                     (hateoas/collection-link (str (url org) "/stories")
-                                        {:accept mt/story-collection-media-type}
-                                        {:count (:story-count org)})
-                                     (hateoas/create-link (str (url org) "/stories/")
-                                        {:content-type mt/share-request-media-type
-                                         :accept mt/story-media-type})])
-                      links)]
+                      (concat activity-links [(board-create-link org)
+                                              (partial-update-link org)
+                                              (add-author-link org)
+                                              (hateoas/collection-link (str (url org) "/stories")
+                                                  {:accept mt/story-collection-media-type}
+                                                  {:count (:story-count org)})
+                                              (hateoas/create-link (str (url org) "/stories/")
+                                                  {:content-type mt/share-request-media-type
+                                                   :accept mt/story-media-type})])
+                      activity-links)]
     (assoc org :links full-links)))

 (def auth-link (hateoas/link-map "authenticate" hateoas/GET config/auth-server-url {:accept "application/json"}))
@@ -85,7 +85,7 @@
         full-links (if authed?
                       (conj links (hateoas/create-link "/orgs/" {:content-type mt/org-media-type
                                                                  :accept mt/org-media-type}))
-                links)]
+                      links)]
     (json/generate-string
       {:collection {:version hateoas/json-collection-version
                     :href "/"


post/distindex.clj: handle missing HTML

post/distindex.clj: handle missing HTML

--- src/org/altlaw/jobs/post/distindex.clj
+++ src/org/altlaw/jobs/post/distindex.clj
@@ -61,8 +61,13 @@
   (.add server (solr/make-solr-document (prepare-solr-document doc))))

 (defn my-map [docid document]
-  (index-document (:server @*config*) document)
-  [[(:zip-file-name @*config*) 1]])
+  (if (empty? (:html document))  ;; or nil, (empty? nil) is true
+    (do (h/counter "No HTML")
+        (log/warn "No HTML for document " docid)
+        nil)
+    (do (h/counter "Indexed documents")
+        (index-document (:server @*config*) document)
+        [[(:zip-file-name @*config*) 1]])))

 (def mapper-map (partial h/standard-map my-map))


clojure.lang.LazySeq -> LazySeq

clojure.lang.LazySeq -> LazySeq

--- src/main/clojure/cljs/analyzer.cljc
+++ src/main/clojure/cljs/analyzer.cljc
@@ -32,7 +32,7 @@
                      [cljs.reader :as edn]))
   #?(:clj (:import [java.io File Reader PushbackReader]
                    [java.net URL]
-                   [clojure.lang Namespace Var]
+                   [clojure.lang Namespace Var LazySeq]
                    [cljs.tagged_literals JSValue])))

 #?(:clj (set! *warn-on-reflection* true))
@@ -2078,7 +2078,7 @@
       (wrapping-errors env
         (reduce (fn [ast pass] (pass env ast))
           (binding [reader/*alias-map* (or reader/*alias-map* {})]
-            (let [form (if (instance? clojure.lang.LazySeq form)
+            (let [form (if (instance? LazySeq form)
                          (or (seq form) ())
                          form)]
               #?(:clj (load-core))


Removed reflection warnings on filters.clj

--- src/selmer/filters.clj
+++ src/selmer/filters.clj
@@ -27,7 +27,7 @@
  (fn [x y & rest]
    (let [args (conj rest y x)]
      (try (apply +
-                 (map #(Long/valueOf %) args))
+                 (map #(Long/valueOf ^String %) args))
           (catch NumberFormatException _
             (apply str args))))))

@@ -82,10 +82,10 @@
 ;;; You can also format time with this.
 (add-filter!
  :date
- (fn [d fmt]
+ (fn [^DateTime d fmt]
    (when (instance? DateTime d)
-     (let [fmt (or (valid-date-formats fmt)
-                   (DateTimeFormat/forPattern fmt))]
+     (let [^DateTimeFormatter fmt (or (valid-date-formats fmt)
+                                      (DateTimeFormat/forPattern fmt))]
        (.print fmt d)))))

 ;;; Default if x is falsey


Profile sequences

Profile sequences

--- src/profile/cljs/lean_map/profile.cljs
+++ src/profile/cljs/lean_map/profile.cljs
@@ -17,11 +17,25 @@
       (recur (assoc m (nth test-keys i) i) (inc i))
       m)))

+(def seq-lem (lean-assoc))
+
+(defn lean-seq []
+  (loop [s (seq seq-lem)]
+    (if (seq s)
+      (recur (next s)))))
+
 (defn cljs-assoc []
   (loop [m cem i 0]
     (if (< i test-size)
       (recur (assoc m (nth test-keys i) i) (inc i))
       m)))
+
+(def seq-cem (cljs-assoc))
+
+(defn cljs-seq []
+  (loop [s (seq seq-cem)]
+    (if (seq s)
+      (recur (next s)))))

 (defn profile [f name]
   (dotimes [i 5]
@@ -31,4 +45,6 @@

 (defn run-profile []
   (profile cljs-assoc "ClJS Assoc")
-  (profile lean-assoc "Lean Assoc"))
+  (profile cljs-seq "ClJS Seq")
+  (profile lean-assoc "Lean Assoc")
+  (profile lean-seq "Lean Seq"))


use tags instead of an attribute

use tags instead of an attribute

--- src/riemann/plugin/acknowledgement.clj
+++ src/riemann/plugin/acknowledgement.clj
@@ -22,6 +22,11 @@
   [member]
   (swap! acks disj (vec member)))

+(defn acked?
+  [{:keys [tags] :as event}]
+  (let [tags (set tags)]
+    (tags "acked")))
+
 (defroutes api-routes
   "Our simple acknowledgement API with three resty routes.
    We use PUT instead of DELETE here to simplify client side work"
@@ -37,10 +42,13 @@

 (defn with-ack-status
   "Associate acknowledgement status to events"
-  [{:keys [host service acked] :as event}]
+  [{:keys [host service tags] :as event}]
   (try
-    (let [acked? (or acked (@acks [host service]))]
-      (assoc event :acked acked?))
+    (if (acked? event)
+      event
+      (if (@acks [host service])
+        (update-in event [:tags] #(-> % (conj "acked") set))
+        event))
     (catch Exception e
       (info "could not process acked status for: " event)
       event)))
@@ -55,9 +63,10 @@
    The double arity version does the same and sends acked events to
    its second argument. This can be useful to index events."
   ([non-acked]
-     (where* (complement :acked) non-acked))
+     (where* (complement acked?) non-acked))
   ([non-acked acked]
-     (where* (complement :acked) non-acked (else acked))))
+     ()
+     (where* (complement acked?) non-acked (else acked))))

 (defrecord AcknowledgementServer [host port headers core server]
   ServiceEquiv


Add safe-subvec and remove trailing whitespace

--- src/storemi/common.clj
+++ src/storemi/common.clj
@@ -24,11 +24,11 @@
   (try
     (if (integer? n)
       n
-      (-> n read-string int))
+      (-> n read-string int))
     (catch Exception e defval)))

 (defn find-with-val [col k v]
-  (let [pred
+  (let [pred
         (fn [obj]
           (= v (get obj k)))]
     (->> col
@@ -38,7 +38,7 @@
 (defn trim-slash2 [s]
   (let [is-slash #(= % \/)
         not-slash #(not= % \/)]
-    (->>
+    (->>
       s
       (drop-while is-slash)
       (take-while not-slash)
@@ -50,8 +50,8 @@

 (defn trim-leading-slash [s]
   (if (instance? String s)
-    (apply
-      str
+    (apply
+      str
       (if (= (first s) \/)
         (rest s)
         s))
@@ -73,8 +73,8 @@
        (apply str)))

 (defn with-base [base-url & paths]
-  (clojure.string/join
-    "/" (cons-apply
+  (clojure.string/join
+    "/" (cons-apply
           (cons base-url paths)
           trim-trailing-slash
           trim-slash)))
@@ -93,3 +93,10 @@
         expr
         (future (Thread/sleep millis) (apply f args))))))

+(defn safe-subvec [v start end]
+  (let [end (min (count v)
+                 end)]
+    (try
+      (subvec v start end)
+      (catch IndexOutOfBoundsException e []))))
+


Story ID: append-class-helper Summary: Add append-class helper that extends toggle-class behavior. Comments to QA/Testers: Changelog: - Add append-class helper that extends toggle-class behavior.

--- src/untangled/dom.cljs
+++ src/untangled/dom.cljs
@@ -1,11 +1,30 @@
 (ns untangled.dom
   (:require [clojure.string :as str]
             [cljs-uuid-utils.core :as uuid]
+            [om.next :as om]
             [untangled.logging :as logging]))

 (defn unique-key [] (uuid/uuid-string (uuid/make-random-squuid)))
+
+
+(defn append-class
+  "Given a component and a local state key or keys, to be passed to `om/get-state`,
+  returns a function that takes the `state-value` to test, a `default-class-string`,
+  and optionaol `:when-true` and `:when-false`. The values `:when-false` and `when-true`
+  are appended to `default-class-string` after the test against `state-value`.
+
+  Parameters:
+  `component`: The component to pass to `om/get-state`.
+  `local-state-key`: The key or keys to pass to `om/get-state`."
+  [component local-state-key]
+  (fn [state-key default-class-string & {:keys [when-true when-false]
+                                         :or   {when-true "active" when-false ""}}]
+    (let [append-string (if (= state-key (om/get-state component local-state-key))
+                          when-true
+                          when-false)]
+      (str default-class-string " " append-string))))

 (defn toggle-class


Define the data-store connection only once

--- src/scavenger/client/main.cljs
+++ src/scavenger/client/main.cljs
@@ -28,7 +28,7 @@
          #js {"Content-Type" "application/edn"}))))

 ; Local datascript state storage
-(def conn (d/create-conn {}))
+(defonce conn (d/create-conn {}))

 ; Reader for state
 (defmulti read om/dispatch)


referring only points

referring only points

--- src/the_divine_cheese_code/core.clj
+++ src/the_divine_cheese_code/core.clj
@@ -1,5 +1,5 @@
 (ns the-divine-cheese-code.core
-  (require [the-divine-cheese-code.visualization.svg :as svg])
+  (:require [the-divine-cheese-code.visualization.svg :refer [points]])
   (:gen-class))

 (def heists
@@ -26,4 +26,4 @@

 (defn -main
   [& args]
-  (println (svg/points heists)))
+  (println (points heists)))


Added a display value column to all tables.


`:stop`-ing a pipeline fails the run with a msg

There are (currently) four ways a pipeline can be stopped:
- no filename in the input
- an unsupported csv version
- an unsupported xml version
- an exception is caught

--- src/vip/data_processor/pipeline.clj
+++ src/vip/data_processor/pipeline.clj
@@ -55,11 +55,16 @@
              :pipeline pipeline}
         _ (add-watch spec-version :route-errors
                      (errors/add-watch-fn errors-chan))
-        result (run-pipeline ctx)]
+        result (run-pipeline ctx)
+        import-id (:import-id result)]
     (log/info (pr-str (select-keys result [:import-id :public-id :db :xml-output-file])))
-    (log/debug (pr-str (select-keys result [:spec-version :fatal :critical])))
+    (log/debug (pr-str (select-keys result [:spec-version :fatal :critical :stop])))
+
     (when-let [ex (:exception result)]
-      (psql/fail-run (:import-id result)
-                     (with-out-str (stacktrace/print-throwable ex)))
+      (psql/fail-run import-id (with-out-str (stacktrace/print-throwable ex)))
       (log/error (with-out-str (stacktrace/print-stack-trace ex))))
+
+    (when-let [stop (:stop result)]
+      (psql/fail-run import-id stop)
+      (log/error "Stopping run of" import-id "due to:" stop))
     result))


make-factory works and also supports instantiation from given bundle.

--- ccw.core/src/clj/ccw/core/factories.clj
+++ ccw.core/src/clj/ccw/core/factories.clj
@@ -13,18 +13,23 @@
              []
         (execute [event] (when handler (handler this event)))))))

-(defn java-factory
-  "Factory for an Eclipse plugin executable extension which calls the no-arg
-   constructor of the java class whose fully qualified name is passed in javaClass"
-  [{java-class "javaClass"}]
-  (println "I was called, hey!")
-  (try
-    (let [class (-> (Thread/currentThread)
-                  .getContextClassLoader
-                  (.loadClass java-class))]
-      (let [i (Reflector/invokeConstructor class (make-array Object 0))]
-        (println "instance created: " i)
-        i))
-    (catch Exception e
-      (println "sent exception: " (.getMessage e) "," e)
-      (.printStackTrace e))))
+(defn make-factory
+  "Creates a factory function for creating instances of the given java
+   class name using the constructor with given argument types.
+   The types of the arguments must be specified in a symbol sequence,
+   which must be emtpy when the no arg constructor is to be used.
+   The fn produced uses type hints to enable compiler/jit
+   optimizations, at the expense of making this factory method slower
+   so it's best to store its result in a var.
+   A Bundle instance can optionally be passed for loading the class.
+   Example:
+     (def int-factory (make-factory \"Integer\" ['String]))
+     (int-factory \"42\")
+   See http://stackoverflow.com/a/3752276 for original inspiration."
+  ([classname types]
+    (let [args (map #(with-meta (symbol (str "x" %2)) {:tag %1}) types (range)) ]
+      (eval `(fn [~@args] (new ~(symbol classname) ~@args)))))
+  ([bundle classname types]
+    (let [zclass (.. bundle (loadClass classname))
+          constructor (.getConstructor zclass (into-array Class (map resolve types)))]
+      (fn [& args] (.newInstance constructor (into-array Object args))))))


start tracking time to repaint

start tracking time to repaint

--- src/sierpinski_sieve/core.cljs
+++ src/sierpinski_sieve/core.cljs
@@ -47,5 +47,5 @@
   ;; optionally touch your app-state to force rerendering depending on
   ;; your application
   ;; (swap! app-state update-in [:__figwheel_counter] inc)
-  (paint "canvas" 400 (take 400 (sieve '(1) 2)))
+  (time (paint "canvas" 400 (take 400 (sieve '(1) 2))))
 )


[#12819] Fix network fee calculation on xDai chain

--- src/status_im/signing/gas.cljs
+++ src/status_im/signing/gas.cljs
@@ -289,7 +289,9 @@
     (fn []
       (json-rpc/call
        {:method "eth_feeHistory"
-        :params [101 "latest" nil]
+        ;; NOTE(rasom): We don't need `reward` atm but if the last parameter is
+        ;; `nil` request fails on some chains (particularly on xDai).
+        :params [101 "latest" [100]]
         :on-success #(re-frame/dispatch [::header-fetched
                                          (assoc params :fee-history %)])}))
     (fn []
@@ -341,31 +343,44 @@

 (defn check-base-fee [{:keys [baseFeePerGas]}]
   (let [all-base-fees    (mapv money/bignumber baseFeePerGas)
-        current-base-fee (last all-base-fees)
+        next-base-fee    (peek all-base-fees)
         previous-fees    (subvec all-base-fees 0 101)
+        current-base-fee (peek previous-fees)
         percentiles      (calc-percentiles previous-fees [10 20 80])]
     {:normal-base-fee  (money/to-hex
                         (recommended-base-fee
-                         current-base-fee
+                         next-base-fee
                          (get percentiles 20)
                          (get percentiles 80)))
      :slow-base-fee    (money/to-hex
                         (slow-base-fee
-                         current-base-fee
+                         next-base-fee
                          (get percentiles 10)))
      :fast-base-fee    (money/to-hex
                         (fast-base-fee
-                         current-base-fee
+                         next-base-fee
                          (get percentiles 80)))
      :current-base-fee (money/to-hex current-base-fee)}))
+
+(defn max-priority-fee-hex [gas-price base-fee]
+  (money/to-hex
+   (money/sub (money/bignumber gas-price)
+              (money/bignumber base-fee))))

 (fx/defn header-fetched
   {:events [::header-fetched]}
   [_ {:keys [error-callback success-callback fee-history] :as params}]
   {::json-rpc/call
-   [{:method     "eth_maxPriorityFeePerGas"
-     :on-success #(success-callback (merge {:max-priority-fee %}
-                                           (check-base-fee fee-history)))
+   [;; NOTE(rasom): eth_maxPriorityFeePerGas is not supported by some networks
+    ;; so it is more reliable to calculate maxPriorityFeePerGas using the value
+    ;; returned by eth_gasPrice and current base fee.
+    {:method     "eth_gasPrice"
+     :on-success #(success-callback
+                   (let [{:keys [current-base-fee] :as base-fees}
+                         (check-base-fee fee-history)]
+                     (merge {:max-priority-fee
+                             (max-priority-fee-hex % current-base-fee)}
+                            base-fees)))
      :on-error   (if error-callback
                    #(error-callback %)
                    #(log/error "Can't fetch header" %))}]})


[#12668] Fix gas estimation after using Set max

--- src/status_im/signing/gas.cljs
+++ src/status_im/signing/gas.cljs
@@ -228,6 +228,7 @@
 (fx/defn update-estimated-gas-error
   {:events [:signing/update-estimated-gas-error]}
   [{db :db} {:keys [message]}]
+  (log/warn "signing/update-estimated-gas-error" message)
   {:db (-> db
            (assoc-in [:signing/edit-fee :gas-loading?] false)
            (assoc-in [:signing/tx :gas-error-message] message))})
@@ -366,7 +367,10 @@
 (re-frame/reg-fx
  :signing/update-estimated-gas
  (fn [{:keys [obj success-event error-event]}]
-   (json-rpc/call {:method     "eth_estimateGas"
-                   :params     [obj]
-                   :on-success #(re-frame/dispatch [success-event %])
-                   :on-error   #(re-frame/dispatch [error-event %])})))
+   (let [value (:value obj)]
+     (json-rpc/call {:method     "eth_estimateGas"
+                     :params     [(if value
+                                    (assoc obj :value "0x0")
+                                    obj)]
+                     :on-success #(re-frame/dispatch [success-event %])
+                     :on-error   #(re-frame/dispatch [error-event %])}))))


I lowercased my name

I lowercased my name

--- src-cljs/frontend/core.cljs
+++ src-cljs/frontend/core.cljs
@@ -136,7 +136,7 @@
                                         :mult (async/mult mouse-up-ch)}})
               (browser-settings/restore-browser-settings)
               (update-in (state/doc-chat-bot-path document-id)
-                         #(if % % (rand-nth ["Daniel" "Danny" "prcrsr"])))))))
+                         #(if % % (rand-nth ["daniel" "Danny" "prcrsr"])))))))

 (defn log-channels?
   "Log channels in development, can be overridden by the log-channels query param"


Cleaned up a little code.

Cleaned up a little code.

--- src/wombats/game/processor.clj
+++ src/wombats/game/processor.clj
@@ -91,8 +91,6 @@

 (defn- lambda-request
   [player-state aws-credentials bot-code]
-
-  ;; TODO #162
   (let [client (lambda-client aws-credentials)
         request (lambda-invoke-request player-state bot-code)
         result (.invoke client request)
@@ -104,9 +102,8 @@
 (defn- get-decision-maker-code
   [game-state uuid type]

-  (let [key-name (if (= type :wombat) :players type)
-        code (get-in game-state [key-name uuid :state :code])]
-    code))
+  (let [key-name (if (= type :wombat) :players type)]
+    (get-in game-state [key-name uuid :state :code])))

 (defn- get-lamdba-channels
   "Kicks off the AWS Lambda process"


Removed moot dummy-down call

Removed moot dummy-down call

--- src/portal_clj/models/migration.clj
+++ src/portal_clj/models/migration.clj
@@ -164,6 +164,4 @@
   (when (= (first args) "down")
     (nuke-all))
   (when (= (first args) "dummy")
-    (do-dummy))
-  (when (= (first args) "clean")
-    (dummy-down)))
+    (do-dummy)))


resource path

resource path

--- bot/dl.clj
+++ bot/dl.clj
@@ -1,5 +1,6 @@
 (ns dl
   (:require [clojure.core.memoize :as memo]
+            [clojure.java.io :as io]
             [clojure.string :as str]
             [clojure.java.jdbc :as jdbc]
             [cheshire.core :as json]


Add tests for pipeline sockets.

Add tests for pipeline sockets.

--- test/nanomsg_tests.clj
+++ test/nanomsg_tests.clj
@@ -45,6 +45,18 @@
         (is (= @recvd1 "ss1 bar"))
         (is (= @recvd2 "ss2 foo")))))

+  (testing "Pipeline"
+    (let [sockname  (str s-bind-ipc "pipeline")
+          push-sock (nn/socket :push {:bind sockname})
+          receiver  (future
+                      (let [pull-sock (nn/socket :pull {:connect sockname})
+                            received  (nn/recv! pull-sock)]
+                        (nn/close! pull-sock)
+                        received))]
+      (sleep 500)
+      (nn/send! push-sock "message1")
+      (is (= @receiver "message1"))))
+
   (testing "Pair"
     (let [sock (nn/socket :pair)]
       (nn/bind! sock s-bind-tcp)


make encode functional, still can't round trip

--- src/clj/cljs/source_map.clj
+++ src/clj/cljs/source_map.clj
@@ -76,71 +76,65 @@
              (recur (inc gline) (next lines) (assoc relseg 0 0) result))
            result)))))

-;; TODO: line logic is incorrect, we need to group them into lines ourselves, based
-;; on whether (:gline v) has changed
+(defn info->segv [info state]
+  [(:gcol info) (:source-idx state) (:line state) (:col state)])

-(defn encode-cols [vs prev-seg source-idx line col names->idx name-idx]
-  (loop [vs (seq vs) prev-seg prev-seg cols-segs []]
-    (if vs
-      (let [v (first vs)
-            seg [(:gcol v) source-idx line col]
-            seg (if-let [name (:name v)]
-                  (let [idx (if-let [idx (get @names->idx name)]
-                              idx
-                              (let [cidx @name-idx]
-                                (swap! names->idx assoc name cidx)
-                                (swap! name-idx inc)
-                                cidx))]
-                    (conj seg idx))
-                  seg)
-            relseg (if prev-seg
-                      (into [] (map - seg prev-seg))
-                      seg)]
-        (recur (next vs)
-          (if (and (= (count seg) 4)
-                   (= (count prev-seg) 5))
-            (conj seg (peek prev-seg))
-            seg)
-          (conj cols-segs (base64-vlq/encode relseg))))
-      {:cols-segs cols-segs
-       :prev-seg prev-seg})))
-
-(defn encode-source [lines segs prev-seg source-idx names->idx name-idx]
-  (loop [lines (seq lines) segs segs prev-seg prev-seg]
-    (if lines
-      (let [[line cols] (first lines)
-            {:keys [segs prev-seg]}
-            (loop [cols (seq cols) segs segs prev-seg prev-seg]
-              (if cols
-                (let [[col vs] (first cols)
-                      {:keys [cols-segs prev-seg]}
-                      (encode-cols vs prev-seg source-idx line col names->idx name-idx)]
-                  (recur (next cols) (conj segs cols-segs) prev-seg))
-                {:segs segs :prev-seg prev-seg}))]
-        (recur (next lines) segs prev-seg))
-      {:segs segs :prev-seg prev-seg})))
+(defn encode-cols [infos state]
+  (loop [infos (seq infos) state state]
+    (if infos
+      (let [info (first infos)
+            prev-info (:prev-info state)
+            segv (info->segv info state)
+            [segv state] (if-let [name (:name info)]
+                           (let [[idx state]
+                                 (if-let [idx (get-in state [:names->idx name])]
+                                   [idx state]
+                                   (let [cidx (:name-idx state)]
+                                     [cidx (-> state
+                                               (assoc-in [:names->idx name] cidx)
+                                               (assoc :name-idx (inc cidx)))]))]
+                             [(conj segv idx) state])
+                           [segv state])
+            relsegv (if prev-info
+                      (into [] (map - segv (info->segv prev-info state)))
+                      segv)]
+        (recur (next infos)
+          (let [lines (:lines state)
+                lines (conj (pop lines)
+                            (if (and prev-info (not= (:gline info) (:gline prev-info)))
+                              [(base64-vlq/encode relsegv)]
+                              (conj (peek lines) (base64-vlq/encode relsegv))))]
+            (-> state
+                (assoc :lines lines)
+                (assoc :prev-info
+                  (if (:name info) info (assoc info :name (:name prev-info))))))))
+      state)))

 (defn encode [m opts]
-  (let [names->idx (atom {})
-        name-idx   (atom 0)
-        segs
-        (loop [sources (seq m) prev-seg nil source-idx 0 segs []]
-          (if sources
-            (let [[source lines] (first sources)
-                  {:keys [segs prev-seg]}
-                  (encode-source lines segs prev-seg source-idx names->idx name-idx)]
-              (recur (next sources) prev-seg (inc source-idx) segs))
-            segs))]
+  (let [step (fn [state [_ lines]]
+               (update-in
+                 (reduce (fn [state [line cols]]
+                           (reduce (fn [state [col infos]]
+                                     (encode-cols infos (assoc state :col col)))
+                                   (assoc state :line line)
+                                   cols))
+                         state lines)
+                 [:source-idx] inc))
+        init-state {:source-idx 0 :lines [[]]
+                    :names->idx {} :name-idx 0
+                    :prev-info nil}
+        {:keys [names->idx lines]} (reduce step init-state m)]
     (with-out-str
       (json/pprint
        {"version" 3
         "file" (:file opts)
         "sources" (into [] (keys m))
         "lineCount" (:lines opts)
-        "mappings" (->> segs
+        "mappings" (->> lines
                         (map #(string/join "," %))
                         (string/join ";"))
-        "names" (into [] (map (set/map-invert @names->idx) (range (count @names->idx))))}))))
+        "names" (into [] (map (set/map-invert names->idx)
+                              (range (count names->idx))))}))))

 (defn merge-source-maps
   ([cljs-map closure-map] (merge-source-maps cljs-map closure-map 0))


Exclude 8 reserved values from integer ranges

--- src/cljam/io/bcf/writer.clj
+++ src/cljam/io/bcf/writer.clj
@@ -89,15 +89,15 @@

 (defn- value-type
   "Returns an integer indicating type of input value."
-  [v]
+  ^long [v]
   (cond
     (nil? v) 1
     (keyword? v) 1
     (float? v) 5
     (char? v) 7
-    (<= Byte/MIN_VALUE v Byte/MAX_VALUE) 1
-    (<= Short/MIN_VALUE v Short/MAX_VALUE) 2
-    (<= Integer/MIN_VALUE v Integer/MAX_VALUE) 3))
+    (<= (+ Byte/MIN_VALUE 8) v Byte/MAX_VALUE) 1
+    (<= (+ Short/MIN_VALUE 8) v Short/MAX_VALUE) 2
+    (<= (+ Integer/MIN_VALUE 8) v Integer/MAX_VALUE) 3))

 (def ^:private ^:const int8-special-map
   {nil 0x80 :eov 0x81 :exists 1})


Change :refer-macros to :refer [skip ci]

--- src/cljc/mikron/buffer.cljc
+++ src/cljc/mikron/buffer.cljc
@@ -3,7 +3,7 @@
   (:require [mikron.util :as util]
             [mikron.util.math :as math]
             [mikron.compile-util :as compile-util]
-            [mikron.buffer-macros #?(:clj :refer :cljs :refer-macros) [with-delta with-le]])
+            [mikron.buffer-macros :refer [with-delta with-le]])
   #?(:clj (:import [java.nio ByteBuffer ByteOrder])))

 (compile-util/definterface+ BitBufferOps


Show the REST query flag in the view

Show the REST query flag in the view

--- src/cljs/bartleby/view.cljs
+++ src/cljs/bartleby/view.cljs
@@ -23,8 +23,10 @@

 (defn main-view []
   (let [tasks (re-frame/subscribe [:tasks])
+        rest-status (re-frame/subscribe [:rest])
         remaining (filter (fn [t] (not (:done t))) @tasks)]
     [:div
+     [:p @rest-status]
      [:h1 "Remaining tasks"]
      [:div.list-group
       (map todo-item @tasks)]


Transform notify to multimethod to multiplex chat and groupchat messages

--- src/cljs/sloth/browser.cljs
+++ src/cljs/sloth/browser.cljs
@@ -37,18 +37,28 @@
     (.play audio)))

 (defn notify-if-applies
-  [message]
+  ([message]
+  (let [type (:type message)
+        channel-name (get-in message [:from :local])]
+
+    (condp = type
+      :chat (let [author (str/trim (get-in message [:from :local]))
+                  title author]
+              (notify-if-applies message author title))
+
+      :groupchat (let [author (str/trim (get-in message [:from :resource]))
+                       channel-name (get-in message [:from :local])
+                       title (str author "@" channel-name)]
+                   (notify-if-applies message author title)))))
+
+  ([message author title]
   (go
     (let [username (str/trim (get-in @st/state [:user :local]))
-          author (str/trim (get-in message [:from :resource]))
-          channel-name (get-in message [:from :local])
-          title (str author "@" channel-name)
           body (:body message)]

       (when (and (allow-notifications?) (not= username author) (not (st/window-focused?)))
         (play-notification-sound)
-        (notify title body)))))
-
+        (notify title body))))))

 (defn listen-focus-events
   ([]


tests: fixed typos: testings -> deftests

--- test/unit/unpatch.cljc
+++ test/unit/unpatch.cljc
@@ -20,7 +20,8 @@

     (is (= original-val my-var1) "just in case")))

-(testing "unpatch works in explicit context"
+(u/deftest+
+  "unpatch works in explicit context"
   (let [ctx (fc/context)
         original-val my-var1]
     (fc/patch! ctx #'my-var1 200)
@@ -87,7 +88,8 @@
     (is (= original-val1 my-var1) "just in case")
     (is (= original-val2 my-var2) "just in case")))

-(testing "unpatch all works in explicit context"
+(u/deftest+
+  "unpatch-all works in explicit context"
   (let [ctx (fc/context)
         original-val my-var1]
     (fc/patch! ctx #'my-var1 200)


disable collection in async include-vertex!

--- src/thi/ng/fabric/core.cljc
+++ src/thi/ng/fabric/core.cljc
@@ -436,7 +436,7 @@
         (processor v _)
         (when (should-signal? v s-thresh)
           (signal! v async-vertex-signal))
-        (when (should-collect? v c-thresh)
+        #_(when (should-collect? v c-thresh)
           (collect! v))
         _)
       (execute!


only helps print detailed commands - else print just a commandlist

--- src/todos/executor/core.clj
+++ src/todos/executor/core.clj
@@ -31,7 +31,7 @@

     (not= cmd "exit")
     (do
-      (let [help-map (conj {"exit" {"exit" "quit the app"}}
+      (let [help-map (conj {"exit" {"exit" "quit the app"} "help" {"help" "prints a detailed help"}}
                            exec-save/help
                            exec-create/help
                            exec-remove/help
@@ -43,11 +43,15 @@
                                         (apply max (map count (keys (help-map i)))))
                                       (keys help-map)
                                       ))]
-        (doseq [topic (sort (keys help-map))]
-          (println)
-          (println (clojure.string/join " " (seq topic)))
-          (println)
-          (doseq [cmd-help (sort (keys (help-map topic)))]
-            (println (format (str "%-" count-length "s - %s") cmd-help ((help-map topic) cmd-help)))
-            ))))))
+        (if (= cmd "help")
+          (doseq [topic (sort (keys help-map))]
+            (println)
+            (println (clojure.string/join " " (seq topic)))
+            (println)
+            (doseq [cmd-help (sort (keys (help-map topic)))]
+              (println (format (str "%-" count-length "s - %s") cmd-help ((help-map topic) cmd-help)))
+            ))
+          (doseq [topic (sort (keys help-map))]
+            (println (format "%s: %s" topic (clojure.string/join ", " (sort (keys (help-map topic)))))))
+          )))))


remove errant equals sign

remove errant equals sign

--- tech-int/src/tech_int/core.clj
+++ tech-int/src/tech_int/core.clj
@@ -96,7 +96,7 @@
     (println "2. Pig latin to english")
     (def choice (read-line))
     (try
-        (if (and (Integer. choice) (<= (Integer. choice) 3))
+        (if (and (Integer. choice) (< (Integer. choice) 3))
             (do
                 (println "Enter a phrase:")
                 (def inputPhrase (read-line))


revert back changes

revert back changes

--- test/jepsen/voltdb/dirty_read_test.clj
+++ test/jepsen/voltdb/dirty_read_test.clj
@@ -6,7 +6,5 @@

 (deftest a-test
   (loop []
-    (when (is (:valid? (:results (jepsen/run! (dirty-read-test {:tarball tarball
-    :procedure-call-timeout 5000}
-)))))
+    (when (is (:valid? (:results (jepsen/run! (dirty-read-test tarball)))))
       (recur))))


Generative test random peer leaving

Generative test random peer leaving

--- test/onyx/log/generative_peer_join.clj
+++ test/onyx/log/generative_peer_join.clj
@@ -408,7 +408,7 @@
      [2 2 4]))
    (is (= (map count (vals (get (:allocations replica) job-3-id))) []))))

-(deftest peer-leave
+(deftest peer-leave-4
   (checking
     "Checking peer leave is correctly performed"
     (times 50)
@@ -420,9 +420,59 @@
           :message-id 0
           :entries
           (-> (log-gen/generate-join-queues (log-gen/generate-peer-ids 4))
-              (assoc :leave-anytime [{:fn :leave-cluster
-                                      :args {:id :p1}
-                                      :immediate? true}]))
-          :log []
-          :peer-choices []}))]
-    (= 3 (count (:peers replica)))))
+              (assoc :leave {:predicate (fn [replica entry]
+                                          (some #{:p1} (:peers replica)))
+                             :queue [{:fn :leave-cluster
+                                      :args {:id :p1}}]}))
+          :log []
+          :peer-choices []}))]
+    (is (= 3 (count (:peer-state replica))))
+    (is (= 3 (count (:peers replica))))))
+
+(deftest peer-leave
+  (checking
+    "Checking peer leave is correctly performed"
+    (times 50)
+    [{:keys [replica log peer-choices]}
+     (log-gen/apply-entries-gen
+       (gen/return
+         {:replica {:job-scheduler :onyx.job-scheduler/balanced
+                    :messaging {:onyx.messaging/impl :dummy-messenger}}
+          :message-id 0
+          :entries
+          (-> (log-gen/generate-join-queues (log-gen/generate-peer-ids 3))
+              (assoc :leave-anytime {:queue [{:fn :leave-cluster
+                                              :args {:id :p1}}]}))
+          :log []
+          :peer-choices []}))]
+    (is (or (= 2 (count (:peer-state replica)))
+            (= 3 (count (:peer-state replica)))))
+    (is (or (= 2 (count (:peers replica)))
+            (= 3 (count (:peers replica)))))))
+
+
+(deftest peer-leave-still-running
+  (checking
+    "Checking peer leave is correctly performed"
+    (times 50)
+    [{:keys [replica log peer-choices]}
+     (log-gen/apply-entries-gen
+       (gen/return
+         {:replica {:job-scheduler :onyx.job-scheduler/balanced
+                    :messaging {:onyx.messaging/impl :dummy-messenger}}
+          :message-id 0
+          :entries
+          (-> (log-gen/generate-join-queues (log-gen/generate-peer-ids 9))
+              (assoc :job-1 {:queue [(api/create-submit-job-entry
+                                       job-1-id
+                                       peer-config
+                                       job-1-pct-tasks
+                                       (planning/discover-tasks (:catalog job-1-pct-tasks) (:workflow job-1-pct-tasks)))]})
+              (assoc :leave-1 {:queue [{:fn :leave-cluster :args {:id :p1}}]})
+              (assoc :leave-2 {:queue [{:fn :leave-cluster :args {:id :p2}}]}))
+          :log []
+          :peer-choices []}))]
+    ;; peers may have left before they joined, so there should be at LEAST 7 peers allocated
+    ;; since there are enough peers to handle 2 peers leaving without a task being deallocated the
+    ;; job must be able to go on
+    (is (>= (apply + (map count (vals (get (:allocations replica) job-1-id)))) 7))))


(maint) add connection test for alternative certs

This commit augments the ssl-ca-cert-permutation-test to ensure
that the client can connect with the alternative certs so that
the test will fail if the certs are expired or in invalid.

--- test/puppetlabs/pcp/messaging_test.clj
+++ test/puppetlabs/pcp/messaging_test.clj
@@ -201,7 +201,25 @@
                                  (assoc-in (client-config "client01")
                                         [:ssl-context :cacert] (str "test-resources/" client-ca "/certs/ca.pem"))
                                  (constantly true))]
-              (client/wait-for-connection client (* 4 1000))))))))
+              (client/wait-for-connection client (* 4 1000)))))))
+  (testing "alternative certs are valid"
+    ;; if the certs are invalid (expired, etc.), the test above
+    ;; will still pass as the log message still contains TLS Handshake failed...
+    ;; adding a test here as a check that the client can connect with the alt certs
+    (with-app-with-config app broker-services
+      (update-in broker-config [:webserver] merge
+                 {:ssl-crl-path "./test-resources/ssl-alt/ca/ca_crl.pem"
+                  :ssl-ca-cert "./test-resources/ssl-alt/ca/ca_crt.pem"
+                  :ssl-cert "./test-resources/ssl-alt/certs/localhost.pem"
+                  :ssl-key "./test-resources/ssl-alt/private_keys/localhost.pem"})
+      (with-open [client (connect-client-config
+                           (update-in (client-config "client01") [:ssl-context] merge
+                                      {:cacert "test-resources/ssl-alt/certs/ca.pem"
+                                       :cert "test-resources/ssl-alt/certs/client01.example.com.pem"
+                                       :private-key "test-resources/ssl-alt/private_keys/client01.example.com.pem"})
+                           (constantly true))]
+        (client/wait-for-connection client (* 4 1000))
+        (is (client/connected? client) "Client will connect unless certs are invalid")))))

 (deftest ssl-context-test
   (with-app-with-config app broker-services broker-config


Fix unexpected exception on default service handler.

--- src/uxbox/services/core.clj
+++ src/uxbox/services/core.clj
@@ -20,7 +20,7 @@
             :message-type type))

 (defmethod query :default
-  [data]
+  [{:keys [type] :as data}]
   (ex/raise :code ::not-implemented
             :message-category :query
             :message-type type))


Adding centroid function.

Adding centroid function.

--- src/wanderlust/geometry.clj
+++ src/wanderlust/geometry.clj
@@ -2,11 +2,6 @@
   (:require [delaunay-triangulation.core :as delaunay]
             [wanderlust.voronoi :as voronoi]))

-;; y = ((x - xf)^2 +yf^2 - L^2)/(2*(yf - L))
-(defn parabola [x f L]
-  (+
-   (Math/pow (- x (* x f)) 2)
-   (- (* ))))

 (defn triangulate [points]
   (:edges (delaunay/triangulate points)))
@@ -104,7 +99,16 @@
   (boolean (some #(inside-triangle? point %) (polygon->triangles polygon))))

+(defn centroid [polygon]
+  (let [n (count polygon)]
+    [(/ (reduce + (map first polygon)) n)
+     (/ (reduce + (map second polygon)) n)]))
+
+
 (comment
+
+  (centroid [[0 0] [0 10] [10 10] [10 0]])
+

   (line-length [[10 40] [11 30]])


Remove unused code

Remove unused code

--- src/swanson/routes/transactions.clj
+++ src/swanson/routes/transactions.clj
@@ -37,7 +37,6 @@
                    parsed-transaction (utils/parse-transaction body)
                    trans-id (:id parsed-transaction)
                    new-category-id (:category_id parsed-transaction)]
-               (println (str "about to PUT change to id " parsed-id " changing category id to " new-category-id))
                (db/update-category-id parsed-id new-category-id)))
   :respond-with-entity? true)


added say command to referred functions

added say command to referred functions

--- src/test/clojure/naojure/sample.clj
+++ src/test/clojure/naojure/sample.clj
@@ -2,7 +2,7 @@
   (:require [naojure.core :as nao :refer []]))

 (require '[naojure.core :as nao
-           :refer [head arms elbows wrists hands legs knees feet]]
+           :refer [head arms elbows wrists hands legs knees feet say]]
          '[clojure.core.async :as async
            :refer [<! >! timeout chan alt! go]]
          '[clojure.pprint :refer [pprint]])


Better test assertion.

Better test assertion.

--- test/onyx/peer/tail_params_test.clj
+++ test/onyx/peer/tail_params_test.clj
@@ -34,7 +34,7 @@
   {:lifecycle/before-task-start inject-out-ch})

 (defn my-adder [factor {:keys [n] :as segment}]
-  (throw (ex-info "fail" {})))
+  (throw (ex-info "fail" {:x 50})))

 (deftest tail-params
   (let [id (random-uuid)
@@ -89,4 +89,5 @@
           (onyx.test-helper/feedback-exception! peer-config job-id)
           (is false)
           (catch Exception e
-            (is true)))))))
+            (is (= "fail" (.getMessage e)))
+            (is (= {:x 50}) (ex-data e))))))))


remove size checks

remove size checks

--- kafka-clj/src/kafka_clj/client.clj
+++ kafka-clj/src/kafka_clj/client.clj
@@ -71,6 +71,9 @@
     (let [acc2 (+ acc (count (:bts (get-latest-msg messages))))]
       (tuple (>= acc2 v) acc2))))

+(defonce t (tuple false false))
+(defn- always-false ([] false) ([_ _] t))
+
 (defn create-producer-buffer [connector topic partition producer-error-ch {:keys [host port]} {:keys [batch-num-messages queue-buffering-max-ms] :or
                                                                    {batch-num-messages 100 queue-buffering-max-ms 1000} :as conf}]
   "Creates a producer and buffered-chan with a go loop that will read off the buffered chan and send to the producer.
@@ -80,10 +83,7 @@
         ch-source (chan 100)
         read-ch (-> producer :client :read-ch)
                                ;ch-source buffer-count timeout-ms buffer-or-n check-f
-        buff-ch (buffered-chan ch-source batch-num-messages queue-buffering-max-ms 10 (fn ;;do not accumulate more than a megabyte of data
-                                                                                ([] (count-bytes))
-                                                                                ([acc v]
-                                                                                (count-bytes acc v 1048576))))
+        buff-ch (buffered-chan ch-source batch-num-messages queue-buffering-max-ms 10 always-false)

         handle-send-message-error (fn [e producer conf offset v]
                                     (error e e)


working connector- still todo error handling

--- kafka-clj/src/kafka_clj/client.clj
+++ kafka-clj/src/kafka_clj/client.clj
@@ -92,7 +92,7 @@
 (defn close [{:keys [producers-ref]}]
   "Close all producers and channels created for the connected"
   (doseq [{:keys [producer ch-source]} producers-ref]
-    (async/close ch-source)
+    (async/close! ch-source)
     (shutdown producer)))

 (defn create-connector [bootstrap-brokers conf]


add elevation compute logic

add elevation compute logic

--- src-cljs/flatride/core.cljs
+++ src-cljs/flatride/core.cljs
@@ -21,10 +21,38 @@
     }))

 (defn start-compute-routes [from to display-fn]
-  (let [req-obj (directions-config-obj from to)]
-    (.route (window/google.maps.DirectionsService.)
-            req-obj
-            (partial process-routes display-fn))))
+  (let [req-obj (directions-config-obj from to)
+        ds (window/google.maps.DirectionsService.)]
+    (.route ds req-obj (partial process-routes display-fn))))
+
+(defn increasing-seqs [coll]
+  "Vector of subvectors of coll that are increasing"
+  (reductions
+    (fn [current-seq next-elem]
+      (if (>= next-elem (last current-seq))
+        (conj current-seq next-elem)
+        [next-elem]))
+    [(first coll)]
+    (rest coll)))
+
+(defn longest-seq [seqs]
+  "Longest seq within seqs"
+  (reduce #(if (>= (count %1) (count %2)) %1 %2) [] seqs))
+
+(defn greatest-sum-seq [seqs]
+  "Highest sum seq within seqs"
+  (apply max-key #(reduce + %) seqs))
+
+(defn process-elevation-data [elevations status]
+  (log elevations)
+  )
+
+(defn start-compute-elevation-data [route]
+  (let [es (window/google.maps.ElevationService.)
+        path-req (js-obj "path" route "samples" 200)]
+    (.getElevationAlongPath path-req process-elevation-data)))
+
+

 (defn process-routes [display-fn routes status]
   ; when no bike available fall back to car TODO


Removed dead code.

Removed dead code.

--- src-cljs/freactive/dom.cljs
+++ src-cljs/freactive/dom.cljs
@@ -11,10 +11,6 @@

 (defprotocol IElementSpec
   (-get-virtual-dom [x]))
-
-;(defrecord ElementSpec [spec]
-;  IElementSpec
-;  (-get-virtual-dom [x] spec))

 (defn- dom-node? [x]
   (and x (> (.-nodeType x) 0)))
@@ -68,13 +64,6 @@
 (declare set-attr!)

 (declare get-transition)
-
-;; (defn- init-element-meta! [state element-spec tag ]
-;;   (let [m (meta element-spec)]
-;;     (set! (.-meta state) m)
-;;     (when-let [on-disposed (get m :node-disposed)]
-;;       (set! (.-disposed-callback state) on-disposed)))
-;;   (set! (.-tag state) tag))

 (defn- reset-element-spec! [state spec tag]
   (when-let [on-disposed (.-disposed-callback state)]
@@ -145,21 +134,6 @@
       (node-detaching x (fn [] (remove-dom-node x)))
       (remove-dom-node x))
     (-remove! x)))
-
-;; ## Defining Transitions
-
-;(defn- wrap-element-spec [elem-spec]
-;  (if (string? elem-spec)
-;    (ElementSpec. elem-spec)
-;    elem-spec))
-
-;; (defn with-transitions [elem-spec transitions]
-;;   (vary-meta elem-spec merge transitions))
-
-;; (defn- exec-transition [node transition-name callback]
-;;   (if-let [transition (get-transition node transition-name)]
-;;     (transition node callback)
-;;     (when callback (callback))))

 ;; ## Polyfills

@@ -341,7 +315,7 @@
         (.removeAttribute element attr-name)))))

 (defn- bind-lifecycle-callback! [node node-state cb-name cb-value]
-  (when (identical? cb-name "disposed")
+  (when (identical? cb-name "on-disposed")
     (set! (.-disposed-callback node-state) cb-value)
     ;; other callbacks automatically included in attr map
     ))
@@ -702,41 +676,7 @@
         (on-attached state new-elem))
       new-elem)))

-;(defn- do-show-element [parent new-elem nil]
-;  (when new-elem
-;    (let [show (get-transition new-elem :node-attached)
-;          new-elem (replace-or-append-child parent new-elem cur-elem true)]
-;      (when show
-;        (show new-elem)
-;        new-elem)
-;      new-elem)))
-
-(defn- mount-element
-  ([parent new-elem before]
-   (let [show (get-transition new-elem :node-mounted)
-         new-elem (append-or-insert-child parent new-elem before)]
-     (when show
-       (show new-elem)
-       new-elem)
-     new-elem)))
-
-;; (defn- clear-children! [parent]
-;;   (let [dom-node parent
-;;   ;(get-dom-node parent)
-;;         ]
-;;     (loop []
-;;       (let [last-child (.-lastChild dom-node)]
-;;         (when last-child
-;;           (.removeChild dom-node last-child)
-;;           (recur))))))
-
-;; (defn- hide-node [node callback]
-;;   (exec-transition node :node-detaching callback))
-
 ;; Reactive Element Handling
-
-;; (defprotocol INodeContainer
-;;   (-replace [container new-elem-spec]))

 (deftype ReactiveElement [id parent ref cur-element dirty updating disposed
                           animate invalidate]
@@ -839,7 +779,7 @@
         (show-new-elem (get-new-elem) cur)
         state)
       (do
-        (mount-element parent (raw-deref* child-ref) before)))))
+        (insert-child* (raw-deref* child-ref) before)))))

 (defn bind-child [parent child before cur]
   (if-let [binder (:binder (meta child))]
@@ -849,15 +789,10 @@
 ;; Building Elements

 (defn insert-child! [parent child before]
-  (cond
-    (satisfies? IDeref child)
-    (bind-child parent child before nil)
-
-    :default
-    (mount-element parent child before)))
+  (append-or-insert-child parent child before))

 (defn append-child! [parent child]
-  (insert-child! parent child nil))
+  (append-or-insert-child parent child nil))

 (defn- append-children! [elem children]
   (doseq [ch children]