2018-10-29 17:19:37 +08:00
|
|
|
/*
|
2020-01-02 07:24:59 -05:00
|
|
|
* Copyright (C) 2015-2020 Lightbend Inc. <https://www.lightbend.com>
|
2015-05-17 12:28:47 +02:00
|
|
|
*/
|
2018-03-13 23:45:55 +09:00
|
|
|
|
2017-03-16 09:30:00 +01:00
|
|
|
package jdocs.ddata;
|
2015-05-17 12:28:47 +02:00
|
|
|
|
|
|
|
|
import java.util.HashSet;
|
2015-06-18 16:17:53 +02:00
|
|
|
import java.util.Arrays;
|
2015-05-17 12:28:47 +02:00
|
|
|
import java.util.Set;
|
2015-06-18 16:17:53 +02:00
|
|
|
import java.math.BigInteger;
|
|
|
|
|
import java.util.Optional;
|
2016-02-11 16:39:25 +01:00
|
|
|
|
|
|
|
|
import akka.actor.*;
|
2017-03-17 03:02:47 +08:00
|
|
|
import akka.testkit.javadsl.TestKit;
|
2015-06-18 16:17:53 +02:00
|
|
|
import com.typesafe.config.ConfigFactory;
|
2017-03-16 09:30:00 +01:00
|
|
|
import docs.ddata.DistributedDataDocSpec;
|
|
|
|
|
import jdocs.AbstractJavaTest;
|
2018-06-26 15:41:30 +02:00
|
|
|
import java.time.Duration;
|
2017-03-16 09:30:00 +01:00
|
|
|
|
2015-06-18 16:17:53 +02:00
|
|
|
import static org.junit.Assert.assertEquals;
|
2017-03-16 09:30:00 +01:00
|
|
|
|
2015-06-18 16:17:53 +02:00
|
|
|
import org.junit.Test;
|
|
|
|
|
import org.junit.AfterClass;
|
|
|
|
|
import org.junit.BeforeClass;
|
2015-05-17 12:28:47 +02:00
|
|
|
|
|
|
|
|
import akka.cluster.Cluster;
|
2015-06-18 16:17:53 +02:00
|
|
|
import akka.cluster.ddata.*;
|
2015-05-17 12:28:47 +02:00
|
|
|
import akka.japi.pf.ReceiveBuilder;
|
2015-06-18 16:17:53 +02:00
|
|
|
|
|
|
|
|
import static akka.cluster.ddata.Replicator.*;
|
|
|
|
|
|
improve AbstractActor, #21717
* Receive class that wraps PartialFunction, to avoid
scary scala types
* move AbstractActorContext to AbstractActor.ActorContext
* converting docs, many, many UntypedActor
* removing UntypedActor docs
* add unit test for ReceiveBuilder
* MiMa filters
* consistent use of getContext(), self(), sender()
* rename cross references
* migration guide
* skip samples for now
* improve match type safetyi, add matchUnchecked
* the `? extends P` caused code like this to compile:
`match(String.class, (Integer i) -> {})`
* added matchUnchecked, since it can still be useful (um, convenient)
to be able to do:
`matchUnchecked(List.class, (List<String> list) -> {})`
* eleminate some scala.Option
* preRestart
* findChild
* ActorIdentity.getActorRef
2016-12-13 10:59:29 +01:00
|
|
|
@SuppressWarnings({"unchecked", "unused"})
|
2016-02-11 16:39:25 +01:00
|
|
|
public class DistributedDataDocTest extends AbstractJavaTest {
|
2019-01-12 04:00:53 +08:00
|
|
|
|
2015-05-17 12:28:47 +02:00
|
|
|
static ActorSystem system;
|
2016-02-11 16:39:25 +01:00
|
|
|
|
2015-05-17 12:28:47 +02:00
|
|
|
@BeforeClass
|
|
|
|
|
public static void setup() {
|
2019-01-12 04:00:53 +08:00
|
|
|
system =
|
|
|
|
|
ActorSystem.create(
|
|
|
|
|
"DistributedDataDocTest", ConfigFactory.parseString(DistributedDataDocSpec.config()));
|
2015-05-17 12:28:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@AfterClass
|
|
|
|
|
public static void tearDown() {
|
2017-03-17 03:02:47 +08:00
|
|
|
TestKit.shutdownActorSystem(system);
|
2015-05-17 12:28:47 +02:00
|
|
|
system = null;
|
|
|
|
|
}
|
|
|
|
|
|
improve AbstractActor, #21717
* Receive class that wraps PartialFunction, to avoid
scary scala types
* move AbstractActorContext to AbstractActor.ActorContext
* converting docs, many, many UntypedActor
* removing UntypedActor docs
* add unit test for ReceiveBuilder
* MiMa filters
* consistent use of getContext(), self(), sender()
* rename cross references
* migration guide
* skip samples for now
* improve match type safetyi, add matchUnchecked
* the `? extends P` caused code like this to compile:
`match(String.class, (Integer i) -> {})`
* added matchUnchecked, since it can still be useful (um, convenient)
to be able to do:
`matchUnchecked(List.class, (List<String> list) -> {})`
* eleminate some scala.Option
* preRestart
* findChild
* ActorIdentity.getActorRef
2016-12-13 10:59:29 +01:00
|
|
|
static
|
2019-01-12 04:00:53 +08:00
|
|
|
// #update
|
improve AbstractActor, #21717
* Receive class that wraps PartialFunction, to avoid
scary scala types
* move AbstractActorContext to AbstractActor.ActorContext
* converting docs, many, many UntypedActor
* removing UntypedActor docs
* add unit test for ReceiveBuilder
* MiMa filters
* consistent use of getContext(), self(), sender()
* rename cross references
* migration guide
* skip samples for now
* improve match type safetyi, add matchUnchecked
* the `? extends P` caused code like this to compile:
`match(String.class, (Integer i) -> {})`
* added matchUnchecked, since it can still be useful (um, convenient)
to be able to do:
`matchUnchecked(List.class, (List<String> list) -> {})`
* eleminate some scala.Option
* preRestart
* findChild
* ActorIdentity.getActorRef
2016-12-13 10:59:29 +01:00
|
|
|
class DemonstrateUpdate extends AbstractActor {
|
2019-01-12 04:00:53 +08:00
|
|
|
final SelfUniqueAddress node =
|
|
|
|
|
DistributedData.get(getContext().getSystem()).selfUniqueAddress();
|
|
|
|
|
final ActorRef replicator = DistributedData.get(getContext().getSystem()).replicator();
|
2016-02-11 16:39:25 +01:00
|
|
|
|
improve AbstractActor, #21717
* Receive class that wraps PartialFunction, to avoid
scary scala types
* move AbstractActorContext to AbstractActor.ActorContext
* converting docs, many, many UntypedActor
* removing UntypedActor docs
* add unit test for ReceiveBuilder
* MiMa filters
* consistent use of getContext(), self(), sender()
* rename cross references
* migration guide
* skip samples for now
* improve match type safetyi, add matchUnchecked
* the `? extends P` caused code like this to compile:
`match(String.class, (Integer i) -> {})`
* added matchUnchecked, since it can still be useful (um, convenient)
to be able to do:
`matchUnchecked(List.class, (List<String> list) -> {})`
* eleminate some scala.Option
* preRestart
* findChild
* ActorIdentity.getActorRef
2016-12-13 10:59:29 +01:00
|
|
|
final Key<PNCounter> counter1Key = PNCounterKey.create("counter1");
|
|
|
|
|
final Key<GSet<String>> set1Key = GSetKey.create("set1");
|
|
|
|
|
final Key<ORSet<String>> set2Key = ORSetKey.create("set2");
|
|
|
|
|
final Key<Flag> activeFlagKey = FlagKey.create("active");
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Receive createReceive() {
|
|
|
|
|
ReceiveBuilder b = receiveBuilder();
|
2019-01-12 04:00:53 +08:00
|
|
|
|
|
|
|
|
b.matchEquals(
|
|
|
|
|
"demonstrate update",
|
|
|
|
|
msg -> {
|
|
|
|
|
replicator.tell(
|
|
|
|
|
new Replicator.Update<PNCounter>(
|
|
|
|
|
counter1Key,
|
|
|
|
|
PNCounter.create(),
|
|
|
|
|
Replicator.writeLocal(),
|
|
|
|
|
curr -> curr.increment(node, 1)),
|
|
|
|
|
getSelf());
|
|
|
|
|
|
|
|
|
|
final WriteConsistency writeTo3 = new WriteTo(3, Duration.ofSeconds(1));
|
|
|
|
|
replicator.tell(
|
|
|
|
|
new Replicator.Update<GSet<String>>(
|
|
|
|
|
set1Key, GSet.create(), writeTo3, curr -> curr.add("hello")),
|
|
|
|
|
getSelf());
|
|
|
|
|
|
|
|
|
|
final WriteConsistency writeMajority = new WriteMajority(Duration.ofSeconds(5));
|
|
|
|
|
replicator.tell(
|
|
|
|
|
new Replicator.Update<ORSet<String>>(
|
|
|
|
|
set2Key, ORSet.create(), writeMajority, curr -> curr.add(node, "hello")),
|
|
|
|
|
getSelf());
|
|
|
|
|
|
|
|
|
|
final WriteConsistency writeAll = new WriteAll(Duration.ofSeconds(5));
|
|
|
|
|
replicator.tell(
|
|
|
|
|
new Replicator.Update<Flag>(
|
|
|
|
|
activeFlagKey, Flag.create(), writeAll, curr -> curr.switchOn()),
|
|
|
|
|
getSelf());
|
|
|
|
|
});
|
|
|
|
|
// #update
|
|
|
|
|
|
|
|
|
|
// #update-response1
|
|
|
|
|
b.match(
|
|
|
|
|
UpdateSuccess.class,
|
|
|
|
|
a -> a.key().equals(counter1Key),
|
|
|
|
|
a -> {
|
|
|
|
|
// ok
|
|
|
|
|
});
|
|
|
|
|
// #update-response1
|
|
|
|
|
|
|
|
|
|
// #update-response2
|
|
|
|
|
b.match(
|
|
|
|
|
UpdateSuccess.class,
|
|
|
|
|
a -> a.key().equals(set1Key),
|
|
|
|
|
a -> {
|
|
|
|
|
// ok
|
|
|
|
|
})
|
|
|
|
|
.match(
|
|
|
|
|
UpdateTimeout.class,
|
|
|
|
|
a -> a.key().equals(set1Key),
|
|
|
|
|
a -> {
|
|
|
|
|
// write to 3 nodes failed within 1.second
|
|
|
|
|
});
|
|
|
|
|
// #update-response2
|
|
|
|
|
|
|
|
|
|
// #update
|
improve AbstractActor, #21717
* Receive class that wraps PartialFunction, to avoid
scary scala types
* move AbstractActorContext to AbstractActor.ActorContext
* converting docs, many, many UntypedActor
* removing UntypedActor docs
* add unit test for ReceiveBuilder
* MiMa filters
* consistent use of getContext(), self(), sender()
* rename cross references
* migration guide
* skip samples for now
* improve match type safetyi, add matchUnchecked
* the `? extends P` caused code like this to compile:
`match(String.class, (Integer i) -> {})`
* added matchUnchecked, since it can still be useful (um, convenient)
to be able to do:
`matchUnchecked(List.class, (List<String> list) -> {})`
* eleminate some scala.Option
* preRestart
* findChild
* ActorIdentity.getActorRef
2016-12-13 10:59:29 +01:00
|
|
|
return b.build();
|
|
|
|
|
}
|
2015-05-17 12:28:47 +02:00
|
|
|
}
|
2019-01-12 04:00:53 +08:00
|
|
|
// #update
|
improve AbstractActor, #21717
* Receive class that wraps PartialFunction, to avoid
scary scala types
* move AbstractActorContext to AbstractActor.ActorContext
* converting docs, many, many UntypedActor
* removing UntypedActor docs
* add unit test for ReceiveBuilder
* MiMa filters
* consistent use of getContext(), self(), sender()
* rename cross references
* migration guide
* skip samples for now
* improve match type safetyi, add matchUnchecked
* the `? extends P` caused code like this to compile:
`match(String.class, (Integer i) -> {})`
* added matchUnchecked, since it can still be useful (um, convenient)
to be able to do:
`matchUnchecked(List.class, (List<String> list) -> {})`
* eleminate some scala.Option
* preRestart
* findChild
* ActorIdentity.getActorRef
2016-12-13 10:59:29 +01:00
|
|
|
|
|
|
|
|
static
|
2019-01-12 04:00:53 +08:00
|
|
|
// #update-request-context
|
improve AbstractActor, #21717
* Receive class that wraps PartialFunction, to avoid
scary scala types
* move AbstractActorContext to AbstractActor.ActorContext
* converting docs, many, many UntypedActor
* removing UntypedActor docs
* add unit test for ReceiveBuilder
* MiMa filters
* consistent use of getContext(), self(), sender()
* rename cross references
* migration guide
* skip samples for now
* improve match type safetyi, add matchUnchecked
* the `? extends P` caused code like this to compile:
`match(String.class, (Integer i) -> {})`
* added matchUnchecked, since it can still be useful (um, convenient)
to be able to do:
`matchUnchecked(List.class, (List<String> list) -> {})`
* eleminate some scala.Option
* preRestart
* findChild
* ActorIdentity.getActorRef
2016-12-13 10:59:29 +01:00
|
|
|
class DemonstrateUpdateWithRequestContext extends AbstractActor {
|
2020-08-04 13:47:38 +02:00
|
|
|
final SelfUniqueAddress node = DistributedData.get(system).selfUniqueAddress();
|
2019-01-12 04:00:53 +08:00
|
|
|
final ActorRef replicator = DistributedData.get(getContext().getSystem()).replicator();
|
2015-05-17 12:28:47 +02:00
|
|
|
|
2018-06-26 15:41:30 +02:00
|
|
|
final WriteConsistency writeTwo = new WriteTo(2, Duration.ofSeconds(3));
|
improve AbstractActor, #21717
* Receive class that wraps PartialFunction, to avoid
scary scala types
* move AbstractActorContext to AbstractActor.ActorContext
* converting docs, many, many UntypedActor
* removing UntypedActor docs
* add unit test for ReceiveBuilder
* MiMa filters
* consistent use of getContext(), self(), sender()
* rename cross references
* migration guide
* skip samples for now
* improve match type safetyi, add matchUnchecked
* the `? extends P` caused code like this to compile:
`match(String.class, (Integer i) -> {})`
* added matchUnchecked, since it can still be useful (um, convenient)
to be able to do:
`matchUnchecked(List.class, (List<String> list) -> {})`
* eleminate some scala.Option
* preRestart
* findChild
* ActorIdentity.getActorRef
2016-12-13 10:59:29 +01:00
|
|
|
final Key<PNCounter> counter1Key = PNCounterKey.create("counter1");
|
2019-01-12 04:00:53 +08:00
|
|
|
|
improve AbstractActor, #21717
* Receive class that wraps PartialFunction, to avoid
scary scala types
* move AbstractActorContext to AbstractActor.ActorContext
* converting docs, many, many UntypedActor
* removing UntypedActor docs
* add unit test for ReceiveBuilder
* MiMa filters
* consistent use of getContext(), self(), sender()
* rename cross references
* migration guide
* skip samples for now
* improve match type safetyi, add matchUnchecked
* the `? extends P` caused code like this to compile:
`match(String.class, (Integer i) -> {})`
* added matchUnchecked, since it can still be useful (um, convenient)
to be able to do:
`matchUnchecked(List.class, (List<String> list) -> {})`
* eleminate some scala.Option
* preRestart
* findChild
* ActorIdentity.getActorRef
2016-12-13 10:59:29 +01:00
|
|
|
@Override
|
|
|
|
|
public Receive createReceive() {
|
|
|
|
|
return receiveBuilder()
|
2019-01-12 04:00:53 +08:00
|
|
|
.match(
|
|
|
|
|
String.class,
|
|
|
|
|
a -> a.equals("increment"),
|
|
|
|
|
a -> {
|
|
|
|
|
// incoming command to increase the counter
|
|
|
|
|
Optional<Object> reqContext = Optional.of(getSender());
|
|
|
|
|
Replicator.Update<PNCounter> upd =
|
|
|
|
|
new Replicator.Update<PNCounter>(
|
|
|
|
|
counter1Key,
|
|
|
|
|
PNCounter.create(),
|
|
|
|
|
writeTwo,
|
|
|
|
|
reqContext,
|
|
|
|
|
curr -> curr.increment(node, 1));
|
|
|
|
|
replicator.tell(upd, getSelf());
|
|
|
|
|
})
|
|
|
|
|
.match(
|
|
|
|
|
UpdateSuccess.class,
|
|
|
|
|
a -> a.key().equals(counter1Key),
|
|
|
|
|
a -> {
|
|
|
|
|
ActorRef replyTo = (ActorRef) a.getRequest().get();
|
|
|
|
|
replyTo.tell("ack", getSelf());
|
|
|
|
|
})
|
|
|
|
|
.match(
|
|
|
|
|
UpdateTimeout.class,
|
|
|
|
|
a -> a.key().equals(counter1Key),
|
|
|
|
|
a -> {
|
|
|
|
|
ActorRef replyTo = (ActorRef) a.getRequest().get();
|
|
|
|
|
replyTo.tell("nack", getSelf());
|
|
|
|
|
})
|
|
|
|
|
.build();
|
|
|
|
|
}
|
2015-05-17 12:28:47 +02:00
|
|
|
}
|
2019-01-12 04:00:53 +08:00
|
|
|
// #update-request-context
|
2015-05-17 12:28:47 +02:00
|
|
|
|
improve AbstractActor, #21717
* Receive class that wraps PartialFunction, to avoid
scary scala types
* move AbstractActorContext to AbstractActor.ActorContext
* converting docs, many, many UntypedActor
* removing UntypedActor docs
* add unit test for ReceiveBuilder
* MiMa filters
* consistent use of getContext(), self(), sender()
* rename cross references
* migration guide
* skip samples for now
* improve match type safetyi, add matchUnchecked
* the `? extends P` caused code like this to compile:
`match(String.class, (Integer i) -> {})`
* added matchUnchecked, since it can still be useful (um, convenient)
to be able to do:
`matchUnchecked(List.class, (List<String> list) -> {})`
* eleminate some scala.Option
* preRestart
* findChild
* ActorIdentity.getActorRef
2016-12-13 10:59:29 +01:00
|
|
|
static
|
2019-01-12 04:00:53 +08:00
|
|
|
// #get
|
improve AbstractActor, #21717
* Receive class that wraps PartialFunction, to avoid
scary scala types
* move AbstractActorContext to AbstractActor.ActorContext
* converting docs, many, many UntypedActor
* removing UntypedActor docs
* add unit test for ReceiveBuilder
* MiMa filters
* consistent use of getContext(), self(), sender()
* rename cross references
* migration guide
* skip samples for now
* improve match type safetyi, add matchUnchecked
* the `? extends P` caused code like this to compile:
`match(String.class, (Integer i) -> {})`
* added matchUnchecked, since it can still be useful (um, convenient)
to be able to do:
`matchUnchecked(List.class, (List<String> list) -> {})`
* eleminate some scala.Option
* preRestart
* findChild
* ActorIdentity.getActorRef
2016-12-13 10:59:29 +01:00
|
|
|
class DemonstrateGet extends AbstractActor {
|
2019-01-12 04:00:53 +08:00
|
|
|
final ActorRef replicator = DistributedData.get(getContext().getSystem()).replicator();
|
|
|
|
|
|
|
|
|
|
final Key<PNCounter> counter1Key = PNCounterKey.create("counter1");
|
|
|
|
|
final Key<GSet<String>> set1Key = GSetKey.create("set1");
|
|
|
|
|
final Key<ORSet<String>> set2Key = ORSetKey.create("set2");
|
|
|
|
|
final Key<Flag> activeFlagKey = FlagKey.create("active");
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Receive createReceive() {
|
|
|
|
|
ReceiveBuilder b = receiveBuilder();
|
|
|
|
|
|
|
|
|
|
b.matchEquals(
|
|
|
|
|
"demonstrate get",
|
|
|
|
|
msg -> {
|
|
|
|
|
replicator.tell(
|
|
|
|
|
new Replicator.Get<PNCounter>(counter1Key, Replicator.readLocal()), getSelf());
|
|
|
|
|
|
|
|
|
|
final ReadConsistency readFrom3 = new ReadFrom(3, Duration.ofSeconds(1));
|
|
|
|
|
replicator.tell(new Replicator.Get<GSet<String>>(set1Key, readFrom3), getSelf());
|
|
|
|
|
|
|
|
|
|
final ReadConsistency readMajority = new ReadMajority(Duration.ofSeconds(5));
|
|
|
|
|
replicator.tell(new Replicator.Get<ORSet<String>>(set2Key, readMajority), getSelf());
|
|
|
|
|
|
|
|
|
|
final ReadConsistency readAll = new ReadAll(Duration.ofSeconds(5));
|
|
|
|
|
replicator.tell(new Replicator.Get<Flag>(activeFlagKey, readAll), getSelf());
|
|
|
|
|
});
|
|
|
|
|
// #get
|
|
|
|
|
|
|
|
|
|
// #get-response1
|
|
|
|
|
b.match(
|
|
|
|
|
GetSuccess.class,
|
|
|
|
|
a -> a.key().equals(counter1Key),
|
|
|
|
|
a -> {
|
|
|
|
|
GetSuccess<PNCounter> g = a;
|
|
|
|
|
BigInteger value = g.dataValue().getValue();
|
|
|
|
|
})
|
|
|
|
|
.match(
|
|
|
|
|
NotFound.class,
|
|
|
|
|
a -> a.key().equals(counter1Key),
|
|
|
|
|
a -> {
|
|
|
|
|
// key counter1 does not exist
|
|
|
|
|
});
|
|
|
|
|
// #get-response1
|
|
|
|
|
|
|
|
|
|
// #get-response2
|
|
|
|
|
b.match(
|
|
|
|
|
GetSuccess.class,
|
|
|
|
|
a -> a.key().equals(set1Key),
|
|
|
|
|
a -> {
|
|
|
|
|
GetSuccess<GSet<String>> g = a;
|
|
|
|
|
Set<String> value = g.dataValue().getElements();
|
|
|
|
|
})
|
|
|
|
|
.match(
|
|
|
|
|
GetFailure.class,
|
|
|
|
|
a -> a.key().equals(set1Key),
|
|
|
|
|
a -> {
|
|
|
|
|
// read from 3 nodes failed within 1.second
|
|
|
|
|
})
|
|
|
|
|
.match(
|
|
|
|
|
NotFound.class,
|
|
|
|
|
a -> a.key().equals(set1Key),
|
|
|
|
|
a -> {
|
|
|
|
|
// key set1 does not exist
|
|
|
|
|
});
|
|
|
|
|
// #get-response2
|
|
|
|
|
|
|
|
|
|
// #get
|
improve AbstractActor, #21717
* Receive class that wraps PartialFunction, to avoid
scary scala types
* move AbstractActorContext to AbstractActor.ActorContext
* converting docs, many, many UntypedActor
* removing UntypedActor docs
* add unit test for ReceiveBuilder
* MiMa filters
* consistent use of getContext(), self(), sender()
* rename cross references
* migration guide
* skip samples for now
* improve match type safetyi, add matchUnchecked
* the `? extends P` caused code like this to compile:
`match(String.class, (Integer i) -> {})`
* added matchUnchecked, since it can still be useful (um, convenient)
to be able to do:
`matchUnchecked(List.class, (List<String> list) -> {})`
* eleminate some scala.Option
* preRestart
* findChild
* ActorIdentity.getActorRef
2016-12-13 10:59:29 +01:00
|
|
|
return b.build();
|
|
|
|
|
}
|
2015-05-17 12:28:47 +02:00
|
|
|
}
|
2019-01-12 04:00:53 +08:00
|
|
|
// #get
|
2015-05-17 12:28:47 +02:00
|
|
|
|
improve AbstractActor, #21717
* Receive class that wraps PartialFunction, to avoid
scary scala types
* move AbstractActorContext to AbstractActor.ActorContext
* converting docs, many, many UntypedActor
* removing UntypedActor docs
* add unit test for ReceiveBuilder
* MiMa filters
* consistent use of getContext(), self(), sender()
* rename cross references
* migration guide
* skip samples for now
* improve match type safetyi, add matchUnchecked
* the `? extends P` caused code like this to compile:
`match(String.class, (Integer i) -> {})`
* added matchUnchecked, since it can still be useful (um, convenient)
to be able to do:
`matchUnchecked(List.class, (List<String> list) -> {})`
* eleminate some scala.Option
* preRestart
* findChild
* ActorIdentity.getActorRef
2016-12-13 10:59:29 +01:00
|
|
|
static
|
2019-01-12 04:00:53 +08:00
|
|
|
// #get-request-context
|
improve AbstractActor, #21717
* Receive class that wraps PartialFunction, to avoid
scary scala types
* move AbstractActorContext to AbstractActor.ActorContext
* converting docs, many, many UntypedActor
* removing UntypedActor docs
* add unit test for ReceiveBuilder
* MiMa filters
* consistent use of getContext(), self(), sender()
* rename cross references
* migration guide
* skip samples for now
* improve match type safetyi, add matchUnchecked
* the `? extends P` caused code like this to compile:
`match(String.class, (Integer i) -> {})`
* added matchUnchecked, since it can still be useful (um, convenient)
to be able to do:
`matchUnchecked(List.class, (List<String> list) -> {})`
* eleminate some scala.Option
* preRestart
* findChild
* ActorIdentity.getActorRef
2016-12-13 10:59:29 +01:00
|
|
|
class DemonstrateGetWithRequestContext extends AbstractActor {
|
2019-01-12 04:00:53 +08:00
|
|
|
final ActorRef replicator = DistributedData.get(getContext().getSystem()).replicator();
|
|
|
|
|
|
|
|
|
|
final ReadConsistency readTwo = new ReadFrom(2, Duration.ofSeconds(3));
|
|
|
|
|
final Key<PNCounter> counter1Key = PNCounterKey.create("counter1");
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Receive createReceive() {
|
|
|
|
|
return receiveBuilder()
|
|
|
|
|
.match(
|
|
|
|
|
String.class,
|
|
|
|
|
a -> a.equals("get-count"),
|
|
|
|
|
a -> {
|
|
|
|
|
// incoming request to retrieve current value of the counter
|
|
|
|
|
Optional<Object> reqContext = Optional.of(getSender());
|
|
|
|
|
replicator.tell(new Replicator.Get<PNCounter>(counter1Key, readTwo), getSelf());
|
|
|
|
|
})
|
|
|
|
|
.match(
|
|
|
|
|
GetSuccess.class,
|
|
|
|
|
a -> a.key().equals(counter1Key),
|
|
|
|
|
a -> {
|
|
|
|
|
ActorRef replyTo = (ActorRef) a.getRequest().get();
|
|
|
|
|
GetSuccess<PNCounter> g = a;
|
|
|
|
|
long value = g.dataValue().getValue().longValue();
|
|
|
|
|
replyTo.tell(value, getSelf());
|
|
|
|
|
})
|
|
|
|
|
.match(
|
|
|
|
|
GetFailure.class,
|
|
|
|
|
a -> a.key().equals(counter1Key),
|
|
|
|
|
a -> {
|
|
|
|
|
ActorRef replyTo = (ActorRef) a.getRequest().get();
|
|
|
|
|
replyTo.tell(-1L, getSelf());
|
|
|
|
|
})
|
|
|
|
|
.match(
|
|
|
|
|
NotFound.class,
|
|
|
|
|
a -> a.key().equals(counter1Key),
|
|
|
|
|
a -> {
|
|
|
|
|
ActorRef replyTo = (ActorRef) a.getRequest().get();
|
|
|
|
|
replyTo.tell(0L, getSelf());
|
|
|
|
|
})
|
improve AbstractActor, #21717
* Receive class that wraps PartialFunction, to avoid
scary scala types
* move AbstractActorContext to AbstractActor.ActorContext
* converting docs, many, many UntypedActor
* removing UntypedActor docs
* add unit test for ReceiveBuilder
* MiMa filters
* consistent use of getContext(), self(), sender()
* rename cross references
* migration guide
* skip samples for now
* improve match type safetyi, add matchUnchecked
* the `? extends P` caused code like this to compile:
`match(String.class, (Integer i) -> {})`
* added matchUnchecked, since it can still be useful (um, convenient)
to be able to do:
`matchUnchecked(List.class, (List<String> list) -> {})`
* eleminate some scala.Option
* preRestart
* findChild
* ActorIdentity.getActorRef
2016-12-13 10:59:29 +01:00
|
|
|
.build();
|
2019-01-12 04:00:53 +08:00
|
|
|
}
|
2015-05-17 12:28:47 +02:00
|
|
|
}
|
2019-01-12 04:00:53 +08:00
|
|
|
// #get-request-context
|
2015-05-17 12:28:47 +02:00
|
|
|
|
improve AbstractActor, #21717
* Receive class that wraps PartialFunction, to avoid
scary scala types
* move AbstractActorContext to AbstractActor.ActorContext
* converting docs, many, many UntypedActor
* removing UntypedActor docs
* add unit test for ReceiveBuilder
* MiMa filters
* consistent use of getContext(), self(), sender()
* rename cross references
* migration guide
* skip samples for now
* improve match type safetyi, add matchUnchecked
* the `? extends P` caused code like this to compile:
`match(String.class, (Integer i) -> {})`
* added matchUnchecked, since it can still be useful (um, convenient)
to be able to do:
`matchUnchecked(List.class, (List<String> list) -> {})`
* eleminate some scala.Option
* preRestart
* findChild
* ActorIdentity.getActorRef
2016-12-13 10:59:29 +01:00
|
|
|
static
|
2019-01-12 04:00:53 +08:00
|
|
|
// #subscribe
|
improve AbstractActor, #21717
* Receive class that wraps PartialFunction, to avoid
scary scala types
* move AbstractActorContext to AbstractActor.ActorContext
* converting docs, many, many UntypedActor
* removing UntypedActor docs
* add unit test for ReceiveBuilder
* MiMa filters
* consistent use of getContext(), self(), sender()
* rename cross references
* migration guide
* skip samples for now
* improve match type safetyi, add matchUnchecked
* the `? extends P` caused code like this to compile:
`match(String.class, (Integer i) -> {})`
* added matchUnchecked, since it can still be useful (um, convenient)
to be able to do:
`matchUnchecked(List.class, (List<String> list) -> {})`
* eleminate some scala.Option
* preRestart
* findChild
* ActorIdentity.getActorRef
2016-12-13 10:59:29 +01:00
|
|
|
class DemonstrateSubscribe extends AbstractActor {
|
2019-01-12 04:00:53 +08:00
|
|
|
final ActorRef replicator = DistributedData.get(getContext().getSystem()).replicator();
|
2015-05-17 12:28:47 +02:00
|
|
|
final Key<PNCounter> counter1Key = PNCounterKey.create("counter1");
|
2019-01-12 04:00:53 +08:00
|
|
|
|
2015-05-17 12:28:47 +02:00
|
|
|
BigInteger currentValue = BigInteger.valueOf(0);
|
2019-01-12 04:00:53 +08:00
|
|
|
|
improve AbstractActor, #21717
* Receive class that wraps PartialFunction, to avoid
scary scala types
* move AbstractActorContext to AbstractActor.ActorContext
* converting docs, many, many UntypedActor
* removing UntypedActor docs
* add unit test for ReceiveBuilder
* MiMa filters
* consistent use of getContext(), self(), sender()
* rename cross references
* migration guide
* skip samples for now
* improve match type safetyi, add matchUnchecked
* the `? extends P` caused code like this to compile:
`match(String.class, (Integer i) -> {})`
* added matchUnchecked, since it can still be useful (um, convenient)
to be able to do:
`matchUnchecked(List.class, (List<String> list) -> {})`
* eleminate some scala.Option
* preRestart
* findChild
* ActorIdentity.getActorRef
2016-12-13 10:59:29 +01:00
|
|
|
@Override
|
|
|
|
|
public Receive createReceive() {
|
|
|
|
|
return receiveBuilder()
|
2019-01-12 04:00:53 +08:00
|
|
|
.match(
|
|
|
|
|
Changed.class,
|
|
|
|
|
a -> a.key().equals(counter1Key),
|
|
|
|
|
a -> {
|
|
|
|
|
Changed<PNCounter> g = a;
|
|
|
|
|
currentValue = g.dataValue().getValue();
|
|
|
|
|
})
|
|
|
|
|
.match(
|
|
|
|
|
String.class,
|
|
|
|
|
a -> a.equals("get-count"),
|
|
|
|
|
a -> {
|
|
|
|
|
// incoming request to retrieve current value of the counter
|
|
|
|
|
getSender().tell(currentValue, getSender());
|
|
|
|
|
})
|
|
|
|
|
.build();
|
2015-05-17 12:28:47 +02:00
|
|
|
}
|
2019-01-12 04:00:53 +08:00
|
|
|
|
improve AbstractActor, #21717
* Receive class that wraps PartialFunction, to avoid
scary scala types
* move AbstractActorContext to AbstractActor.ActorContext
* converting docs, many, many UntypedActor
* removing UntypedActor docs
* add unit test for ReceiveBuilder
* MiMa filters
* consistent use of getContext(), self(), sender()
* rename cross references
* migration guide
* skip samples for now
* improve match type safetyi, add matchUnchecked
* the `? extends P` caused code like this to compile:
`match(String.class, (Integer i) -> {})`
* added matchUnchecked, since it can still be useful (um, convenient)
to be able to do:
`matchUnchecked(List.class, (List<String> list) -> {})`
* eleminate some scala.Option
* preRestart
* findChild
* ActorIdentity.getActorRef
2016-12-13 10:59:29 +01:00
|
|
|
@Override
|
2015-05-17 12:28:47 +02:00
|
|
|
public void preStart() {
|
|
|
|
|
// subscribe to changes of the Counter1Key value
|
2017-03-16 09:30:00 +01:00
|
|
|
replicator.tell(new Subscribe<PNCounter>(counter1Key, getSelf()), ActorRef.noSender());
|
2015-05-17 12:28:47 +02:00
|
|
|
}
|
|
|
|
|
}
|
2019-01-12 04:00:53 +08:00
|
|
|
// #subscribe
|
2015-05-17 12:28:47 +02:00
|
|
|
|
improve AbstractActor, #21717
* Receive class that wraps PartialFunction, to avoid
scary scala types
* move AbstractActorContext to AbstractActor.ActorContext
* converting docs, many, many UntypedActor
* removing UntypedActor docs
* add unit test for ReceiveBuilder
* MiMa filters
* consistent use of getContext(), self(), sender()
* rename cross references
* migration guide
* skip samples for now
* improve match type safetyi, add matchUnchecked
* the `? extends P` caused code like this to compile:
`match(String.class, (Integer i) -> {})`
* added matchUnchecked, since it can still be useful (um, convenient)
to be able to do:
`matchUnchecked(List.class, (List<String> list) -> {})`
* eleminate some scala.Option
* preRestart
* findChild
* ActorIdentity.getActorRef
2016-12-13 10:59:29 +01:00
|
|
|
static
|
2019-01-12 04:00:53 +08:00
|
|
|
// #delete
|
improve AbstractActor, #21717
* Receive class that wraps PartialFunction, to avoid
scary scala types
* move AbstractActorContext to AbstractActor.ActorContext
* converting docs, many, many UntypedActor
* removing UntypedActor docs
* add unit test for ReceiveBuilder
* MiMa filters
* consistent use of getContext(), self(), sender()
* rename cross references
* migration guide
* skip samples for now
* improve match type safetyi, add matchUnchecked
* the `? extends P` caused code like this to compile:
`match(String.class, (Integer i) -> {})`
* added matchUnchecked, since it can still be useful (um, convenient)
to be able to do:
`matchUnchecked(List.class, (List<String> list) -> {})`
* eleminate some scala.Option
* preRestart
* findChild
* ActorIdentity.getActorRef
2016-12-13 10:59:29 +01:00
|
|
|
class DemonstrateDelete extends AbstractActor {
|
2019-01-12 04:00:53 +08:00
|
|
|
final ActorRef replicator = DistributedData.get(getContext().getSystem()).replicator();
|
|
|
|
|
|
improve AbstractActor, #21717
* Receive class that wraps PartialFunction, to avoid
scary scala types
* move AbstractActorContext to AbstractActor.ActorContext
* converting docs, many, many UntypedActor
* removing UntypedActor docs
* add unit test for ReceiveBuilder
* MiMa filters
* consistent use of getContext(), self(), sender()
* rename cross references
* migration guide
* skip samples for now
* improve match type safetyi, add matchUnchecked
* the `? extends P` caused code like this to compile:
`match(String.class, (Integer i) -> {})`
* added matchUnchecked, since it can still be useful (um, convenient)
to be able to do:
`matchUnchecked(List.class, (List<String> list) -> {})`
* eleminate some scala.Option
* preRestart
* findChild
* ActorIdentity.getActorRef
2016-12-13 10:59:29 +01:00
|
|
|
final Key<PNCounter> counter1Key = PNCounterKey.create("counter1");
|
|
|
|
|
final Key<ORSet<String>> set2Key = ORSetKey.create("set2");
|
2019-01-12 04:00:53 +08:00
|
|
|
|
improve AbstractActor, #21717
* Receive class that wraps PartialFunction, to avoid
scary scala types
* move AbstractActorContext to AbstractActor.ActorContext
* converting docs, many, many UntypedActor
* removing UntypedActor docs
* add unit test for ReceiveBuilder
* MiMa filters
* consistent use of getContext(), self(), sender()
* rename cross references
* migration guide
* skip samples for now
* improve match type safetyi, add matchUnchecked
* the `? extends P` caused code like this to compile:
`match(String.class, (Integer i) -> {})`
* added matchUnchecked, since it can still be useful (um, convenient)
to be able to do:
`matchUnchecked(List.class, (List<String> list) -> {})`
* eleminate some scala.Option
* preRestart
* findChild
* ActorIdentity.getActorRef
2016-12-13 10:59:29 +01:00
|
|
|
@Override
|
|
|
|
|
public Receive createReceive() {
|
|
|
|
|
return receiveBuilder()
|
2019-01-12 04:00:53 +08:00
|
|
|
.matchEquals(
|
|
|
|
|
"demonstrate delete",
|
|
|
|
|
msg -> {
|
|
|
|
|
replicator.tell(
|
|
|
|
|
new Delete<PNCounter>(counter1Key, Replicator.writeLocal()), getSelf());
|
|
|
|
|
|
|
|
|
|
final WriteConsistency writeMajority = new WriteMajority(Duration.ofSeconds(5));
|
|
|
|
|
replicator.tell(new Delete<PNCounter>(counter1Key, writeMajority), getSelf());
|
|
|
|
|
})
|
|
|
|
|
.build();
|
improve AbstractActor, #21717
* Receive class that wraps PartialFunction, to avoid
scary scala types
* move AbstractActorContext to AbstractActor.ActorContext
* converting docs, many, many UntypedActor
* removing UntypedActor docs
* add unit test for ReceiveBuilder
* MiMa filters
* consistent use of getContext(), self(), sender()
* rename cross references
* migration guide
* skip samples for now
* improve match type safetyi, add matchUnchecked
* the `? extends P` caused code like this to compile:
`match(String.class, (Integer i) -> {})`
* added matchUnchecked, since it can still be useful (um, convenient)
to be able to do:
`matchUnchecked(List.class, (List<String> list) -> {})`
* eleminate some scala.Option
* preRestart
* findChild
* ActorIdentity.getActorRef
2016-12-13 10:59:29 +01:00
|
|
|
}
|
2015-05-17 12:28:47 +02:00
|
|
|
}
|
2019-01-12 04:00:53 +08:00
|
|
|
// #delete
|
2015-05-17 12:28:47 +02:00
|
|
|
|
|
|
|
|
public void demonstratePNCounter() {
|
2019-01-12 04:00:53 +08:00
|
|
|
// #pncounter
|
2018-12-14 15:53:08 -05:00
|
|
|
final SelfUniqueAddress node = DistributedData.get(system).selfUniqueAddress();
|
2015-05-17 12:28:47 +02:00
|
|
|
final PNCounter c0 = PNCounter.create();
|
|
|
|
|
final PNCounter c1 = c0.increment(node, 1);
|
|
|
|
|
final PNCounter c2 = c1.increment(node, 7);
|
|
|
|
|
final PNCounter c3 = c2.decrement(node, 2);
|
|
|
|
|
System.out.println(c3.value()); // 6
|
2019-01-12 04:00:53 +08:00
|
|
|
// #pncounter
|
2015-05-17 12:28:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void demonstratePNCounterMap() {
|
2019-01-12 04:00:53 +08:00
|
|
|
// #pncountermap
|
2018-12-14 15:53:08 -05:00
|
|
|
final SelfUniqueAddress node = DistributedData.get(system).selfUniqueAddress();
|
2016-12-22 11:47:27 +01:00
|
|
|
final PNCounterMap<String> m0 = PNCounterMap.create();
|
|
|
|
|
final PNCounterMap<String> m1 = m0.increment(node, "a", 7);
|
|
|
|
|
final PNCounterMap<String> m2 = m1.decrement(node, "a", 2);
|
|
|
|
|
final PNCounterMap<String> m3 = m2.increment(node, "b", 1);
|
2015-05-17 12:28:47 +02:00
|
|
|
System.out.println(m3.get("a")); // 5
|
|
|
|
|
System.out.println(m3.getEntries());
|
2019-01-12 04:00:53 +08:00
|
|
|
// #pncountermap
|
2015-05-17 12:28:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void demonstrateGSet() {
|
2019-01-12 04:00:53 +08:00
|
|
|
// #gset
|
2015-05-17 12:28:47 +02:00
|
|
|
final GSet<String> s0 = GSet.create();
|
|
|
|
|
final GSet<String> s1 = s0.add("a");
|
|
|
|
|
final GSet<String> s2 = s1.add("b").add("c");
|
2019-01-12 04:00:53 +08:00
|
|
|
if (s2.contains("a")) System.out.println(s2.getElements()); // a, b, c
|
|
|
|
|
// #gset
|
2015-05-17 12:28:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void demonstrateORSet() {
|
2019-01-12 04:00:53 +08:00
|
|
|
// #orset
|
2019-10-14 14:03:04 +02:00
|
|
|
final SelfUniqueAddress node = DistributedData.get(system).selfUniqueAddress();
|
2015-05-17 12:28:47 +02:00
|
|
|
final ORSet<String> s0 = ORSet.create();
|
|
|
|
|
final ORSet<String> s1 = s0.add(node, "a");
|
|
|
|
|
final ORSet<String> s2 = s1.add(node, "b");
|
|
|
|
|
final ORSet<String> s3 = s2.remove(node, "a");
|
|
|
|
|
System.out.println(s3.getElements()); // b
|
2019-01-12 04:00:53 +08:00
|
|
|
// #orset
|
2015-05-17 12:28:47 +02:00
|
|
|
}
|
|
|
|
|
|
2015-06-18 16:17:53 +02:00
|
|
|
public void demonstrateORMultiMap() {
|
2019-01-12 04:00:53 +08:00
|
|
|
// #ormultimap
|
2018-12-14 15:53:08 -05:00
|
|
|
final SelfUniqueAddress node = DistributedData.get(system).selfUniqueAddress();
|
2016-12-22 11:47:27 +01:00
|
|
|
final ORMultiMap<String, Integer> m0 = ORMultiMap.create();
|
2019-01-12 04:00:53 +08:00
|
|
|
final ORMultiMap<String, Integer> m1 = m0.put(node, "a", new HashSet<>(Arrays.asList(1, 2, 3)));
|
2016-12-22 11:47:27 +01:00
|
|
|
final ORMultiMap<String, Integer> m2 = m1.addBinding(node, "a", 4);
|
|
|
|
|
final ORMultiMap<String, Integer> m3 = m2.removeBinding(node, "a", 2);
|
|
|
|
|
final ORMultiMap<String, Integer> m4 = m3.addBinding(node, "b", 1);
|
2015-06-18 16:17:53 +02:00
|
|
|
System.out.println(m4.getEntries());
|
2019-01-12 04:00:53 +08:00
|
|
|
// #ormultimap
|
2015-06-18 16:17:53 +02:00
|
|
|
}
|
|
|
|
|
|
2015-05-17 12:28:47 +02:00
|
|
|
public void demonstrateFlag() {
|
2019-01-12 04:00:53 +08:00
|
|
|
// #flag
|
2015-05-17 12:28:47 +02:00
|
|
|
final Flag f0 = Flag.create();
|
|
|
|
|
final Flag f1 = f0.switchOn();
|
|
|
|
|
System.out.println(f1.enabled());
|
2019-01-12 04:00:53 +08:00
|
|
|
// #flag
|
2015-05-17 12:28:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void demonstrateLWWRegister() {
|
2019-01-12 04:00:53 +08:00
|
|
|
// #lwwregister
|
2018-12-14 15:53:08 -05:00
|
|
|
final SelfUniqueAddress node = DistributedData.get(system).selfUniqueAddress();
|
2015-05-17 12:28:47 +02:00
|
|
|
final LWWRegister<String> r1 = LWWRegister.create(node, "Hello");
|
|
|
|
|
final LWWRegister<String> r2 = r1.withValue(node, "Hi");
|
|
|
|
|
System.out.println(r1.value() + " by " + r1.updatedBy() + " at " + r1.timestamp());
|
2019-01-12 04:00:53 +08:00
|
|
|
// #lwwregister
|
2015-05-17 12:28:47 +02:00
|
|
|
assertEquals("Hi", r2.value());
|
|
|
|
|
}
|
2019-01-12 04:00:53 +08:00
|
|
|
|
2015-05-17 12:28:47 +02:00
|
|
|
static
|
2019-01-12 04:00:53 +08:00
|
|
|
// #lwwregister-custom-clock
|
2015-05-17 12:28:47 +02:00
|
|
|
class Record {
|
|
|
|
|
public final int version;
|
|
|
|
|
public final String name;
|
|
|
|
|
public final String address;
|
|
|
|
|
|
|
|
|
|
public Record(int version, String name, String address) {
|
|
|
|
|
this.version = version;
|
|
|
|
|
this.name = name;
|
|
|
|
|
this.address = address;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-01-12 04:00:53 +08:00
|
|
|
|
|
|
|
|
// #lwwregister-custom-clock
|
|
|
|
|
|
2015-05-17 12:28:47 +02:00
|
|
|
public void demonstrateLWWRegisterWithCustomClock() {
|
2019-01-12 04:00:53 +08:00
|
|
|
// #lwwregister-custom-clock
|
2015-05-17 12:28:47 +02:00
|
|
|
|
2018-12-14 15:53:08 -05:00
|
|
|
final SelfUniqueAddress node = DistributedData.get(system).selfUniqueAddress();
|
2019-01-12 04:00:53 +08:00
|
|
|
final LWWRegister.Clock<Record> recordClock =
|
|
|
|
|
new LWWRegister.Clock<Record>() {
|
|
|
|
|
@Override
|
|
|
|
|
public long apply(long currentTimestamp, Record value) {
|
|
|
|
|
return value.version;
|
|
|
|
|
}
|
|
|
|
|
};
|
2015-05-17 12:28:47 +02:00
|
|
|
|
|
|
|
|
final Record record1 = new Record(1, "Alice", "Union Square");
|
|
|
|
|
final LWWRegister<Record> r1 = LWWRegister.create(node, record1);
|
|
|
|
|
|
|
|
|
|
final Record record2 = new Record(2, "Alice", "Madison Square");
|
|
|
|
|
final LWWRegister<Record> r2 = LWWRegister.create(node, record2);
|
|
|
|
|
|
|
|
|
|
final LWWRegister<Record> r3 = r1.merge(r2);
|
|
|
|
|
System.out.println(r3.value());
|
2019-01-12 04:00:53 +08:00
|
|
|
// #lwwregister-custom-clock
|
2015-05-17 12:28:47 +02:00
|
|
|
|
|
|
|
|
assertEquals("Madison Square", r3.value().address);
|
|
|
|
|
}
|
|
|
|
|
}
|