The errata list is a list of errors and their corrections that were found after the product was released. If the error was corrected in a later version or reprint the date of the correction will be displayed in the column titled "Date Corrected".
The following errata were submitted by our customers and approved as valid errors by the author or editor.
Version |
Location |
Description |
Submitted By |
Date submitted |
Date corrected |
Printed, |
Chapter 4 |
In code for Ask Pattern and Alternatives
find is an upper case class but used incorrectly in lower-case as if it's a method:
AvailabilityCalendarWrapper.find(resourceId)
Note from the Author or Editor: This occurs on page 57 of the printed version.
It should read AvailabilityCalendardWrapper.Find(resourceId).
|
Philippe Derome |
Feb 19, 2017 |
|
Printed, |
Chapter 4 |
There's a reference to Account but that does not exist actually:
Encapsulating State by Using “State” Containers
In the previous example, you can extract some of the logic from Account into a separate, nonactor-based PersonalInformation class.
Note from the Author or Editor: On Page 49:
In the previous example, you can extract some of the logic from Account into a separate, nonactor-based PersonalInformation class.
This should read:
In the previous example, you can extract some of the logic from Person into a separate, nonactor-based PersonalInformation class.
|
Philippe Derome |
Feb 19, 2017 |
|
|
Chapter 4 |
in Alternatives to Ask
there is still several usages of implicit val timeout, which seems completely superfluous; it appears to be left over copy from other examples and having forgotten to take it out.
override def receive: Receive = {
case ProcessData(data, response) =>
val processedData = processData(data)
implicit val timeout = Timeout(5.seconds)
nextStage ! ProcessData(processedData, response)
}
Note from the Author or Editor: Page 61: Alternatives to Ask
In the code section following the text "The following example shows how to do this:"
All of the code `implicit val timeout = Timeout(5.seconds)` sections can be removed here. They are not necessary. There should be two instances to remove. One in the "Stage1" actor and one in the "Stage2" actor.
|
Philippe Derome |
Feb 19, 2017 |
|
Printed, |
Chapter 4 |
In Constructor Dependency Injector
the code could be more complete or self-contained as reader needs to complete the gap:
val peopleActor: ActorRef = ...
val projectsActor: ActorRef = system.actorOf(ProjectsActor.props(peopleActor))
Reader must understand that ProjectsActor is an Object companion having a props method returning a Props type and that there's likely a ProjectsActor.apply method taking a peopleActorRef: ActorRef as parameter to actually instantiate a class object of type ProjectsActor taking an ActorRef as parameter.
Note from the Author or Editor: Replace:
val peopleActor: ActorRef = ...
val projectsActor: ActorRef = system.actorOf(ProjectsActor.props(peopleActor))
With:
val peopleActor: ActorRef = system.actorOf(Props(new PeopleActor()))
val projectsActor: ActorRef = system.actorOf(Props(new ProjectsActor(peopleActor)))
|
Philippe Derome |
Feb 19, 2017 |
|
|
Chapter 4 |
The following statement is a little contentious if left unclarified as it's not clear what the author meant really.
You can think of this as being similar to littering your code with singleton objects, which is usually considered a bad practice.
Does the author mean lots of "case object"? If so, it'd be nice to make explicit and I would tend to agree. If it's about objects that present pure functions to clients (without any data inside the singleton), I don't see the problem.
Note from the Author or Editor: Replace:
You can think of this as being similar to littering your code with singleton objects, which is usually considered a bad practice.
With:
You can think of this as being similar to littering your code with traditional singletons (i.e. static classes with "getInstance"), which is usually considered a bad practice.
|
Philippe Derome |
Feb 19, 2017 |
|
|
Chapter 4 conclusion |
The conclusion is hard to follow, specifically the issue around 'blocking':
In summary, by keeping in mind a few basic principles and techniques, you can create actors that retain cohesion, avoid unnecessary blocking and complexity, and allow the data flow within your actor system to be as smooth and concurrent as possible.
Now, in Chapter 4, I learned about using actors retaining cohesion and avoiding unnecessary complexity, but I saw nowhere a discussion about how we're solving a "blocking" problem. It is sort of implied by encouraging usage of tell over ask, but nowhere does it say that excessive usage of ask will likely lead to scaling/blocking problems, so it's hard to follow.
There's a reference in Chapter 4 about scheduling project not scaling and what not but there's no code sample showing blocking call in the 4 chapters to make that obvious. This sounds more like hand-waving arguments and being more specific in code would help.
I mean Chapter 4 reads well, but I don't see how it ties to the conclusion of having learned something that scales by preventing harmful blocking calls since the word 'block' hardly appears in the 4 first chapters and almost not at all in Chapter 4 (aside for block meaning section or segment of code).
Note from the Author or Editor: Replace
In summary, by keeping in mind a few basic principles and techniques, you can create actors that retain cohesion, avoid unnecessary blocking and complexity, and allow the data flow within your actor system to be as smooth and concurrent as possible.
With:
In summary, by keeping in mind a few basic principles and techniques, you can create actors that retain cohesion, avoid unnecessary complexity, and allow the data flow within your actor system to be as smooth and concurrent as possible.
|
Philippe Derome |
Feb 19, 2017 |
|
|
Chapter 4 Work Pulling code |
when project master looks for work and finds there's none (scheduleNextProject), it should just use the timer to check later on. Here, however it generates two events, check later once with a given delay AND check immediately asynchronously, which looks wrong.
At issue here is the last line of this code sample:
case None =>
context.system.scheduler.scheduleOnce(pollingInterval, self, CheckForWork(worker))
self ! CheckForWork(worker)
Note from the Author or Editor: Page 78:
Remove the line:
self ! CheckForWork(worker)
In the code block at the top of the page.
|
Philippe Derome |
Feb 20, 2017 |
|
PDF |
Page 27
2nd line |
... Akka also provides a one-to-mbany messaging mechanism ...
|
Anonymous |
Sep 21, 2016 |
Dec 09, 2016 |
PDF, Mobi |
Page 27
2nd paragraph of Domain Services |
The first sentence of the paragraph does not scan /is missing some words: "Generally we try leave Services as a last resort."
It should perhaps read "Generally, we try to use Services as a last resort." or perhaps "Generally, we use Services only as a last resort."
|
Anonymous |
Nov 23, 2016 |
Dec 09, 2016 |
PDF |
Page 31
1st paragraph, line 5 |
... as the lader is only used internally by Akka to make certain cluster-related decisions.
lader instead leader
|
Anonymous |
Sep 21, 2016 |
Dec 09, 2016 |
PDF |
Page 75
Last paragraph |
Using the event stresm in this way, ......
Stream instead stresm
|
Anonymous |
Jun 24, 2016 |
Dec 09, 2016 |