
On 31/01/2014 22:28, Quoth Bjorn Reese:
Consider a secure RPC server, whose full API only can be used if the client has the correct privileges. For simplicity, let us assume that this is a single-client server. There are two modes: unauthenticated and authenticated. In unauthenticated mode, the server should reject all but the authentication requests. The way you typically would do this is to have separate implementations of the API for each mode, and when the client has been authenticated, the server will switch from the unauthenticated to the authenticated implementation. This wholesale replacement of the underlying implementation is much more difficult to do with the parallel initiator-callback style. We could solve the problem with another level of indirection, but that would effectively re-introduce the event listener.
The way to handle that, I would think, would be to have the "public" API be more limited in scope (not an identical copy that mostly returns not-authenticated errors), and to provide an "async_authenticate" request that calls back (single-shot) with an interface that provides the complete API. Async requests wouldn't carry over between the authenticated and unauthenticated API, but you wouldn't want that anyway -- most clients would authenticate first before making any other requests anyway, and one of the clients might be a "broker" that wants to maintain multiple independently authenticated connections with different credentials. Granted that's outside the scope of a single-client server, but the design would be easier to scale if it turns out that single-client isn't sufficient. Again, I'm not saying that Asio-style callbacks are the "best" way of implementing RPC or UI models. Just that it's not impossible to do so. (But at some level, you need a serialisation+networking layer to actually transfer requests between processes or machines. This can be made completely transparent to both server and client, but something has to be able to translate all the possible types of request.)