Typed docs: some spelling and language fixes (#27919)

This commit is contained in:
Enno 2019-10-09 19:43:03 +02:00 committed by Patrik Nordwall
parent 25ff48cca1
commit 3fc148f6f2
12 changed files with 49 additions and 41 deletions

View file

@ -87,7 +87,7 @@ public class InteractionPatternsTest extends JUnitSuite {
private static Behavior<Request> onRequest(Request request) { private static Behavior<Request> onRequest(Request request) {
// ... process request ... // ... process request ...
request.replyTo.tell(new Response("Here's the cookies for " + request.query)); request.replyTo.tell(new Response("Here are the cookies for " + request.query));
return Behaviors.same(); return Behaviors.same();
} }
// #request-response-respond // #request-response-respond

View file

@ -81,7 +81,10 @@ public class RouterTest {
} }
static Behavior<Void> showGroupRouting() { static Behavior<Void> showGroupRouting() {
// #group
ServiceKey<Worker.Command> serviceKey = ServiceKey.create(Worker.Command.class, "log-worker"); ServiceKey<Worker.Command> serviceKey = ServiceKey.create(Worker.Command.class, "log-worker");
// #group
return Behaviors.setup( return Behaviors.setup(
context -> { context -> {
// #group // #group

View file

@ -70,7 +70,7 @@ class InteractionPatternsSpec extends ScalaTestWithActorTestKit with WordSpecLik
Behaviors.receiveMessage[Request] { Behaviors.receiveMessage[Request] {
case Request(query, replyTo) => case Request(query, replyTo) =>
// ... process query ... // ... process query ...
replyTo ! Response(s"Here's the cookies for [$query]!") replyTo ! Response(s"Here are the cookies for [$query]!")
Behaviors.same Behaviors.same
} }
// #request-response-respond // #request-response-respond

View file

@ -36,8 +36,10 @@ object RouterSpec {
} }
// #pool // #pool
// #group
val serviceKey = ServiceKey[Worker.Command]("log-worker") val serviceKey = ServiceKey[Worker.Command]("log-worker")
// #group
} }
class RouterSpec extends ScalaTestWithActorTestKit("akka.loglevel=warning") with WordSpecLike with LogCapturing { class RouterSpec extends ScalaTestWithActorTestKit("akka.loglevel=warning") with WordSpecLike with LogCapturing {

View file

@ -527,7 +527,7 @@ final case class Dropped(message: Any, reason: String, sender: ActorRef, recipie
object Dropped { object Dropped {
/** /**
* Convenience for creating `Cropped` without `sender`. * Convenience for creating `Dropped` without a `sender`.
*/ */
def apply(message: Any, reason: String, recipient: ActorRef): Dropped = def apply(message: Any, reason: String, recipient: ActorRef): Dropped =
Dropped(message, reason, ActorRef.noSender, recipient) Dropped(message, reason, ActorRef.noSender, recipient)

View file

@ -96,7 +96,7 @@ the `PingManager` understands.
The `Receptionist` also works in a cluster, an actor registered to the receptionist will appear in the receptionist The `Receptionist` also works in a cluster, an actor registered to the receptionist will appear in the receptionist
of the other nodes of the cluster. of the other nodes of the cluster.
The state for the receptionist is propagated via @ref:[distributed data](../distributed-data.md) which means that each node The state for the receptionist is propagated via @ref:[distributed data](distributed-data.md) which means that each node
will eventually reach the same set of actors per `ServiceKey`. will eventually reach the same set of actors per `ServiceKey`.
`Subscription`s and `Find` queries to a clustered receptionist will keep track of cluster reachability and only list `Subscription`s and `Find` queries to a clustered receptionist will keep track of cluster reachability and only list

View file

@ -80,7 +80,7 @@ Java
: @@snip [IntroSpec.scala](/akka-actor-typed-tests/src/test/java/jdocs/akka/typed/IntroTest.java) { #hello-world } : @@snip [IntroSpec.scala](/akka-actor-typed-tests/src/test/java/jdocs/akka/typed/IntroTest.java) { #hello-world }
For very simple applications the guardian may contain the actual application logic and handle messages. As soon as the application For very simple applications the guardian may contain the actual application logic and handle messages. As soon as the application
handles more than one concern the the guardian should instead just bootstrap the application, spawn the various subsystems as handles more than one concern the guardian should instead just bootstrap the application, spawn the various subsystems as
children and monitor their lifecycles. children and monitor their lifecycles.
When the guardian actor stops this will stop the `ActorSystem`. When the guardian actor stops this will stop the `ActorSystem`.
@ -159,14 +159,14 @@ A way to find running actors is described in @ref:[Actor discovery](actor-discov
An actor can stop itself by returning `Behaviors.stopped` as the next behavior. An actor can stop itself by returning `Behaviors.stopped` as the next behavior.
Child actors can be forced to be stopped after it finishes processing its current message by using the A child actor can be forced to stop after it finishes processing its current message by using the
`stop` method of the `ActorContext` from the parent actor. Only child actors can be stopped in that way. `stop` method of the `ActorContext` from the parent actor. Only child actors can be stopped in that way.
The child actors will be stopped as part of the shutdown procedure of the parent. All child actors will be stopped when their parent is stopped.
The `PostStop` signal that results from stopping an actor can be used for cleaning up resources. Note that When an actor is stopped, it receives the `PostStop` signal that can be used for cleaning up resources.
a behavior that handles such `PostStop` signal can optionally be defined as a parameter to `Behaviors.stopped` A callback function may be specified as parameter to `Behaviors.stopped` to handle the `PostStop` signal
if different actions is needed when the actor gracefully stops itself from when it is stopped abruptly. when stopping gracefully. This allows to apply different actions from when it is stopped abruptly.
Here is an illustrating example: Here is an illustrating example:

View file

@ -33,8 +33,8 @@ gives excellent performance in most cases.
## Internal dispatcher ## Internal dispatcher
To protect the internal Actors that is spawned by the various Akka modules, a separate internal dispatcher is used by default. To protect the internal Actors that are spawned by the various Akka modules, a separate internal dispatcher is used by default.
The internal dispatcher can be tuned in a fine grained way with the setting `akka.actor.internal-dispatcher`, it can also The internal dispatcher can be tuned in a fine-grained way with the setting `akka.actor.internal-dispatcher`, it can also
be replaced by another dispatcher by making `akka.actor.internal-dispatcher` an @ref[alias](#dispatcher-aliases). be replaced by another dispatcher by making `akka.actor.internal-dispatcher` an @ref[alias](#dispatcher-aliases).
<a id="dispatcher-lookup"></a> <a id="dispatcher-lookup"></a>
@ -68,7 +68,7 @@ Java
* `DispatcherSelector.blocking` can be used to execute actors that block e.g. a legacy database API that does not support @scala[`Future`]@java[`CompletionStage`]s * `DispatcherSelector.blocking` can be used to execute actors that block e.g. a legacy database API that does not support @scala[`Future`]@java[`CompletionStage`]s
* `DispatcherSelector.sameAsParent` to use the same dispatcher as the parent actor * `DispatcherSelector.sameAsParent` to use the same dispatcher as the parent actor
The final example shows how to load a custom dispatcher from configuration and relies on this being in your application.conf: The final example shows how to load a custom dispatcher from configuration and relies on this being in your `application.conf`:
<!-- Same between Java and Scala --> <!-- Same between Java and Scala -->
@@snip [DispatcherDocSpec.scala](/akka-actor-typed-tests/src/test/scala/docs/akka/typed/DispatchersDocSpec.scala) { #config } @@snip [DispatcherDocSpec.scala](/akka-actor-typed-tests/src/test/scala/docs/akka/typed/DispatchersDocSpec.scala) { #config }
@ -80,21 +80,21 @@ There are 2 different types of message dispatchers:
* **Dispatcher** * **Dispatcher**
This is an event-based dispatcher that binds a set of Actors to a thread This is an event-based dispatcher that binds a set of Actors to a thread
pool. It is the default dispatcher used if one is not specified. pool. The default dispatcher is used if no other is specified.
* Sharability: Unlimited * Shareability: Unlimited
* Mailboxes: Any, creates one per Actor * Mailboxes: Any, creates one per Actor
* Use cases: Default dispatcher, Bulkheading * Use cases: Default dispatcher, Bulkheading
* Driven by: `java.util.concurrent.ExecutorService`. * Driven by: `java.util.concurrent.ExecutorService`.
Specify using "executor" using "fork-join-executor", "thread-pool-executor" or the FQCN of Specify using "executor" using "fork-join-executor", "thread-pool-executor" or the fully-qualified
an `akka.dispatcher.ExecutorServiceConfigurator`. class name of an `akka.dispatcher.ExecutorServiceConfigurator` implementation.
* **PinnedDispatcher** * **PinnedDispatcher**
This dispatcher dedicates a unique thread for each actor using it; i.e. This dispatcher dedicates a unique thread for each actor using it; i.e.
each actor will have its own thread pool with only one thread in the pool. each actor will have its own thread pool with only one thread in the pool.
* Sharability: None * Shareability: None
* Mailboxes: Any, creates one per Actor * Mailboxes: Any, creates one per Actor
* Use cases: Bulkheading * Use cases: Bulkheading
* Driven by: Any `akka.dispatch.ThreadPoolExecutorConfigurator`. * Driven by: Any `akka.dispatch.ThreadPoolExecutorConfigurator`.
@ -271,7 +271,7 @@ unless you @ref:[set up a separate dispatcher for the actor](../dispatchers.md#s
One of the most efficient methods of isolating the blocking behavior such that it does not impact the rest of the system One of the most efficient methods of isolating the blocking behavior such that it does not impact the rest of the system
is to prepare and use a dedicated dispatcher for all those blocking operations. is to prepare and use a dedicated dispatcher for all those blocking operations.
This technique is often referred to as as "bulk-heading" or simply "isolating blocking". This technique is often referred to as "bulk-heading" or simply "isolating blocking".
In `application.conf`, the dispatcher dedicated to blocking behavior should In `application.conf`, the dispatcher dedicated to blocking behavior should
be configured as follows: be configured as follows:
@ -280,8 +280,8 @@ be configured as follows:
@@snip [BlockingDispatcherSample.scala](/akka-docs/src/test/scala/docs/actor/typed/BlockingDispatcherSample.scala) { #my-blocking-dispatcher-config } @@snip [BlockingDispatcherSample.scala](/akka-docs/src/test/scala/docs/actor/typed/BlockingDispatcherSample.scala) { #my-blocking-dispatcher-config }
A `thread-pool-executor` based dispatcher allows us to set a limit on the number of threads it will host, A `thread-pool-executor` based dispatcher allows us to limit the number of threads it will host,
and this way we gain tight control over how at-most-how-many blocked threads will be in the system. and this way we gain tight control over the maximum number of blocked threads the system may use.
The exact size should be fine tuned depending on the workload you're expecting to run on this dispatcher. The exact size should be fine tuned depending on the workload you're expecting to run on this dispatcher.
@ -305,7 +305,7 @@ When blocking operations are run on the `my-blocking-dispatcher`,
it uses the threads (up to the configured limit) to handle these operations. it uses the threads (up to the configured limit) to handle these operations.
The sleeping in this case is nicely isolated to just this dispatcher, and the default one remains unaffected, The sleeping in this case is nicely isolated to just this dispatcher, and the default one remains unaffected,
allowing the rest of the application to proceed as if nothing bad was happening. After allowing the rest of the application to proceed as if nothing bad was happening. After
a certain period idleness, threads started by this dispatcher will be shut down. a certain period of idleness, threads started by this dispatcher will be shut down.
In this case, the throughput of other actors was not impacted - In this case, the throughput of other actors was not impacted -
they were still served on the default dispatcher. they were still served on the default dispatcher.

View file

@ -61,7 +61,7 @@ Java
## Request-Response ## Request-Response
Many interactions between actors requires one or more response message being sent back from the receiving actor. A response message can be a result of a query, some form of acknowledgment that the message was received and processed or events that the request subscribed to. Many interactions between actors require one or more response message being sent back from the receiving actor. A response message can be a result of a query, some form of acknowledgment that the message was received and processed or events that the request subscribed to.
In Akka the recipient of responses has to be encoded as a field in the message itself, which the recipient can then use to send (tell) a response back. In Akka the recipient of responses has to be encoded as a field in the message itself, which the recipient can then use to send (tell) a response back.
@ -106,7 +106,7 @@ Java
* It is hard to detect that a message request was not delivered or processed (see @ref:[ask](#request-response-with-ask-between-two-actors)) * It is hard to detect that a message request was not delivered or processed (see @ref:[ask](#request-response-with-ask-between-two-actors))
* Unless the protocol already includes a way to provide context, for example a request id that is also sent in the * Unless the protocol already includes a way to provide context, for example a request id that is also sent in the
response, it is not possible to tie an interaction to some specific context without introducing a new, response, it is not possible to tie an interaction to some specific context without introducing a new,
separate, actor (see ask or per session child actor) separate, actor (see @ref:[ask](#request-response-with-ask-between-two-actors) or @ref:[per session child actor](#per-session-child-actor))
## Adapted Response ## Adapted Response
@ -136,9 +136,9 @@ their registration order, i.e. the last registered first.
A message adapter (and the returned `ActorRef`) has the same lifecycle as A message adapter (and the returned `ActorRef`) has the same lifecycle as
the receiving actor. It's recommended to register the adapters in a top level the receiving actor. It's recommended to register the adapters in a top level
`Behaviors.setup` or constructor of `AbstractBehavior` but it's possible to `Behaviors.setup` or constructor of `AbstractBehavior` but it's possible to
register them later also if needed. register them later if needed.
The adapter function is running in the receiving actor and can safely access state of it, but if it throws an exception the actor is stopped. The adapter function is running in the receiving actor and can safely access its state, but if it throws an exception the actor is stopped.
**Useful when:** **Useful when:**
@ -173,7 +173,7 @@ Java
: @@snip [InteractionPatternsTest.java](/akka-actor-typed-tests/src/test/java/jdocs/akka/typed/InteractionPatternsTest.java) { #actor-ask } : @@snip [InteractionPatternsTest.java](/akka-actor-typed-tests/src/test/java/jdocs/akka/typed/InteractionPatternsTest.java) { #actor-ask }
The response adapting function is running in the receiving actor and can safely access state of it, but if it throws an exception the actor is stopped. The response adapting function is running in the receiving actor and can safely access its state, but if it throws an exception the actor is stopped.
**Useful when:** **Useful when:**
@ -187,12 +187,12 @@ The response adapting function is running in the receiving actor and can safely
* There can only be a single response to one `ask` (see @ref:[per session child Actor](#per-session-child-actor)) * There can only be a single response to one `ask` (see @ref:[per session child Actor](#per-session-child-actor))
* When `ask` times out, the receiving actor does not know and may still process it to completion, or even start processing it after the fact * When `ask` times out, the receiving actor does not know and may still process it to completion, or even start processing it after the fact
* Finding a good value for the timeout, especially when `ask` is triggers chained `ask`s in the receiving actor. You want a short timeout to be responsive and answer back to the requester, but at the same time you do not want to have many false positives * Finding a good value for the timeout, especially when `ask` triggers chained `ask`s in the receiving actor. You want a short timeout to be responsive and answer back to the requester, but at the same time you do not want to have many false positives
<a id="outside-ask"></a> <a id="outside-ask"></a>
## Request-Response with ask from outside an Actor ## Request-Response with ask from outside an Actor
Some times you need to interact with actors from outside of the actor system, this can be done with fire-and-forget as described above or through another version of `ask` that returns a @scala[`Future[Response]`]@java[`CompletionStage<Response>`] that is either completed with a successful response or failed with a `TimeoutException` if there was no response within the specified timeout. Sometimes you need to interact with actors from the outside of the actor system, this can be done with fire-and-forget as described above or through another version of `ask` that returns a @scala[`Future[Response]`]@java[`CompletionStage<Response>`] that is either completed with a successful response or failed with a `TimeoutException` if there was no response within the specified timeout.
To do this we use @scala[`ActorRef.ask` (or the symbolic `ActorRef.?`) implicitly provided by `akka.actor.typed.scaladsl.AskPattern`]@java[`akka.actor.typed.javadsl.AskPattern.ask`] to send a message to an actor and get a @scala[`Future[Response]`]@java[`CompletionState[Response]`] back. To do this we use @scala[`ActorRef.ask` (or the symbolic `ActorRef.?`) implicitly provided by `akka.actor.typed.scaladsl.AskPattern`]@java[`akka.actor.typed.javadsl.AskPattern.ask`] to send a message to an actor and get a @scala[`Future[Response]`]@java[`CompletionState[Response]`] back.
@ -255,7 +255,7 @@ Therefore it is better to map the result to a message and perform further proces
In some cases a complete response to a request can only be created and sent back after collecting multiple answers from other actors. For these kinds of interaction it can be good to delegate the work to a per "session" child actor. The child could also contain arbitrary logic to implement retrying, failing on timeout, tail chopping, progress inspection etc. In some cases a complete response to a request can only be created and sent back after collecting multiple answers from other actors. For these kinds of interaction it can be good to delegate the work to a per "session" child actor. The child could also contain arbitrary logic to implement retrying, failing on timeout, tail chopping, progress inspection etc.
Note that this in fact essentially how `ask` is implemented, if all you need is a single response with a timeout it is better to use `ask`. Note that this is essentially how `ask` is implemented, if all you need is a single response with a timeout it is better to use `ask`.
The child is created with the context it needs to do the work, including an `ActorRef` that it can respond to. When the complete result is there the child responds with the result and stops itself. The child is created with the context it needs to do the work, including an `ActorRef` that it can respond to. When the complete result is there the child responds with the result and stops itself.
@ -363,7 +363,7 @@ Java
**Problems:** **Problems:**
* Increased load since more messages are sent and "work" is performed more than once * Increased load since more messages are sent and "work" is performed more than once
* Can't be used when the "work" is not idempotent and must only performed once * Can't be used when the "work" is not idempotent and must only be performed once
* Message protocols with generic types are difficult since the generic types are erased in runtime * Message protocols with generic types are difficult since the generic types are erased in runtime
* Children have life cycles that must be managed to not create a resource leak, it can be easy to miss a scenario where the session actor is not stopped * Children have life cycles that must be managed to not create a resource leak, it can be easy to miss a scenario where the session actor is not stopped
@ -389,11 +389,11 @@ There are a few things worth noting here:
* To get access to the timers you start with `Behaviors.withTimers` that will pass a `TimerScheduler` instance to the function. * To get access to the timers you start with `Behaviors.withTimers` that will pass a `TimerScheduler` instance to the function.
This can be used with any type of `Behavior`, including `receive`, `receiveMessage`, but also `setup` or any other behavior. This can be used with any type of `Behavior`, including `receive`, `receiveMessage`, but also `setup` or any other behavior.
* Each timer has a key and if a new timer with same key is started the previous is cancelled and it's guaranteed that a message from the previous timer is not received, even though it might already be enqueued in the mailbox when the new timer is started. * Each timer has a key and if a new timer with the same key is started, the previous is cancelled and it's guaranteed that a message from the previous timer is not received, even though it might already be enqueued in the mailbox when the new timer is started.
* Both periodic and single message timers are supported. * Both periodic and single message timers are supported.
* The `TimerScheduler` is mutable in itself, because it performs and manages the side effects of registering the scheduled tasks. * The `TimerScheduler` is mutable in itself, because it performs and manages the side effects of registering the scheduled tasks.
* The `TimerScheduler` is bound to the lifecycle of the actor that owns it and it's cancelled automatically when the actor is stopped. * The `TimerScheduler` is bound to the lifecycle of the actor that owns it and it's cancelled automatically when the actor is stopped.
* `Behaviors.withTimers` can also be used inside `Behaviors.supervise` and it will automatically cancel the started timers correctly when the actor is restarted, so that the new incarnation will not receive scheduled messages from previous incarnation. * `Behaviors.withTimers` can also be used inside `Behaviors.supervise` and it will automatically cancel the started timers correctly when the actor is restarted, so that the new incarnation will not receive scheduled messages from a previous incarnation.
### Schedule periodically ### Schedule periodically
@ -438,6 +438,9 @@ which may in worst case cause undesired load on the system. `scheduleWithFixedDe
## Responding to a sharded actor ## Responding to a sharded actor
When @ref:[Akka Cluster](cluster.md) is used to @ref:[shard actors](cluster-sharding.md) you need to
take into account that an actor may move or get passivated.
The normal pattern for expecting a reply is to include an @apidoc[akka.actor.typed.ActorRef] in the message, typically a message adapter. This can be used The normal pattern for expecting a reply is to include an @apidoc[akka.actor.typed.ActorRef] in the message, typically a message adapter. This can be used
for a sharded actor but if @scala[`ctx.self`]@java[`ctx.getSelf()`] is sent and the sharded actor is moved or passivated then the reply for a sharded actor but if @scala[`ctx.self`]@java[`ctx.getSelf()`] is sent and the sharded actor is moved or passivated then the reply
will sent to dead letters. will sent to dead letters.

View file

@ -44,7 +44,7 @@ Java
The group router is created with a `ServiceKey` and uses the receptionist (see @ref:[Receptionist](actor-discovery.md#receptionist)) to discover The group router is created with a `ServiceKey` and uses the receptionist (see @ref:[Receptionist](actor-discovery.md#receptionist)) to discover
available actors for that key and routes messages to one of the currently known registered actors for a key. available actors for that key and routes messages to one of the currently known registered actors for a key.
Since the receptionist is used this means the group router is cluster aware out of the box. The router route Since the receptionist is used this means the group router is cluster-aware out of the box. The router sends
messages to registered actors on any node in the cluster that is reachable. If no reachable actor exists the router messages to registered actors on any node in the cluster that is reachable. If no reachable actor exists the router
will fallback and route messages to actors on nodes marked as unreachable. will fallback and route messages to actors on nodes marked as unreachable.
@ -53,7 +53,7 @@ the group router is started the set of routees it knows about is empty, until it
it stashes incoming messages and forwards them as soon as it gets a listing from the receptionist. it stashes incoming messages and forwards them as soon as it gets a listing from the receptionist.
When the router has received a listing from the receptionist and the set of registered actors is empty the router will When the router has received a listing from the receptionist and the set of registered actors is empty the router will
drop them (published them to the event stream as `akka.actor.Dropped`). drop them (publish them to the event stream as `akka.actor.Dropped`).
Scala Scala
: @@snip [RouterSpec.scala](/akka-actor-typed-tests/src/test/scala/docs/akka/typed/RouterSpec.scala) { #group } : @@snip [RouterSpec.scala](/akka-actor-typed-tests/src/test/scala/docs/akka/typed/RouterSpec.scala) { #group }
@ -96,4 +96,4 @@ it will not give better performance to create more routees than there are thread
Since the router itself is an actor and has a mailbox this means that messages are routed sequentially to the routees Since the router itself is an actor and has a mailbox this means that messages are routed sequentially to the routees
where it can be processed in parallel (depending on the available threads in the dispatcher). where it can be processed in parallel (depending on the available threads in the dispatcher).
In a high throughput use cases the sequential routing could be a bottle neck. Akka Typed does not provide an optimized tool for this. In a high throughput use cases the sequential routing could become a bottle neck. Akka Typed does not provide an optimized tool for this.

View file

@ -21,9 +21,9 @@ be handled using the actor's current behavior.
A typical example when this is useful is if the actor has to load some initial state or initialize A typical example when this is useful is if the actor has to load some initial state or initialize
some resources before it can accept the first real message. Another example is when the actor some resources before it can accept the first real message. Another example is when the actor
is waiting for something to complete before processing next message. is waiting for something to complete before processing the next message.
Let's illustrate these two with an example. It's an actor that is used like a single access point Let's illustrate these two with an example. The `DataAccess` actor below is used like a single access point
to a value stored in a database. When it's started it loads current state from the database, and to a value stored in a database. When it's started it loads current state from the database, and
while waiting for that initial value all incoming messages are stashed. while waiting for that initial value all incoming messages are stashed.

View file

@ -23,9 +23,9 @@ object Paradox {
"extref.github.base_url" -> (GitHub.url(version.value) + "/%s"), // for links to our sources "extref.github.base_url" -> (GitHub.url(version.value) + "/%s"), // for links to our sources
"extref.samples.base_url" -> "https://developer.lightbend.com/start/?group=akka&amp;project=%s", "extref.samples.base_url" -> "https://developer.lightbend.com/start/?group=akka&amp;project=%s",
"extref.ecs.base_url" -> "https://example.lightbend.com/v1/download/%s", "extref.ecs.base_url" -> "https://example.lightbend.com/v1/download/%s",
"scaladoc.akka.base_url" -> "https://doc.akka.io/api/akka/2.5", "scaladoc.akka.base_url" -> "https://doc.akka.io/api/akka/2.6",
"scaladoc.akka.http.base_url" -> "https://doc.akka.io/api/akka-http/current", "scaladoc.akka.http.base_url" -> "https://doc.akka.io/api/akka-http/current",
"javadoc.akka.base_url" -> "https://doc.akka.io/japi/akka/2.5", "javadoc.akka.base_url" -> "https://doc.akka.io/japi/akka/2.6",
"javadoc.akka.http.base_url" -> "https://doc.akka.io/japi/akka-http/current", "javadoc.akka.http.base_url" -> "https://doc.akka.io/japi/akka-http/current",
"scala.version" -> scalaVersion.value, "scala.version" -> scalaVersion.value,
"scala.binary_version" -> scalaBinaryVersion.value, "scala.binary_version" -> scalaBinaryVersion.value,