Re: Atomicity in network protocols



Hi Robert,

On 7/17/2011 12:14 AM, Robert Wessel wrote:
On Sat, 16 Jul 2011 23:46:44 -0700, Don Y<nowhere@xxxxxxxx> wrote:

I was suggesting altering the protocol to something along the lines of
how you'd implement many of the lock-free algorithms in multi-threaded
applications. IOW, by providing a robust way for the client to see
that another update has happened, it can then retry. Obviously that

Ah, OK. But, the client will still *infer* that something has
changed simply because his SET failed.

While I don't know if this applies in your situation, that would not
usually be adequate. Consider the case where the client knows the
server is in state A, and therefore wishes to set state B. In the
mean time, another client sets the server to state C. Setting the
server from C to B may be perfectly valid (thus not generating an
error), but might not be what the first client actually wanted. The
idea being that the update works if the server was in the state
expected by the client, and only then.

Not the case, here.

The server is always in a "valid" state (i.e., if you equate the
configuration that the server is imposing on the actual "device"
as being the state of the server).

SETs can only move the server to another valid state (else they
fail).

SETs can bring the server to a more restricted or *less* restricted
state. I.e., if a client changes *his* current configuration to
one that is more tolerant (e.g., changing from 1% accuracy to 5%)
then the server (device) can (possibly) move from a more tightly
defined state to a more permissive one (e.g., at 5% accuracy, the
range of measurable data values might be greater than it was at 1%).

Note that actions of another client can never invalidate the *current*
configuration for any of the connected clients. E.g., if client1
wants 1% accuracy and the other clients want 5%, then the device
still operates at 1% even though "most" of the clients don't need/want
that accuracy.

However, if one of those clients has dropped his accuracy to 5%
in the hope of increasing the measurement range to something larger,
that SET RANGE can be denied -- because the device might be forced to
remain in a narrower range in order to satisfy the needs of the "1%"
client.

A "problem" with this whole scheme is that clients are deliberately
isolated from the needs of other clients. Instead, the responsibility
of coordinating their requirements lies with the system designer.
I.e., if you designed a (single CPU) system with multiple consumers
of a particular data, it would fall to you to ensure each consumer had
the right data, with the right accuracy, timeliness, etc. -- even *if*
those consumers all knew about each other.

Then instead of letting the client set a server's state, let a client
tell the server its requirements. The server then keeps track of what
each client wants, and adjusts its behavior appropriately. If a
client specifies requirement that are incompatible with what the
server can do (presumably because conflicting requirements have
already been set), you'd have to fail them at that point.

Yes, this is how it works currently.

A client (initially) knows nothing about a server's (i.e., the
device that the server is managing for the client(s)) capabilities.

A client (recall there can be multiple) connects to the server.

It then queries the capabilities available for that device
(low/high measurement limits, accuracy, error, latency, rate,
resolution, precision, etc.).

The current protocol allows *one* parameter at a time to be queried
(simplifies the protocol and also avoids the issue of "what param
values fit with which other param values) or set.

The client can query the "ideal" limit of the device (i.e., as if NO
contracts have been established), the *current* configuration of it's
connection (contract) or the current "best case" value for a
parameter (taking into consideration all other contracts in effect
at that instant). These are just different verbs in the protocol
which map to different "configuration_t" structs in the server.

So, if a device has operating ranges of {[1,10], [5,50], [10,100]}
queries for the *ideal* LOW and HIGH limits would yield "1" and "100"
regardless of WHEN they are issued. If a client had previously
(successfully) issued "SET LOW 7", then a query of the *current*
LOW would be reported as "7". In the absence of any HIGH contractual
obligations BY ANY CLIENTS, a query of the *best* LOW would report
"1" (because the [1,10] and [5,50] ranges can satisfy the "LOW of
not greater than 7". However, if some other client had requested a
HIGH limit of 40, then the *best* LOW would be reported as "5"
(because the [1,10] range would not be capable of handling this
"HIGH of at least 40" and "my" LOW of 7 -- but, the [5,50] range
*would*!)

The client can RESET any or all of it's configuration parameters
(i.e., for *its* contract). (It can also issue another SET for
a parameter that has already been SET -- subject to the same
constraints)

So, typically, a client would connect and then start querying
the device (server) about the parameters of greatest interest to it.
Typically, you are most interested in the range of values that
can be reported. So, you query the HIGH and LOW limits (two
queries) available. [actually, you query just *one* limit since
SETting that limit could affect the choices available to you for the
other limit... imagine a device supporting 3 ranges: [1,10], [5,50],
[10,100] -- clearly, your choice of HIGH limit will determine the
LOW limit possibilities]

Then, you SET the limits as per your requirements. If there is
no intervening SET activity from other clients, these SETs will
succeed.

The server now knows what it must do to satisfy your *range*
of values. So, it can rule out certain operating configurations
for the device based on those choices. Of the configurations
that remain, it has a potentially narrowed set of options for
the other parameters (accuracy, resolution, etc.).

The client then queries the *next* most significant (to it) parameter
and makes a configuration choice accordingly.

In this way, it incrementally queries the server for the device's
capabilities *and* informs it of its requirements.

[this allows a client to "fudge" what it is willing to accept
based on the capabilities available to it at the time -- for the
device. E.g., a client might *want* a latency of 0.1 seconds but
would be willing to tolerate something ten times greater -- *if*
other parameters are appropriate]

Add a periodic poll to make sure each client still existed, so that
you can delete requirements when a client dies. Obviously if the
client told you it was going away, you'd do the same.

A client can RESET any or all of the parameters in its contract.
It can also close the connection. Or, the connection can be
*dropped* (either way, that contract is "voided").

If a client wants to guarantee a particular configuration remains
available, it must hold the connection open for the duration
(since a closed connection allows the server to revise how it
configures the device based on *new* clients connecting to the
service)

What you really want to be able to do is send a list of
potential configurations/requirements where each is accompanied
by a suitable predicate. So, you can, in effect, tell the server:
"Give me this configuration. But, if you can't, then *this*
would be my second choice -- unless you can't satisfy that
ACCURACY requirement, in which case you can try this one,
instead..."

Doing this in a comm protocol seems inappropriate. Instead,
let the client make those decisions "in code" and just convey
its prioritized choices, in order, *sequentially* to the server
as each one is rejected.

Again, this works *great*. It is lightweight, cheap to implement
(both in the protocol and the server), and easy to map your
"requirements" onto a (previously unseen) device's "capabilities".

*Except* when several clients are simultaneously negotiating contracts.
A kludge would be to deliberately impose an order on negotiations to
(effectively) cause clients to negotiate sequentially... <frown>

The problem I'm having is trying to forget about how I would
do this if these "client connections" were just "competing *tasks*"
operating on a uniprocessor. I.e., in that case, you would
put a mutex (or a monitor) around the "configuration" and
*discipline* tasks to take the lock *briefly*, do their query(s)
and set(s), and then release the lock.

But, in a distributed system, nothing is "quick". And, the
clients are developed by a greater number of personalities
(some of which might be less cooperative/skilled than others).
.



Relevant Pages

  • Re: .Net Scalability problem
    ... LoadRunner will peak out a server with a few virtual users. ... To get an idea of load, ... Fire off the test client and watch the number of ... > So I think that the MTC generate concurrent connection and per ...
    (microsoft.public.dotnet.framework.adonet)
  • Re: Connection lost at same time every hour (sometimes)
    ... After making the two following alterations on the server the problem seems ... After analyze your ipconfig on SBS and client, ... Then, other connection is good, ...
    (microsoft.public.windows.server.sbs)
  • Re: server disconnection - very often
    ... Reason of permanent popups is VMware server aplication on clients. ... Run CEICW to configure the network of SBS: ... Two network adapters - manual router connection to broadband ... Uninstall VMware on client. ...
    (microsoft.public.windows.server.sbs)
  • Re: Lan setup 2 nic
    ... The external nic only has TCP/IP enabled. ... Ipconfig of the server is looking good, but the client is still missing the ... > connection so we have a 2 nic with router setup now. ...
    (microsoft.public.windows.server.sbs)
  • Re: Regular disconnections from remote web workplace
    ... I can connect to office server and all office clients from home at all times ... be physically working right up until the connection is lost. ... If I enter http://companyip from a client I receive the login screen for the ... Click Services tab and select Hide All Microsoft Services and Disable ...
    (microsoft.public.windows.server.sbs)