Fork me on GitHub
#luminus
<
2022-02-11
>
Marius08:02:52

Hi, I’m trying to set up https://github.com/luminus-framework/jdbc-ring-session in my Luminus-based app, but have problems creating the session store. The line

(def session-store (jdbc-store (env :database-url)))
in clj/db/core.clj is causing exception
Caused by: java.lang.ClassCastException: class mount.core.DerefableState cannot be cast to class clojure.lang.IFn (mount.core.DerefableState is in unnamed module of loader clojure.lang.DynamicClassLoader @61799544; clojure.lang.IFn is in unnamed module of loader 'app')
        at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3702)
        ... 122 more
What am I doing wrong?

javahippie08:02:58

Not a lot of context, but I see that error message sometimes if a mount component was not initialized, so I assume that’s what happened to the component you are trying to reference with env?

Marius09:02:04

Oh okay, well then env seem not to be initialized

(defstate env
  :start
  (load-config
    :merge
    [(args)
     (source/from-system-props)
     (source/from-env)]))

javahippie09:02:53

Did env work for other components? What do you see if you type (start) in the user ns in your REPL?

Marius09:02:59

Right now the application REPL does not come up. I think what I am doing wrong here is to use env before the application is started, because of the (static?) definition of (def session-store (jdbc-store (env :database-url)))

Marius09:02:24

Exception in thread "main" Syntax error macroexpanding at (core.clj:25:32).
	at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3711)
	at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3705)
...
	at clojure.lang.RT.init(RT.java:467)
	at clojure.main.main(main.java:38)
Caused by: java.lang.ClassCastException: class mount.core.DerefableState cannot be cast to class clojure.lang.IFn (mount.core.DerefableState is in unnamed module of loader clojure.lang.DynamicClassLoader @61799544; clojure.lang.IFn is in unnamed module of loader 'app')
	at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3702)
	... 122 more

javahippie09:02:59

Ah yes, I did not think about that 🙂 The def is loaded on ns-initialization, before (start), you are right.

javahippie09:02:54

I just checked in one of our applications, we just add it to our wrap-base function in the project-name.middleware namespace

javahippie09:02:59

(defn wrap-base [handler]
  (-> ((:middleware defaults) handler)
      (wrap-idle-session-timeout {:timeout (* 30 60)
                                  :timeout-response {:status 200
                                                     :body "Session timed out"}})
      (wrap-defaults
        (-> site-defaults
            (assoc-in [:security :anti-forgery] false)
            (assoc-in  [:session :store] (jdbc-store (:datasource *db*)))))
      wrap-internal-error))

javahippie09:02:29

Which might look different than yours, of course

Marius09:02:50

Ah okay, that makes sense. Then it’s within the function and will be executed then the app is running. Also you’re passing *db* instead of the connection url, which probably makes sense to use the same connection pool…?!

javahippie09:02:12

Yes, that’s correct

Marius09:02:21

Cool, that works! Thank you very much, you saved me a lot of time 🙂

javahippie09:02:29

Happy to hear that 🙂

Marius09:02:00

Btw. I will shamelessly copy that wrap-idle-session-timeout - that solves another item on my todo list 😉

javahippie09:02:20

Feel free 😄

Marius10:02:16

When persisting sessions using https://github.com/luminus-framework/jdbc-ring-session the following exception is thrown:

2022-02-11 10:39:04,743 [worker-2] ERROR payroll.middleware - Unfreezable type: class next.jdbc.result_set$navize_row$fn__21563 
clojure.lang.ExceptionInfo: Unfreezable type: class next.jdbc.result_set$navize_row$fn__21563
        at taoensso.nippy$throw_unfreezable.invokeStatic(nippy.clj:1003)
        at taoensso.nippy$throw_unfreezable.invoke(nippy.clj:1000)
Could this be caused by certain objects in the session which are not serializable or something like that?

javahippie10:02:07

Yes, nippy cannot handle that type. I’m wondering why it gets this type, however. Does jdbc-ring-session write values into the db for you?

Marius11:02:44

Well each session is written to the db, serialized as blob, or what do you mean?

javahippie11:02:33

Yes, so writing works, but reloading from the db does not?

Marius11:02:19

Ah sorry, I misunderstood. No, it is not writing. Above exception occurs when the first session is about to be written.

jmckitrick22:02:46

I’m implementing ‘logout’ for a basic web app. Has anyone else seen a difference between (assoc session :identity nil) vs (dissoc session :identity) ? It seems to me that dissoc doesn’t really clear the identity in the session, but I’m not clear on why.