These are chat archives for atomix/atomix

26th
Jan 2017
Chris Cleveland
@ccleve
Jan 26 2017 22:49
I like JAX RS, but I don't know that it's right for StateMachine implementations. What you need is simpler: just a way to identify a method that handles a particular Command or Query. If you don't like your current scheme, then just a simple @ Command(commandClass=MyClass.class) annotation will do it. I don't see a need for anything else. I'd actually rather see better support for error handling when an unrecognized command shows up, or you try to send an object that isn't serializing properly.
Jordan Halterman
@kuujo
Jan 26 2017 23:08

@ccleve that is more or less what's done now, and an HTTP API can certainly be supported from that information, but the problem is that will limit HTTP API significantly. Without more rich information related specifically to REST protocols - like methods, headers, path and query parameters, etc - the Atomix HTTP API for resources would be limited to state machine method names and two HTTP methods. The DistributedMap API would look something like:

POST /sessions/1/myMap/put {"key": "foo", "value": "bar"}
GET /sessions/1/myMap/get?key=foo
POST /sessions/1/myMap/delete {"key": "foo"}
etc

While I agree that using the JAX-RS annotations for resources in Atomix feels less than ideal, something like it is almost certainly needed to build a flexible REST API. The goal is to support managing resources using the native Java API or HTTP/web sockets, and ideally both are efficient and well designed, meaning using binary serialization for the Java API and JSON with properly defined APIs for HTTP. The addition of JAX-RS annotations will just allow Atomix to expose a richer HTTP API for resources, so the map resource example above can have the map API one would expect:

POST/PUT /sessions/1/myMap/foo bar
GET /sessions/1/myMap/foo
DELETE /sessions/myMap/foo

I'm still not entirely sure what this will ultimately look like in state machines. There are actually a couple ways to go about it. State machines in Atomix could remain untouched and define a separate class for HTTP that converts HTTP requests into commands. Alternatively, JAX-RS does support annotating beans, so state machine command classes can just be annotated to handle the conversion from HTTP into commands. Finally, resource state machines can just be annotated with the JAX-RS annotations, which doesn't quite feel right.

We’ll see how it works out. Copycat 2.0 should be done in a couple days, then I’ll be building the HTTP API for Atomix and see if I can make it feel right
Chris Cleveland
@ccleve
Jan 26 2017 23:15
Consider the issue I just submitted on github. By adding a .submit() method directly on the server, you could cleanly separate any future HTTP API from Raft / Copycat operations. It strikes me that any HTTP API is really a very separate thing and should be in a completely independent, optional module. Since my app already has an HTTP API, I would really prefer to talk to Copycat or Atomix by making a straight Java method call.
Jordan Halterman
@kuujo
Jan 26 2017 23:48

Thanks for your input!

I would say HTTP will definitely be an optional feature in the Atomix programmatic API and will be in a separate module, but may or may not be optional in the standalone Atomix server. AtomixReplica already essentially does what you're describing. When you use a resource created on an AtomixReplica, it submits all commands/queries locally using a LocalTransport that just uses Executors. I think this is totally fine to do for simple state management, and that's what the replica API is made for. The reason that's not done in Copycat is just because sessions are needed to handle certain consistency issues, and I don't want to merge all the server and client code together, so Atomix does that instead.

But the problem with wrapping Atomix in an HTTP API is for more complex resources like locks and leader elections and that depend on sessions, it's both less efficient and more complex. It's not currently a simple feat to manage sessions over an HTTP API even if you do that, because each AtomixReplica has only one session. A lot of consistency information like indexes isn't exposed in that API. The HTTP support for Atomix 2.0 is implemented as a Copycat Protocol that makes session management possible and provides all the information necessary to manage consistency issues over HTTP, which is important.

To be clear, nothing is changing externally with the current versions of Copycat and Atomix. Everything that's possible now will still be possible with no added dependencies. Copycat is actually a lot more lightweight than it was before. The HTTP API is just a Protocol implementation - HttpProtocol - which is up to the user to use. I'm not sure if Atomix resources will have to have a dependency on JAX-RS yet or not. It should be possible to implement the HTTP APIs in a separate module.