Remoting (codename Artery)
Note
This page describes the experimental remoting subsystem, codenamed Artery that will eventually replace the old remoting implementation. For the current stable remoting system please refer to Remoting.
Remoting enables Actor systems on different hosts or JVMs to communicate with each other. By enabling remoting the system will start listening on a provided network address and also gains the ability to connect to other systems through the network. From the application's perspective there is no API difference between local or remote systems, ActorRef instances that point to remote systems look exactly the same as local ones: they can be sent messages to, watched, etc. Every ActorRef contains hostname and port information and can be passed around even on the network. This means that on a network every ActorRef is a unique identifier of an actor on that network.
Remoting is not a server-client technology. All systems using remoting can contact any other system on the network if they possess an ActorRef pointing to those system. This means that every system that is remoting enabled acts as a "server" to which arbitrary systems on the same network can connect to.
What is new in Artery
Artery is a reimplementation of the old remoting module aimed at improving performance and stability. It is mostly source compatible with the old implementation and it is a drop-in replacement in many cases. Main features of Artery compared to the previous implementation:
- Based on Aeron (UDP) instead of TCP
- Focused on high-throughput, low-latency communication
- Isolation of internal control messages from user messages improving stability and reducing false failure detection in case of heavy traffic by using a dedicated subchannel.
- Mostly allocation-free operation
- Support for a separate subchannel for large messages to avoid interference with smaller messages
- Compression of actor paths on the wire to reduce overhead for smaller messages
- Support for faster serialization/deserialization using ByteBuffers directly
- Built-in Flight-Recorder to help debugging implementation issues without polluting users logs with implementation specific events
- Providing protocol stability across major Akka versions to support rolling updates of large-scale systems
The main incompatible change from the previous implementation that the protocol field of the string representation of an ActorRef is always akka instead of the previously used akka.tcp or akka.ssl.tcp. Configuration properties are also different.
Preparing your ActorSystem for Remoting
The Akka remoting is a separate jar file. Make sure that you have the following dependency in your project:
"com.typesafe.akka" %% "akka-remote" % "2.4.11"
To enable remote capabilities in your Akka project you should, at a minimum, add the following changes to your application.conf file:
akka {
actor {
provider = remote
}
remote {
artery {
enabled = on
canonical.hostname = "<IP_ADDRESS>"
canonical.port = 25520
}
}
}
As you can see in the example above there are four things you need to add to get started:
- Change provider from local to remote
- Enable Artery to use it as the remoting implementation
- Add host name - the machine you want to run the actor system on; this host name is exactly what is passed to remote systems in order to identify this system and consequently used for connecting back to this system if need be, hence set it to a reachable IP address or resolvable name in case you want to communicate across the network.
- Add port number - the port the actor system should listen on, set to 0 to have it chosen automatically
Note
The port number needs to be unique for each actor system on the same machine even if the actor systems have different names. This is because each actor system has its own networking subsystem listening for connections and handling messages as not to interfere with other actor systems.
The example above only illustrates the bare minimum of properties you have to add to enable remoting. All settings are described in Remote Configuration.
Canonical address
In order to remoting to work properly, where each system can send messages to any other system on the same network (for example a system forwards a message to a third system, and the third replies directly to the sender system) it is essential for every system to have a unique, globally reachable address and port. This address is part of the unique name of the system and will be used by other systems to open a connection to it and send messages. This means that if a host has multiple names (different DNS records pointing to the same IP address) then only one of these can be canonical. If a message arrives to a system but it contains a different hostname than the expected canonical name then the message will be dropped. If multiple names for a system would be allowed, then equality checks among ActorRef instances would no longer to be trusted and this would violate the fundamental assumption that an actor has a globally unique reference on a given network. As a consequence, this also means that localhost addresses (e.g. <IP_ADDRESS>) cannot be used in general (apart from local development) since they are not unique addresses in a real network.
In cases, where Network Address Translation (NAT) is used or other network bridging is involved, it is important to configure the system so that it understands that there is a difference between his externally visible, canonical address and between the host-port pair that is used to listen for connections. See Akka behind NAT or in a Docker container for details.
Acquiring references to remote actors
In order to communicate with an actor, it is necessary to have its ActorRef. In the local case it is usually the creator of the actor (the caller of actorOf()) is who gets the ActorRef for an actor that it can then send to other actors. In other words:
- An Actor can get a remote Actor's reference simply by receiving a message from it (as it's available as sender() then), or inside of a remote message (e.g. PleaseReply(message: String, remoteActorRef: ActorRef))
Alternatively, an actor can look up another located at a known path using ActorSelection. These methods are available even in remoting enabled systems:
- Remote Lookup : used to look up an actor on a remote node with actorSelection(path)
- Remote Creation : used to create an actor on a remote node with actorOf(Props(...), actorName)
In the next sections the two alternatives are described in detail.
Looking up Remote Actors
actorSelection(path) will obtain an ActorSelection to an Actor on a remote node, e.g.:
val selection =
context.actorSelection("akka://actorSystemName@<IP_ADDRESS>:25520/user/actorName")
As you can see from the example above the following pattern is used to find an actor on a remote node:
akka://<actor system>@<hostname>:<port>/<actor path>
Note
Unlike with earlier remoting, the protocol field is always akka as pluggable transports are no longer supported.
Once you obtained a selection to the actor you can interact with it in the same way you would with a local actor, e.g.:
selection ! "Pretty awesome feature"
To acquire an ActorRef for an ActorSelection you need to send a message to the selection and use the sender reference of the reply from the actor. There is a built-in Identify message that all Actors will understand and automatically reply to with a ActorIdentity message containing the ActorRef. This can also be done with the resolveOne method of the ActorSelection, which returns a Future of the matching ActorRef.
For more details on how actor addresses and paths are formed and used, please refer to Actor References, Paths and Addresses.
Note
Message sends to actors that are actually in the sending actor system do not get delivered via the remote actor ref provider. They're delivered directly, by the local actor ref provider.
Aside from providing better performance, this also means that if the hostname you configure remoting to listen as cannot actually be resolved from within the very same actor system, such messages will (perhaps counterintuitively) be delivered just fine.
Creating Actors Remotely
If you want to use the creation functionality in Akka remoting you have to further amend the application.conf file in the following way (only showing deployment section):
akka {
actor {
deployment {
/sampleActor {
remote = "akka://sampleActorSystem@<IP_ADDRESS>:2553"
}
}
}
}
The configuration above instructs Akka to react when an actor with path /sampleActor is created, i.e. using system.actorOf(Props(...), "sampleActor"). This specific actor will not be directly instantiated, but instead the remote daemon of the remote system will be asked to create the actor, which in this sample corresponds to sampleActorSystem@<IP_ADDRESS>:2553.
Once you have configured the properties above you would do the following in code:
ActorRef actor = system.actorOf(Props.create(SampleActor.class), "sampleActor");
actor.tell("Pretty slick", ActorRef.noSender());
The actor class SampleActor has to be available to the runtimes using it, i.e. the classloader of the actor systems has to have a JAR containing the class.
Note
In order to ensure serializability of Props when passing constructor arguments to the actor being created, do not make the factory an inner class: this will inherently capture a reference to its enclosing object, which in most cases is not serializable. It is best to create a factory method in the companion object of the actor’s class.
Serializability of all Props can be tested by setting the configuration item akka.actor.serialize-creators=on. Only Props whose deploy has LocalScope are exempt from this check.
You can use asterisks as wildcard matches for the actor paths, so you could specify: /*/sampleActor and that would match all sampleActor on that level in the hierarchy. You can also use wildcard in the last position to match all actors at a certain level: /someParent/*. Non-wildcard matches always have higher priority to match than wildcards, so: /foo/bar is considered more specific than /foo/* and only the highest priority match is used. Please note that it cannot be used to partially match section, like this: /foo*/bar, /f*o/bar etc.
Programmatic Remote Deployment
To allow dynamically deployed systems, it is also possible to include deployment configuration in the Props which are used to create an actor: this information is the equivalent of a deployment section from the configuration file, and if both are given, the external configuration takes precedence.
With these imports:
import akka.actor.ActorRef;
import akka.actor.Address;
import akka.actor.AddressFromURIString;
import akka.actor.Deploy;
import akka.actor.Props;
import akka.actor.ActorSystem;
import akka.remote.RemoteScope;
and a remote address like this:
Address addr = new Address("akka", "sys", "host", 1234);
addr = AddressFromURIString.parse("akka://sys@host:1234"); // the same
you can advise the system to create a child on that remote node like so:
ActorRef ref = system.actorOf(Props.create(SampleActor.class).withDeploy(
new Deploy(new RemoteScope(addr))));
Untrusted Mode
As soon as an actor system can connect to another remotely, it may in principle send any possible message to any actor contained within that remote system. One example may be sending a PoisonPill to the system guardian, shutting that system down. This is not always desired, and it can be disabled with the following setting:
akka.remote.artery.untrusted-mode = on
This disallows sending of system messages (actor life-cycle commands, DeathWatch, etc.) and any message extending PossiblyHarmful to the system on which this flag is set. Should a client send them nonetheless they are dropped and logged (at DEBUG level in order to reduce the possibilities for a denial of service attack). PossiblyHarmful covers the predefined messages like PoisonPill and Kill, but it can also be added as a marker trait to user-defined messages.
Messages sent with actor selection are by default discarded in untrusted mode, but permission to receive actor selection messages can be granted to specific actors defined in configuration:
akka.remote.artery..trusted-selection-paths = ["/user/receptionist", "/user/namingService"]
The actual message must still not be of type PossiblyHarmful.
In summary, the following operations are ignored by a system configured in untrusted mode when incoming via the remoting layer:
- remote deployment (which also means no remote supervision)
- remote DeathWatch
- system.stop(), PoisonPill, Kill
- sending any message which extends from the PossiblyHarmful marker interface, which includes Terminated
- messages sent with actor selection, unless destination defined in trusted-selection-paths.
Note
Enabling the untrusted mode does not remove the capability of the client to freely choose the target of its message sends, which means that messages not prohibited by the above rules can be sent to any actor in the remote system. It is good practice for a client-facing system to only contain a well-defined set of entry point actors, which then forward requests (possibly after performing validation) to another actor system containing the actual worker actors. If messaging between these two server-side systems is done using local ActorRef (they can be exchanged safely between actor systems within the same JVM), you can restrict the messages on this interface by marking them PossiblyHarmful so that a client cannot forge them.
Quarantine
Akka remoting is using Aeron as underlying message transport. Aeron is using UDP and adds among other things reliable delivery and session semantics, very similar to TCP. This means that the order of the messages are preserved, which is needed for the Actor message ordering guarantees. Under normal circumstances all messages will be delivered but there are cases when messages may not be delivered to the destination:
- during a network partition and the Aeron session is broken, this automatically recovered once the partition is over
- when sending too many messages without flow control and thereby filling up the outbound send queue (outbound-message-queue-size config)
- if serialization or deserialization of a message fails (only that message will be dropped)
- if an unexpected exception occurs in the remoting infrastructure
In short, Actor message delivery is “at-most-once” as described in Message Delivery Reliability
Some messages in Akka are called system messages and those cannot be dropped because that would result in an inconsistent state between the systems. Such messages are used for essentially two features; remote death watch and remote deployment. These messages are delivered by Akka remoting with “exactly-once” guarantee by confirming each message and resending unconfirmed messages. If a system message anyway cannot be delivered the association with the destination system is irrecoverable failed, and Terminated is signaled for all watched actors on the remote system. It is placed in a so called quarantined state. Quarantine usually does not happen if remote watch or remote deployment is not used.
Each ActorSystem instance has an unique identifier (UID), which is important for differentiating between incarnations of a system when it is restarted with the same hostname and port. It is the specific incarnation (UID) that is quarantined. The only way to recover from this state is to restart one of the actor systems.
Messages that are sent to and received from a quarantined system will be dropped. However, it is possible to send messages with actorSelection to the address of a quarantined system, which is useful to probe if the system has been restarted.
An association will be quarantined when:
- Cluster node is removed from the cluster membership.
- Remote failure detector triggers, i.e. remote watch is used. This is different when Akka Cluster is used. The unreachable observation by the cluster failure detector can go back to reachable if the network partition heals. A cluster member is not quarantined when the failure detector triggers.
- Overflow of the system message delivery buffer, e.g. because of too many watch requests at the same time (system-message-buffer-size config).
- Unexpected exception occurs in the control subchannel of the remoting infrastructure.
The UID of the ActorSystem is exchanged in a two-way handshake when the first message is sent to a destination. The handshake will be retried until the other system replies and no other messages will pass through until the handshake is completed. If the handshake cannot be established within a timeout (handshake-timeout config) the association is stopped (freeing up resources). Queued messages will be dropped if the handshake cannot be established. It will not be quarantined, because the UID is unknown. New handshake attempt will start when next message is sent to the destination.
Handshake requests are actually also sent periodically to be able to establish a working connection when the destination system has been restarted.
Watching Remote Actors
Watching a remote actor is API wise not different than watching a local actor, as described in Lifecycle Monitoring aka DeathWatch. However, it is important to note, that unlike in the local case, remoting has to handle when a remote actor does not terminate in a graceful way sending a system message to notify the watcher actor about the event, but instead being hosted on a system which stopped abruptly (crashed). These situations are handled by the built-in failure detector.
Failure Detector
Under the hood remote death watch uses heartbeat messages and a failure detector to generate Terminated message from network failures and JVM crashes, in addition to graceful termination of watched actor.
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 Remote Configuration you can adjust the akka.remote.watch-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 10 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.remote.watch-failure-detector.acceptable-heartbeat-pause. You may want to adjust the Remote Configuration of this depending on you environment. This is how the curve looks like for acceptable-heartbeat-pause configured to 3 seconds.
Serialization
When using remoting for actors you must ensure that the props and messages used for those actors are serializable. Failing to do so will cause the system to behave in an unintended way.
For more information please see Serialization.
ByteBuffer based serialization
Artery introduces a new serialization mechanism which allows the ByteBufferSerializer to directly write into a shared java.nio.ByteBuffer instead of being forced to allocate and return an Array[Byte] for each serialized message. For high-throughput messaging this API change can yield significant performance benefits, so we recommend changing your serializers to use this new mechanism.
This new API also plays well with new versions of Google Protocol Buffers and other serialization libraries, which gained the ability to serialize directly into and from ByteBuffers.
As the new feature only changes how bytes are read and written, and the rest of the serializatio infrastructure remained the same, we recommend reading the Serialization documentation first.
Implementing an akka.serialization.ByteBufferSerializer works the same way as any other serializer,
interface ByteBufferSerializer {
/**
* Serializes the given object into the `ByteBuffer`.
*/
void toBinary(Object o, ByteBuffer buf);
/**
* Produces an object from a `ByteBuffer`, with an optional type-hint;
* the class should be loaded using ActorSystem.dynamicAccess.
*/
void fromBinary(ByteBuffer buf, String manifest);
}
Implementing a serializer for Artery is therefore as simple as implementing this interface, and binding the serializer as usual (which is explained in Serialization).
Implementations should typically extend SerializerWithStringManifest and in addition to the ByteBuffer based toBinary and fromBinary methods also implement the array based toBinary and fromBinary methods. The array based methods will be used when ByteBuffer is not used, e.g. in Akka Persistence.
Note that the array based methods can be implemented by delegation like this:
import akka.serialization.ByteBufferSerializer;
import akka.serialization.SerializerWithStringManifest;
class ExampleByteBufSerializer extends SerializerWithStringManifest
implements ByteBufferSerializer {
@Override
public int identifier() {
return 1337;
}
@Override
public String manifest(Object o) {
return "serialized-" + o.getClass().getSimpleName();
}
@Override
public byte[] toBinary(Object o) {
// in production code, aquire this from a BufferPool
final ByteBuffer buf = ByteBuffer.allocate(256);
toBinary(o, buf);
buf.flip();
final byte[] bytes = new byte[buf.remaining()];
buf.get(bytes);
return bytes;
}
@Override
public Object fromBinary(byte[] bytes, String manifest) {
return fromBinary(ByteBuffer.wrap(bytes), manifest);
}
@Override
public void toBinary(Object o, ByteBuffer buf) {
// Implement actual serialization here
}
@Override
public Object fromBinary(ByteBuffer buf, String manifest) {
// Implement actual deserialization here
return null;
}
}
Disabling the Java Serializer
With Artery it is possible to completely disable Java Serialization for the entire Actor system.
Java serialization is known to be slow and prone to attacks of various kinds - it never was designed for high throughput messaging after all. However it is very convenient to use, thus it remained the default serialization mechanism that Akka used to serialize user messages as well as some of its internal messages in previous versions. Since the release of Artery, Akka internals do not rely on Java serialization anymore (exceptions to that being java.lang.Throwable and "remote deployment").
Note
When using Artery, Akka does not use Java Serialization for any of it's internal messages. It is highly encouraged to disable java serialization, so please plan to do so at the earliest possibility you have in your project.
One may think that network bandwidth and latency limit the performance of remote messaging, but serialization is a more typical bottleneck.
For user messages, the default serializer, implemented using Java serialization, remains available and enabled in Artery. We do however recommend to disable it entirely and utilise a proper serialization library instead in order effectively utilise the improved performance and ability for rolling deployments using Artery. Libraries that we recommend to use include, but are not limited to, Kryo by using the akka-kryo-serialization library or Google Protocol Buffers if you want more control over the schema evolution of your messages.
In order to completely disable Java Serialization in your Actor system you need to add the following configuration to your application.conf:
akka {
actor {
serialization-bindings {
"java.io.Serializable" = none
}
}
}
Please note that this means that you will have to configure different serializers which will able to handle all of your remote messages. Please refer to the Serialization documentation as well as ByteBuffer based serialization to learn how to do this.
Routers with Remote Destinations
It is absolutely feasible to combine remoting with Routing.
A pool of remote deployed routees can be configured as:
akka.actor.deployment {
/parent/remotePool {
router = round-robin-pool
nr-of-instances = 10
target.nodes = ["tcp://app@<IP_ADDRESS>:2552", "akka://app@<IP_ADDRESS>:2552"]
}
}
This configuration setting will clone the actor defined in the Props of the remotePool 10 times and deploy it evenly distributed across the two given target nodes.
A group of remote actors can be configured as:
akka.actor.deployment {
/parent/remoteGroup2 {
router = round-robin-group
routees.paths = [
"akka://app@<IP_ADDRESS>:2552/user/workers/w1",
"akka://app@<IP_ADDRESS>:2552/user/workers/w1",
"akka://app@<IP_ADDRESS>:2552/user/workers/w1"]
}
}
This configuration setting will send messages to the defined remote actor paths. It requires that you create the destination actors on the remote nodes with matching paths. That is not done by the router.
Remoting Sample
There is a more extensive remote example that comes with Lightbend Activator. The tutorial named Akka Remote Samples with Java demonstrates both remote deployment and look-up of remote actors.
Performance tuning
Dedicated subchannel for large messages
All the communication between user defined remote actors are isolated from the channel of Akka internal messages so a large user message cannot block an urgent system message. While this provides good isolation for Akka services, all user communications by default happen through a shared network connection (an Aeron stream). When some actors send large messages this can cause other messages to suffer higher latency as they need to wait until the full message has been transported on the shared channel (and hence, shared bottleneck). In these cases it is usually helpful to separate actors that have different QoS requirements: large messages vs. low latency.
Akka remoting provides a dedicated channel for large messages if configured. Since actor message ordering must not be violated the channel is actually dedicated for actors instead of messages, to ensure all of the messages arrive in send order. It is possible to assign actors on given paths to use this dedicated channel by using path patterns:
akka.remote.artery.large-message-destinations = [
"/user/largeMessageActor",
"/user/largeMessagesGroup/*",
"/user/anotherGroup/*/largeMesssages",
"/user/thirdGroup/**",
]
This means that all messages sent to the following actors will pass through the dedicated, large messages channel:
- /user/largeMessageActor
- /user/largeMessageActorGroup/actor1
- /user/largeMessageActorGroup/actor2
- /user/anotherGroup/actor1/largeMessages
- /user/anotherGroup/actor2/largeMessages
- /user/thirdGroup/actor3/
- /user/thirdGroup/actor4/actor5
Messages destined for actors not matching any of these patterns are sent using the default channel as before.
Aeron Tuning
See Aeron documentation about Performance Testing.
Fine-tuning CPU usage latency tradeoff
Artery has been designed for low latency and as a result it can be CPU hungry when the system is mostly idle. This is not always desirable. It is possible to tune the tradeoff between CPU usage and latency with the following configuration:
# Values can be from 1 to 10, where 10 strongly prefers low latency # and 1 strongly prefers less CPU usage akka.remote.artery.advanced.idle-cpu-level = 1
By setting this value to a lower number, it tells Akka to do longer "sleeping" periods on its thread dedicated for spin-waiting and hence reducing CPU load when there is no immediate task to execute at the cost of a longer reaction time to an event when it actually happens. It is worth to be noted though that during a continuously high-throughput period this setting makes not much difference as the thread mostly has tasks to execute. This also means that under high throughput (but below maximum capacity) the system might have less latency than at low message rates.
Internal Event Log for Debugging (Flight Recorder)
Note
In this version (2.4.11) the flight-recorder is disabled by default because there is no automatic file name and path calculation implemented to make it possible to reuse the same file for every restart of the same actor system without clashing with files produced by other systems (possibly running on the same machine). Currently, you have to set the path and file names yourself to avoid creating an unbounded number of files and enable flight recorder manually by adding akka.remote.artery.advanced.flight-recorder.enabled=on to your configuration file. This a limitation of the current version and will not be necessary in the future.
Emitting event information (logs) from internals is always a tradeoff. The events that are usable for the Akka developers are usually too low level to be of any use for users and usually need to be fine-grained enough to provide enough information to be able to debug issues in the internal implementation. This usually means that these logs are hidden behind special flags and emitted at low log levels to not clutter the log output of the user system. Unfortunately this means that during production or integration testing these flags are usually off and events are not available when an actual failure happens - leaving maintainers in the dark about details of the event. To solve this contradiction, remoting has an internal, high-performance event store for debug events which is always on. This log and the events that it contains are highly specialized and not directly exposed to users, their primary purpose is to help the maintainers of Akka to identify and solve issues discovered during daily usage. When you encounter production issues involving remoting, you can include the flight recorder log file in your bug report to give us more insight into the nature of the failure.
There are various important features of this event log:
- Flight Recorder produces a fixed size file completely encapsulating log rotation. This means that this file will never grow in size and will not cause any unexpected disk space shortage in production.
- This file is crash resistant, i.e. its contents can be recovered even if the JVM hosting the ActorSystem crashes unexpectedly.
- Very low overhead, specialized, binary logging that has no significant overhead and can be safely left enabled for production systems.
The location of the file can be controlled via the akka.remote.artery.advanced.flight-recoder.destination setting (see akka-remote (artery) for details). By default, a file with the .afr extension is produced in the temporary directory of the operating system. In cases where the flight recorder casuses issues, it can be disabled by adding the setting akka.remote.artery.advanced.flight-recorder.enabled=off, although this is not recommended.
Remote Configuration
There are lots of configuration properties that are related to remoting in Akka. We refer to the reference configuration for more information.
Note
Setting properties like the listening IP and port number programmatically is best done by using something like the following:
ConfigFactory.parseString("akka.remote.artery.canonical.hostname=\"<IP_ADDRESS>\"")
.withFallback(ConfigFactory.load());
Akka behind NAT or in a Docker container
In setups involving Network Address Translation (NAT), Load Balancers or Docker containers the hostname and port pair that Akka binds to will be different than the "logical" host name and port pair that is used to connect to the system from the outside. This requires special configuration that sets both the logical and the bind pairs for remoting.
akka {
remote {
artery {
canonical.hostname = my.domain.com # external (logical) hostname
canonical.port = 8000 # external (logical) port
bind.hostname = local.address # internal (bind) hostname
bind.port = 25520 # internal (bind) port
}
}
}
Contents


frequency-sweep
Copyright (c) Rafael da Silva Rocha.
https://github.com/rochars/frequency-sweep
Sweep tone generator to create chirps with multiple stages.
Install
npm install frequency-sweep
Example
const frequencySweep = require('frequency-sweep');
// Define a sweep sequence.
// This sequence have 2 steps, each using a different waveform.
const sequence = [
{
start: 1, // start in 1 Hz
end: 100, // end in 100 Hz
time: 1, // goes from 1 Hz to 100 Hz in 1 second
wave: "sine" // use a sine wave
},
{
start: 100, // start in 100 Hz
end: 1400, // end in 1.4 kHz
time: 5.2, // goes from 100 Hz to 1.4 kHz in 5.2 seconds
wave: "sawtooth" // use a sawtooth wave
}
];
// Get the samples of the 2-step sweep sequence in 44.1kHz.
// The samples are 64-bit, in the -1 to 1 range.
let samples = frequencySweep.sweep(sequence, 44100);
By default the samples are returned in a Array. To return the samples as a Float64Array, set the optional outputTyped param to true:
// will return a Float64Array
let samples = frequencySweep.sweep(sequence, 44100, true);
Available waveforms:
- 'sine'
- 'triangle'
- 'square'
- 'sawtooth'
'noise' is also available.
In the browser:
<script src="https://unpkg.com/frequency-sweep"></script>
<script>
var samples = frequencySweep.sweep(sequence, 44100);
</script>
API
/**
* Return the samples of a frequency sweep. The sweep may be divided
* in segments, each using a different waveform (or noise), and each with
* a start and end frequency.
* @param {!Array<Object<string, string|number>>} sequence The sequence.
* Each item in the array must have the properties:
* start: Integer value, the start frequency of the segment.
* end: Integer value, the end frequency of the segment.
* time: Float value, the duration of the segment. 1 = 1 second.
* wave: String, "sine", "square", "triangle", "sawtooth" or "noise".
* @param {number} sampleRate The sample rate.
* @param {?boolean} outputTyped True to return Float64Array, false for Array.
* @return {!Array<number>|!Float64Array}
*/
function sweep(sequence, sampleRate, outputTyped=false) {}
LICENSE
Copyright (c) 2018 Rafael da Silva Rocha.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


The way we see it
Too much information
Our expertise
Facts and figures
Bisnode Germany
450 employees 4 locations
Know-how &
Supply
A TOTAL OF 240 years of experiance. Now United in one Brand.
BISNODE - USPs


[attribute]
Should be green
[attribute=value]
Should be blue
Should not be blue
[attribute|=value]
Should be purple
Should be purple
Should not be purple
[attribute^=value]
Should be not red
Should be red
[attribute$=value]
Should be gray
Should be not gray
[attribute~=value]
Should be lime
Should not be lime
[attribute*=value]
Should be steelblue
Should not be steelblue
[]
Should be clear
注释：对于 IE8 及更早版本的浏览器中的 [attribute]，必须声明 。


All Classes
Betweenness
BetweennessProcedure
BFS
CentralityResult
CentralityService
Closeness
ClosenessProcedure
Degree
Degree
DegreeResult
Direction
Edge
Example
FullTextIndex
FullTextIndex.SearchHit
Graph
GraphLoader
Join
RandomGraph


--- layout: gl-example category: examples title: Mapbox GL JS Examples exampletitle: Toggle style class examplesubtitle: Toggle a class of map styles. permalink: /examples/toggle-class navigation: - title: Toggle style class url: /examples/toggle-class ---


sexual transmission men Zika women Figure {border-style epidemic model number px;} vectorial #ffffff;} infection parameters []. cases force virus ZIKV dynamics transmission, male population prevalence rate relative infectious reported transmission. data disease new px; {font-family Sexual Table define font-size model, mosquito parameter posterior transmissibility values vector F.C.C.; Infect. K.G.S.; Rio attack different distribution double; given infections mathematical men, models period proposed ratio sexually underreporting A.C.W.G.d.B. basic border-color border-width calculate constant contact effective female infected matrix model. modes reproduction resulting sex shown shows solid; state transmitted women, {font-style {font-weight (a) (b) (day Equation Transmission [,]. [], assume asymmetrical bold cases. compartments confirmed courier; distributions effects em; estimate expression fact form forms humans importance incidence individual individuals infection. latent longer men. modifier obtained outbreak partners possible presence pt;} rates represent single time worth


Ocean [al53], ocean, in The Inner Sea ------------------------------------------------------------------------ 1: Groucho [hu9z], ship, 10 hulls, 1 rowing port, 30 sails, with ram, 1: departed for Ocean [al52]. 30: It is no longer windy. Routes leaving Ocean: North, to Ocean [ak53], 6 days East, to Ocean [al54], 6 days South, to Ocean [am53], 6 days West, to Ocean [al52], 6 days


- get(Object) - Method in class com.sun.net.httpserver.Headers
-
- getAddress() - Method in class com.sun.net.httpserver.HttpServer
-
returns the address this server is listening on
- getAttribute(String) - Method in class com.sun.net.httpserver.HttpExchange
-
Filter modules may store arbitrary objects with HttpExchange
instances as an out-of-band communication mechanism.
- getAttributes() - Method in class com.sun.net.httpserver.HttpContext
-
returns a mutable Map, which can be used to pass
configuration and other data to Filter modules
and to the context's exchange handler.
- getAuthenticator() - Method in class com.sun.net.httpserver.HttpContext
-
Returns the currently set Authenticator for this context
if one exists.
- getCipherSuites() - Method in class com.sun.net.httpserver.HttpsParameters
-
Returns a copy of the array of ciphersuites or null if none
have been set.
- getClientAddress() - Method in class com.sun.net.httpserver.HttpsParameters
-
Returns the address of the remote client initiating the
connection.
- getExecutor() - Method in class com.sun.net.httpserver.HttpServer
-
- getFilters() - Method in class com.sun.net.httpserver.HttpContext
-
returns this context's list of Filters.
- getFirst(String) - Method in class com.sun.net.httpserver.Headers
-
returns the first value from the List of String values
for the given key (if at least one exists).
- getHandler() - Method in class com.sun.net.httpserver.HttpContext
-
returns the handler for this context
- getHttpContext() - Method in class com.sun.net.httpserver.HttpExchange
-
Get the HttpContext for this exchange
- getHttpsConfigurator() - Method in class com.sun.net.httpserver.HttpsParameters
-
Returns the HttpsConfigurator for this HttpsParameters.
- getHttpsConfigurator() - Method in class com.sun.net.httpserver.HttpsServer
-
- getLocalAddress() - Method in class com.sun.net.httpserver.HttpExchange
-
Returns the local address on which the request was received
- getName() - Method in class com.sun.net.httpserver.HttpPrincipal
-
returns the contents of this principal in the form
realm:username
- getNeedClientAuth() - Method in class com.sun.net.httpserver.HttpsParameters
-
Returns whether client authentication should be required.
- getPath() - Method in class com.sun.net.httpserver.HttpContext
-
returns the path this context was created with
- getPrincipal() - Method in class com.sun.net.httpserver.Authenticator.Success
-
returns the authenticated user Principal
- getPrincipal() - Method in class com.sun.net.httpserver.HttpExchange
-
If an authenticator is set on the HttpContext that owns this exchange,
then this method will return the
HttpPrincipal
that represents
the authenticated user for this HttpExchange.
- getProtocol() - Method in class com.sun.net.httpserver.HttpExchange
-
Returns the protocol string from the request in the form
protocol/majorVersion.minorVersion.
- getProtocols() - Method in class com.sun.net.httpserver.HttpsParameters
-
Returns a copy of the array of protocols or null if none
have been set.
- getRealm() - Method in class com.sun.net.httpserver.BasicAuthenticator
-
returns the realm this BasicAuthenticator was created with
- getRealm() - Method in class com.sun.net.httpserver.HttpPrincipal
-
returns the realm this object was created with.
- getRemoteAddress() - Method in class com.sun.net.httpserver.HttpExchange
-
Returns the address of the remote entity invoking this request
- getRequestBody() - Method in class com.sun.net.httpserver.HttpExchange
-
returns a stream from which the request body can be read.
- getRequestHeaders() - Method in class com.sun.net.httpserver.HttpExchange
-
Returns an immutable Map containing the HTTP headers that were
included with this request.
- getRequestMethod() - Method in class com.sun.net.httpserver.HttpExchange
-
Get the request method
- getRequestURI() - Method in class com.sun.net.httpserver.HttpExchange
-
Get the request URI
- getResponseBody() - Method in class com.sun.net.httpserver.HttpExchange
-
returns a stream to which the response body must be
written.
- getResponseCode() - Method in class com.sun.net.httpserver.Authenticator.Failure
-
returns the response code to send to the client
- getResponseCode() - Method in class com.sun.net.httpserver.Authenticator.Retry
-
returns the response code to send to the client
- getResponseCode() - Method in class com.sun.net.httpserver.HttpExchange
-
Returns the response code, if it has already been set
- getResponseHeaders() - Method in class com.sun.net.httpserver.HttpExchange
-
Returns a mutable Map into which the HTTP response headers can be stored
and which will be transmitted as part of this response.
- getServer() - Method in class com.sun.net.httpserver.HttpContext
-
returns the server this context was created with
- getSSLContext() - Method in class com.sun.net.httpserver.HttpsConfigurator
-
Returns the SSLContext for this HttpsConfigurator.
- getSSLSession() - Method in class com.sun.net.httpserver.HttpsExchange
-
Get the SSLSession for this exchange.
- getUsername() - Method in class com.sun.net.httpserver.HttpPrincipal
-
returns the username this object was created with.
- getWantClientAuth() - Method in class com.sun.net.httpserver.HttpsParameters
-
Returns whether client authentication should be requested.
- handle(HttpExchange) - Method in interface com.sun.net.httpserver.HttpHandler
-
Handle the given request and generate an appropriate response.
- hashCode() - Method in class com.sun.net.httpserver.Headers
-
- hashCode() - Method in class com.sun.net.httpserver.HttpPrincipal
-
returns a hashcode for this HttpPrincipal.
- Headers - Class in com.sun.net.httpserver
-
HTTP request and response headers are represented by this class which implements
the interface
Map
<
String
,
List
<
String
>>.
- Headers() - Constructor for class com.sun.net.httpserver.Headers
-
- HttpContext - Class in com.sun.net.httpserver
-
HttpContext represents a mapping between the root URI path of an application
to a
HttpHandler
which is invoked to handle requests destined
for that path on the associated HttpServer or HttpsServer.
- HttpContext() - Constructor for class com.sun.net.httpserver.HttpContext
-
- HttpExchange - Class in com.sun.net.httpserver
-
This class encapsulates a HTTP request received and a
response to be generated in one exchange.
- HttpExchange() - Constructor for class com.sun.net.httpserver.HttpExchange
-
- HttpHandler - Interface in com.sun.net.httpserver
-
A handler which is invoked to process HTTP exchanges.
- HttpPrincipal - Class in com.sun.net.httpserver
-
Represents a user authenticated by HTTP Basic or Digest
authentication.
- HttpPrincipal(String, String) - Constructor for class com.sun.net.httpserver.HttpPrincipal
-
creates a HttpPrincipal from the given username and realm
- HttpsConfigurator - Class in com.sun.net.httpserver
-
This class is used to configure the https parameters for each incoming
https connection on a HttpsServer.
- HttpsConfigurator(SSLContext) - Constructor for class com.sun.net.httpserver.HttpsConfigurator
-
Creates an Https configuration, with the given SSLContext.
- HttpServer - Class in com.sun.net.httpserver
-
This class implements a simple HTTP server.
- HttpServer() - Constructor for class com.sun.net.httpserver.HttpServer
-
- HttpServerProvider - Class in com.sun.net.httpserver.spi
-
Service provider class for HttpServer.
- HttpServerProvider() - Constructor for class com.sun.net.httpserver.spi.HttpServerProvider
-
Initializes a new instance of this class.
- HttpsExchange - Class in com.sun.net.httpserver
-
This class encapsulates a HTTPS request received and a
response to be generated in one exchange and defines
the extensions to HttpExchange that are specific to the HTTPS protocol.
- HttpsExchange() - Constructor for class com.sun.net.httpserver.HttpsExchange
-
- HttpsParameters - Class in com.sun.net.httpserver
-
Represents the set of parameters for each https
connection negotiated with clients.
- HttpsParameters() - Constructor for class com.sun.net.httpserver.HttpsParameters
-
- HttpsServer - Class in com.sun.net.httpserver
-
This class is an extension of
HttpServer
which provides
support for HTTPS.
- HttpsServer() - Constructor for class com.sun.net.httpserver.HttpsServer
-


What do you expect from Congress?
Programs, powers, and laws
Tell us how you believe the legislative body can better do it's job
Name
Email
Phone Number
Age
Party Affiliation
Democrat
Republican
Libertarian
Green
Independent
Choose Not To Disclose
Male
Female
Choose Not To Disclose
Likelihood of voting:
Very Likely
Likely
I Don't Know
Unlikely
Name Three Primary Responsibilities of Congress:
Pick Your Top Two Issues Congress Needs To Address Now:


| Basic | Standard | Premium | |
|---|---|---|---|
| Monthly price after free month | $7.99 | $9.99 | $11.99 |
| HD available | No | Yes | Yes |
| Ultra HD available | No | No | Yes |
| Screens you can watch on at the same time | 1 | 2 | 4 |
| Watch on your laptop, TV, phone and tablet | Yes | Yes | Yes |
| Unlimited movies and TV shows | Yes | Yes | Yes |
| Cancel anytime | Yes | Yes | Yes |
| First month free | Yes | Yes | Yes |


Alumni Management System is a platform where former students can interact among themselves and with the institute after graduation. The Alumni Portal is linked to your institute website and can be accessed using a user name and password after initial signup. Alumni Portal Module makes it possible to celebrate the legacy and longevity of your institution with your own private online community.


The facilities/default.h
header defines macros used to apply default values for true-optional parameters.
#include <chaos/preprocessor/facilities/default.h>
The CHAOS_PP_DEFAULT
macro is used to apply a default argument value if a true-optional argument doesn't exist.
CHAOS_PP_DEFAULT
(def, ...)
The default value to be used if no true-optional argument exists in __VA_ARGS__
.
The argument that possibly contains a true-optional argument.
If __VA_ARGS__
contains more than a single argument, this macro expands to the second argument.
Otherwise, it expands to def.
#include<chaos/preprocessor/config.h>
#include<chaos/preprocessor/facilities/default.h>
#include<chaos/preprocessor/facilities/optional.h>
#define MACRO(...) \ MACRO_I( \CHAOS_PP_NON_OPTIONAL
(__VA_ARGS__), \CHAOS_PP_DEFAULT
(Chaos, __VA_ARGS__) \ ) \ /**/ #define MACRO_I(a, b) b Preprocessor [a] MACRO(+) // Chaos Preprocessor [+] MACRO(-, Boost) // Boost Preprocessor [-]
The CHAOS_PP_DEFAULT_ID
macro indirectly expands to CHAOS_PP_DEFAULT
.
CHAOS_PP_DEFAULT_ID
()
This macro effectively allows CHAOS_PP_DEFAULT
to pass through itself without becoming disabled.
The CHAOS_PP_DEFAULT_
macro expands to a λ expression representing CHAOS_PP_DEFAULT
.
CHAOS_PP_DEFAULT_
This macro is a shorthand form of the following λ binding:
The CHAOS_PP_DEFAULT_AT
macro is used to apply a default argument value for true-optional parameters other than just the first.
CHAOS_PP_DEFAULT_AT
(i, def, ...)
The index of the true-optional argument possibly contained in __VA_ARGS__
.
The default value to be used if the i-th true-optional argument does not exist.
The argument that possibly contains true-optional arguments.
If an i-th true-optional argument exists, this macro expands to that argument. Otherwise, it expands to def.
This macro uses bypass semantics.
If bypass semantics are already in effect, CHAOS_PP_DEFAULT_AT_BYPASS
must be used instead.
#include<chaos/preprocessor/config.h>
#include<chaos/preprocessor/facilities/default.h>
#include<chaos/preprocessor/facilities/optional.h>
#ifCHAOS_PP_VARIADICS
// NAME(first, last => Mensonides, middle => /**/) #define NAME(...) \ NAME_I( \CHAOS_PP_NON_OPTIONAL
(__VA_ARGS__), \CHAOS_PP_DEFAULT_AT
(0, Mensonides, __VA_ARGS__), \CHAOS_PP_DEFAULT_AT
(1,, __VA_ARGS__) \ ) \ /**/ #define NAME_I(first, last, middle) first middle last NAME(Paul) // Paul Mensonides NAME(Paul, Mensonides, Jelle) // Paul Jelle Mensonides #endif
The CHAOS_PP_DEFAULT_AT_ID
macro indirectly expands to CHAOS_PP_DEFAULT_AT
.
CHAOS_PP_DEFAULT_AT_ID
()
This macro effectively allows CHAOS_PP_DEFAULT_AT
to pass through itself without becoming disabled.
The CHAOS_PP_DEFAULT_AT_
macro expands to a λ expression representing CHAOS_PP_DEFAULT_AT
.
CHAOS_PP_DEFAULT_AT_
This macro is a shorthand form of the following λ binding:
The CHAOS_PP_DEFAULT_AT_BYPASS
macro behaves identically to CHAOS_PP_DEFAULT_AT
except that it is parametized by the bypass recursion state.
CHAOS_PP_DEFAULT_AT_BYPASS
(s, i, def, ...)
The current bypass recursion state.
The index of the true-optional argument possibly contained in __VA_ARGS__
.
The default value to be used if the i-th true-optional argument does not exist.
The argument that possibly contains true-optional arguments.
If bypass semantics are already in effect, this macro must be used instead of CHAOS_PP_DEFAULT_AT
.
The CHAOS_PP_DEFAULT_AT_BYPASS_ID
macro indirectly expands to CHAOS_PP_DEFAULT_AT_BYPASS
.
CHAOS_PP_DEFAULT_AT_BYPASS_ID
()
This macro effectively allows CHAOS_PP_DEFAULT_AT_BYPASS
to pass through itself without becoming disabled.
The CHAOS_PP_DEFAULT_AT_BYPASS_
macro expands to a λ expression representing CHAOS_PP_DEFAULT_AT_BYPASS
.
CHAOS_PP_DEFAULT_AT_BYPASS_
This macro is a shorthand form of the following λ binding:


{{blog.body|safe}}
{%for i in featured_blogs%}
{%endfor%}
{{i.title}}
{{i.sub_title}}
Loading
{%endblock%}
Get in Touch


Copyright (c) websitename. All rights reserved. < www.alltemplateneeds.com > Images From: www.photorack.net


|
|
Name | Address | Category | |
|---|---|---|---|---|
|
|
A Pinch of Creativity
Tannis,attn |
296 McDermot Avenue Winnipeg, MB |
Category 1 |
|
|
|
A Pinch of Creativity
Tannis,attn |
1500 McGill Collège Avenue Montreal, QC |
Category 2 |
|
|
|
Chef'sChoice by EdgeCraft
DaRin,Mary |
296 McDermot Avenue Winnipeg, MB |
Category 3 |
|
|
|
A Pinch of Creativity
Tannis,attn |
296 McDermot Avenue Winnipeg, MB |
Category |
|
|
|
A Pinch of Creativity
Tannis,attn |
East GuangXing Xingxing County Guangdong |
Category 4 |
|
|
|
Chef'sChoice by EdgeCraft
DaRin,Mary |
1500 McGill Collège Avenue Montreal, QC |
Category 1 |
|
|
|
Chef'sChoice by EdgeCraft
DaRin,Mary |
East GuangXing Xingxing County Guangdong |
Category 2 |
|
|
|
A Pinch of Creativity
Tannis,attn |
1500 McGill Collège Avenue Montreal, QC |
Category 4 |
|
|
|
Chef'sChoice by EdgeCraft
DaRin,Mary |
East GuangXing Xingxing County Guangdong |
Category 3 |
|
Showing 1 to 9 of 9 entries


Values
Combating Stereotype threat
July 30, 2015
Last week we researched and wrote a post about stereotype threat, the documented pheomenon where people from negatively stereotyped groups internalize anticipated judgments about themselves and perform below their ability because of it. The social environment and our perceptions of ourselves in it has a deep, almost subconsious role in shaping how we act.
To combat sterotype threat, it's important to remind ourselves of our values, so that we're centered in the best version of who we know we're capable of being, rather than caught up in other people's judgments. I try to center myself in community, creativity, and curiosity.
I think of community and freedom together because when we want to be free of some social oppression, the best way to do it is by building a liberated space with other people. By ourselves, our only choices are to conform to or reject the consensus reality. With others, we can build up a new narrative and transform it. For example, when facing stereotype threat, if you are alone or think you are alone in battling negative judgments, you must retreat to an isolated position of defense in your mind. If, however, you have a community that supports you to discuss these experiences with, it reaffirms your self-worth and can give you the strength to speak out, engaging with these perceptions directly and perhaps transforming the space.
Sometimes communities we are tied to can be difficult to inhabit. When our social environment is filled with all sorts of judgments, pressures, and misperceptions, it’s so important to learn how to speak our truth and push back from a place of love and consideration. We are only able to move towards a shared understanding when confrontation takes place in a way where people feel respected and are able to listen to one another. Freedom from others is a weak sort of freedom. Only when we find freedom with others can we truly flourish and transform our world for the better.
Remaining creative and curious about the world is what renews me. I’m learning how to code because I’m curious about how computers work and want to have the ability to create with new tools. It's hard work to master the tools of a craft well enough so that ideas can flow off the fingertips, but it's well worth it. When working in the state of flow where one loses sense of the distinction between creator, instrument, and creation, there is a deep sense of harmony.
When I get stuck, these are qualities I draw upon to push me forward again. I try to get curious about what the block is, and come up with ways to transform or get around it. This can apply to people too. When we feel stereotyped, it’s interesting to ask why the person judging us feels the need to constrain our humanity in a labeled box. It could be coming from inner insecurity, a historical legacy, or lack of exposure to different perspectives. If we see their judgment as emanating from them for reasons that don’t actually have much to do with us, we can brush it off and have some understanding of them. Then we can speak and try to listen and be heard.


|
WebWork 2 : Using Checkboxes
This page last changed on Nov 30, 2004 by jcarreira.
Using Checkboxes (General)The biggest gotcha for newbies is that you must set the 'value' attribute in the html <input> field to use Checkboxes with WW. By default your browser will set this to some value. Firebird uses "on" - not sure what IE or others use. You must make this a sensible value for whatever property you are setting.Using Checkboxes to set boolean fieldsHTML:<input type="checkbox" name="user.lockedOut" value="true"/> private boolean m_lockedOut = false; public void setLockedOut(boolean lockedOut) { m_lockedOut = lockedOut; } Using Checkboxes to set a collectionOur user has a number of priviliges that are stored as a Set of strings. To use checkboxes for these, we have HTML that looks like:<input type="checkbox" name="user.priv" value="boss"/> <input type="checkbox" name="user.priv" value="admin"/> <input type="checkbox" name="user.priv" value="manager"/> Say a user checks the first 2; the browser will send the query string: user.priv=boss&user.priv=admin. OGNL will end up callingaction.getUser().setPriv(String[] {"boss", "admin"}) You can write this method like: Set m_privileges = new HashSet(); public void setPriv(String[] privs) { for (int i = 0; i < privs.length; i++) { m_privileges.add(privs[i]); } } Full Detailed example:This example uses a kind-of XW:Interceptors#ModelDriven Action. The action returns a single getter for the User object whose values are populated. |
| Document generated by Confluence on Dec 14, 2004 16:36 |


Next: remove-duplicates, Previous: merge, Up: Sequences Dictionary
remove
item sequence &key from-end test test-not start end count key ⇒ result-sequence
remove-if
test sequence &key from-end start end count key ⇒ result-sequence
remove-if-not
test sequence &key from-end start end count key ⇒ result-sequence
delete
item sequence &key from-end test test-not start end count key ⇒ result-sequence
delete-if
test sequence &key from-end start end count key ⇒ result-sequence
delete-if-not
test sequence &key from-end start end count key ⇒ result-sequence
item—an object.
sequence—a proper sequence.
test—a designator for a function of one argument that returns a generalized boolean.
from-end—a generalized boolean. The default is false.
test—a designator for a function of two arguments that returns a generalized boolean.
test-not—a designator for a function of two arguments that returns a generalized boolean.
start, end—bounding index designators of sequence. The defaults for start and end are 0 and nil, respectively.
count—an integer or nil.
The default is nil.
key—a designator for a function of one argument, or nil.
result-sequence—a sequence.
remove, remove-if, and remove-if-not return a sequence from which the elements that satisfy the test have been removed.
delete, delete-if, and delete-if-not are like remove, remove-if, and remove-if-not respectively, but they may modify sequence.
If sequence is a vector, the result is a vector that has the same actual array element type as sequence. The result might or might not be simple, and might or might not be identical to sequence. If sequence is a list, the result is a list.
Supplying a from-end of true matters only when the count is provided; in that case only the rightmost count elements satisfying the test are deleted.
Count, if supplied, limits the number of elements removed or deleted; if more than count elements satisfy the test, then of these elements only the leftmost or rightmost, depending on from-end, are deleted or removed, as many as specified by count.
If count is supplied and negative, the behavior is as if zero had been supplied instead.
If count is nil, all matching items are affected.
For all these functions, elements not removed or deleted occur in the same order in the result as they did in sequence.
remove, remove-if, remove-if-not return a sequence of the same type as sequence that has the same elements except that those in the subsequence bounded by start and end and satisfying the test have been removed. This is a non-destructive operation. If any elements need to be removed, the result will be a copy. The result of remove may share with sequence; the result may be identical to the input sequence if no elements need to be removed.
delete, delete-if, and delete-if-not return a sequence of the same type as sequence that has the same elements except that those in the subsequence bounded by start and end and satisfying the test have been deleted. Sequence may be destroyed and used to construct the result; however, the result might or might not be identical to sequence.
delete, when sequence is a list, is permitted to setf any part, car or cdr, of the top-level list structure in that sequence. When sequence is a vector, delete is permitted to change the dimensions of the vector and to slide its elements into new positions without permuting them to produce the resulting vector.
delete-if is constrained to behave exactly as follows:
(delete nil sequence :test #'(lambda (ignore item) (funcall test item)) ...)
(remove 4 '(1 3 4 5 9)) ⇒ (1 3 5 9) (remove 4 '(1 2 4 1 3 4 5)) ⇒ (1 2 1 3 5) (remove 4 '(1 2 4 1 3 4 5) :count 1) ⇒ (1 2 1 3 4 5) (remove 4 '(1 2 4 1 3 4 5) :count 1 :from-end t) ⇒ (1 2 4 1 3 5) (remove 3 '(1 2 4 1 3 4 5) :test #'>) ⇒ (4 3 4 5) (setq lst '(list of four elements)) ⇒ (LIST OF FOUR ELEMENTS) (setq lst2 (copy-seq lst)) ⇒ (LIST OF FOUR ELEMENTS) (setq lst3 (delete 'four lst)) ⇒ (LIST OF ELEMENTS) (equal lst lst2) ⇒ false (remove-if #'oddp '(1 2 4 1 3 4 5)) ⇒ (2 4 4) (remove-if #'evenp '(1 2 4 1 3 4 5) :count 1 :from-end t) ⇒ (1 2 4 1 3 5) (remove-if-not #'evenp '(1 2 3 4 5 6 7 8 9) :count 2 :from-end t) ⇒ (1 2 3 4 5 6 8) (setq tester (list 1 2 4 1 3 4 5)) ⇒ (1 2 4 1 3 4 5) (delete 4 tester) ⇒ (1 2 1 3 5) (setq tester (list 1 2 4 1 3 4 5)) ⇒ (1 2 4 1 3 4 5) (delete 4 tester :count 1) ⇒ (1 2 1 3 4 5) (setq tester (list 1 2 4 1 3 4 5)) ⇒ (1 2 4 1 3 4 5) (delete 4 tester :count 1 :from-end t) ⇒ (1 2 4 1 3 5) (setq tester (list 1 2 4 1 3 4 5)) ⇒ (1 2 4 1 3 4 5) (delete 3 tester :test #'>) ⇒ (4 3 4 5) (setq tester (list 1 2 4 1 3 4 5)) ⇒ (1 2 4 1 3 4 5) (delete-if #'oddp tester) ⇒ (2 4 4) (setq tester (list 1 2 4 1 3 4 5)) ⇒ (1 2 4 1 3 4 5) (delete-if #'evenp tester :count 1 :from-end t) ⇒ (1 2 4 1 3 5) (setq tester (list 1 2 3 4 5 6)) ⇒ (1 2 3 4 5 6) (delete-if #'evenp tester) ⇒ (1 3 5) tester ⇒ implementation-dependent
(setq foo (list 'a 'b 'c)) ⇒ (A B C) (setq bar (cdr foo)) ⇒ (B C) (setq foo (delete 'b foo)) ⇒ (A C) bar ⇒ ((C)) or ... (eq (cdr foo) (car bar)) ⇒ T or ...
For delete, delete-if, and delete-if-not, sequence may be destroyed and used to construct the result.
Should be prepared to signal an error of type type-error if sequence is not a proper sequence.
Traversal Rules and Side Effects
The :test-not argument is deprecated.
The functions delete-if-not and remove-if-not are deprecated.
Next: remove-duplicates, Previous: merge, Up: Sequences Dictionary


Seth Meyers unpacks a 'devastating' day 4 of the Trump impeachment hearings
by Caitlin WelshIf you didn't have time to watch the absolutely massive fourth day of public impeachment hearings, featuring the explosive testimony of Gordon Sondland and Donald Trump's instantly memed Sharpie notes, here's Seth Meyers' Closer Look at it.
And if you don't have time even for the 15-minute wrap-up, Meyers noted on Wednesday night that the look on ranking committee member and GOP Rep. Devin Nunes' face after Sondland's testimony should tell you all you need to know.
"There's only two explanations for that face," Meyers said at the beginning of the segment, pointing to the congressman's glum look. "Either he just heard lengthy testimony detailing a criminal scheme so shocking it could bring down the presidency of Donald Trump, or he sharted and he's trying to remember how far away his backup pants are."


Creates a new datatable type, instanciating a new Settings object.
The identifier of this datatable type
Transformation functions to use for table operations
Transformation functions to use for table operations
The identifier of this datatable type
Defines the function used to paginate data
Defines the function used to filter data
Defines the function used to paginate data
Defines the function used to sort data
Settings object used to get various values for the datatable & other components
Factory function that copy the VueDatatablePager prototype, and configure as this type.
a new factored VueDatatablePager constructor.
Factory function that copy the VueDatatable prototype, and configure as this type.
a new factored VueDatatable constructor.
Merge a settings object with the TableType.setting object of the instance.
Values to merge.
this
for chaining.
Override the table type's handler method with the provided one. It can be used to override a single handler step, or to change the behavior of a table type at runtime.
The type of the handler ('filter' | 'sort' | 'paginate' | 'display'
)
The new handler to set.
Set a Settings value at a specific path.
Path to the setting value to set.
Value to set at the specified path.
this
for chaining.
Get a Settings value at a specific path.
Path to the setting value to get.
the value at the given path.
Generated using TypeDoc
Defines a type of Datatable, with its Settings object.


These statistics apply to the n/a activities matching the current filter settings.
Types |
||
Distance |
||
| Sum: | n/a | |
| Avg: | n/a | |
| Max: | n/a | |
Elevation |
||
| Sum: | n/a | |
| Avg: | n/a | |
| Max: | n/a | |
Time |
||
| Sum: | n/a | |
| Avg: | n/a | |
| Max: | n/a |


This chapter covers the blosxom renderer in Pyblosxom. There are other renderers (like the debug renderer) that operate differently. See the chapter on renderers for more details.
If you want your blog rendered using a different template system—say Cheetah or htmltmpl—implement a renderer that renders the output. This new renderer can be implemented as a Pyblosxom plugin. See the chapter on writing plugins for more information.
The rest of this chapter talks about the various things you can do with the blosxom renderer which comes with Pyblosxom.
The blosxom renderer renders the output of a request with a flavour.
A flavour is a group of templates for a specific output format or style. For example, html, xhtml, atom, rss, rdf, etc.
A flavour consists of at least the following templates:
Note
Many plugins require additional templates to render their output in addition to the standard templates listed above. See the documentation for the plugin for more information.
Note
Refer to Lifecycle of a Pyblosxom request for detailed information on how Pyblosxom’s default renderer blosxom uses these templates.
More on flavours, how they’re stored, and such later.
A template is one piece of a flavour that specifies a specific portion of the output. For example, the head template of an html flavour would be in a file called head and might look like this:

<title>$(blog_title)</title>

More on templates later.
Pyblosxom allows you to manage the flavours and templates for your blog in several different ways:
Note
Pyblosxom is backwards compatible with previous versions of Pyblosxom. You can put your flavour files in your datadir. You can also put your flavour files in the categories of your datadir. However you cannot have a flavourdir and put flavour files in your datadir—Pyblosxom will look at EITHER your datadir OR your flavourdir for flavour files.
This is the easiest way to store your flavours separately from the entries in your blog. This is the preferred way.
If you specify the flavourdir directory in your config.py file, you can store each flavour in a directory in the flavourdir.
For example, Joe has this in his config.py:
py["flavourdir"] = "/home/joe/blog/flavours/"
Joe’s blog directory structure would look like this:
/home/joe/blog/
|- entries/ <-- datadir
| |- work/ <-- work category of entries
| |- home/ <-- home category of entries
|
|- flavours/
|- html.flav/ <-- html flavour
| |- content_type
| |- head
| |- foot
| |- story
| |- ...
|
|- rss.flav/ <-- rss flavour
| |- content_type
| |- head
| |- foot
| |- story
| |- ...
The flavourdir specifies the directory in which Joe stores his flavours.
Note
Flavour directories must end in .flav.
Note
Templates in the flavour directory don’t need an extension.
This structure also makes it easier to use flavour packs found in the flavour registry on the Pyblosxom website.
Flavours can be stored in directories in the directory specified by your datadir. This works exactly the same as having a separate flavourdir except that the flavourdir is not a separate directory tree—it’s the same tree as your datadir.
For example, Joe stores his flavours alongside his entries and his blog directory tree looks like this:
/home/joe/blog/
|- entries/ <-- datadir
|- html.flav/ <-- html flavour
| |- content_type
| |- head
| |- foot
| |- story
| |- ...
|
|- work/ <-- work category of entries
| |- html.flav/ <-- html flavour for the work category
| |- ...
|
|- home/ <-- home category of entries
In this way your entries are intermixed with your flavour directories.
Instead of storing flavour templates in separate flavour directories in either your datadir or your flavourdir, you can store the templates alongside your entries.
 It’s supported since this is how Pyblosxom used to work.
The template files for a given flavour all have to have the flavour name as the extension of the file. For example, if you were using an “html” flavour, the flavour itself would be composed of the following files:
If you want to create an “atom” flavour, you would have the following files:
Warning
If you intermix flavour templates with entries, make sure you don’t have flavours that have the same name as the extension of your blog entries.
For example, if .txt is the extension for entries in your blog, don’t create a txt flavour!
Pyblosxom comes with the following flavours:
These flavours are included with Pyblosxom and they will work out of the box with no modifications and no configuration changes.
When you run pyblosxom-cmd create <blog-dir>, these get copied into the flavourdir.
Play with them! Modify them! Extend them!
Pyblosxom allows you to override templates and flavours on a category-by-category basis.
For example, Joe has a category devoted to his work on plants which he wants branded differently than the rest of his blog. Joe uses the category work for all his plant work and has a different flavour for this category of his blog.
Joe’s blog directory looks like this:
/home/joe/blog/
|- entries/ <-- datadir
| |- work/ <-- work category of entries
| |- home/ <-- home category of entries
|
|- flavours/
|- html.flav/ <-- html flavour
| |- content_type
| |- head
| |- foot
| |- story
| |- ...
|
|- work/
|- html.flav/ <-- html flavour for the work category
|- ...
There is a work directory in his flavours directory that parallels the work directory in his entries directory. In Joe’s blog, the work category has a different html flavour than the root and home categories.
You can override individual templates, too.
For example, if you had a math category and wanted the story template to look different, you could set up your blog like this:
blog/
|- entries/
| |- math/ <-- math category in datadir
|
|- flavours/
|- html.flav/
| |- content_type
| |- head
| |- date_head
| |- story
| |- date_foot
| |- foot
|
|- math/ <-- math category in flavourdir
|- html.flav/
|- story
If the request is for an entry in the math category, then the story file will be taken from the flavours/math/html.flav/ directory and the rest of the templates will be taken from flavours/html.flav/.
There is a flavour registry on the Pyblosxom website. You can find flavours here that have been created by other people and submit flavours that you’ve created and want to share.
Additionally, you can use flavours from Blosxom and themes from WordPress after spending some time converting them.
The order of overiding works like this:
This allows you to easily override specific templates in your blog (like the header or footer) depending on what category the user is looking at.
This is the list of variables that are available to your templates. Templates contain variables that are expanded when the template is rendered. Plugins may add additional variables—refer to plugin documentation for a list of which variables they add and in which templates they’re available.
To use a variable in a template, prefix the variable name with a $. For example, this would expand to the blog’s title as an h2:

$title

To reduce ambiguity, use parenthesized variables.:

$(title)

You can also use variables that expand into functions which are evaluated:

$(escape(title))

If you want a $ in your template that shouldn’t signify variable expansion, then you need to escape it with a \:

This blog is all about \$!

renders as:
This blog is all about $!
To get a complete list of what variables are available in your blog, use the debug renderer by changing the value of the renderer property in your config.py file to debug like this:
py["renderer"] = "debug"
That will tell you all kinds of stuff about the data structures involved in the request. Don’t forget to change it back when you’re done!
There are two filters allowing for escaped and urlencoded values:
Plugins can add additional filters.
Note
Pyblosxom versions 1.3 and 1.4 escaped and urlencoded variables that ended with _escaped and _urlencoded.
Deprecated in Pyblosxom 1.5.
Anything in your config.py file is a variable available to all of your templates. For example, these standard properties in your config.py file are available:
Additionally, any other properties you set in config.py are available in your templates. If you wanted to create a blog_images variable holding the base url of the directory with all your images in it:
py["blog_images"] = "http://example.com/~joe/images/"
to your config.py file and it would be available in all your templates.
These template variables are available to all templates as well. They are calculated based on the request.
The root datadir of this page?
Example: /home/subtle/blosxom/weblogs/tools/pyblosxom
The PATH_INFO to this page.
Example: pyblosxom/weblogs/tools/pyblosxom
The flavour that’s being used to render this page.
Example: html
The date of the most recent entry that is going to be rendered.
Example: Tue, 15 Nov 2005
The date of the most recent entry that is going to be rendered in w3cdate format.
Example: 2005-11-13T17:50:02Z
The date of the most recent entry that is going to show in RFC 822 format.
Example: Sun, 13 Nov 2005 17:50 GMT
The four-digit year if the request indicated a year.
Example: 2002
The month name if the request indicated a month.
Example: Sep
The day of the month if the request indicated a day of the month.
Example: 15
The entry the user requested to see if the request indicated a specific entry.
Example: weblogs/tools/pyblosxom
The version number and release date of the pyblosxom version you’re using.
Example: 1.2 3/25/2005
date_head and date_foot templates have these additional variables:
The date string of this day.
Example: Sun, 23 May 2004
These template variables are only available in your story template.
The title of the entry.
Example: First Post!
The absolute path of the file that the entry is stored in.
Example: /home/subtle/blosxom/weblogs/tools/pyblosxom/firstpost.txt
The filename and extension of the file that the entry is stored in.
Example: firstpost.txt
The filename with no extension of the file that the entry is stored in.
Example: firstpost
The category/path of the entry (from the perspective of the url).
Example: weblogs/tools/pyblosxom
The text of the entry.
Example:
This is my first post!

The trackback id of the entry.
Example: _firstpost
The category/path of the entry.
Example: weblogs/tools/pyblosxom
The four-digit year of the mtime of this entry.
Example: 2004
The month abbreviation of the mtime of this entry.
Example: Jan
The zero-padded month number of the mtime of this entry.
Example: 01
The 24-hour hour and minute of the mtime of this entry.
Example: 16:40
The date string of the mtime of this entry.
Example: Sun, 23 May 2004
The date in w3cdate format of the mtime of this entry.
Example: 2005-11-13T17:50:02Z
The date in RFC 822 format of the mtime of this entry.
Example: Sun, 13 Nov 2005 17:50 GMT
The date in YYYYMMDDHHMMSS format of the mtime of this entry.
Example:<PHONE_NUMBER>4000
The time tuple (year, month, month-day, hour, minute, second, week-day, year-day, isdst) of the mtime of this entry.
Example: (2004, 5, 23, 16, 40, 0, 6, 144, 1)
The mtime of this entry measured in seconds since the epoch.
Example:<PHONE_NUMBER>.0
The day of the week of the mtime of this entry.
Example: Sunday
The day of the month of the mtime of this entry.
Example: 23
Also, any variables created by plugins that are entry-centric and any variables that come from metadata in the entry are available. See those sections in this document for more details.
Many plugins will create additional variables that are available in templates. Refer to the documentation of the plugins that you have installed to see what variables are available and what they do.
You can add metadata to your entries on an individual basis and this metadata is available to your story templates.
For example, if I had a blog entry like this:
First Post!
#mood happy
#music The Doors - Break on Through to the Other Side

This is the first post to my new Pyblosxom blog. I've
also got two metadata items in it which will be available
as variables!

You’ll have two variables $mood and $music that will also be available in your story templates.
The flavour for a given page is specified in the extension of the file being requested. For example:
Additionally, you can specify the flavour by adding a flav variable in the query-string. Examples:
You can change the default flavour from html to some other flavour in your config.py file with the default_flavour property:
py["default_flavour"] = "joy"
Doing this will set the default flavour to use when the URI the user has used doesn’t specify which flavour to use.
This url doesn’t specify the flavour to use, so it will be rendered with the default flavour:
http://example.com/cgi-bin/pyblosxom.cgi/2005/03
This url specifies the flavour, so it will be rendered with that flavour:
http://example.com/cgi-bin/pyblosxom.cgi/2005/03/?flav=html
We know that you can specify the default flavour to use in the config.py file with the default_flavour property. We know that the user can specify which flavour to use by the file extension of the URI. We also know that the user can specify which flavour to use by using the flav variable in the query string.
The order in which we figure out which flavour to use is this:
For examples of templates and flavours, see the included flavours that come with your Pyblosxom installation.


3. File Uploads¶
Uploading files to the server, handling and linking them
3.1. Description¶
File Upload is handled via Commons FileUpload. We don’t use the Servlet 3 API because, when we had to make a choice, we couldn’t figure out how to set the file size limit via our configuration file.
Yada offers some utility classes to more easily handle files after they have been uploaded:
storing files on disk
resizing images
assigning files to Entity objects
generating download links
managing the pool of uploaded files
3.2. Configuration¶
3.2.1. Maximum file size setting¶
You can set the maximum file size for an upload by means of the maxFileUploadSizeBytes configuration entry:
<config>
<maxFileUploadSizeBytes>3000000</maxFileUploadSizeBytes>
The default is 50MB.
3.2.2. Maximum file size check¶
When the upload limit is reached, a message is logged with a debug severity. You can ensure to see the message with the following logback configuration:
<logger name="org.springframework.web.multipart.commons.YadaCommonsMultipartResolver" level="DEBUG"/>
A Request Attribute is also added to the Request with the name MaxUploadSizeExceededException and the MaxUploadSizeExceededException as a value. All Request Parameters sent with the form are lost.
By default, Tomcat will also drop the connection and no response will be sent to the browser. This will result in a low-level error shown by the browser.
The reason for this is explained here and can only avoided if you configure Tomcat not to drop the connection but keep uploading any excess data (maxSwallowSize="-1"
).
The drawback would be that network bandwidth would be wasted and the user will have to wait until the whole file is uploaded before being told that it was too big.
The best solution would be to only check file size on the browser via javascript. This is not currently implemented in Yada but is something like the following:
function fileTooBig() {
var file = $('input[name=attachment]')[0].files[0];
if (file==null) {
return false;
}
var sizeMega = file.size/1024/1024;
if (sizeMega>3) {
$('#fileTooBig').show();
return true;
}
$('#fileTooBig').hide();
return false;
}
$('input[name=attachment]').on('change', function() {
fileTooBig();
});
$('#theForm').submit(function() {
if (fileTooBig()) {
event.preventDefault();
}
});
Todo
Automate javascript checking of file size
3.3. HTML¶
File upload starts from a "multipart/form-data"
form. This is a standard form with a input element of type "file"
:
<form method="POST" enctype="multipart/form-data" action="doUpload">
File to upload: <input type="file" name="upfile">

<input type="submit" value="Press"> to upload the file!
</form>
3.3.1. Form Fragment /yada/form/fileUpload¶
If you’re using a form backing bean you can include a yada fragment for the input tag. The following example also shows any error:
<form th:action="@{/profile}" th:object="${formProfile}" enctype="multipart/form-data" method="post"
th:classappend="${#fields.hasErrors('*')}? has-error" role="form">

You can display a link to the uploaded file underneath the input field by passing an instance of YadaAttachedFile
to the attachedFile
fragment attribute.
For other usage instructions see the source file for /yada/form/fileUpload
.
3.4. JAVA¶
After submission, the uploaded file will be processed by Commons File Upload and sent to the @Controller as a MultipartFile
object.
You would normally add a field of that type to the form backing bean, but you can also handle it independently from the other form fields if you wish,
by adding it to the @RequestMapping signature.
In the @Controller you have many options.
3.4.1. Just save the file¶
You can just save the file somewhere with YadaWebUtil.saveAttachment():
public String storeFile(MultipartFile submittedFile) {
File destination = new File("someFolder");
YadaWebUtil.saveAttachment(submittedFile, destination):
Then you will have to keep track of the file yourself somehow. The following sections show an alternative and more convenient way of dealing with file uploads.
3.4.2. YadaAttachedFile¶
Usually the uploaded file has to be associated to some Entity in the database: a user avatar or CV, the image of a product, the pdf for a trip. Use YadaAttachedFile to easily handle file attachments:
@Entity
public class Product {
@OneToOne(cascade=CascadeType.REMOVE, orphanRemoval=true)
protected YadaAttachedFile icon;
@OneToOne(cascade=CascadeType.REMOVE, orphanRemoval=true)
protected YadaAttachedFile specSheet;
After doing this you can make use of the functionality of YadaFileManager explained below. Strictly speaking, the above annotation is not needed because YadaAttachedFile instances can exist on their own, having the entity id as a field, but this wouldn’t enforce database integrity.
The YadaAttachedFile class stores some file-related information that you might want to keep:
the original name of the file uploaded by the user
the upload time
localized title and description
the folder where the file is stored
the name of three versions of the file: the original one and the ones scaled for desktop and mobile
the sort order relative to files of the same “group”
the Entity to which the file is attached
a “published” flag
a locale if the file has to be made available only to some specific locale. This could be useful for pdf files in different languages
3.4.3. YadaFileManager¶
<IP_ADDRESS>. Introduction¶
The YadaFileManager @Component is the single entry to all operations on uploaded files.
Every time a file is uploaded, it is stored in a folder named “uploads” in the <basePath> configured directory. This folder is created automatically if the tomcat process has enough permissions, otherwise you have to create it manually.
<IP_ADDRESS>. Saving the file¶
Every file is stored using the original file name. To prevent name duplicates a number is automatically appended at the end.
public String updateProfile(MultipartFile thumbnailImage) {
File managedFile = yadaFileManager.uploadFile(thumbnailImage);
The File can then be attached to an Entity:
yadaFileManager.attachNew(user.getId(), managedFile, "userData", "icon");
When the attach method is called, the original uploaded file is copied from the “uploads” folder into the target folder. The new file will have the new prefix specified and the YadaAttachedFile id at the end of the name. The original file is by default deleted from the “uploads” folder unless a specific configuration is set to false:
<yadaFileManager>
<deleteUploads>false</deleteUploads>
</yadaFileManager>
Not deleting uploaded files allows the implementation of a filesystem-like feature where single files could be reused many times.
Todo
implement filesystem feature
The association between the owning Entity and the new YadaAttachedFile instance is not created automatically by yadaFileManager.attachNew() and you have to do it explicitly:
YadaAttachedFile newIcon = yadaFileManager.attachNew(user.getId(), managedFile, "userData", "icon");
user.setIcon(newIcon);
userRepository.save(user);
In case you’re replacing a previous attachment, you only need to pass the previous YadaAttachedFile: the old files will be deleted and replaced with the new ones. Non database operation is needed in this case.
YadaAttachedFile previousIcon = user.getIcon();
YadaAttachedFile iconAttachedFile = yadaFileManager.attachReplace(previousIcon, managedFile, "icon", "jpg", null, null);
Todo
test that the above code works
<IP_ADDRESS>. Image variants¶
If the uploaded file is an image, it can be resized for desktop and mobile as needed by specifying the alternative dimensions:
yadaFileManager.attach(user.getId(), managedFile, "userData", "icon", "jpg", 1280, 768);
In the above example the image is converted to jpg and two additional versions are saved on disk.
The conversion is performed with the command line tool configured in config/shell/resize
(usually imagemagick).
Todo
link to the configuration section
<IP_ADDRESS>. File URL¶
In order to show images and allow file download, you need to add the relevant URL to the page.
This is done by the methods YadaFileManager.getFileUrl()
, YadaFileManager.getDesktopImageUrl()
, YadaFileManager.getMobileImageUrl()
that can
either be used in the @Controller or directly in the HTML:

Download manual
If you call getMobileImageUrl()
and a mobile image is not present, it will fall back to getDesktopImageUrl()
which in turn
falls back to getFileUrl()
.
<IP_ADDRESS>. Delete Files¶
Files can be removed from the filesystem with YadaFileManager.deleteFileAttachment()
. All database objects must then be deleted manually.
YadaAttachedFile icon = user.getIcon();
yadaFileManager.deleteFileAttachment(icon);
yadaAttachedFileRepository.delete(icon);
user.setIcon(null);
userRepository.save(user);
Todo
test that the above code works


wework
Businessmodel of WeWork
Customer Segments
WeWork provides co-working facilities, and various business services to a range of customers. The Company rents office space and hot-desk space to two principal customer segments:
- Individuals, comprising freelancers, independent professionals, and solo entrepreneurs; and
- Enterprises, comprising small and medium-sized businesses, tech start-ups, as well as larger enterprises. WeWork provides a dedicated service to larger enterprises, providing a range of office solutions – including private and custom offices, satellite offices, and conference rooms - to multinational corporations and their remote workers. The Company’s enterprise customers include high-profile companies, particularly tech businesses, such as Microsoft, Pinterest, BuzzFeed, IBM, Dell, KPMG, and Spotify.
WeWork’s principal market is its native US, where it serves customers across a network of major cities, including New York, Los Angeles, Detroit, Chicago, San Francisco, Portland, and Miami. The Company additionally serves customers in the UK, Australia, Canada, China, Germany, France, India, Mexico, Israel, Hong Kong, the Netherlands, and South Korea.
WeWork has also recently launched a WeLive unit which provides flexible stay co-living rentals to general consumers seeking flexible and affordable living solutions.
Value Propositions
WeWork provides value to its customers in the following ways:
- Its competitive and flexible pricing model, with the Company providing workspace and larger office spaces to customers at competitive monthly rental prices, offering flexible rental contracts that can be renewed;
- The quality of its facilities and provision of amenities, with the Company operating high-quality, modern office locations, with a range of supplemental amenities such as free internet, free refreshments, office equipment, and private phone booths;
- Its international reach, with the Company operating an extensive international network of office locations across North America, Europe, and Asia Pacific, including in the UK, Australia, China, India, the US, and Mexico;
- Its community atmosphere, with the Company’s office locations fostering a community atmosphere and organising networking events, that allow customers to interact with one another, provide feedback, and share ideas; and
- Its service partnerships, with the Company providing various discounted services to its customers through its network of partners, including lower costs on healthcare and HR solutions, payment processing services, and shipping and distribution solutions. ### Channels
WeWork operates a website at www.wework.com, through which it provides information on its services, locations, and amenities. Potential customers are able to schedule site visits and make enquiries directly through the WeWork website. The Company also operates an online customer portal, which enables customers to manage their accounts and make payments online. Similar functionality is available through the Company’s mobile app.
WeWork operates an in-house sales and service team which sells services and provides support directly to customers. It also operates a dedicated Corporate Sales Department, which works closely with its larger enterprise customers, such as Microsoft, IBM, and Dell. Additionally, the Company operates team of on-site support and service personnel that are able to provide assistance to customers in-person and in real time.
In addition to its WeWork office locations, the Company also operates WeLive co-living developments in New York and Washington DC.
Customer Relationships
WeWork provides services on a largely self-service basis. This includes the Company’s website, which allows potential customers to arrange office viewings, as well as its dedicated online customer portal, which allows customers to make payments, manage account details, and access other services without interacting directly with members of the Company’s sales and marketing teams.
WeWork provides services directly to its customers through its sales teams, notably its dedicated corporate sales personnel, which deal with the Company’s larger enterprise clients. This includes specialist account management teams that are available to provide a personal service to WeWork’s corporate customers. WeWork also provides personalised service to customers through its on-site staff, who are available to customers to provide tailored assistance with enquiries and complaints.
Alternatively, customers can contact WeWork’s support teams over the phone or via post, and can leave messages with the Company via an online contact form. Customers are also able to interact with the Company directly through its social media accounts with Facebook, Twitter, LinkedIn, and Instagram.
Key Activities
WeWork operates as a real estate developer and property manager. It principally provides various consulting, office rental, and other business services to a range of customers, primarily freelance workers, small businesses, start-ups, and large enterprises.
The Company offers shared office space in return for a monthly fee. Its facilities come with a range of amenities included, such as high speed internet, private phone service, mail handling, free refreshments, and other amenities.
The Company has a range of office locations across the US, including in all major cities, such as New York, Los Angeles, San Francisco, and Chicago. serves customers worldwide. Additionally, WeWork operates a WeLive business that provides co-living solutions to customers in the US.
Key Partners
WeWork works in conjunction with a range of companies and business in order to provide its customers with the best possible services and amenities. These partners can be categorised broadly as:
- Broker and Referral Partners, comprising a range of websites and companies that assist in the marketing of the Company’s services, operating primarily as affiliates that earn commissions when introducing new clients to the Company;
- Real Estate Partners, principally comprising property developers with which the Company collaborates on the development of office locations;
- Supplier and Service Partners, comprising suppliers of equipment, tools, technologies, and resources across the Company’s international network of offices, and providers of various services that support the Company’s operations and activities; and
- Strategic and Alliance Partners, comprising a range of companies and organisations, with which the Company shares resources and collaborates on joint projects. WeWork has a number of service partnerships. This includes a banking partnerships with Chase Bank, a distribution and delivery partnerships with UPS, a human resources partnership with TriNet, and accounting partnership with inDinero.
Key Resources
WeWork’s key resources are its network of office locations and related equipment, its IT and communications infrastructure, its partnerships and service providers, and its personnel. The Company’s most important resource is its portfolio of owned and leased properties, at which it rents space to customers.
This includes office locations in more than 30 cities across North America, Europe, and Asia Pacific – including in London, Seoul, Amsterdam, Hong Kong, Berlin, Montreal, and Shanghai – as well as WeLive co-living spaces in New York and Washington DC.
Cost Structure
WeWork incurs costs in relation to the development of its property portfolio – including the lease and acquisition of properties and the development of new buildings, the maintenance of its IT and communications infrastructure, the management of its partnerships, the payment of professional services fees, and the retention of its personnel.
With WeWork’s major costs relating to property rental and lease fees and the payment of salaries and benefits to its workforce, it principally has fixed costs.
Revenue Streams
WeWork primarily generates revenue through the rental of office space. The Company’s business model is to rent office space at a cheap rate, via long-term lease contracts, which it then re-rents to small businesses, start-ups, and individuals at higher rates under a flexible renting model.
WeWork’s rates vary considerably across its various properties, with We Membership plans starting at $45 per month, Hot Desk rental starting at $220 per month, Dedicated Desk rental starting at $350 per month, and Private Office rental starting at $450 per month. Additionally, the Company derives revenue from its WeLive co-living unit, which operates under a similar model.
WeWork remains a privately-owned company and as such does not publish its financial performance figures. Reports, however, suggest that the Company initially expected to bring in $620 million in revenue for 2016, but revised this number down to $532 million.


Hi! I'm LankyBox01.
I love to code.
I can also make you a website in HTML if you want it :P
Here's a link!
(you can modify this page to put any information you want on it! copy this page and modify this "main" section to make new pages. just credit voxalice)


Ungrouped Students
| Name | |
|---|---|
| Chase Hamrick |<EMAIL_ADDRESS>|
| John Schmidt |<EMAIL_ADDRESS>|
| Katherine Delgado |<EMAIL_ADDRESS>|
| Quang Ty |<EMAIL_ADDRESS>|
| Sheng Li |<EMAIL_ADDRESS>|
| Best 6th person |<EMAIL_ADDRESS>|
Groups
| Name | |
|---|---|
| Random person |<EMAIL_ADDRESS>|


Your browser does not support IFrames. You will need to switch to a different browser to complete this problem.


Janelle was born in Prince Williams Virgina. She moved to North Carolina in 2006 and is now living in Wake Forest. In her free time she enjoys spending time with her friends and family and doing self reflection.
Janelle was baptized on June 1st, 2014. She has enjoyed being able to work with others in the ministry by pioneering for the past four years. She descibes it as a strong learning experience. Currently Janelle is doing duel enrollment with James Madison High School and Wake Tech Communiuty College for HVAC. Janelle plans to use her HVAC certification to help her grow in the workforce.
In the future Janelle would like to travel and serve in the ministry full time. She plans to put God first in every decision she makes.Janelle plans to make him the main focus in her life.