Cluster Usage
For introduction to the Akka Cluster concepts please see Cluster Specification.
Preparing Your Project for Clustering
The Akka cluster is a separate jar file. Make sure that you have the following dependency in your project:
<dependency>
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-cluster_2.10</artifactId>
<version>2.2.3</version>
</dependency>
A Simple Cluster Example
The following small program together with its configuration starts an ActorSystem with the Cluster enabled. It joins the cluster and logs some membership events.
Try it out:
- Add the following application.conf in your project, place it in src/main/resources:
akka {
actor {
provider = "akka.cluster.ClusterActorRefProvider"
}
remote {
log-remote-lifecycle-events = off
netty.tcp {
hostname = "<IP_ADDRESS>"
port = 0
}
}
cluster {
seed-nodes = [
"akka.tcp://ClusterSystem@<IP_ADDRESS>:2551",
"akka.tcp://ClusterSystem@<IP_ADDRESS>:2552"]
auto-down = on
}
}
To enable cluster capabilities in your Akka project you should, at a minimum, add the Remoting settings, but with akka.cluster.ClusterActorRefProvider. The akka.cluster.seed-nodes should normally also be added to your application.conf file.
The seed nodes are configured contact points for initial, automatic, join of the cluster.
Note that if you are going to start the nodes on different machines you need to specify the ip-addresses or host names of the machines in application.conf instead of <IP_ADDRESS>
- Add the following main program to your project, place it in src/main/java:
package sample.cluster.simple.japi;
import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import akka.actor.Props;
import akka.cluster.Cluster;
import akka.cluster.ClusterEvent.ClusterDomainEvent;
public class SimpleClusterApp {
public static void main(String[] args) {
// Override the configuration of the port
// when specified as program argument
if (args.length > 0)
System.setProperty("akka.remote.netty.tcp.port", args[0]);
// Create an Akka system
ActorSystem system = ActorSystem.create("ClusterSystem");
// Create an actor that handles cluster domain events
ActorRef clusterListener = system.actorOf(Props.create(
SimpleClusterListener.class), "clusterListener");
// Add subscription of cluster events
Cluster.get(system).subscribe(clusterListener,
ClusterDomainEvent.class);
}
}
Start the first seed node. Open a terminal window and run (one line):
mvn exec:java -Dexec.mainClass="sample.cluster.simple.japi.SimpleClusterApp" \ -Dexec.args="2551"
2551 corresponds to the port of the first seed-nodes element in the configuration. In the log output you see that the cluster node has been started and changed status to 'Up'.
Start the second seed node. Open another terminal window and run:
mvn exec:java -Dexec.mainClass="sample.cluster.simple.japi.SimpleClusterApp" \ -Dexec.args="2552"
2552 corresponds to the port of the second seed-nodes element in the configuration. In the log output you see that the cluster node has been started and joins the other seed node and becomes a member of the cluster. Its status changed to 'Up'.
Switch over to the first terminal window and see in the log output that the member joined.
Start another node. Open a maven session in yet another terminal window and run:
mvn exec:java -Dexec.mainClass="sample.cluster.simple.japi.SimpleClusterApp"
Now you don't need to specify the port number, and it will use a random available port. It joins one of the configured seed nodes. Look at the log output in the different terminal windows.
Start even more nodes in the same way, if you like.
6. Shut down one of the nodes by pressing 'ctrl-c' in one of the terminal windows. The other nodes will detect the failure after a while, which you can see in the log output in the other terminals.
Look at the source code of the program again. What it does is to create an actor and register it as subscriber of certain cluster events. It gets notified with an snapshot event, CurrentClusterState that holds full state information of the cluster. After that it receives events for changes that happen in the cluster.
Joining to Seed Nodes
You may decide if joining to the cluster should be done manually or automatically to configured initial contact points, so-called seed nodes. When a new node is started it sends a message to all seed nodes and then sends join command to the one that answers first. If no one of the seed nodes replied (might not be started yet) it retries this procedure until successful or shutdown.
You define the seed nodes in the Configuration file (application.conf):
akka.cluster.seed-nodes = [
"akka.tcp://ClusterSystem@host1:2552",
"akka.tcp://ClusterSystem@host2:2552"]
This can also be defined as Java system properties when starting the JVM using the following syntax:
-Dakka.cluster.seed-nodes.0=akka.tcp://ClusterSystem@host1:2552
-Dakka.cluster.seed-nodes.1=akka.tcp://ClusterSystem@host2:2552
The seed nodes can be started in any order and it is not necessary to have all seed nodes running, but the node configured as the first element in the seed-nodes configuration list must be started when initially starting a cluster, otherwise the other seed-nodes will not become initialized and no other node can join the cluster. It is quickest to start all configured seed nodes at the same time (order doesn't matter), otherwise it can take up to the configured seed-node-timeout until the nodes can join.
Once more than two seed nodes have been started it is no problem to shut down the first seed node. If the first seed node is restarted it will first try join the other seed nodes in the existing cluster.
If you don't configure the seed nodes you need to join manually, using JMX or Command Line Management. You can join to any node in the cluster. It doesn't have to be configured as a seed node.
Joining can also be performed programatically with Cluster.get(system).join(address).
Unsuccessful join attempts are automatically retried after the time period defined in configuration property retry-unsuccessful-join-after. When using seed-nodes this means that a new seed node is picked. When joining manually or programatically this means that the last join request is retried. Retries can be disabled by setting the property to off.
An actor system can only join a cluster once. Additional attempts will be ignored. When it has successfully joined it must be restarted to be able to join another cluster or to join the same cluster again. It can use the same host name and port after the restart, but it must have been removed from the cluster before the join request is accepted.
Automatic vs. Manual Downing
When a member is considered by the failure detector to be unreachable the leader is not allowed to perform its duties, such as changing status of new joining members to 'Up'. The status of the unreachable member must be changed to 'Down'. This can be performed automatically or manually. By default it must be done manually, using using JMX or Command Line Management.
It can also be performed programatically with Cluster.get(system).down(address).
You can enable automatic downing with configuration:
akka.cluster.auto-down = on
Be aware of that using auto-down implies that two separate clusters will automatically be formed in case of network partition. That might be desired by some applications but not by others.
Leaving
There are two ways to remove a member from the cluster.
You can just stop the actor system (or the JVM process). It will be detected as unreachable and removed after the automatic or manual downing as described above.
A more graceful exit can be performed if you tell the cluster that a node shall leave. This can be performed using JMX or Command Line Management. It can also be performed programatically with Cluster.get(system).leave(address).
Note that this command can be issued to any member in the cluster, not necessarily the one that is leaving. The cluster extension, but not the actor system or JVM, of the leaving member will be shutdown after the leader has changed status of the member to Exiting. Thereafter the member will be removed from the cluster. Normally this is handled automatically, but in case of network failures during this process it might still be necessary to set the node’s status to Down in order to complete the removal.
Subscribe to Cluster Events
You can subscribe to change notifications of the cluster membership by using Cluster.get(system).subscribe(subscriber, to). A snapshot of the full state, akka.cluster.ClusterEvent.CurrentClusterState, is sent to the subscriber as the first event, followed by events for incremental updates.
Note that you may receive an empty CurrentClusterState, containing no members, if you start the subscription before the initial join procedure has completed. This is expected behavior. When the node has been accepted in the cluster you will receive MemberUp for that node, and other nodes.
The events to track the life-cycle of members are:
- ClusterEvent.MemberUp - A new member has joined the cluster and its status has been changed to Up.
- ClusterEvent.MemberExited - A member is leaving the cluster and its status has been changed to Exiting. Note that the node might already have been shutdown when this event is published on another node.
- ClusterEvent.MemberRemoved - Member completely removed from the cluster.
- ClusterEvent.UnreachableMember - A member is considered as unreachable by the failure detector.
There are more types of change events, consult the API documentation of classes that extends akka.cluster.ClusterEvent.ClusterDomainEvent for details about the events.
Worker Dial-in Example
Let's take a look at an example that illustrates how workers, here named backend, can detect and register to new master nodes, here named frontend.
The example application provides a service to transform text. When some text is sent to one of the frontend services, it will be delegated to one of the backend workers, which performs the transformation job, and sends the result back to the original client. New backend nodes, as well as new frontend nodes, can be added or removed to the cluster dynamically.
In this example the following imports are used:
import akka.actor.UntypedActor;
import akka.cluster.Cluster;
import akka.cluster.ClusterEvent.CurrentClusterState;
import akka.cluster.ClusterEvent.MemberUp;
import akka.cluster.Member;
import akka.cluster.MemberStatus;
Messages:
public interface TransformationMessages {
public static class TransformationJob implements Serializable {
private final String text;
public TransformationJob(String text) {
this.text = text;
}
public String getText() {
return text;
}
}
public static class TransformationResult implements Serializable {
private final String text;
public TransformationResult(String text) {
this.text = text;
}
public String getText() {
return text;
}
@Override
public String toString() {
return "TransformationResult(" + text + ")";
}
}
public static class JobFailed implements Serializable {
private final String reason;
private final TransformationJob job;
public JobFailed(String reason, TransformationJob job) {
this.reason = reason;
this.job = job;
}
public String getReason() {
return reason;
}
public TransformationJob getJob() {
return job;
}
@Override
public String toString() {
return "JobFailed(" + reason + ")";
}
}
public static final String BACKEND_REGISTRATION = "BackendRegistration";
}
The backend worker that performs the transformation job:
public class TransformationBackend extends UntypedActor {
Cluster cluster = Cluster.get(getContext().system());
//subscribe to cluster changes, MemberUp
@Override
public void preStart() {
cluster.subscribe(getSelf(), MemberUp.class);
}
//re-subscribe when restart
@Override
public void postStop() {
cluster.unsubscribe(getSelf());
}
@Override
public void onReceive(Object message) {
if (message instanceof TransformationJob) {
TransformationJob job = (TransformationJob) message;
getSender()
.tell(new TransformationResult(job.getText().toUpperCase()),
getSelf());
} else if (message instanceof CurrentClusterState) {
CurrentClusterState state = (CurrentClusterState) message;
for (Member member : state.getMembers()) {
if (member.status().equals(MemberStatus.up())) {
register(member);
}
}
} else if (message instanceof MemberUp) {
MemberUp mUp = (MemberUp) message;
register(mUp.member());
} else {
unhandled(message);
}
}
void register(Member member) {
if (member.hasRole("frontend"))
getContext().actorSelection(member.address() + "/user/frontend").tell(
BACKEND_REGISTRATION, getSelf());
}
}
Note that the TransformationBackend actor subscribes to cluster events to detect new, potential, frontend nodes, and send them a registration message so that they know that they can use the backend worker.
The frontend that receives user jobs and delegates to one of the registered backend workers:
public class TransformationFrontend extends UntypedActor {
List<ActorRef> backends = new ArrayList<ActorRef>();
int jobCounter = 0;
@Override
public void onReceive(Object message) {
if ((message instanceof TransformationJob) && backends.isEmpty()) {
TransformationJob job = (TransformationJob) message;
getSender().tell(
new JobFailed("Service unavailable, try again later", job),
getSender());
} else if (message instanceof TransformationJob) {
TransformationJob job = (TransformationJob) message;
jobCounter++;
backends.get(jobCounter % backends.size())
.forward(job, getContext());
} else if (message.equals(BACKEND_REGISTRATION)) {
getContext().watch(getSender());
backends.add(getSender());
} else if (message instanceof Terminated) {
Terminated terminated = (Terminated) message;
backends.remove(terminated.getActor());
} else {
unhandled(message);
}
}
}
Note that the TransformationFrontend actor watch the registered backend to be able to remove it from its list of availble backend workers. Death watch uses the cluster failure detector for nodes in the cluster, i.e. it detects network failures and JVM crashes, in addition to graceful termination of watched actor.
This example is included in akka-samples/akka-sample-cluster and you can try it by copying the source to your maven project, defined as in A Simple Cluster Example. Run it by starting nodes in different terminal windows. For example, starting 2 frontend nodes and 3 backend nodes:
mvn exec:java \
-Dexec.mainClass="sample.cluster.transformation.japi.TransformationFrontendMain" \
-Dexec.args="2551"
mvn exec:java \
-Dexec.mainClass="sample.cluster.transformation.japi.TransformationBackendMain" \
-Dexec.args="2552"
mvn exec:java \
-Dexec.mainClass="sample.cluster.transformation.japi.TransformationBackendMain"
mvn exec:java \
-Dexec.mainClass="sample.cluster.transformation.japi.TransformationBackendMain"
mvn exec:java \
-Dexec.mainClass="sample.cluster.transformation.japi.TransformationFrontendMain"
Node Roles
Not all nodes of a cluster need to perform the same function: there might be one sub-set which runs the web front-end, one which runs the data access layer and one for the number-crunching. Deployment of actors—for example by cluster-aware routers—can take node roles into account to achieve this distribution of responsibilities.
The roles of a node is defined in the configuration property named akka.cluster.roles and it is typically defined in the start script as a system property or environment variable.
The roles of the nodes is part of the membership information in MemberEvent that you can subscribe to.
How To Startup when Cluster Size Reached
A common use case is to start actors after the cluster has been initialized, members have joined, and the cluster has reached a certain size.
With a configuration option you can define required number of members before the leader changes member status of 'Joining' members to 'Up'.
akka.cluster.min-nr-of-members = 3
In a similar way you can define required number of members of a certain role before the leader changes member status of 'Joining' members to 'Up'.
akka.cluster.role {
frontend.min-nr-of-members = 1
backend.min-nr-of-members = 2
}
You can start the actors in a registerOnMemberUp callback, which will be invoked when the current member status is changed tp 'Up', i.e. the cluster has at least the defined number of members.
Cluster.get(system).registerOnMemberUp(new Runnable() {
@Override
public void run() {
system.actorOf(Props.create(FactorialFrontend.class, upToN, true),
"factorialFrontend");
}
});
This callback can be used for other things than starting actors.
Cluster Singleton Pattern
For some use cases it is convenient and sometimes also mandatory to ensure that you have exactly one actor of a certain type running somewhere in the cluster.
This can be implemented by subscribing to member events, but there are several corner cases to consider. Therefore, this specific use case is made easily accessible by the Cluster Singleton Pattern in the contrib module. You can use it as is, or adjust to fit your specific needs.
Distributed Publish Subscribe Pattern
See Distributed Publish Subscribe in Cluster in the contrib module.
Cluster Client
See Cluster Client in the contrib module.
Failure Detector
The nodes in the cluster monitor each other by sending heartbeats to detect if a node is unreachable from the rest of the cluster. The heartbeat arrival times is interpreted by an implementation of The Phi Accrual Failure Detector.
The suspicion level of failure is given by a value called phi. The basic idea of the phi failure detector is to express the value of phi on a scale that is dynamically adjusted to reflect current network conditions.
The value of phi is calculated as:
phi = -log10(1 - F(timeSinceLastHeartbeat))
where F is the cumulative distribution function of a normal distribution with mean and standard deviation estimated from historical heartbeat inter-arrival times.
In the Configuration you can adjust the akka.cluster.failure-detector.threshold to define when a phi value is considered to be a failure.
A low threshold is prone to generate many false positives but ensures a quick detection in the event of a real crash. Conversely, a high threshold generates fewer mistakes but needs more time to detect actual crashes. The default threshold is 8 and is appropriate for most situations. However in cloud environments, such as Amazon EC2, the value could be increased to 12 in order to account for network issues that sometimes occur on such platforms.
The following chart illustrates how phi increase with increasing time since the previous heartbeat.
Phi is calculated from the mean and standard deviation of historical inter arrival times. The previous chart is an example for standard deviation of 200 ms. If the heartbeats arrive with less deviation the curve becomes steeper, i.e. it is possible to determine failure more quickly. The curve looks like this for a standard deviation of 100 ms.
To be able to survive sudden abnormalities, such as garbage collection pauses and transient network failures the failure detector is configured with a margin, akka.cluster.failure-detector.acceptable-heartbeat-pause. You may want to adjust the Configuration of this depending on you environment. This is how the curve looks like for acceptable-heartbeat-pause configured to 3 seconds.
Death watch uses the cluster failure detector for nodes in the cluster, i.e. it generates Terminated message from network failures and JVM crashes, in addition to graceful termination of watched actor.
If you encounter suspicious false positives when the system is under load you should define a separate dispatcher for the cluster actors as described in Cluster Dispatcher.
Cluster Aware Routers
All routers can be made aware of member nodes in the cluster, i.e. deploying new routees or looking up routees on nodes in the cluster. When a node becomes unavailable or leaves the cluster the routees of that node are automatically unregistered from the router. When new nodes join the cluster additional routees are added to the router, according to the configuration.
There are two distinct types of routers.
- Router that lookup existing actors and use them as routees. The routees can be shared between routers running on different nodes in the cluster. One example of a use case for this type of router is a service running on some backend nodes in the cluster and used by routers running on front-end nodes in the cluster.
- Router that creates new routees as child actors and deploy them on remote nodes. Each router will have its own routee instances. For example, if you start a router on 3 nodes in a 10 nodes cluster you will have 30 routee actors in total if the router is configured to use one inctance per node. The routees created by the the different routers will not be shared between the routers. One example of a use case for this type of router is a single master that coordinate jobs and delegates the actual work to routees running on other nodes in the cluster.
Router with Lookup of Routees
When using a router with routees looked up on the cluster member nodes, i.e. the routees are already running, the configuration for a router looks like this:
akka.actor.deployment {
/statsService/workerRouter {
router = consistent-hashing
nr-of-instances = 100
cluster {
enabled = on
routees-path = "/user/statsWorker"
allow-local-routees = on
use-role = compute
}
}
}
Note
The routee actors should be started as early as possible when starting the actor system, because the router will try to use them as soon as the member status is changed to 'Up'. If it is not available at that point it will be removed from the router and it will only re-try when the cluster members are changed.
It is the relative actor path defined in routees-path that identify what actor to lookup. It is possible to limit the lookup of routees to member nodes tagged with a certain role by specifying use-role.
nr-of-instances defines total number of routees in the cluster, but there will not be more than one per node. That routee actor could easily fan out to local children if more parallelism is needed. Setting nr-of-instances to a high value will result in new routees added to the router when nodes join the cluster.
The same type of router could also have been defined in code:
int totalInstances = 100;
String routeesPath = "/user/statsWorker";
boolean allowLocalRoutees = true;
String useRole = "compute";
ActorRef workerRouter = getContext().actorOf(
Props.empty().withRouter(new ClusterRouterConfig(
new ConsistentHashingRouter(0), new ClusterRouterSettings(
totalInstances, routeesPath, allowLocalRoutees, useRole))),
"workerRouter2");
See Configuration section for further descriptions of the settings.
Router Example with Lookup of Routees
Let's take a look at how to use a cluster aware router with lookup of routees.
The example application provides a service to calculate statistics for a text. When some text is sent to the service it splits it into words, and delegates the task to count number of characters in each word to a separate worker, a routee of a router. The character count for each word is sent back to an aggregator that calculates the average number of characters per word when all results have been collected.
In this example we use the following imports:
import akka.actor.ActorRef;
import akka.actor.Props;
import akka.actor.UntypedActor;
import akka.cluster.routing.ClusterRouterConfig;
import akka.cluster.routing.ClusterRouterSettings;
import akka.routing.ConsistentHashingRouter;
import akka.routing.ConsistentHashingRouter.ConsistentHashableEnvelope;
import akka.routing.FromConfig;
Messages:
public interface StatsMessages {
public static class StatsJob implements Serializable {
private final String text;
public StatsJob(String text) {
this.text = text;
}
public String getText() {
return text;
}
}
public static class StatsResult implements Serializable {
private final double meanWordLength;
public StatsResult(double meanWordLength) {
this.meanWordLength = meanWordLength;
}
public double getMeanWordLength() {
return meanWordLength;
}
@Override
public String toString() {
return "meanWordLength: " + meanWordLength;
}
}
public static class JobFailed implements Serializable {
private final String reason;
public JobFailed(String reason) {
this.reason = reason;
}
public String getReason() {
return reason;
}
@Override
public String toString() {
return "JobFailed(" + reason + ")";
}
}
}
The worker that counts number of characters in each word:
public class StatsWorker extends UntypedActor {
Map<String, Integer> cache = new HashMap<String, Integer>();
@Override
public void onReceive(Object message) {
if (message instanceof String) {
String word = (String) message;
Integer length = cache.get(word);
if (length == null) {
length = word.length();
cache.put(word, length);
}
getSender().tell(length, getSelf());
} else {
unhandled(message);
}
}
}
The service that receives text from users and splits it up into words, delegates to workers and aggregates:
public class StatsService extends UntypedActor {
// This router is used both with lookup and deploy of routees. If you
// have a router with only lookup of routees you can use Props.empty()
// instead of Props.create(StatsWorker.class).
ActorRef workerRouter = getContext().actorOf(
Props.create(StatsWorker.class).withRouter(FromConfig.getInstance()),
"workerRouter");
@Override
public void onReceive(Object message) {
if (message instanceof StatsJob) {
StatsJob job = (StatsJob) message;
if (job.getText().equals("")) {
unhandled(message);
} else {
final String[] words = job.getText().split(" ");
final ActorRef replyTo = getSender();
// create actor that collects replies from workers
ActorRef aggregator = getContext().actorOf(
Props.create(StatsAggregator.class, words.length, replyTo));
// send each word to a worker
for (String word : words) {
workerRouter.tell(new ConsistentHashableEnvelope(word, word),
aggregator);
}
}
} else {
unhandled(message);
}
}
}
public class StatsAggregator extends UntypedActor {
final int expectedResults;
final ActorRef replyTo;
final List<Integer> results = new ArrayList<Integer>();
public StatsAggregator(int expectedResults, ActorRef replyTo) {
this.expectedResults = expectedResults;
this.replyTo = replyTo;
}
@Override
public void preStart() {
getContext().setReceiveTimeout(Duration.create(3, TimeUnit.SECONDS));
}
@Override
public void onReceive(Object message) {
if (message instanceof Integer) {
Integer wordCount = (Integer) message;
results.add(wordCount);
if (results.size() == expectedResults) {
int sum = 0;
for (int c : results)
sum += c;
double meanWordLength = ((double) sum) / results.size();
replyTo.tell(new StatsResult(meanWordLength), getSelf());
getContext().stop(getSelf());
}
} else if (message == ReceiveTimeout.getInstance()) {
replyTo.tell(new JobFailed("Service unavailable, try again later"),
getSelf());
getContext().stop(getSelf());
} else {
unhandled(message);
}
}
}
Note, nothing cluster specific so far, just plain actors.
All nodes start StatsService and StatsWorker actors. Remember, routees are the workers in this case. The router is configured with routees-path:
akka.actor.deployment {
/statsService/workerRouter {
router = consistent-hashing
nr-of-instances = 100
cluster {
enabled = on
routees-path = "/user/statsWorker"
allow-local-routees = on
use-role = compute
}
}
}
This means that user requests can be sent to StatsService on any node and it will use StatsWorker on all nodes. There can only be one worker per node, but that worker could easily fan out to local children if more parallelism is needed.
This example is included in akka-samples/akka-sample-cluster and you can try it by copying the source to your maven project, defined as in A Simple Cluster Example. Run it by starting nodes in different terminal windows. For example, starting 3 service nodes and 1 client:
mvn exec:java \
-Dexec.mainClass="sample.cluster.stats.japi.StatsSampleMain" \
-Dexec.args="2551"
mvn exec:java \
-Dexec.mainClass="sample.cluster.stats.japi.StatsSampleMain" \
-Dexec.args="2552"
mvn exec:java \
-Dexec.mainClass="sample.cluster.stats.japi.StatsSampleMain"
mvn exec:java \
-Dexec.mainClass="sample.cluster.stats.japi.StatsSampleMain"
Router with Remote Deployed Routees
When using a router with routees created and deployed on the cluster member nodes the configuration for a router looks like this:
akka.actor.deployment {
/singleton/statsService/workerRouter {
router = consistent-hashing
nr-of-instances = 100
cluster {
enabled = on
max-nr-of-instances-per-node = 3
allow-local-routees = off
use-role = compute
}
}
}
It is possible to limit the deployment of routees to member nodes tagged with a certain role by specifying use-role.
nr-of-instances defines total number of routees in the cluster, but the number of routees per node, max-nr-of-instances-per-node, will not be exceeded. Setting nr-of-instances to a high value will result in creating and deploying additional routees when new nodes join the cluster.
The same type of router could also have been defined in code:
int totalInstances = 100;
int maxInstancesPerNode = 3;
boolean allowLocalRoutees = false;
String useRole = "compute";
ActorRef workerRouter = getContext().actorOf(
Props.create(StatsWorker.class).withRouter(new ClusterRouterConfig(
new ConsistentHashingRouter(0), new ClusterRouterSettings(
totalInstances, maxInstancesPerNode, allowLocalRoutees, useRole))),
"workerRouter3");
See Configuration section for further descriptions of the settings.
Router Example with Remote Deployed Routees
Let's take a look at how to use a cluster aware router on single master node that creates and deploys workers. To keep track of a single master we use the Cluster Singleton Pattern in the contrib module. The ClusterSingletonManager is started on each node.
system.actorOf(ClusterSingletonManager.defaultProps(
"statsService", PoisonPill.getInstance(), "compute",
new ClusterSingletonPropsFactory() {
@Override
public Props create(Object handOverData) {
return Props.create(StatsService.class);
}
}), "singleton");
We also need an actor on each node that keeps track of where current single master exists and delegates jobs to the StatsService.
public class StatsFacade extends UntypedActor {
final LoggingAdapter log = Logging.getLogger(getContext().system(), this);
final Cluster cluster = Cluster.get(getContext().system());
final Comparator<Member> ageComparator = new Comparator<Member>() {
public int compare(Member a, Member b) {
if (a.isOlderThan(b)) return -1;
else if (b.isOlderThan(a)) return 1;
else return 0;
}
};
final SortedSet<Member> membersByAge = new TreeSet<Member>(ageComparator);
//subscribe to cluster changes
@Override
public void preStart() {
cluster.subscribe(getSelf(), MemberEvent.class);
}
//re-subscribe when restart
@Override
public void postStop() {
cluster.unsubscribe(getSelf());
}
@Override
public void onReceive(Object message) {
if (message instanceof StatsJob && membersByAge.isEmpty()) {
getSender().tell(new JobFailed("Service unavailable, try again later"),
getSelf());
} else if (message instanceof StatsJob) {
currentMaster().tell(message, getSender());
} else if (message instanceof CurrentClusterState) {
CurrentClusterState state = (CurrentClusterState) message;
List<Member> members = new ArrayList<Member>();
for (Member m : state.getMembers()) {
if (m.hasRole("compute")) members.add(m);
}
membersByAge.clear();
membersByAge.addAll(members);
} else if (message instanceof MemberUp) {
Member m = ((MemberUp) message).member();
if (m.hasRole("compute")) membersByAge.add(m);
} else if (message instanceof MemberRemoved) {
Member m = ((MemberUp) message).member();
if (m.hasRole("compute")) membersByAge.remove(m);
} else if (message instanceof MemberEvent) {
// not interesting
} else {
unhandled(message);
}
}
ActorSelection currentMaster() {
return getContext().actorSelection(membersByAge.first().address() +
"/user/singleton/statsService");
}
}
The StatsFacade receives text from users and delegates to the current StatsService, the single master. It listens to cluster events to lookup the StatsService on the oldest node.
All nodes start StatsFacade and the ClusterSingletonManager. The router is now configured like this:
akka.actor.deployment {
/singleton/statsService/workerRouter {
router = consistent-hashing
nr-of-instances = 100
cluster {
enabled = on
max-nr-of-instances-per-node = 3
allow-local-routees = off
use-role = compute
}
}
}
This example is included in akka-samples/akka-sample-cluster and you can try it by copying the source to your maven project, defined as in A Simple Cluster Example. Also add the akka-contrib dependency to your pom.xml.
Run it by starting nodes in different terminal windows. For example, starting 3 service nodes and 1 client:
mvn exec:java \
-Dexec.mainClass="sample.cluster.stats.japi.StatsSampleOneMasterMain" \
-Dexec.args="2551"
mvn exec:java \
-Dexec.mainClass="sample.cluster.stats.japi.StatsSampleOneMasterMain" \
-Dexec.args="2552"
mvn exec:java \
-Dexec.mainClass="sample.cluster.stats.japi.StatsSampleOneMasterClientMain"
mvn exec:java \
-Dexec.mainClass="sample.cluster.stats.japi.StatsSampleOneMasterMain"
Note
The above example will be simplified when the cluster handles automatic actor partitioning.
Cluster Metrics
The member nodes of the cluster collects system health metrics and publishes that to other nodes and to registered subscribers. This information is primarily used for load-balancing routers.
Hyperic Sigar
The built-in metrics is gathered from JMX MBeans, and optionally you can use Hyperic Sigar for a wider and more accurate range of metrics compared to what can be retrieved from ordinary MBeans. Sigar is using a native OS library. To enable usage of Sigar you need to add the directory of the native library to -Djava.libarary.path=<path_of_sigar_libs> add the following dependency:
<dependency>
<groupId>org.fusesource</groupId>
<artifactId>sigar</artifactId>
<version>1.6.4</version>
</dependency>
Download the native Sigar libraries from Maven Central
Adaptive Load Balancing
The AdaptiveLoadBalancingRouter performs load balancing of messages to cluster nodes based on the cluster metrics data. It uses random selection of routees with probabilities derived from the remaining capacity of the corresponding node. It can be configured to use a specific MetricsSelector to produce the probabilities, a.k.a. weights:
- heap / HeapMetricsSelector - Used and max JVM heap memory. Weights based on remaining heap capacity; (max - used) / max
- load / SystemLoadAverageMetricsSelector - System load average for the past 1 minute, corresponding value can be found in top of Linux systems. The system is possibly nearing a bottleneck if the system load average is nearing number of cpus/cores. Weights based on remaining load capacity; 1 - (load / processors)
- cpu / CpuMetricsSelector - CPU utilization in percentage, sum of User + Sys + Nice + Wait. Weights based on remaining cpu capacity; 1 - utilization
- mix / MixMetricsSelector - Combines heap, cpu and load. Weights based on mean of remaining capacity of the combined selectors.
- Any custom implementation of akka.cluster.routing.MetricsSelector
The collected metrics values are smoothed with exponential weighted moving average. In the Configuration you can adjust how quickly past data is decayed compared to new data.
Let's take a look at this router in action.
In this example the following imports are used:
import java.math.BigInteger;
import java.util.concurrent.Callable;
import scala.concurrent.Future;
import akka.actor.UntypedActor;
import akka.dispatch.Mapper;
import static akka.dispatch.Futures.future;
import static akka.pattern.Patterns.pipe;
The backend worker that performs the factorial calculation:
public class FactorialBackend extends UntypedActor {
@Override
public void onReceive(Object message) {
if (message instanceof Integer) {
final Integer n = (Integer) message;
Future<BigInteger> f = future(new Callable<BigInteger>() {
public BigInteger call() {
return factorial(n);
}
}, getContext().dispatcher());
Future<FactorialResult> result = f.map(
new Mapper<BigInteger, FactorialResult>() {
public FactorialResult apply(BigInteger factorial) {
return new FactorialResult(n, factorial);
}
}, getContext().dispatcher());
pipe(result, getContext().dispatcher()).to(getSender());
} else {
unhandled(message);
}
}
BigInteger factorial(int n) {
BigInteger acc = BigInteger.ONE;
for (int i = 1; i <= n; ++i) {
acc = acc.multiply(BigInteger.valueOf(i));
}
return acc;
}
}
The frontend that receives user jobs and delegates to the backends via the router:
public class FactorialFrontend extends UntypedActor {
final int upToN;
final boolean repeat;
LoggingAdapter log = Logging.getLogger(getContext().system(), this);
ActorRef backend = getContext().actorOf(
Props.empty().withRouter(FromConfig.getInstance()),
"factorialBackendRouter");
public FactorialFrontend(int upToN, boolean repeat) {
this.upToN = upToN;
this.repeat = repeat;
}
@Override
public void preStart() {
sendJobs();
}
@Override
public void onReceive(Object message) {
if (message instanceof FactorialResult) {
FactorialResult result = (FactorialResult) message;
if (result.n == upToN) {
log.debug("{}! = {}", result.n, result.factorial);
if (repeat) sendJobs();
}
} else {
unhandled(message);
}
}
void sendJobs() {
log.info("Starting batch of factorials up to [{}]", upToN);
for (int n = 1; n <= upToN; n++) {
backend.tell(n, getSelf());
}
}
}
As you can see, the router is defined in the same way as other routers, and in this case it is configured as follows:
akka.actor.deployment {
/factorialFrontend/factorialBackendRouter = {
router = adaptive
# metrics-selector = heap
# metrics-selector = load
# metrics-selector = cpu
metrics-selector = mix
nr-of-instances = 100
cluster {
enabled = on
routees-path = "/user/factorialBackend"
use-role = backend
allow-local-routees = off
}
}
}
It is only router type adaptive and the metrics-selector that is specific to this router, other things work in the same way as other routers.
The same type of router could also have been defined in code:
int totalInstances = 100;
String routeesPath = "/user/factorialBackend";
boolean allowLocalRoutees = true;
String useRole = "backend";
ActorRef backend = getContext().actorOf(
Props.empty().withRouter(new ClusterRouterConfig(
new AdaptiveLoadBalancingRouter(HeapMetricsSelector.getInstance(), 0),
new ClusterRouterSettings(
totalInstances, routeesPath, allowLocalRoutees, useRole))),
"factorialBackendRouter2");
int totalInstances = 100;
int maxInstancesPerNode = 3;
boolean allowLocalRoutees = false;
String useRole = "backend";
ActorRef backend = getContext().actorOf(
Props.create(FactorialBackend.class).withRouter(new ClusterRouterConfig(
new AdaptiveLoadBalancingRouter(
SystemLoadAverageMetricsSelector.getInstance(), 0),
new ClusterRouterSettings(
totalInstances, maxInstancesPerNode, allowLocalRoutees, useRole))),
"factorialBackendRouter3");
This example is included in akka-samples/akka-sample-cluster and you can try it by copying the source to your maven project, defined as in A Simple Cluster Example. Run it by starting nodes in different terminal windows. For example, starting 3 backend nodes and one frontend:
mvn exec:java \
-Dexec.mainClass="sample.cluster.factorial.japi.FactorialBackendMain" \
-Dexec.args="2551"
mvn exec:java \
-Dexec.mainClass="sample.cluster.factorial.japi.FactorialBackendMain" \
-Dexec.args="2552"
mvn exec:java \
-Dexec.mainClass="sample.cluster.factorial.japi.FactorialBackendMain"
mvn exec:java \
-Dexec.mainClass="sample.cluster.factorial.japi.FactorialFrontendMain"
Press ctrl-c in the terminal window of the frontend to stop the factorial calculations.
Subscribe to Metrics Events
It is possible to subscribe to the metrics events directly to implement other functionality.
import akka.actor.UntypedActor;
import akka.cluster.Cluster;
import akka.cluster.ClusterEvent.ClusterMetricsChanged;
import akka.cluster.ClusterEvent.CurrentClusterState;
import akka.cluster.NodeMetrics;
import akka.cluster.StandardMetrics;
import akka.cluster.StandardMetrics.HeapMemory;
import akka.cluster.StandardMetrics.Cpu;
import akka.event.Logging;
import akka.event.LoggingAdapter;
public class MetricsListener extends UntypedActor {
LoggingAdapter log = Logging.getLogger(getContext().system(), this);
Cluster cluster = Cluster.get(getContext().system());
//subscribe to ClusterMetricsChanged
@Override
public void preStart() {
cluster.subscribe(getSelf(), ClusterMetricsChanged.class);
}
//re-subscribe when restart
@Override
public void postStop() {
cluster.unsubscribe(getSelf());
}
@Override
public void onReceive(Object message) {
if (message instanceof ClusterMetricsChanged) {
ClusterMetricsChanged clusterMetrics = (ClusterMetricsChanged) message;
for (NodeMetrics nodeMetrics : clusterMetrics.getNodeMetrics()) {
if (nodeMetrics.address().equals(cluster.selfAddress())) {
logHeap(nodeMetrics);
logCpu(nodeMetrics);
}
}
} else if (message instanceof CurrentClusterState) {
// ignore
} else {
unhandled(message);
}
}
void logHeap(NodeMetrics nodeMetrics) {
HeapMemory heap = StandardMetrics.extractHeapMemory(nodeMetrics);
if (heap != null) {
log.info("Used heap: {} MB", ((double) heap.used()) / 1024 / 1024);
}
}
void logCpu(NodeMetrics nodeMetrics) {
Cpu cpu = StandardMetrics.extractCpu(nodeMetrics);
if (cpu != null && cpu.systemLoadAverage().isDefined()) {
log.info("Load: {} ({} processors)", cpu.systemLoadAverage().get(),
cpu.processors());
}
}
}
Custom Metrics Collector
You can plug-in your own metrics collector instead of akka.cluster.SigarMetricsCollector or akka.cluster.JmxMetricsCollector. Look at those two implementations for inspiration. The implementation class can be defined in the Configuration.
JMX
Information and management of the cluster is available as JMX MBeans with the root name akka.Cluster. The JMX information can be displayed with an ordinary JMX console such as JConsole or JVisualVM.
From JMX you can:
- see what members that are part of the cluster
- see status of this node
- join this node to another node in cluster
- mark any node in the cluster as down
- tell any node in the cluster to leave
Member nodes are identified by their address, in format akka.<protocol>://<actor-system-name>@<hostname>:<port>.
Command Line Management
The cluster can be managed with the script bin/akka-cluster provided in the Akka distribution.
Run it without parameters to see instructions about how to use the script:
Usage: bin/akka-cluster <node-hostname> <jmx-port> <command> ...
Supported commands are:
join <node-url> - Sends request a JOIN node with the specified URL
leave <node-url> - Sends a request for node with URL to LEAVE the cluster
down <node-url> - Sends a request for marking node with URL as DOWN
member-status - Asks the member node for its current status
members - Asks the cluster for addresses of current members
unreachable - Asks the cluster for addresses of unreachable members
cluster-status - Asks the cluster for its current status (member ring,
unavailable nodes, meta data etc.)
leader - Asks the cluster who the current leader is
is-singleton - Checks if the cluster is a singleton cluster (single
node cluster)
is-available - Checks if the member node is available
Where the <node-url> should be on the format of
'akka.<protocol>://<actor-system-name>@<hostname>:<port>'
Examples: bin/akka-cluster localhost 9999 is-available
bin/akka-cluster localhost 9999 join akka.tcp://MySystem@darkstar:2552
bin/akka-cluster localhost 9999 cluster-status
To be able to use the script you must enable remote monitoring and management when starting the JVMs of the cluster nodes, as described in Monitoring and Management Using JMX Technology
Example of system properties to enable remote monitoring and management:
java -Dcom.sun.management.jmxremote.port=9999 \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false
Configuration
There are several configuration properties for the cluster. We refer to the following reference file for more information:
######################################
# Akka Cluster Reference Config File #
######################################
# This is the reference config file that contains all the default settings.
# Make your edits/overrides in your application.conf.
akka {
cluster {
# Initial contact points of the cluster.
# The nodes to join automatically at startup.
# Comma separated full URIs defined by a string on the form of
# "akka://system@hostname:port"
# Leave as empty if the node is supposed to be joined manually.
seed-nodes = []
# how long to wait for one of the seed nodes to reply to initial join request
seed-node-timeout = 5s
# If a join request fails it will be retried after this period.
# Disable join retry by specifying "off".
retry-unsuccessful-join-after = 10s
# Should the 'leader' in the cluster be allowed to automatically mark
# unreachable nodes as DOWN?
# Using auto-down implies that two separate clusters will automatically be
# formed in case of network partition.
auto-down = off
# The roles of this member. List of strings, e.g. roles = ["A", "B"].
# The roles are part of the membership information and can be used by
# routers or other services to distribute work to certain member types,
# e.g. front-end and back-end nodes.
roles = []
role {
# Minimum required number of members of a certain role before the leader
# changes member status of 'Joining' members to 'Up'. Typically used together
# with 'Cluster.registerOnMemberUp' to defer some action, such as starting
# actors, until the cluster has reached a certain size.
# E.g. to require 2 nodes with role 'frontend' and 3 nodes with role 'backend':
# frontend.min-nr-of-members = 2
# backend.min-nr-of-members = 3
#<role-name>.min-nr-of-members = 1
}
# Minimum required number of members before the leader changes member status
# of 'Joining' members to 'Up'. Typically used together with
# 'Cluster.registerOnMemberUp' to defer some action, such as starting actors,
# until the cluster has reached a certain size.
min-nr-of-members = 1
# Enable/disable info level logging of cluster events
log-info = on
# Enable or disable JMX MBeans for management of the cluster
jmx.enabled = on
# how long should the node wait before starting the periodic tasks
# maintenance tasks?
periodic-tasks-initial-delay = 1s
# how often should the node send out gossip information?
gossip-interval = 1s
# how often should the leader perform maintenance tasks?
leader-actions-interval = 1s
# how often should the node move nodes, marked as unreachable by the failure
# detector, out of the membership ring?
unreachable-nodes-reaper-interval = 1s
# How often the current internal stats should be published.
# A value of 0s can be used to always publish the stats, when it happens.
# Disable with "off".
publish-stats-interval = off
# The id of the dispatcher to use for cluster actors. If not specified
# default dispatcher is used.
# If specified you need to define the settings of the actual dispatcher.
use-dispatcher = ""
# Gossip to random node with newer or older state information, if any with
# this probability. Otherwise Gossip to any random live node.
# Probability value is between 0.0 and 1.0. 0.0 means never, 1.0 means always.
gossip-different-view-probability = 0.8
# Settings for the Phi accrual failure detector (http://ddg.jaist.ac.jp/pub/HDY+04.pdf
# [Hayashibara et al]) used by the cluster subsystem to detect unreachable
# members.
failure-detector {
# FQCN of the failure detector implementation.
# It must implement akka.remote.FailureDetector and have
# a public constructor with a com.typesafe.config.Config and
# akka.actor.EventStream parameter.
implementation-class = "akka.remote.PhiAccrualFailureDetector"
# How often keep-alive heartbeat messages should be sent to each connection.
heartbeat-interval = 1 s
# Defines the failure detector threshold.
# A low threshold is prone to generate many wrong suspicions but ensures
# a quick detection in the event of a real crash. Conversely, a high
# threshold generates fewer mistakes but needs more time to detect
# actual crashes.
threshold = 8.0
# Number of the samples of inter-heartbeat arrival times to adaptively
# calculate the failure timeout for connections.
max-sample-size = 1000
# Minimum standard deviation to use for the normal distribution in
# AccrualFailureDetector. Too low standard deviation might result in
# too much sensitivity for sudden, but normal, deviations in heartbeat
# inter arrival times.
min-std-deviation = 100 ms
# Number of potentially lost/delayed heartbeats that will be
# accepted before considering it to be an anomaly.
# This margin is important to be able to survive sudden, occasional,
# pauses in heartbeat arrivals, due to for example garbage collect or
# network drop.
acceptable-heartbeat-pause = 3 s
# Number of member nodes that each member will send heartbeat messages to,
# i.e. each node will be monitored by this number of other nodes.
monitored-by-nr-of-members = 5
# When a node stops sending heartbeats to another node it will end that
# with this number of EndHeartbeat messages, which will remove the
# monitoring from the failure detector.
nr-of-end-heartbeats = 8
# When no expected heartbeat message has been received an explicit
# heartbeat request is sent to the node that should emit heartbeats.
heartbeat-request {
# Grace period until an explicit heartbeat request is sent
grace-period = 10 s
# After the heartbeat request has been sent the first failure detection
# will start after this period, even though no heartbeat mesage has
# been received.
expected-response-after = 3 s
# Cleanup of obsolete heartbeat requests
time-to-live = 60 s
}
}
metrics {
# Enable or disable metrics collector for load-balancing nodes.
enabled = on
# FQCN of the metrics collector implementation.
# It must implement akka.cluster.MetricsCollector and
# have public constructor with akka.actor.ActorSystem parameter.
# The default SigarMetricsCollector uses JMX and Hyperic SIGAR, if SIGAR
# is on the classpath, otherwise only JMX.
collector-class = "akka.cluster.SigarMetricsCollector"
# How often metrics are sampled on a node.
# Shorter interval will collect the metrics more often.
collect-interval = 3s
# How often a node publishes metrics information.
gossip-interval = 3s
# How quickly the exponential weighting of past data is decayed compared to
# new data. Set lower to increase the bias toward newer values.
# The relevance of each data sample is halved for every passing half-life
# duration, i.e. after 4 times the half-life, a data sample’s relevance is
# reduced to 6% of its original relevance. The initial relevance of a data
# sample is given by 1 – 0.5 ^ (collect-interval / half-life).
# See http://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average
moving-average-half-life = 12s
}
# If the tick-duration of the default scheduler is longer than the
# tick-duration configured here a dedicated scheduler will be used for
# periodic tasks of the cluster, otherwise the default scheduler is used.
# See akka.scheduler settings for more details.
scheduler {
tick-duration = 33ms
ticks-per-wheel = 512
}
}
# Default configuration for routers
actor.deployment.default {
# MetricsSelector to use
# - available: "mix", "heap", "cpu", "load"
# - or: Fully qualified class name of the MetricsSelector class.
# The class must extend akka.cluster.routing.MetricsSelector
# and have a public constructor with com.typesafe.config.Config
# parameter.
# - default is "mix"
metrics-selector = mix
}
actor.deployment.default.cluster {
# enable cluster aware router that deploys to nodes in the cluster
enabled = off
# Maximum number of routees that will be deployed on each cluster
# member node.
# Note that nr-of-instances defines total number of routees, but
# number of routees per node will not be exceeded, i.e. if you
# define nr-of-instances = 50 and max-nr-of-instances-per-node = 2
# it will deploy 2 routees per new member in the cluster, up to
# 25 members.
max-nr-of-instances-per-node = 1
# Defines if routees are allowed to be located on the same node as
# the head router actor, or only on remote nodes.
# Useful for master-worker scenario where all routees are remote.
allow-local-routees = on
# Actor path of the routees to lookup with actorFor on the member
# nodes in the cluster. E.g. "/user/myservice". If this isn't defined
# the routees will be deployed instead of looked up.
# max-nr-of-instances-per-node should not be configured (default value is 1)
# when routees-path is defined.
routees-path = ""
# Use members with specified role, or all members if undefined or empty.
use-role = ""
}
# Protobuf serializer for cluster messages
actor {
serializers {
akka-cluster = "akka.cluster.protobuf.ClusterMessageSerializer"
}
serialization-bindings {
"akka.cluster.ClusterMessage" = akka-cluster
}
}
}
Cluster Info Logging
You can silence the logging of cluster events at info level with configuration property:
akka.cluster.log-info = off
Cluster Dispatcher
Under the hood the cluster extension is implemented with actors and it can be necessary to create a bulkhead for those actors to avoid disturbance from other actors. Especially the heartbeating actors that is used for failure detection can generate false positives if they are not given a chance to run at regular intervals. For this purpose you can define a separate dispatcher to be used for the cluster actors:
akka.cluster.use-dispatcher = cluster-dispatcher
cluster-dispatcher {
type = "Dispatcher"
executor = "fork-join-executor"
fork-join-executor {
parallelism-min = 2
parallelism-max = 4
}
}
Contents


Pathfinder Agent:
Once you enter the Chamber of Delusion, you will find managers for each area. There are 6 total, entry to which is regulated in the individual manager. Ask each manager for more details.
If you've been to the Dimensional Rift, you will understand quickly.
Challenge the Chamber of Delusion.


{% extends "base.html" %} {% block title %}PyPI - the Python Package Index{% endblock %} {% macro project_snippet(release) -%} {% set version = release.version %} {% set uploader_username = release.uploader.username %} {% set uploader_name = release.uploader.name|default(uploader_username, true) %}
{{ release.summary }}
The Python Package Index (PyPI) is a repository of software for the Python programming language.
PyPI helps you find and install third-party software developed and shared by other members of the Python community. Learn about installing packages.
Package authors use PyPI to distribute their software. Learn how to package your Python code for PyPI.
Top projects as downloaded by the community
Hot off the press: the newest projects to be released to PyPI


--- title: Blank draft: false weight: 5 widget: handler: blank # Options: sm, md, lg and xl. Default is md. width: sidebar: # Options: left and right. Leave blank to hide. position: # Options: sm, md, lg and xl. Default is md. scale: background: # Options: primary, secondary, tertiary or any valid color value. Default is primary. color: image: images/hero-left.jpg # Options: auto, cover and contain. Default is auto. size: cover # Options: center, top, right, bottom, left. position: # Options: fixed, local, scroll. attachment: ---
Write anything you like here!


| internal class | TokenMap |
| public int | GetTokenId(const String<uchar>& tokenName) |
| public String<uchar> | GetTokenInfo(int tokenId) |
| public String<uchar> | GetTokenName(int tokenId) |
| public const int | ACTIVEPROJECT = 13 |
| public const int | ASSIGN = 16 |
| public const int | DOT = 18 |
| public const int | END = 0 |
| public const int | FILEPATH = 15 |
| public const int | ID = 14 |
| public const int | LIBRARY = 10 |
| public const int | PROGRAM = 7 |
| public const int | PROJECT = 1 |
| public const int | REFERENCE = 3 |
| public const int | SEMICOLON = 17 |
| public const int | SOLUTION = 2 |
| public const int | SOURCE = 4 |
| public const int | TARGET = 6 |
| public const int | TEXT = 5 |
| public const int | UNITTEST = 12 |
| public const int | WINAPP = 9 |
| public const int | WINGUIAPP = 8 |
| public const int | WINLIB = 11 |


Everything pertaining to your company in one place on an SEO friendly webpage searchable from anywhere on Digital Commerce 360. A must for all advertisers!
List your E-commerce Service in the Vendor Directory prolifically with testimonials from your best clients, editorial mentions, links to your website’s lead generating assets, and key information where and when online retailers are looking to spend on e-commerce technology this year. All placements are highly relevant and personalized to your category of solutions and cost a limited budget spend per year so you can fully advertise your brand and services across this e-commerce business audience.
More Information View Vendor Directory Online
Informative case studies, economic reports, white papers, and special offers submitted by e-commerce Service providers.
These Featured Resources are curated for the Internet Retailer audience to give the latest perspectives and intelligence from solution providers who are at the forefront of e-commerce technology and services.
According to a recent Internet Retailer survey, 85% of online retailers plan to increase their e-commerce technology spending in the next 12 months.
Expand your message to the entire IRNewsLink Daily audience in your own words in special edition emails that are delivered to the entire Internet Retailer subscriber base.
Describe your latest technological advances, content marketing pieces, case studies, products, and white papers reaching to links on your website for the same large audience that is reading Internet Retailer’s quality news and reporting daily. View sample
The May and June issues will focus entirely on IRCE exhibitors, inform IRCE attendees about your services and booth with special promotions in the IRCE Trendsetters newsletter. View sample
Promotional Dates: May & June
Distribution: IRNewsLink audience (34,000 + subscribers) and all IRCE attendees before the event.
A cost effective package that combines Digital, Print, and Web Advertising
offerings out
to a targeted audience of e-commerce executives and business owners.
Advertise next to Internet Retailer Magazine articles that are focused on your specific industry and solutions while simultaneously gaining mention as a “Featured Solution Provider” in the online article with full logo, profile, and link to your services.
Minimum spend value ads categorically listed for retailers to discover your services, links to press releases, freelance work, sales offers, open positions, and company inside Internet Retailer Magazine® with great entry level pricing. Double sizing is available!
In order to showcase your role in helping keep the industry standards of
quality raised high, we have outlined
key promotional options for you
to stand out from the rest of the crowd and generate leads.


HTML elements may be positioned in several specific ways: absolute, fixed, relative, and the default, static. Let's go over each so we may see how they differ.
Static
Starting with the default, static, is the normal default position. This usually does not have to be set. (If it needed to be set, the code example is below.)
Example: position:static;
Relative
Example: position: relative: top: 10px.
Relative positioning allows a developer to shift an element from its normal, static position. When using relative positioning, you need to specify where to shift and how much. (Note that, by setting relative position, the element will on top of any static elements it overlaps.)
Absolute
Example: {position:absolute;top:0;left:0;}
Absolute positioning allows a developer to place an element irrespective of random elements on the page. Its positioning on the page is only constrained relative to the next parents element with relative or absolute positioning, or html element if none other such elements exist.
Fixed
[Hard to show in a picture. Position is fixed and remains in place even when scrolling the window.]
Example: {position:fixed;top:0;left:0}
Fixed positioning positions element relative to the actual page, staying fixed even when the window is scrolled.
*Images and code courtesy of http://www.webdevbydoing.com/css/whats-the-difference-between-static-relative-absolute-and-fixed-positioning/


Process Manager - User View
This page displays all running processes, group by the user who owns the
process. Processes are ranked by CPU utilization below the name of each user
who has one or more processes running. For each process the PID, CPU use
and command are displayed. The PID can be clicked on to display more
information.


00:00:00
Start
Stop
Start Color
Stop Color
to Birthday of My Busic
11
Days
11
Hours
11
Minutes
11
Seconds


In this step you will identify questions you have about your paper, and design two new experiments that can answer those questions.
Make a list with 2-5 items that can include problems with the paper, questions that were not addressed, or questions related to the paper that can be answered in the future.
Here are some questions to help guide your thinking:
Let’s ask ourselves, “What experiments should be done next?”
Now you are ready to design your own experiments! When you finish, use this checklist to double-check your work:


Introducing ASP.NET Core Blazor / Razor Components | Syncfusion Blogs Like everyone else, we are excited about the upcoming Microsoft ASP.Net Core 3.0 framework. We are particularly eager to try Blazor /Razor Components, which have the potential to turn web development more towards strongly-typed C# and WebAssembly. Syncfus...
Download .NET (Linux, macOS, and Windows) Free downloads for building and running .NET apps on Linux, macOS, and Windows. Runtimes, SDKs, and developer packs for .NET Framework, .NET Core, and ASP.NET.
Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30 pm US/Eastern) Update 2019-04-23: The maintenance went as planned. Current status We have hit some unexpected issues and have rescheduled - title and dates below are updated. The work listed below for Monday/
Slack Is Not Where 'Deep Work' Happens | Inside Nuclino How did you start your day today? Probably reached for the phone. Turned off the alarm. Glanced at the time. Scrolled through the Slack...
Reactive approach to FSAC design - discussion · Issue #1 · Krzysztof-Cieslak/notes I’ve written a document describing some of the more interesting ideas for improving general FSAC/language server/IDE backend. https://github.com/Krzysztof-Cieslak/notes/blob/master/FSAC%20design/Re...
Creating an ASP.NET Core Markdown TagHelper and Parser A couple of months ago I wrote about creating a WebForms based Markdown control. This time around I'll build an ASP.NET Core MVC TagHelper that performs similar functionality for embedding Markdown text into a content area of a Razor page. The component a...
x86/Linux progress · Issue #7335 · dotnet/runtime This issue for tracking x86/Linux progress with respect to the regression tests. Here is the current status on Ubuntu 14.04 Docker Container (on Ubuntu 16.04 x64) and full result: =================...
unoplatform/Uno.SkiaSharp SkiaSharp fork for the Uno Platform and WebAssembly. Skia is a cross-platform 2D graphics API for .NET platforms based on Google's Skia Graphics Library. It provides a comprehensive 2D API that...
Chapter 7: The Polymath and the Specialist – The Analog Antiquarian The last time anyone in Egypt wrote anything using hieroglyphs was in approximately AD 400. Yet even well before this date, at the height of the classical age, the writing system was known to virtually no one outside of Egypt. Certainly none of the ancien...
A .vsconfig file should automatically prompt to install extensions - Developer Community Developer Community for Visual Studio Product family
ZIO hackathon September 21-22 · Issue #743 · zio/zio I'm planning a ZIO hackathon weekend on September 21-22 (possibly preceded by a day of informal talks), open to everyone—regardless of level, experience, or contributions to OSS, and of course,...
Tamir DRESHER: .NET Debugging tricks you wish you knew @ Update Conference Prague 2018 Do you know what developers do most of their day (except for surfing the internet)? Writing code? WRONG! They are debugging. The debugger is a powerful tool, but in this talk you'll learn tricks that will help find bugs in half the time and with less frus...
NativeMemoryDiagnoser by WojciechNagorski · Pull Request #1131 · dotnet/BenchmarkDotNet Fix for #457. I am open to all suggestions and comments. Information I added new columns: Total native memory and Native memory leak. Example of output: | Method | M...
We have discovered and addressed a security breach. (Updated 2019-04-12) | Matrix.org TL;DR: An attacker gained access to the servers hosting Matrix.org. The intruder had access to the production databases, potentially giving them access to unencrypted message data, password hashes and access tokens.
Understanding Insider Threats [Free Video Course] A free video training course from security expert Troy Hunt that teaches you all about insider threats and how to stop them.
Annotating platform-specific APIs and detecting its use by terrajobst · Pull Request #63 · dotnet/designs This is a proposal to improve and productize the API Analyzer tool. Discuss potential fixers Discuss how the platform will be annotated Discuss integration with multi-targeting


About: Vendedor de Juegos / UI.
Hobbies: Read, out with friends, listen to music, draw and learn new things.
Please fill in this form to sell your product.


RENCI at UNC-Chapel Hill
Chapel Hill, North Carolina, USA
March 24 - March 26, 2010
iRODS UGM 2010 Proceedings (PDF 2.0MB)
iRODS UGM 2010 - NSF Report (PDF 1.3MB)
Wednesday, March 24 |
|
| 9:00 AM | Introduction to iRODS [slides] Reagan Moore, DICE |
| 9:15 AM | iRODS Overview [slides] Wayne Schroeder, Paul Tooby, DICE |
| 9:30 AM | iRODS Version 2.3 [release notes] Wayne Schroeder, DICE |
| 10:00 AM | Introduction to Microservices [slides] Reagan Moore, DICE |
| 10:30 AM | Break |
| 11:00 AM | Introduction to Policies [slides] Reagan Moore, DICE |
| 11:30 AM | Writing Policies [slides] Arcot Rajasekar, DICE |
| 12:30 PM | Lunch |
| 1:30 PM | Writing Microservices [slides] Mike Wan, DICE |
| 2:30 PM | Advanced iCommands [slides] Mike Wan, DICE |
| 3:00 PM | Break |
| 3:30 PM | iCAT Interactions [slides] Wayne Schroeder, Arcot Rajasekar, DICE |
| 4:30 PM | Questions |
Thursday, March 25 |
|
| 9:00 AM | High Availability iRODS System (HAIRS) [slides] [paper] Yutaka Kawai (KEK, Japan), Adil Hasan (University of Liverpool) |
| 9:15 AM | iRODS at CC-IN2P3 [slides] [paper] Jean-Yves Nief, Pascal Calvat, Yonny Cardenas, Pierre-Yves Jallud, Thomas Kachelhoffer (CC-IN2P3, Lyon, France) |
| 9:30 AM | Using iRODS to Preserve and Publish a Dataverse Archive [slides] [paper] Mason Chua (Odum Institute, UNC), Antoine de Torcy (DICE Center, UNC), Jewel H. Ward (SILS, UNC), Jonathan Crabtree (Odum Institute, UNC) |
| 9:45 AM | Distributed Data Sharing with PetaShare for Collaborative Research [slides] [paper] Sreekanth Pothanis, Tevfik Kosar, PetaShare Team (LSU) |
| 10:00 AM | UNC Information Technology Services & iRODS [slides][paper] William Schulz (ITS, UNC) |
| 10:30 AM | Break |
| 11:00 AM | The ARCS Data Fabric [slides] [paper] Shunde Zhang, Florian Goessmann, Pauline Mak (Australian Research Collaboration Service) |
| 11:15 AM | A Service-Oriented Interface to the iRODS Data Grid [slides] [paper] Nicola Venuti, Francesco Locunto (Nice, S.r.l.), Michael Conway (DICE, UNC), Leesa Brieger (RENCI, UNC) |
| 11:30 AM | iExplore for iRODS Distributed Data Management [slides] [slides] Bing Zhu (DICE, UCSD) |
| 11:45 AM | A GridFTP Interface for iRODS [slides] [paper] Shunde Zhang (ARCS) |
| 12:00 PM | Break |
| 12:30 PM | Lunch |
| 1:30 PM | The Development of Digital Archives Management Tools for iRODS [slides] [paper] Tsung-Tai Yeh, Hsin-Wen Wei, Shin-Hao Liu (Academia Sinica, Taiwan), Pei-Chi Huang (Tsing Hua University, Taiwan), Tsan-sheng Hsu (Academia Sinica, Taiwan), Yen-Chiu Chen (Tsing Hua University, Taiwan) |
| 1:50 PM | Building a Trusted Distributed Archival Preservation Service with iRODS [slides] [paper] Jewel H. Ward, Terrell G. Russell, and Alexandra Chassanoff (SILS, UNC) |
| 2:10 PM | Conceptualizing Policy-Driven Repository Interoperability (PoDRI) - Using iRODS and Fedora [slides] [paper] David Pcolar (Carolina Digital Repository UNC), Daniel W. Davis (Cornell, DuraSpace), Bing Zhu (DICE, UCSD), Alexandra Chassanoff (SILS, UNC), Chien-Yi Hou (SALT, UNC), Richard Marciano (SALT, UNC) |
| 2:40 PM | Community-Driven Development of Preservation Services [paper] Richard Marciano (SALT, UNC), Chien-Yi Hou (SALT, UNC), Jennifer Ricker (NC State Library), Glen McAninch (KY Dept. Lib. & Archives), David Pcolar (Carolina Digital Repository UNC) |
| 3:00 PM | Break |
| 3:30 PM | Enhancing iRODS Integration: Jargon and an Evolving iRODS Service Model [slides] [paper] Mike Conway, DICE |
| 4:30 PM | Questions on porting clients |
Friday, March 26 |
|
| 9:00 AM | iRODS Task Prioritization [slides] Reagan Moore, DICE |
| 10:30 PM | Break |
| 11:00 AM | Q&A Reagan Moore, DICE |
| 12:00 AM | iRODS Security [slides] Wayne Schroeder, DICE |
| 12:30 PM | Lunch |
| 1:30 PM | Workflow Integration Mike Conway, DICE |
| 1:50 PM | iRODS Client List [report] Reagan Moore, DICE |
| 2:10 PM | iRODS User-Prioritized Feature Requests [report] Reagan Moore, DICE |
| 2:30 AM | Data Intensive Cyberinfrastructure Foundation [slides] Paul Tooby, DICE |


IndiGo, Qatar Airways to announce strategic deal
by ReutersHighlights
- Qatar has in the past shown interest in investing in IndiGo but the Indian airline has resisted
- IndiGo, which has about 40% share of the domestic market, is planning an aggressive push into more international destinations
NEW DELHI: India's largest airline IndiGo and Qatar Airways will make a strategic business announcement on Thursday, which media reports said would involve a codeshare agreement.
IndiGo shares, which rose as much as 5% early in the day, pared those gains to trade up 1% in the afternoon.
Qatar has in the past shown interest in investing in IndiGo but the Indian airline has resisted.
"We are very interested in IndiGo ... We are talking to IndiGo of doing codeshare, joint flights but not yet an equity stake in the airline," Qatar Airways chief executive, Akbar Al Baker, told Reuters in an interview in August.
Al Baker said they had talked to IndiGo but the airline was "not yet ready to take a foreign investor". When it is ready, Qatar would be interested, he had said at the time.
Television news agencies, citing other sources, said on Tuesday Qatar Airways was not looking at a stake purchase in IndiGo.
Any deal, however, would come at a time when IndiGo's two co-founders, Rakesh Gangwal and Rahul Bhatia, have been embroiled in a dispute about corporate governance of the airline, sparking concern among investors it could have an impact on the airline's valuation and strategy.
IndiGo, which has about 40% share of the domestic market, is planning an aggressive push into more international destinations.
The airline's chief executive, Ronojoy Dutta, and Al Baker would "talk about the vision and future for both the airlines," they said in the statement.
Last week, IndiGo placed a historic order for 300 Airbus A320neo family planes, including the newest jet, a long-range version of the single-aisle A320 Neo family called the A321XLR.
IndiGo flies to 60 international destinations including Turkey, China, Vietnam, Myanmar and Saudi Arabia, which it added this year.


Data Scientist: loves good data, hates bad statistics.
Machine Learning Engineer: faster, stronger, better humans, through machines.
Developmental Biology Researcher: how we see, before you can see.


Kuwait - Profile
Facts
- Kuwait lies on the north-west coast of the Persian Gulf and has boundaries with Iraq and Saudi Arabia. The land is mainly desert, with a more fertile narrow coastal belt.
- The northern area of the Bay of Kuwait is shallow (under 5 m) and characterised by mud flats, whereas the southern coast of the bay and along the Arabian Gulf is deeper and has sandy beaches. Most ports are on the southern shores and there are about twenty anchorages for small boats.
- Although tourism is discouraged by the authorities, the few cruising boats that have visited Kuwait since the Gulf War have been allowed to stay for a limited period.
- There are a number of locally owned yachts, mainly power, and two well-endowed marinas, one near the capital, the other in the south of the country. Because of the large number of local yachts, facilities are of a high standard. There are two marinas, one near Kuwait City, referred to as the Yacht Club, the other near the Khiran tourist resort, some 60 miles (97 km) south of the capital near the Saudi border.
Weather
Summers (April to October) are hot and humid with very little rain. Winters (November to March) are cool with limited rain. Springs are cool and pleasant.
Kuwait Weather Forecast
For links to free global weather information, forecast services and extreme weather information see the Noonsite Weather Page
Main Ports


Model mixed integer linear programs in an algebraic way directly in R. The model is solver-independent and thus offers the possibility to solve a model with different solvers. It currently only supports linear constraints and objective functions. See the 'ompr' website <https://dirkschumacher.github.io/ompr> for more information, documentation and examples.
| Version: | 0.8.0 |
| Depends: | R (≥ 3.2.0) |
| Imports: | lazyeval, progress, rlang (≥ 0.2.0), methods, data.table, Rcpp (≥ 0.12.12), Matrix |
| LinkingTo: | Rcpp |
| Suggests: | magrittr, testthat |
| Published: | 2018-06-11 |
| Author: | Dirk Schumacher [aut, cre] |
| Maintainer: | Dirk Schumacher <mail at dirk-schumacher.net> |
| BugReports: | https://github.com/dirkschumacher/ompr/issues |
| License: | GPL-3 |
| URL: | https://github.com/dirkschumacher/ompr |
| NeedsCompilation: | yes |
| Materials: | NEWS |
| In views: | Optimization |
| CRAN checks: | ompr results |
| Reference manual: | ompr.pdf |
| Package source: | ompr_0.8.0.tar.gz |
| Windows binaries: | r-devel: ompr_0.8.0.zip, r-release: ompr_0.8.0.zip, r-oldrel: ompr_0.8.0.zip |
| OS X binaries: | r-release: ompr_0.8.0.tgz, r-oldrel: ompr_0.8.0.tgz |
| Old sources: | ompr archive |
| Reverse imports: | ompr.roi |
Please use the canonical form https://CRAN.R-project.org/package=ompr to link to this page.


Haws beats buzzer, BYU beats Houston 72-71
by The Associated PressHOUSTON (AP) — T.J. Haws hit a contested jump shot as time ran out to give BYU a 72-71 win over Houston on Friday night.
Haws received an inbounds pass in the back court with 5.1 seconds left and as he neared the top of the key angled right and then shot a contested, fadeaway jumper over Quentin Grimes. The ball hit the front of the rim and time expired before the ball dropped through the basket.
Haws finished with 10 points for BYU (3-1), which was led by Alex Barcello with 16. Jake Toolson and Kolby Lee had 14 points apiece for BYU. Haws was 4-of-13 shooting.
Caleb Mills had 17 points off the bench for Houston (1-1). Fabian White Jr. added 14 points and Grimes and DeJon Jarreau had 10 apiece.
Mills made two free throws with 1:25 to play to put Houston on top. BYU’s next two possessions ended in turnovers but Houston missed a 3-pointer between the turnovers and had a turnover with 5.1 seconds to go.
_____
For more AP college basketball: https://apnews.com/Collegebasketball and https://twitter.com/AP_Top25
The Associated Press


How to begin quickly with MediaInfo
Example
What you should do
A quick example, explained line per line in the next chapters (note : with the DLL, and you must adapt it to your language):
-
Init (only one time):
MediaInfo::Options("Info_Version", "**VERSION**;**APP_NAME**;**APP_VERSION**")
MediaInfo Handle
(for DLL : void* Handle=MediaInfo::New()
)
-
For each file:
MediaInfo::Open("**FILENAME**")
MediaInfo::Inform()
...
(for DLL only: MediaInfo::Delete(Handle)
)
Too long? Try this!
This should be use only if you don't expect all error messages (there will be only one error message for all possible errors) and want to open only one file:
void* Hande=MediaInfo::OpenQuick("**FILENAME**", "**VERSION**;**APP_NAME**;**APP_VERSION**")
MediaInfo::Inform()
...
(for DLL only: MediaInfo::Delete(Handle)
)
Unicode?
As for every modern library, MediaInfo(Lib) support Unicode. With this, you don't mind of the location of your program to show text. This is internationalization (I18N), and you can show to the user multiple alphabets (Greek, russian, french...) without coding problems!
You should use the Unicode enabled library and make your program Unicode ready if you start a new program.
Exception : Microsoft Windows command line does not support Unicode, so if you use command line, let use MediaInfo without Unicode.
For the DLL, because only one version of it is released, you have:
- MediaInfo::XXX methods. They are Unicode enabled (2 or 4 bytes character).
-
MediaInfoA_XXX methods. Legacy version of above, with ANSI (one byte per character) characters in place of Unicode. The local codepage is used.
Note : in the DLL only, you can use UTF-8 codepage: MediaInfoA_Options("CodePage", "UTF-8")
Init the library
Internet connection
MediaInfoLib tries to connect to an Internet server for availability of newer software, anonymous statistics and retrieving information about a file (Later... To be done)
If for some reasons you don't want this connection, deactivate it.
MediaInfo::Options("Internet", "No")
The version of the library
First, you need to know the version of the DLL.
Because if you have a newer version, you can have crash or unwanted behaviour...
MediaInfo::Options("Info_Version", "**VERSION**;**APP_NAME**;**APP_VERSION**")
**VERSION** is the version of MediaInfo you have tested. Must be like this : "A.B.C.D" (example : "<IP_ADDRESS>")
**APP_NAME** is the unique name of your application. Examples : "MediaInfoGUI", "MediaInfoCmd".
**APP_VERSION** is the version of your application. Example : "<IP_ADDRESS>", "1.2", "1.26beta1".
Note : if during beta tests, you detect incompatibilities between the library and an old application, contact the MediaInfo developer, he will put the application version in a black list.
The returned string is:
- "MediaInfoLib - vA.B.C.D xxx" if there is no incompatibilities beween the version in the command and the version of the library (xxx may be URL, modification information of the DLL...).
- "" (empty string) if there is incompatibility between the version in the command and the version of the library. In this case you should exit the application (with a message "MediaInfo.dll is not compatible with this version, you must use MediaInfo.dll vX.X.X.X"
Set the language of the library
The library is by default set in English.
You can change the language with a language string.
MediaInfo::Options("Language", "**LANGUAGE_STRING**")
**LANGUAGE_STRING** is CSV-like string :
Internal name1;translation1
Internal name2;translation2
Note : when developing, you can have internal names list with :
MediaInfo::Options("Language_Get")
Create a new Handle
A Handle must be created before using MediaInfoLib :
"C++" : MediaInfo Handle;
"C" (DLL...) : void* Handle=MediaInfo::New();
Open one or multiple files
Before retrieving information about one or multiples files, you must open them :
MediaInfo::Open("**FILENAME**")
or
MediaInfoList::Open("**FILENAMES**")
Get information
Get a pre-formated text
Standart output
If you want a text output:
MediaInfo::Inform(InformOption_Nothing)
If you want a HTML output :
MediaInfo::Inform(InformOption_HTML)
Customize it
Default is a list of most used pieces of information. But you can customize it :
MediaInfo::Option("Inform", "**YOUR_TEXT**")
MediaInfo::Inform(InformOption_Custom)
**YOUR_TEXT** is a list of items. you can have more information about Inform method
Get a piece of information
You can access directly to one wanted piece of information:
MediaInfo::Get ("**StreamKind**", "**StreamNumber**", "**Parameter**", "**InfoKind**")
**StreamKind** can be : Stream_General, Stream_Video, Stream_Audio, Stream_Text, Stream_Chapters
**StreamNumber** is the position of the stream you want. example for Audio : 0 if you want the first Audio, 1 if you want the second Audio.
**Parameter** is the name of the piece of information you want. example : "BitRate", "Width"...
**InfoKind** should be set to MediaInfo::Info_Text, except if you want a more advanced interface
Note : when developing, you can have parameters list with:
MediaInfo::Options("Info_Parameters")
Release memory
To release memory, you must delete the handle:
"C++" : Nothing to do, will be deleted at the end of the method
"C" (DLL...) : MediaInfo::Delete(Handle);
Note : You can re-use the Handle for another MediaInfo::Open("**FILENAME**")
call without deleting something.


On dev-theme branch I got rid of the landing page. Saves a click and gets newcomers into docs faster. This came at request of management.
However, this meant that we needed a default page. I was not able to find a way to make plain https://developers.komodoplatform.com/ forward directly to our introduction, https://developers.komodoplatform.com/basic-docs/start-here/introduction.html.
I found a temporary workaround.
The default for the / directory is the README.md file in th...


Description
-
Are you like me and want to get a taste of the old Microsoft App Icons? Well you've come to the right place. With this Anemone theme, you can change the new icons to what they were before.
-
If you want a Microsoft Icon to be added, contact me using the contact information below.
Screenshots
Compatibility
-
All versions of iOS that, I suppose
Dependencies
-
None
Conflicts
-
None
In this version
-
1.0
- Initial Release
May 22, 2019
Known Issues
- No known issues. Report issues using the contact info below.
Report Issues to
-<EMAIL_ADDRESS>- Skylar#5039 (Discord)


How to use the Feathers TabBar
component
The TabBar
class displays a set of togglable buttons with a vertical or horizontal layout, where only one button at a time may be selected. A tab bar's tabs may be added or removed at runtime through its data provider, and the first and last tabs may be optionally styled differently. For instance, one could create a more "pill" shaped control that looks more like a segmented button bar than a set of tabs.
The Basics
First, let's create a TabBar
control, set its data provider to display a few tabs, and add it to the display list:
var tabs:TabBar = new TabBar();
tabs.dataProvider = new ArrayCollection(
[
{ label: "One" },
{ label: "Two" },
{ label: "Three" },
]);
this.addChild( tabs );
The label
field in each item from the data provider will set the label
property on the corresponding tab. In addition to the label, you can also provide an icon for a tab by setting the defaultIcon
field, which gets passed to the tab's defaultIcon
property.
To know when the selected tab changes, we need to listen to Event.CHANGE
:
tabs.addEventListener( Event.CHANGE, tabs_changeHandler );
A listener might look something like this:
function tabs_changeHandler( event:Event ):void
{
var tabs:TabBar = TabBar( event.currentTarget );
trace( "selectedIndex:", tabs.selectedIndex );
}
The selectedIndex
property indicates the zero-based index of the currently selected tab.
Skinning a TabBar
Except for a couple of layout properties, most of the skinning happens on the tabs. For full details about what skin and style properties are available, see the TabBar
API reference. We'll look at a few of the most common ways of styling a tab bar below.
Layout
For layout, you can set the direction
property to Direction.HORIZONTAL
or Direction.VERTICAL
.
The gap
property sets the extra space, measured in pixels, between tabs. You can also use the firstGap
property to provide a different gap after the first tab, and the lastGap
property to provide a different gap before the last tab.
The distributeTabSizes
property controls whether the combined size of tabs fill the entire length of the TabBar
or if they use the minimum space required.
Skinning the Tabs
This section only explains how to access the tab sub-components, which are simply toggle buttons. Please read How to use the Feathers ToggleButton
component for full details about the skinning properties that are available on ToggleButton
components.
With a Theme
If you're creating a theme, you can target the TabBar.DEFAULT_CHILD_STYLE_NAME_TAB
style name.
getStyleProviderForClass( ToggleButton )
.setFunctionForStyleName( TabBar.DEFAULT_CHILD_STYLE_NAME_TAB, setTabStyles );
The styling function might look like this:
private function setTabStyles( tab:ToggleButton ):void
{
var skin:ImageSkin = new ImageSkin( texture );
skin.scale9Grid = new Rectangle( 2, 3, 1, 6 );
tab.defaultSkin = skin;
tab.fontStyles = new TextFormat( "Helvetica", 20, 0x3c3c3c );
}
You can override the default style name to use a different one in your theme, if you prefer:
tabBar.customTabStyleName = "custom-tab";
You can set the function for the customTabStyleName
like this:
getStyleProviderForClass( ToggleButton )
.setFunctionForStyleName( "custom-tab", setCustomTabStyles );
Without a Theme
If you are not using a theme, you can use tabFactory
to provide skins for the tabs:
tabBar.tabFactory = function():ToggleButton
{
var tab:ToggleButton = new ToggleButton();
//skin the tab here, if not using a theme
var skin:ImageSkin = new ImageSkin( texture );
skin.scale9Grid = new Rectangle( 2, 3, 1, 6 );
tab.defaultSkin = skin;
tab.fontStyles = new TextFormat( "Helvetica", 20, 0x3c3c3c );
return tab;
};
Skinning the First and Last Tabs
This section only explains how to access the first and last tab sub-components. Please read How to use the Feathers ToggleButton
component for full details about the skinning properties that are available on ToggleButton
components.
The tab bar's first and last tabs will have the same skins as the other tabs by default. However, their skins may be customized separately, if desired.
For the first tab, you can customize the name with customFirstTabStyleName
. If you aren't using a theme, then you can use firstTabFactory
.
For the last tab, you can customize the name with customLastTabStyleName
. If you aren't using a theme, then you can use lastTabFactory
.
Separate skins for the first and last tabs are completely optional.


eLife home page
Careers
About
eLife
Labs
Submit my research
Alerts
Profile
Menu
Home
Magazine
Search
Search by keyword or author
Reset form
Search
Limit my search to
Cell biology


Some MPs Want Corporal Punishment Re-Introduced At Schools, Homes
by NT EditorSome parties have called for the Constitution to be changed to allow for corporal punishment to be used in schools and at home.
The call came from the African Christian Democratic Party (ACDP) and the African Transformation Movement (ATM) on Thursday during a parliamentary debate on combating rising levels of violence, drug and sexual abuse in schools.
Corporal punishment is not allowed in schools, and last month the Constitutional Court ruled that moderate and reasonable chastisement in the home, including spanking, was inconsistent with the Constitution.
Bring back the cane; that was the call from the ACDP’s Reverend Kenneth Meshoe, to deal with the rising tide of sexual abuse, drugs and violence in schools.
“Corporal punishment should be restored in our homes and schools, even if an amendment to the Constitution would be required.”
The ATM’s Thandiswa Marawu also called for the Constitution to be changed.
“It is unfortunate that South Africa now operates on a ‘spare the rod, spoil the child,’ modus operandi.”
The Economic Freedom Fighters’ Nazier Paulsen disagreed, saying high levels of violence, drugs and sexual abuse occurred mostly in townships and rural schools because they catered for those considered to be surplus by “the system”.
“I can’t understand how you can even think that you can moer (beat) the problem away with a cane.”


Java reduces costs, shortens developer timeframes, drives innovation, and improves application services as the programming language of choice for enterprise architecture, finance, and HR.
Java is used in many industries including manufacturing, automotive, insurance, and public sector.
The main features of Java are:
- Object oriented
- Inheritance
- Polymorphism
- Portability
- Robust
class HelloWorldApp {
public static void main(String[] args) {
System.out.println("Hello World!");
}
}
JavaScript is a scripting language developed to enable Web authors to design interactive sites. It is compatible with most modern browsers.
JavaScript shares features and structures of the full Java language, but was developed independently. It can interact with HTML source code, which enables dynamic content.
function myFunc(a, b) {
return a * b;
}
document.getElementById('demo').innerHTML = myFunc(4, 3);
Scala is a general-purpose programming language providing support for functional programming and a strong static type system.
Designed to be concise, many of Scala's design decisions aimed to address criticisms of Java.
/ Scala: Direct conversion from Java
// no import needed; scala.math
// already imported as `math`
def mathFunction(num: Int): Int = {
var numSquare: Int = num*num
return (math.cbrt(numSquare) + math.log(numSquare)).
asInstanceOf[Int]
}
C++ is a general-purpose programming language created by Bjarne Stroustrup as an extension of the C programming language, or "C with Classes".
The language has expanded significantly over time, and modern C++ now has object-oriented, generic, and functional features in addition to facilities for low-level memory manipulation.
#include
using namespace std;
int main () {
cout << "Hello World!";
return 0;
}
Python is an interpreted, high-level, general-purpose programming language. Created by Guido van Rossum and first released in 1991, Python's design philosophy emphasizes code readability with its notable use of significant whitespace. Its language constructs and object-oriented approach aim to help programmers write clear, logical code for small and large-scale projects.
Python is dynamically typed and garbage-collected. It supports multiple programming paradigms, including structured (particularly, procedural), object-oriented, and functional programming. Python is often described as a "batteries included" language due to its comprehensive standard library
words = ['cat', 'window', 'defenestrate']
for w in words:
print w, len(w)


Status
Everything looks fine. Continue working
Project Description
Members
10 Members
Sprints
Sprints plots goes here


src/plugin/providerPlugin.js
/**
* The provider plugin base class
*
* A Provider provides a source of events
* The watchdog uses _three_ source providers, each provider type must be a single instance, i.e. there cannot be two Explorers
* - Explorer: Is responsible for getting the most recent mined block height of the BURST network
* - Miner Observable: Is responsible for delegating the current block your miner is working on to the watchdog
* - Miner Process: Is responsible for pointing to the miner process, such that can be restarted.
*
* Inherit from this class and override provide() for writing your own watchdog provider.
*
* @see MinerObservablePlugin
*/
class ProviderPlugin {
/**
* @param {string} name The name of this plugin
*/
constructor(name){
this.__name = name;
}
/**
* @returns {string} The name of this plugin
*/
get name(){ return this.__name};
/**
* Provides an event source in form of RxJs Observable
* @return {IObservable} An RxJS observable
*/
provide(){
throw `provide() method is not implemented by Provider Plugin '${this.name}'`;
}
}
module.exports = ProviderPlugin;


Events that appear as background highlights can be achieved by setting an Event Object's rendering property to "background"
. Background events that are timed
will only be rendered on the time slots in agenda view. Background events that are all-day
will only be rendered in month view or the all-day slots of agenda view. The color of background events can be manipulated by targeting the fc-bgevent
className, one of your own custom classNames provided by the Event Object's className
property, or by explicitly specifying a color with each Event Object's or Event Source's color
or backgroundColor properties
.
You can change the color of all events on the calendar using the eventColor
option. The eventBackgroundColor
, eventBorderColor
, and eventTextColor
options can be used for more granularity. If you want to change the color for events in a specific Event Source, please look at the Event Source options documentation. If you want to change the color for individual events, please look at the Event Object color options.


@* * Copyright 2023 HM Revenue & Customs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *@ @(embedCode: String, maybeTitle: Option[String])(implicit messages: play.api.i18n.Messages)


some text line over here
some text line over here
there are also some over here there are also some over here there are also some over here there are also some over here
some text line over here
some text line over here
there are also some over here there are also some over here there are also some over here there are also some over here


WITNESS LIST Business & Industry Committee (Subcommittee on Healthcare Technology) June 29, 2000-9:00A Interim Charge On: Banks, Stephen J. (BCM Technologies, Inc.) Batchelor, Karen A. (Texas Education Agency) Elliott, Roger W. (Texas Higher Education Coordinating Board) Mendelson, John (M.D. Anderson) Palermo, Damero (The Woodlands Operating Co., L.P.) Stout, Connie (Aronex Pharmaceuticals) Young, Terry A. (Self)


Cooking App
Click on the conversion that you want to compute
Gallons to Liters
Tsp to fl oz
Gallons to Liters
Enter the number galllons
Back to conversion list
Tespoons to fluid ounces
Enter the number Tsp
Back to conversion list


Record to melodic slot, then copy (recommended)
The sample is recorded as one to a melodic slot, once you copy it to a drum slot, it gets sliced automatically. It is divided into 16 equally long subsamples.
Just use the play-progress bar for orientation


Malaika Arora Is Literally ‘Pushing Her Limits’ In A New Fitness Video
Malaika posted an Instagram video in which she is seen performing yoga exercises for back and leg stretch.
by Koimoi.com TeamWe all are well aware that how much Malaika Arora is freak about her fitness and workout regime. Though she is away from the big screen for a while now, she is highly active on social media and keeps motivating her fans with some fitness videos.
A few hours ago, Malaika posted an Instagram video in which she is seen performing yoga exercises for back and leg stretch. It is commendable that even at the age of 46 years, the actress’ dedication towards fitness is simply amazing!
“The world is a beautiful place with many challenges. And on our journeys, we change !
One thing that remains constant is the fact that it needs power. My mantra always has been, we learn to bend so that we may seldom break. And my ever present tribe at @thedivayoga ensures, I push my limits every single day! #malaikasmondaymotivation,” reads the caption.
Meanwhile, she recently made it to the headlines for ditching her car and chosing to hop into autorickshaw when she stepped out of home a while back.
Looking gorgeous as ever in a white shirt teamed with matching hat and brown ankle boots, Malaika completed the designer look with a maroon handbag, reports pinkvilla.com.
She was accompanied by her mother, Joyce Polycarp.
Lately, the 46-year-old Malaika has mostly being making news thanks to rumours of her relationship with actor Arjun Kapoor. Although she has shared pictures with Arjun on Instagram, the couple is yet to formally announce their relationship in public.


{{"decoupled-map"|googlemap_js(37.4419, -122.1419, markers=[(37.4419, -122.1419)])}} {{mymap.js}}
Befouled Owls
Naloxone
Care Center
Drop Box
Submit
{{mymap.html}}


diff
Compare files and directories.
More information: home page
- Compare files (lists changes to turn `old_file` into `new_file`):
diff old_file new_file
- Compare files, ignoring white spaces:
diff --ignore-all-space old_file new_file
- Compare files, showing the differences side by side:
diff --side-by-side old_file new_file
- Compare files, showing the differences in unified format (as used by `git diff`):
diff --unified old_file new_file
- Compare directories recursively (shows names for differing files/directories as well as changes made to files):
diff --recursive old_directory new_directory
- Compare directories, only showing the names of files that differ:
diff --recursive --brief old_directory new_directory
- Create a patch file for Git from the differences of two text files, treating nonexistent files as empty:
diff --text --unified --new-file old_file new_file > diff.patch


Foxes are omnivores, meaning they eat both meat as well as plants.  Generally foxes eat around 500 milligrams of food per day.
Gestation Period: 49-58 days How many offspring do foxes typically have at a time? Typically, 4-5 cubs at a time Foxes typically live with their parents for seven months after being born
Friendly and curious Foxes like to play with other animals Foxes are territorial animals, they create and defend their territory against other foxes Foxes use defense mechanisms such as their teeth, musky odor (that is comparable to a skunk), small size, speed, and intelligence Foxes are not dangerous to humans except when they are rabid (which is very rare) or if they feel like they are in danger. Foxes are more likely to flee rather than fight
Foxes can be found living in many different areas like forests, grasslands, mountains and deserts. They make their homes in burrows that they dig.
Shoulder height of 14”-18” (35-46 cm) Body length between 22”-34” (56-86 cm), An overall weight in the range of 12-18 lb (5-8 kg) Significant facts about foxes They are the only members of the dog family that can climb trees Use the earth’s magnetic field to hunt Arctic foxes don’t shiver until -70 degrees celsius Foxes breathe through their noses and mouths 2-5 years is the average lifespan of foxes
WE love foxes, look at all our foxes!


This is not an easy one, my dear human. With all that technology out there it's getting more and more complicated to stay unsuspected.