Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

:resume-subscriptions? on subsequent init #67

Closed
hipitihop opened this issue May 22, 2020 · 6 comments
Closed

:resume-subscriptions? on subsequent init #67

hipitihop opened this issue May 22, 2020 · 6 comments

Comments

@hipitihop
Copy link

We use JWT auth tokens with expiry time and organise to refresh the JWT token prior to expiry, in turn, when we get the refreshed token, we dispatch ::re-graph/init again, however, despite specifying
:resume-subscriptions? true any existing subscriptions are dropped.

Is this a bug or do you recommend a way to deal with this use case ?

@oliyh
Copy link
Owner

oliyh commented May 22, 2020

Hi,

That option is actually to determine the behaviour when the websocket connection is lost and then reconnected - it will re-subscribe if that flag is true, and won't if not. If you re-initialise re-graph it loses all state including which subscriptions existed (its usage is here: https://github.com/oliyh/re-graph/blob/master/src/re_graph/internals.cljc#L211)

There's nothing to directly support your use case, but it should be possible. You need to reach into the re-frame database via re-frame.db/app-db and set your new connection-init-payload (where I presume your token goes) at [:re-graph :re-graph.internals/default :websocket :connection-init-payload] and then grab the websocket connection at [:re-graph :re-graph.internals/default :websocket :connection] and close it - that should trigger re-graph into reconnecting the websocket, sending the new connection-init-payload and resuming subscriptions.

If this works for you then we could add a new API call to achieve this so you're not delving around in the internals.

@stumitchell
Copy link

stumitchell commented May 25, 2020

Hi thanks for your help @hipitihop and I work together

The following code worked to refresh the jwt authentication

(reg-event-fx
  ::success-jwt
  (fn success-jwt-handler
    [{:keys [db]} [_ jwt]]
      (let [ms-prior-exp  (* 5 60 1000)                     ; 5 minutes in milliseconds
            jwt           (utils/map->nsmap jwt "jwt")
            refresh-ms    (-> (get jwt :jwt/exp)
                              (* 1000)
                              (time.coerce/from-long)
                              (refresh-in-milliseconds ms-prior-exp))
           headers       {:headers {"Authorization" (str "Bearer " (get jwt :jwt/token))}}]

        ;; Hang on to the token we were given and init re-graph
        (debug "Will refresh JWT in " refresh-ms "ms")
         {:db             (-> db
                                 (assoc :jwt jwt)
                                 (assoc-in [:re-graph :re-graph.internals/default 
                                            :websocket :connection-init-payload] headers)
                                 (update-in [:re-graph :re-graph.internals/default 
                                             :websocket :connection] #(.close %)))
            :dispatch-later [{:ms refresh-ms :dispatch [::fetch-jwt (get db :session) 1 true]}]}
          ))))

note the above code is heavy edited.

An API call to refresh the connection-payload would be great.
would also be nice if it triggered an immediate re-connection instead of having to wait the 5000ms or whatever the default timeout is.

Thanks

@oliyh
Copy link
Owner

oliyh commented May 25, 2020

Hi,
Glad that worked. I just had a simpler idea - if your server side would support it, could you just update the connection init payload and then call (dispatch [:re-graph.internals/connection-init]) to send it to the server? Then you don't have the overhead of new connections and the delay.

@oliyh
Copy link
Owner

oliyh commented Jun 8, 2020

Hi @stumitchell and @hipitihop did you have a chance to look at my suggestion?

Thanks,

@stumitchell
Copy link

yeah that seems to work too,

Not noticeably faster though still about a 6 second delay,

Stu

@oliyh
Copy link
Owner

oliyh commented Aug 10, 2020

Hi @stumitchell and @hipitihop I have just pushed 0.1.14-SNAPSHOT to clojars which adds the re-init api described in the README, this should be a more elegant solution for you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants