[id='key-affinity-service_{context}']
= Key affinity service

In a distributed cache, a key is allocated to a list of nodes with an opaque algorithm.
There is no easy way to reverse the computation and generate a key that maps to a particular node.
However, {brandname} can generate a sequence of (pseudo-)random keys, see what their primary owner is, and hand them out to the application when it needs a key mapping to a particular node.

Following code snippet depicts how a reference to this service can be obtained and used.

[source,java]
----
include::code_examples/KeyAffinityService.java[]
----

The service is started at step 2: after this point it uses the supplied _Executor_ to generate and queue keys.
At step 3, we obtain a key from the service, and at step 4 we use it.

[discrete]
== Lifecycle

`KeyAffinityService` extends `Lifecycle`, which allows stopping and (re)starting it:

[source,java]
----
include::code_examples/Lifecycle.java[]
----

The service is instantiated through `KeyAffinityServiceFactory`.
All the factory methods have an `Executor` parameter, that is used for asynchronous key generation (so that it
won't happen in the caller's thread).
It is the user's responsibility to handle the shutdown of this `Executor`.

The `KeyAffinityService`, once started, needs to be explicitly stopped.
This stops the background key generation and releases other held resources.

The only situation in which `KeyAffinityService` stops by itself is when the Cache Manager with which it was registered is shutdown.

[discrete]
== Topology changes

When the cache topology changes, the ownership of the keys generated by the `KeyAffinityService` might change.
The key affinity service keep tracks of these topology changes and doesn't return keys that would currently map to a different node, but it won't do anything about keys generated earlier.

As such, applications should treat `KeyAffinityService` purely as an optimization, and they should not rely on the location of a generated key for correctness.

In particular, applications should not rely on keys generated by `KeyAffinityService` for the same address to always be located together.
Collocation of keys is only provided by the `Grouping` API.
