def call(conn, _opts) do
last_seen = get_session(conn, :last_seen)
user = conn.assigns[:current_user]
cond do
user && last_seen && last_seen < (unix_now() - @one_hour) ->
persist_last_seen(user) # Saves last_seen to DB
put_session(conn, :last_seen, unix_now())
user && !last_seen ->
put_session(conn, :last_seen, unix_now())
true ->
conn
end
end
A few questions:
This doesn’t look like it will update last_seen for the first hour in a new session?
Why do we need to store last_seen in the session at all?
It feels like I can replace the above with much simpler code:
def call(conn, _opts) do
user = conn.assigns[:current_user]
if user && DateTime.diff(unix_now(), user.last_seen) > @one_hour do
persist_last_seen(user, unix_now())
end
conn
end
NB. Both plugs assume the user was fetched in a previous plug.
Is my understanding correct on this? Thanks for the help.
I think that you’re right @tyr0 - with this code, the timestamp won’t be updated until the session is longer than one hour. It may have gone unnoticed because the migration sets a default timestamp.
The missing piece would be to also persist the timestamp in the second condition, that is, the first time you remember last_seen in the session:
cond do
user && last_seen && last_seen < (unix_now() - @one_hour) ->
persist_last_seen(user)
put_session(conn, :last_seen, unix_now())
user && !last_seen ->
persist_last_seen(user)
put_session(conn, :last_seen, unix_now())
true ->
conn
end
That is, we want to persist_last_seen(user) in both cases: on the first visit (second clause) and on subsequent visits after the first hour (first clause).
Now, both clauses do the same, persist to DB and remember in session, so what I did is just this:
def call(conn, _opts) do
last_seen = get_session(conn, :last_seen)
user = conn.assigns[:current_user]
if user && (!last_seen || (last_seen && last_seen < unix_now() - @five_minutes)) do
persist_last_seen(user)
put_session(conn, :last_seen, unix_now())
else
conn
end
end
Like “if there’s a user and it’s the first time seen in this session or was seen earlier than 5 minutes ago…”
Regarding session variables, I think it’s a good idea at least in my case, as I use Pow and it has a cache, so conn.assigns[:current_user] won’t be as up to date as the session variable.
Ha. Didn’t expect a reply to this after so long! And I didn’t realise that Pow has a cache, so yes, makes sense to persist the data to session in that case.