sql

All things SQL and JDBC...
orestis 2021-06-25T11:56:35.281700Z

If you Google for Postgres “skip locked” you will find exactly what you want

11🎉
Jakub Holý 2021-06-25T12:41:24.287200Z

Hi @seancorfield! Is it possible that the effect of extend-protocol next.jdbc.result-set/ReadableColumn somehow "randomly" depends on the order of loading things? I sometimes observe that it seems not to have taken effect and I suspect it it because this is inside a library my app depends on while the app also depends on next.jdbc directly. Could it happend based on through which of the two "paths" next.jdbc is loaded first? The library has the extend-protocol call at the very top, extending ReadableColumn to java.sql.Timestamp to convert it into java.time.Instant . Further down in the same namespace I have a function that reads a timestamp from the DB and tries to use it as an Instant and fails in some instances of the REPL because it gets java.sql.Timestamp instead. This never happens in prod, only when running the app locally, from a REPL. Any tips? 🙏

emccue 2021-06-25T16:22:26.288Z

@holyjak If the protocol itself gets reloaded and your extend calls don't, that could be the cause

1❤️
emccue 2021-06-25T16:22:46.288500Z

it would essentially be the same as

emccue 2021-06-25T16:23:20.289600Z

(deftype A [])

(defprotocol B 
  (f [_]))

(extend-protocol B
  A
  (f [_] "abc"))

(defprotocol B 
  (f [_]))

emccue 2021-06-25T16:23:44.289900Z

so the var f would be rebound to the new protocol function

emccue 2021-06-25T16:24:01.290100Z

and would throw if called on A

Jakub Holý 2021-06-25T16:24:28.290200Z

Hm, that could be related, thank you! I think we did (clojure.tools.namespace.repl/refresh) Though I would expect it to reload both things and in the correct order ... /cc @haakon

seancorfield 2021-06-25T16:26:43.290700Z

Solution: don't use tnr/refresh 🙂

seancorfield 2021-06-25T16:26:57.290900Z

(this is exactly why I avoid these reload/refresh workflows!)

1👍
unbalanced 2021-06-25T17:31:11.291200Z

@lancetarn @orestis thanks so much, just to close the loop on this:

(do
      (future
        (time
         (do
           (with-open [conn (pg-autoconn/auto-conn! "my_db")]
             (jdbc/with-transaction [conn conn]
               (let [rows (jdbc/execute! conn ["select * from client_notification_queue for update skip locked limit 3"])]
                 (Thread/sleep 3000)
                 (println "Expecting 3: " (count rows))))))))
      (time
       (do
         (Thread/sleep 1000)
         (with-open [conn (pg-autoconn/auto-conn! "my_db")]
           (jdbc/with-transaction [conn conn]
             (let [rows (jdbc/execute! conn ["select * from client_notification_queue for update skip locked"])]
               (println "Expecting 1: " (count rows))))))))

;;=>
Expecting 1:  1
"Elapsed time: 1015.007809 msecs"
Expecting 3:  3
"Elapsed time: 3025.2133 msecs"
Thanks so much!! Also thanks @seancorfield for the awesome toolkit!

unbalanced 2021-06-25T17:31:30.291400Z

(excuse the hideous code, just trying to get the concept worked out)