These are chat archives for atomix/atomix

30th
Jul 2018
Jordan Halterman
@kuujo
Jul 30 2018 00:07
Maybe will push a release candidate tonight.
Johno Crawford
@johnou
Jul 30 2018 00:17
io.atomix.core.multiset.DistributedMultisetTest#testMultisetViews failure on java 10+ is weird
tried updating guava, still fails
Jordan Halterman
@kuujo
Jul 30 2018 00:18
I was wondering if it was a change in Stream semantics, but that would be a major no no
Johno Crawford
@johnou
Jul 30 2018 00:19
yeah..
although
Returns the count of elements in this stream. This is a special case of
 * a <a href="package-summary.html#Reduction">reduction</a> and is
 * equivalent to:
 * <pre>{@code
 *     return mapToLong(e -> 1L).sum();
 * }</pre>
Jordan Halterman
@kuujo
Jul 30 2018 00:19
I’d be curious to see what the client actually gets back from the partition before creating the stream
The batch it gets back
Also what the count is if you just iterate over the sets
Johno Crawford
@johnou
Jul 30 2018 00:20
multiset.setCount("foo", 1);
multiset.setCount("bar", 2);
multiset.setCount("baz", 3);
is it actually counting all of them
Jordan Halterman
@kuujo
Jul 30 2018 00:20
Maybe
Could be counting them twice
Johno Crawford
@johnou
Jul 30 2018 00:21
i just changed the values to 1, 2, 4
Jordan Halterman
@kuujo
Jul 30 2018 00:21
Have to see what’s actually received from the partition
Johno Crawford
@johnou
Jul 30 2018 00:21
java.lang.AssertionError:
Expected :3
Actual :7
<Click to see difference>
Jordan Halterman
@kuujo
Jul 30 2018 00:21
Did you have to change the Guava version?
Has to be something inside Multiset then
Johno Crawford
@johnou
Jul 30 2018 00:21
no, but i've reverted that
Jordan Halterman
@kuujo
Jul 30 2018 00:21
Maybe try it on a simple Multiset
Which is what’s in the state machine
Johno Crawford
@johnou
Jul 30 2018 00:22
yeah was trying to find that in the code to set breakpoints but i think it's obscure because it extends it
Jordan Halterman
@kuujo
Jul 30 2018 00:22
No
Oops
But I mean create a Guava Multiset and do the same thing
No primitive
It actually iterates over entrySet()
Johno Crawford
@johnou
Jul 30 2018 00:26
  public static void main(String[] args) {
    Multiset<String> set = HashMultiset.create();
    set.setCount("foo", 1);
    set.setCount("bar", 2);
    set.setCount("baz", 4);

    assertEquals(3, set.entrySet().stream().count());
  }
works fine
Jordan Halterman
@kuujo
Jul 30 2018 00:29
That is the state machine ^^ which is where the actual Multiset being read is
nextEntries
Johno Crawford
@johnou
Jul 30 2018 00:32
not invoked in java 10
is there another default method we need to override like the spliterator
Jordan Halterman
@kuujo
Jul 30 2018 00:33
It’s overridden in DistributedMultiset
That doesn’t make any sense
Those values are coming from somewhere
The only place where they exit in memory is in the state machine
exist*
Johno Crawford
@johnou
Jul 30 2018 00:41
count has changed
in stream
Junbo Ruan
@aruanruan
Jul 30 2018 00:41
could i say something about the Map or Set ?
Jordan Halterman
@kuujo
Jul 30 2018 00:42
If they’re in the stream then they were read from the state machine at some point, via the iterator methods. Nothing is stored on the client
Junbo Ruan
@aruanruan
Jul 30 2018 00:43
i think it is not a 'perfect' idea just cloning the java collection or map interface
Johno Crawford
@johnou
Jul 30 2018 00:44
Screenshot from 2018-07-30 02-43-42.png
it's not cloned, it's being implemented, which is what interfaces are for
looks like they just refactored the internal impl of streams
Junbo Ruan
@aruanruan
Jul 30 2018 00:48
i met several performance issues just only implements java interface based rpc last 2 years
Jordan Halterman
@kuujo
Jul 30 2018 00:49
Hmm
no that screenshot shows it has the correct iterator
Jordan Halterman
@kuujo
Jul 30 2018 00:56
@aruanruan how was it implemented?
Johno Crawford
@johnou
Jul 30 2018 00:57
so java 8 invokes forEachRemaining in Iterator
default void forEachRemaining(Consumer<? super E> action) {
    Objects.requireNonNull(action);
    while (hasNext())
        action.accept(next());
Jordan Halterman
@kuujo
Jul 30 2018 00:57
sounds familiar
Johno Crawford
@johnou
Jul 30 2018 00:57
which comes around to invoke io.atomix.core.iterator.impl.PartitionedProxyIterator#hasNext
that's not invoked in java 11 / 10
Junbo Ruan
@aruanruan
Jul 30 2018 01:00
@kuujo Some guys implement map interface base redis for caching data . but we need get or set lots of caching data, so the way of onekey-by-onekey is so infficient
Jordan Halterman
@kuujo
Jul 30 2018 01:06
@aruanruan so you mean it’s inefficient to treat each method call as a distinct operation, right?
Junbo Ruan
@aruanruan
Jul 30 2018 01:06
@kuujo yes
Johno Crawford
@johnou
Jul 30 2018 01:06
lucky atomix has batching
;)
Jordan Halterman
@kuujo
Jul 30 2018 01:07
That’s true but...
Jordan Halterman
@kuujo
Jul 30 2018 01:14

The Raft and primary-backup protocols are not really built for performance by batching operations. They’re built for providing atomicity and strong consistency for individual operations, meaning when you set one key, its guaranteed to be immediately visible to all other nodes and all nodes will see time progress in the same order. These are the types of strong consistency semantics needed to do costly coordination like leader election, distributed locking, configuration, etc. Scalability is achieved by partitioning primitives across different sunsets of the cluster, and throughput is indeed still achieved by batching and pipelining operations and events internally.

If I were looking for a cache, though, I’d be using DistributedMap/DistributedSet with the AntiEntropyProtocol which is a lot different from the Raft/primary-backup protocols. It’s more like DynamoDB/Cassandra (actually it was written by one of the DynamoDB authors). The entire state of the map/set is cached locally on any node that creates it, replication is asynchronous, and an anti-entropy protocol resolves missing changes. Changed keys are periodically replicated in batches.

The only philosophy of Atomix is to have a common abstraction that suits all use cases for consistency, redundancy, scalability, and fault tolerance. It started with Raft and is most commonly associated with it, but should be able to satisfy the opposite requirements - high throughout/scale and low latency reads/writes, which is what the anti-entropy protocol does. Ditto CRDTs

There’s still some work to be done on the anti-entropy protocol. It needs to be integrated with partition groups to scale size. The way it’s done now is not consistent with the Atomix architecture. But we’ve been using it for high throughput, low latency replication for years.
Actually I just had a revaluation thanks! :-)
Ugh
Revelation
Johno Crawford
@johnou
Jul 30 2018 01:24
what's that?
Jordan Halterman
@kuujo
Jul 30 2018 02:19
The last point: need to implement a Gossip partition group for the MultiPrimaryProtocol which will have a dynamic number of partitions (equal to the number of nodes) and use consistent hashing
Jordan Halterman
@kuujo
Jul 30 2018 02:45
The eventually consistent primitives currently break from that core abstraction. Will be nice for them to use t
it*
Alexander Richter
@alex-richter
Jul 30 2018 05:46

In the RaftPartitionGroup builder that is

I just looked it up in the code, i can find the property in the RaftPartitionGroupConfig but it seems like the RaftPartitionGroupBuilder does not have an appropriate setter for the segment size. Only the partition size can be changed through the builder.

Johno Crawford
@johnou
Jul 30 2018 07:58
@alex-richter we love pull requests :wink:
Junbo Ruan
@aruanruan
Jul 30 2018 08:12
can i manage primitives ( such as list primitive name , type, create time、delete some primitives by name)?
there’s not currently a creation time, but we could add one
Junbo Ruan
@aruanruan
Jul 30 2018 08:15
got it, thx
Jordan Halterman
@kuujo
Jul 30 2018 08:15
Primitive deletes are actually not currently implemented. There’s no good reason they’re not, it just hasn’t been done yet because we never delete primitives 🤷‍♂️ . Has to be done a little carefully to ensure all clients that remain open see some exception that indicates a primitive was deleted
I could try to take a stab at it
@alex-richter yeah that’s an oversight. Feel free to add it. There are probably some other storage properties we can expose
Junbo Ruan
@aruanruan
Jul 30 2018 08:20
I am designing a task scheduling system including parallel, serial, tick-driven, event-driven task (like https://github.com/github/orchestrator), it contains execution context of lots value), when one project (compose with different type tasks) exists, maybe it remains some primitives
we will orchestate some projects, and schedule them every day to testing lots of devices using the projects
Alexander Richter
@alex-richter
Jul 30 2018 08:23

@alex-richter we love pull requests :wink:

Just submitted one. This is my first time submitting to a project like this on GitHub, let me know if i missed out on anything!

Junbo Ruan
@aruanruan
Jul 30 2018 08:25
or i create my service to manage these computing-context
Jordan Halterman
@kuujo
Jul 30 2018 08:40
It will be simple to add deletes to the Raft implementation, but less so to the primary-backup protocol. Reliably deleting data in eventually consistent protocols is an often monumental task. That protocol is a lot less mature and essentially does a get-or-create on every write to create a state machine, so if we deleted a state machine it would just get recreated by any other open session. We’d have to refactor the session management in that protocol to replicate active sessions properly, which really needs to be done anyways TBH.
Should still be doable in a day or two
Maybe I will release another RC after @alex-richter’s change is merged and then tackle deletes. I have some Atomix work to do in ONOS too, though, so may or may not take a few more days
Johno Crawford
@johnou
Jul 30 2018 08:43
did you want me to put this as a issue btw? "need to implement a Gossip partition group for the MultiPrimaryProtocol which will have a dynamic number of partitions (equal to the number of nodes) and use consistent hashing"
and that java 10 bug is really bothering me
need to fix some stuff with our games first though
@kuujo heads up there is a regression in Netty wrt memory and epoll
Jordan Halterman
@kuujo
Jul 30 2018 08:45
Nope, still thinking it through. But deletes should be in there
Obvious necessity
Gotta take a nap
william.z
@zwillim
Jul 30 2018 09:30

Hi, I want to do leader election in atomix 3.0.0-rc5 like this:

 LeaderElection<MemberId> election = atomix.getLeaderElection("group");
Leadership leadership = election.run(atomix.getMembershipService().getLocalMember().id());

and found this error when using leader election:

Exception in thread "main" java.lang.IllegalArgumentException: Class is not registered: io.atomix.cluster.MemberId
Note: To register this class use: kryo.register(io.atomix.cluster.MemberId.class);
    at com.esotericsoftware.kryo.Kryo.getRegistration(Kryo.java:503)
    at com.esotericsoftware.kryo.util.DefaultClassResolver.writeClass(DefaultClassResolver.java:97)
    at com.esotericsoftware.kryo.Kryo.writeClass(Kryo.java:540)
    at com.esotericsoftware.kryo.Kryo.writeClassAndObject(Kryo.java:645)
    at io.atomix.utils.serializer.Namespace.lambda$null$0(Namespace.java:388)
    at com.esotericsoftware.kryo.pool.KryoPoolQueueImpl.run(KryoPoolQueueImpl.java:58)
    at io.atomix.utils.serializer.Namespace.lambda$serialize$1(Namespace.java:387)
    at io.atomix.utils.serializer.KryoIOPool.run(KryoIOPool.java:45)
    at io.atomix.utils.serializer.Namespace.serialize(Namespace.java:386)
    at io.atomix.utils.serializer.Namespace.serialize(Namespace.java:375)
    at io.atomix.utils.serializer.Serializer$1.encode(Serializer.java:52)
    at io.atomix.core.election.impl.DefaultLeaderElectionBuilder.lambda$null$1(DefaultLeaderElectionBuilder.java:44)
    at io.atomix.core.election.impl.TranscodingAsyncLeaderElection.run(TranscodingAsyncLeaderElection.java:52)
    at io.atomix.core.election.impl.BlockingLeaderElection.run(BlockingLeaderElection.java:48)
    at cn.ac.iie.di.atomix3test.atomix.n.Server1.main(Server1.java:51)

I think some classes are not registered in namespace.
So, are the namespaces of different primitives isolated?
How can I add classes like MemberId in the namespace of LeaderElection.
And what is the difference and relationship between LeaderElection and LeaderElector?

Jordan Halterman
@kuujo
Jul 30 2018 09:32
Add a Serializer using withSerializer
Johno Crawford
@johnou
Jul 30 2018 09:32
@kuujo goto bed
Jordan Halterman
@kuujo
Jul 30 2018 09:32
It used to be part of the default namespace
Was just about to
Crap my son woke up bye bye
william.z
@zwillim
Jul 30 2018 09:36
thanks and good night :)
Jordan Halterman
@kuujo
Jul 30 2018 09:40
The only difference between the two is that LeaderElector handles multiple leaders while LeaderElection elects only a single leader. The benefit of the former is that it can then balance leaders. But it’s really a legacy primitive and may be deprecated in the future.
You could also just use a <String> if you don’t want to add a serializer.
Now sleep gotta meeting in the morning