users@jersey.java.net

RE: [Jersey] RESTful Ordering (was: JAX-RS == REST? Or not? (was Re: [Jersey] What HATEOAS actually means))

From: Markus Karg <markus.karg_at_gmx.net>
Date: Sun, 21 Feb 2010 17:13:30 +0100

> I promise to try to understand the value of a "client state".. because
> most of system I ever worked in life has no meaning for such thing..
> as soon the data remains stored in the server side....... Looking to
> see a real and easy-to-understand usage for such feature..
>
> Your example of an ATM machine doesn't appear to help since doesn't
> matter what the client is seeing on the screen, every transaction will
> require a server side validation against the state stored in the
> server side ... So, such state in the client side is a temporary and
> worthless data... only when the ATM opens a session and the operator
> requests a transaction on the terminal (debt, payment, etc.) the data
> is consistent.. and for a small amount of time..
>
> but perhaps I am missing something.. I will keep following your
> threads.. let's see.......

Well, it was an example to learn what the difference between stateful and
stateless ist, not an example about what it could be useful of. ;-)

The benefit of the client state is this: Think of the case that you have one
single bank server (not a cluster like Amazon and Google has). So you must
take care of scarce central resources. Now your bank starts building ATMs.
After several weeks you'll have an ATM in any other petrol station, shipping
mall, cinema, and whatever. You don't like the idea that you must add lots
of servers to scale with this. You like to stick with at least servers as
possible.

So you start using the client as a resource, loading off as much of the
per-client state to exactly that client. This frees your central server from
the needed space to keep this information, by offloading it "to the other
side" (and in part to the wire, actually).

When you go to an ATM, the ATM needs to know "what to do next". As it knows
it's current state ("idle"), it knows that there is no need to talk to the
server so far. Great. It asks you for your PIN, you type it in, and next
uses your account card to check whether that PIN is valid. No need for a
server so far. (actually I don't know whether this information is stored on
that card; this is just an example after all)

Now as it knows you are authenticated, it knows that you may see your
balance. So it shows a menu what you can do currently. (At least here in
Germany there are lots of actions that I can do at an ATM that do not need a
server, like putting in coins which the ATM keeps and stored the amount in a
special chip, useful for direct electronic payment. So still, no server
needed, actually. This proofs that the overall systems works but does NOT
need a roundtrip after EACH step.)

Next you click on "balance". To know the balance, we obviously need a
roundtrip. So Account Number and PIN are sent to the server to request the
balance.

The result is that the server presents some data, containing the current
balance, and a list of URIs which the client could follow now. Let's be one
of them titled "payoff". Since the client knows that it is a ATM (let's keep
things simple for this example) it must know whether it may show the current
user the balance. How does it know? Since it stored its own state and knows
that you are still there, have not logged out so far, but have correctly
typed in your PIN. This information is not needed to get requested from the
server. It knows it on its own.

Next you will type in your amount and press "payoff". The client uses the
"payoff" link provided by the server in the first round (as the ATM knows
that it is an ATM and such understands what a "payoff" link is good for). It
sends not only the amount, but also the account number and PIN to the
server. Again! Yes! Why? Because the server did not store the information
that you are standing at an ATM and already identified yourself. In fact,
the server discarded the knowledge that you had been correctly identified
before and that your balance was sent just a minute before to that ATM.
Without sending back the account number and PIN, he wouldn't actually know
who you are or at what ATM you are standing. THAT is why the client must
know his own state: To be able to provide it to the server, since the server
just forgot about meanwhile.

Why did the server discard the information and not just stored the relation
between your IP, account and PIN to prevent later "unnecessary" resending?
Because it is RESTful! ;-) No, seriously, because with thousands of people
using ATMs at every other minute, this would need lots of resources (port
numbers, RAM, HDD). Port numbers are not endless, and you need one for each
client. RAM is cheap, but not for free. HDDs are slow. If an ATM would crash
down, or the connection would be cut, the session would stay "alive" forever
on the server, squandering resources forever, and you'd need a complex
rollback procedure to safely free that resources explicitly. But if the
server just forgets about it, nothing bad happens. All the ATM must do after
the connection is back again (or it was rebooted) is to remember it's own
last state, and go on. As the server doesn't expect any particular sequence
of steps, it plays no role whether this will be a minute later, a year
later, or never.

This allows you to add virtually endless numbers of ATMs to one single
server. As long as they do not send requests, the server doesn't squander
any resource to them (no IP ports, RAM, HDD space, no orphan checking / keep
alive pings, and so on). That means, in case one single person would use
*all* ATMs at the same time in a round-robin fashion, but keeping logged in
for hours, the actual workload on the server would be between zero and one
requests at any time (as one person cannot trigger two "payoff" buttons at
the same time)! If you instead would keep the information stored on the
server (i. e. stateful session), at any time the server would have to store
the complete account number and PIN for each ATM, resulting in tremendous
resources getting squandered, resulting in side effects like swapping, long
response times, and so on. In practice certainly there is more than one
person at any time, but never will be the needed resources on the server as
big as keeping all login state of all ATMs.

As this example shows, it is not about benefits on the client side, but
benefits on the server side: Freeing Resources and Removing Transaction
Rollbacks.

BTW, not to get you confused: "Account number" and "PIN" as part of the
state kept by the client are just any sample data chosen for the sake of
this example, but I have not explicitly chosen those because they look like
being related to security or authentication! One could imagine a sample
where it is not about account and PIN, but anything else that the server
needs in the next step.