discard all wf:session values for all users

10 views
Skip to first unread message

braun...@gmail.com

unread,
Dec 17, 2020, 2:16:09 AM12/17/20
to Nitrogen Project / The Nitrogen Web Framework for Erlang
I have found wf:session values dont get discarded after application:stop(nitrogen).
The clients can still access the data.

Session handler uses process_registry_handler which dont implement this kind of selection. They only do K/V match. I dont think nproc_registry_handler could ever
support this broad selection. Gproc_registry_handler seems to be possible as it does a qlc query there...

I have shoot myself many times the last month testing an app, I reinitialize the database tables, I stop/start nitrogen again, but the clients will reference the now non-existing
data in their wf:session/wf:user. It has been a nightmare to find myself looking in complete awe for 30 minutes not understanding why my code crashes for no apparent reason.

So, now I'm wrapping session data with:
-define(SESSION_HASH, persistent_term:get(session_hash, nohash)).
session(K, V) -> wf:session(K, {data, ?SESSION_HASH, V}).
session(K) -> case wf:session(K) of
   {data, ?SESSION_HASH, V} -> V;
   _ -> undefined
end

And with this hack I can now "cancel" all session data "atomically"
cancel_sessions() ->
    persistent_term:put(session_hash, SomeNewRandomHash).

And voila,  clients now dont reference non-existing data anymore.

1) Why session data doesnt get discarded after stopping nitrogen. Is this by design?

I dont think I have the time to study the handlers (session and registry handlers) so I will imlement my own on top of ets.

2) What performance do you think I would get implementing session data in ets.

Jesse Gumm

unread,
Dec 17, 2020, 9:41:09 AM12/17/20
to nitrogenweb
Hi Franklin,

I don't think I've ever heard of wanting to discard all session values if the application is started or stopped.  It's extremely common to store sessions in external systems like Redis, or memcached, or even storing them to disk for persistence (consider the PHP default sessions are all stored on disk, each session getting its own file called something like "sess_abc123gfh9ng3"). All this is specifically so that sessions can survive a crash, reboot, or other system restart, and in the cases of the external sessions, so that multiple systems can share session data across nodes.

That Nitrogen doesn't discard all session data when the nitrogen application is stopped is merely a side-effect of the way sessions are built.   If the whole VM goes down in a single-node setup, then yes, all sessions would be eliminated.

The quickest way to wipe this data would be to start and stop nprocreg.

Regarding ETS, I'm unsure of what the performance might be if sessions get migrated to ETS.  It may be faster, it may be slower.  Given that each session, by default, is a sleeping process awaiting a message, I don't suspect the performance improvement would be significant, but benchmarking would be the only way to really know.

Indeed, I'd like to add a session handler with *greater* persistence - something that can survive a system crash, VM restart, or system Restart.

Can I ask what kind of data is being stored in your sessions that would cause a crash when the session survives nitrogen being restarted?  My gut is telling me it's more likely something like this would more appropriately be stored in something other than sessions.

-Jesse

--
You received this message because you are subscribed to the Google Groups "Nitrogen Project / The Nitrogen Web Framework for Erlang" group.
To unsubscribe from this group and stop receiving emails from it, send an email to nitrogenweb...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/nitrogenweb/2ba95ebb-e10c-4cb2-9cfe-497194c29cc3n%40googlegroups.com.


--
Jesse Gumm
Owner, Sigma Star Systems
414.940.4866 || sigma-star.com || @jessegumm

braun...@gmail.com

unread,
Dec 17, 2020, 12:31:36 PM12/17/20
to Nitrogen Project / The Nitrogen Web Framework for Erlang
Im just storing wf:user. This is an app that provides a neat experience to from the very first visit, there are welcoming messages and UX when the user accesses something for the first time. So I have to start from zero (recreate DBs) to check Im not breaking this coreography

The crashes are just typical matches that should never fail. Maybe Im a bit lazy:
[ThisRecordMustExist] = mnesia:dirty_read(userpreferences, wf:user())

Restarting nprocreg does the trick for me. Is there something else that nitrogen loses after this other than session data?

Jesse Gumm

unread,
Dec 17, 2020, 1:05:14 PM12/17/20
to nitrogenweb
Interesting.

Restarting nprocreg will also lose any active comet processes.

Basically, restarting nprocreg doesn't *stop* the processes it has started and registered, it just *forgets* about them.  They'll run their course and end automatically on their own.  So the existing sessions become orphaned processes that will autoexpire once the timeout hits (they just sit in a receive block waiting). Same with the comet processes, they'll sit waiting for a response, and eventually die on their own from their built-in timeout.

In vanilla Nitrogen, that's about it.

-Jesse


Reply all
Reply to author
Forward
0 new messages