I think this is a good idea. Allowing the user to acquire a session ID
could also allow for session-based authentication mechanisms to
function. And it could be optional, in the event that a user wants to
(for example) rapid-fire stateless or one-way requests to a large number
of balanced nodes. It could also be expanded to cover the
transaction/SFSB case we discussed, in that creation or acquisition of
these things would reuse or create a new ID based on whether one was
provided.
On 05/04/2016 09:59 PM, Stuart Douglas wrote:
I have updated the spec doc to now use client side generated id that
is
paired with a session cookie to ensure uniqueness and node affinity.
If the client does not already have a session id it can request one with
an affinity message.
Stuart
On Thu, May 5, 2016 at 10:03 AM, Stuart Douglas
<stuart.w.douglas(a)gmail.com <mailto:stuart.w.douglas@gmail.com>> wrote:
On Thu, May 5, 2016 at 8:55 AM, Stuart Douglas
<stuart.w.douglas(a)gmail.com <mailto:stuart.w.douglas@gmail.com>> wrote:
There are two problems with client generated ID's, and the main
one is that you can't guarantee that the cancellation message
will go to the same server as the original invocation. With my
current design the initial request will send back a JSESSIONID
that allows the cancel request to be targeted at the correct
server (of course if we already have affinity then this is not a
problem, but we can't guarantee that).
The other problem is that there is no easy way to guarantee
there will not be conflicts, although I guess you could send
back a 409 and force the client to retry with a new cancellation
id if a conflict happens. You can't really tie this to IP
because it may be behind a load balancer, and something like a
GUID may be expensive to generate for every invocation.
I just thought of a way to get around this. If we require the use of
an existing JSESSIONID for cancellable invocations both these
problems are resolved. The sticky session makes sure the correct
node is targeted, and the server can use the session id + invocation
id as a unique key.
The only overhead of this is that we could need some kind of
'affinity' request message that has no other purpose than generating
a session id if the client does not already have one (although this
would only need to be executed once).
Stuart
With the 1xx approach I am worried that not all load
balancers/proxies will properly support it. As this is not
really used outside of 'Expect: 100-continue' I would be
surprised if this works correctly without problems, even though
it is valid according to the spec.
Another potentially yucky way to do this would be to have the
client use chunked encoding and keep the request open, allowing
it to send some kind of cancellation token at any time. This
feels really hacky though.
Basically all the options suck, the one I put in the doc was
that one that I thought sucked the least when dealing with load
balancers.
Stuart
On Thu, May 5, 2016 at 12:11 AM, David M. Lloyd
<david.lloyd(a)redhat.com <mailto:david.lloyd@redhat.com>> wrote:
On 05/04/2016 12:50 AM, Stuart Douglas wrote:
> Hi everyone,
>
> I have started looking into support for service invocation over HTTP.
> Unlike our existing HTTP upgrade support this will map EJB
> requests/responses directly to HTTP requests and responses, which
should
> allow it to be used behind existing load balancers.
>
> I have started an initial description of the protocol at:
>https://github.com/stuartwdouglas/wildfly-http-client/blob/master/docs/wire-spec-v1.asciidoc
>
> The intention is to follow HTTP semantics as closely as possible.
> Clustering will be provided in a similar manner to web clustering (i.e.
> it will require a load balancer, and work in a similar manner to web
> clustering).
>
> There is still plenty work that needs to be done (especially around
> security), so if anyone has any feedback let me know.
One thing I noticed is that you went a different way with async
invocations and cancellation support.
The way I originally proposed was that the request/response
works as per
normal, but a 1xx header is used to send the client a
cancellation token
which can be POSTed back to the server to cancel the
invocation. I
understand that this approach requires 1xx support which
some clients
might not have.
In your proposal, the async EJB request always returns
immediately and
uses an invocation ID which can later be retrieved. I
rejected this
approach because it requires the server to maintain state
outside of the
request - something that is sure to fail. Also the client
doesn't
really have any notion as to when it can GET the response:
it would have
to do it more or less immediately to avoid a late response
(or when
Future.get() is called), meaning you need two round trips in
the common
case, which is not so good.
I think that the best compromise solution is to treat async
invocations
identically to regular invocations, and instead let the
*client* give a
cancellation ID to the server, which it can later POST to
the server as
I described in my original document. If the server receives the
client's ID (maybe also matching the client's IP address)
then the
request can be canceled if it is still running.
Failing this I still prefer the 1xx approach where the
server gives a
cancellation ID at the beginning of the request, as this
avoids problems
where the server has to maintain large object state for
indefinite
amounts of time. Either of these two options means only one
server
round trip for async invocation, and no server-side caching
of responses.
--
- DML
_______________________________________________
wildfly-dev mailing list
wildfly-dev(a)lists.jboss.org <mailto:wildfly-dev@lists.jboss.org>
https://lists.jboss.org/mailman/listinfo/wildfly-dev