cowboy: session state and connection timeout

311 views
Skip to first unread message

jdmeta

unread,
Feb 24, 2021, 1:12:36 PM2/24/21
to erlang-q...@erlang.org

i'm building a web app using cowboy with mnesia as persistent storage.
the current version uses http (may move to websockets in the future).

during the lifetime of a user's session, i need to maintain per-user state that is available to all route handlers.
i plan to initialize this state when a user logs in and write parts of it to persistent storage when the session ends.
sessions can terminate because of the user logging out or because of a connection timeout.

if a user logs out, then my javascript can hit a route which can write persistent storage.
if the connection times out, i need to get a message (presumably from cowboy or ranch) to one of my processes so that it can write persistent storage.

i scoured the documentation for cowboy and ranch but didn't find any mention of a mechanism to receive a message on connection timeout.

any help would be appreciated.
thanx.

Leonard B

unread,
Feb 24, 2021, 2:04:43 PM2/24/21
to jdmeta, Erlang/OTP discussions
My understanding would be that:
1. a connection in cowboy is not what you think it is for plain http.
It only exists for the lifespan of the request/response.
2. the _client_ can experience a 'connection timeout', not the server,
since the client can time out attempting to connect to the server

The behavior in websockets(and h2) is a difference story entirely
since that is a persistent/stateful connection between the client and
server.

jdmeta

unread,
Mar 1, 2021, 11:14:29 PM3/1/21
to Leonard B, erlang-q...@erlang.org

thanx for the reply leonard.

agree about the http vs. websocket distinction.
i started out http because i was hoping i could get to mvp sooner but, as you point out, websockets has some advantages.
since i want to end up there anyway i may bite the bullet and gostraight there in mvp.

agree that clients can implement a timeout but servers can do the same.
on client authorization a token is created by the server and clients include said token as a header in their requests.
servers can start a timer on token accesses and invalidate the token if the timer expires.
subsequent requests from the client will be redirected to the login page.

this feels less brittle to me than solely depending on the javascript to hit a route when the tab/window is closed (or the network goes down, etc.)

it's still not completely clear to me how to maintain session state even for http in cowboy.
this is a well-known function in most web serving frameworks.
do i have to roll-my-own?


Roger Lipscombe

unread,
Mar 2, 2021, 4:05:24 AM3/2/21
to jdmeta, erlang-questions
On Tue, 2 Mar 2021 at 04:14, jdmeta <jdm...@gmail.com> wrote:

> it's still not completely clear to me how to maintain session state even for http in cowboy.
> this is a well-known function in most web serving frameworks.
> do i have to roll-my-own?

Yes.

Cowboy isn't a web *framework*; it's a web *server*. There are several
web frameworks built on top of it. The most popular, if you're
prepared to use Elixir, is Phoenix: https://www.phoenixframework.org/.
For Erlang. I think that the one that's most actively maintained is
https://nitrogenproject.com/. There are others.

If you don't want to use one of those, and if you want session
support, you'll have to find a library that implements it, or
implement your own. There's some documentation about using cookies
with cowboy here:
https://ninenines.eu/docs/en/cowboy/2.5/guide/cookies/, but -- if you
want server-side sessions -- you'll need to combine that with a
session store, probably in ETS. Searching online for "cowboy session"
returns two Erlang libraries, both kinda old, but you can use them as
inspiration.

Lloyd R. Prentice

unread,
Mar 2, 2021, 9:56:48 AM3/2/21
to Roger Lipscombe, jdmeta, erlang-questions
Hi,

A shameless plug for our book Build it with Nitrogen:


It shows how to build Erlang-based sites with Cowboy and other servers, mnesia and other dbs, how to manage state, and much much more.

Best of success with your project,

LRP

Sent from my iPad

On Mar 2, 2021, at 4:05 AM, Roger Lipscombe <ro...@differentpla.net> wrote:

Jesper Louis Andersen

unread,
Mar 2, 2021, 11:22:41 AM3/2/21
to jdmeta, Erlang (E-mail)
On Tue, Mar 2, 2021 at 5:14 AM jdmeta <jdm...@gmail.com> wrote:

thanx for the reply leonard.

agree about the http vs. websocket distinction.
i started out http because i was hoping i could get to mvp sooner but, as you point out, websockets has some advantages.
since i want to end up there anyway i may bite the bullet and gostraight there in mvp.


Websockets have a Ping/Pong setup. You can send a ping frame and expect a pong frame back. TCP sockets have keepalive as an option you can set on the socket.

The reason for both is that an established TCP connection normally has no bytes flowing on it at all. So unless one end tries to transmit, the other end doesn't know the connection is down. I can create a TCP connection, get the handshake and then not send a byte for 7 days on that connection. It's still connected and up! TCP keepalive helps with this by sending a packet every 2 hours or so. And the ping/pong framing in websockets does it even more frequently.

In general, you can use this to eventually clean up, but note that there are some lingering that will be present in some corner cases as you don't know if the other end is slow to respond or gone.

Reply all
Reply to author
Forward
0 new messages