so right worker threads crash-course all
right let's see is this work the way I
wanted to it kind of does yeah so I've
kind of stuck with the title because I
chose it but it's really this is really
more like an introduction to the things
I like / you / want to talk about in
worker threads or perhaps even more
accurately I was doing a thing and I
wanted to talk about the thing and they
ended up talking about worker threads so
that I could stand up here and talk
about the thing so I talk fast I usually
say I will try not to and I will fail
I'm sorry but I have 25 minutes and like
40 billion slides so talking fast is my
superpower right now I know it's not
very Hawaii to talk really fast but
doing the best I can anyway my name is
rich and I work for the University of
California at their San Francisco campus
in the library B and then I'm including
I'm including myself in this we all act
like the internet didn't exist until
Amazon and pets.com
came along but government institutions
including public universities like the
University of California were there for
decades working on hard problems like F
an Ethernet how does it work one of the
Jays convoy organisers had a blog post
about the role of the University of
Hawaii and in that sort of stuff and you
should read it because it's really
fascinating anyway as you might imagine
the UCSF library does not have an
extraordinary large Deverell budget
don't blog devrel positions there's not
a lot of money around for me to travel
to Tropico locales to attend conferences
and talk about javascript so for making
it possible for people like me and
perhaps more importantly people who are
not like me in several respects to be on
the stage of this conference mad props
to the GS convoy organizers and the
sponsors so I am the composer of a rock
opera this would normally be my fun fact
by the way but since there's part of my
talk I held it back I'm the composer of
a rock opera about a steak house and it
includes dancers and in steak suits and
things like that it sounds I hope this
works it sounds something like this
[Music]
okay it's gonna hang on
it's really really groovy so anyway um
but we're gonna that's actually the good
thing to fail because I didn't actually
come here to play excerpts from from a
rock opera I just bring it up because I
put most of the most of the likes I put
a link to the slides and a link to all
the things I talked about in here at
pals family steakhouse calm so now the
only reason I get to stand up here and
play excerpts from my rock operas
because I work on node by the way who
runs node everybody does if you don't
think you did your run node right okay
um so if you're using this yeah it
doesn't point is I only 25 minutes um if
you're running node you're running a lot
of code that I wrote on a 2013 MacBook
just so uh me and like two hundred other
two two thousand other people but anyway
um so some quick disclaimers the views
expressed on my own not show you those
of my employer that's a standard
disclaimer also the views expressed are
my own and not necessarily those of node
there are a lot of other people involved
in node and naturally I don't see
everything the same way just two days
ago was decide to remove a handful of
deprecated API is from the codebase that
I think we should just leave in there so
clearly my opinions are not those of
node necessarily but I wasn't nearly as
angry as this person was about it anyway
without of the way back to node hey have
you heard about worker threads they were
introduced in node 10.5 dot zero but it
required a command line flag to using
that version so in no.12
you don't need a command line flag and
you really want to use twelve dot eleven
or newer because that's the first
version where worker threads were
determined to be stable rather than
experimental and really you want to use
12150 because that's the version that
was released like a day or two ago that
fixes some security issues if you like
to live on the edge use the current
version that won't be supported yet in a
few months but it's node 13 eight zero
which is the version that was released a
few days ago it's security fixes um
anyway yeah worker threads what are they
even so they're kind of like web workers
but different there's no
there's no shared worker for example
uh-oh that's suppose there it is okay if
you've not used web workers don't worry
stay with me um they're also kind of
like threads and other programming
languages but also not like threads and
other programming languages if you use
threads another programming language is
cool if not don't worry stay with me man
that image takes a while to load it's
pretty big okay um anyway javascript is
single threaded as we all know even if
you don't know what that means there's
an excellent chance you've heard
JavaScript is single threaded before
seeing it on this slide that's because
there's one cold hard unchanging fact in
this ever-changing world in which we
live in and that question with a kiss
javascript is single threaded arguably
literally arguably because like some
people like to argue about this um I
don't want to have that argument though
so the point is your code does one thing
at one time it's why this program never
exits there's only one execution I'm
sorry that's why there's only one one
execution thread handling this code the
code in the set timeout which would
cause the while loop to stop never
execute right um it's a you know it's
just going to sit in the wild loop
forever and and and the timeout won't
fire until the wild loop exits the wild
loop is never going to exit to the time
at number fires stuck in the in flew for
ever classic deadlock right so this code
will run forever or until you press
control-c or you turn off your computer
or whatever but it's not gonna exit
cleanly and whatever causes to exit it's
not going to be the set timeout this is
called blocking the event loop you may
have heard that phrase before you've
heard it in Max's talk like 20 minutes
ago he recommended sam roberts video
that's great it's great great talk I
recommend this one this is uh what the
heck is the event loop anyway by philip
roberts if you get nothing else i have
this talk let it be that you should get
more than one thing out of this talk but
if you get only get two things from this
talk let the second one be that you want
to watch this talk okay that talk not
this talk see this is what happens when
i have to compress for hours worth of
material in 25 minutes anyway there's a
link to that talk at pal's family stays
calm now you may be thinking but
note is asynchronous I don't really have
to worry about blocking the event loop
you're probably not thinking that but
you might be someone might be it can you
know node can effectively do many things
at once like handle multiple
simultaneous HTTP requests or read
multiple files max was just telling it
but telling us about this in the last
talk and his slides were gorgeous so it
must be true and it is true because max
is a good egg he would not lead you
astray but the built-in asynchronous
nature of node has been around
input/output IO that's why I mentioned
files and it's why I mentioned HTTP if
you're if you're doing say data science
stuff maybe or like processing graphics
you know image image processing or
basically anything it's CPU intensive
then let's just say that the default
state of things in node and in
JavaScript is not as asynchronous so
prior to worker threads the usual way
people would offload CPU in a
non-blocking way in node was the cluster
module and if that's working for you
great but here's the thing
cluster spreads your work out workload
out across multiple processes and each
of those processes has independent
memory and so on so I make sharing large
amounts of data problematic and each
process consumes the full amount of RAM
required by node so this can be really
inefficient again though if it's working
for you great but if it doesn't work for
you it's if it doesn't work for a lot of
things and even if it is working worker
threads will often work out better and
here's why worker threads are
lightweight it's not a whole process
it's just a thread and they're better at
sharing data which we'll talk about
briefly and then I'll do some hand
waving stuff until you go look at the
documentation um so let's dive in here's
the hello world example and let's just
go through it step by step the first
line pulls in three things from the
worker threads module it pulls in the
let's see here so starting from the
right hand side suppose in the parent
portals in the is main thread boolean
and it also pulls in the worker class
and yeah so his main thread at the
parent port so we use is main thread to
to make sure we are we are not using
we're not inside a worker thread already
basically we're checking you know we're
checking that we're not wearing thread
so that we know that's okay to launch a
worker thread if we didn't do that we
might be in a worker thread that
launches a worker thread that launches a
work thread that launches work thread
and it's just work threats all the way
down until your run out of I don't know
stack heap something some kind of ramp
anyway some kind of resource this check
is usually only necessary if you have
your worker thread code and your main
thread code in the same file I don't
usually like to do that but for a hello
world example it seemed convenient to
just have one blob of code and not like
here's the word huh so that's what I did
is main thread cool anyway so we're in
the main thread so what we're gonna do
is create a worker thread so we use the
constructor for the worker class and
that's what that new worker is all about
right new is the keyword for instructors
in JavaScript and we pass it underbar
underbar our file name which is the
special node.js variable that says you
know the file the path to the file that
contains the the code currently being
executed if you didn't know that that
was what that was now you do um you can
create a worker thread to run any
JavaScript spot file you specify but
like I said here we're just keeping it
one file you can also pass it a string
that and and and tell it that this is a
blob of code to execute I don't like to
do that because that's basically eval
and I you know we've all been taught
that eval is you know God kills a kitten
or something like that when eval you
know you know and so you know like to
avoid it but anyway so we've created a
worker analysis in for messages from the
worker this is the usual event listener
syntax in node remember we're in the
main thread still not the worker thread
we're listening for messages message
events on the worker we've created and
when we get one we're going to use
console.log to print the message okay so
and that's it for the main thread that's
all we're doing now remember we were in
an if block that checked if we were in
the main thread so now let's use the
else block and do the right stuff for
when we're in the worker threads and all
we're gonna do
is use parent port to send a message to
the main thread and the main thread
parent port will be no but you know so
if we want to send a message to the
worker from the parent port we use the
port the post message method that's on
the worker instance we'll see that later
sorry that I'm talking so fast but in a
worker thread parent port dot post
message like we see they are used to
send messages through the main thread so
let's use it to send a message that says
hello world and that's the end of the
file you'll remember them the main
thread we set up a listener that would
take the message and print it out so
this is the convoluted way to
console.log hello world not terribly
useful there are much easier ways to do
that of course but it doesn't reduce the
very basic concepts of worker threads
and now let's do something equally
contrived but more interesting and I'll
try to slow down a little bit
six degrees of Kevin Bacon perhaps you
remember the game if not it's simple
given the name of it an actor in a film
your job is to well that's a cool effect
um your job should you choose to accept
it is to connect to them to Kevin Bacon
in six or fewer steps in the following
manner let's say you're challenged to
connect Katy Perry to Kevin Bacon I
don't think this is gonna get old in six
or fewer steps Katy Perry whirs Katy
Perry was in Zoolander 2 with John
Malkovich and John Malkovich was in
Queens logic with Kevin Bacon boom Katy
Perry to Kevin Bacon in two steps I've
seen neither of those films um anyway
there are already websites to solve six
degrees of Kevin Bacon by using IMDB
data several years ago I wanted to do
this for musicians playing on recordings
of individual songs so I made a site
called music routes and it's been broken
for a long time because some one who I
won't say what it was but removed an API
that I was dependent on and then I never
bother fixing it anyway it's been
brewing for a long time so let's fix it
so first surprisingly there is no usable
database available on what musicians
play on what tracks on what recordings
and some people say what about all music
they only have information who played on
what album not track by track
information other people ask me about
musicbrainz they only have artists
associated with tracks not individual
musicians
so me little ass butt discards they have
published album credits but sometimes
the album credits don't list
track-by-track data and often they are
wrong even intentionally so ask me for
examples after the talk because I love
talking about this sort of stuff but
otherwise just know that discogs data
correctly reflects what's on the album
sleeve which does not correctly reflect
what is in reality all the time that
brings us to wiki data which has some
data along these lines but way less than
you think that's cool though its wiki
data so everyone can add data to it but
it's very very unusable slow for the
many many many queries that would be
required to do this so I built my own
database and published it it's very
incomplete but it will do here I also
built a rudimentary little visualizer
for it and we'll see that in a bit
so ok in order to solve these things we
could use breadth-first search and many
of you maybe most of you maybe all of
you I don't know may already know what
breadth-first searches but just in case
I am now going to give the world's worst
overview of breadth-first search let's
go back to connecting Katy Perry to
Kevin Bacon
step one is Katy Perry Kevin Bacon
that's a JavaScript truth triple equal
there in the middle the answer is
obviously no step two find everyone that
was in a movie with Katy Perry do any of
those people happen to be Kevin Bacon
and the answer is still no step three
find everyone that was in a movie with
any of those people that were in a movie
with Katy Perry do any of those people
happen to be Kevin Bacon and as we saw
before with the Katy Perry John
Malkovich Kevin Bacon thing the answer
is yes so we're done congratulations you
just witnessed the worst explanation of
breadth-first search ever but we're not
done let's do a slightly better
explanation this will be second worst
explanation of breadth-first search ever
we're again going to connect Katy Perry
Kevin Bacon but this time not through
movies this time let's do it through
music Kevin Bacon has a band with his
brother Michael Bacon and the band is
called the bacon brothers I am NOT
making that up so let's see if we can
connect Katy Perry to Kevin Bacon via
music step one is Katy Perry Kevin Bacon
No so here's a visualization of Katy
Perry and everyone she recorded with on
her album one of the boys which I'm
sorry to say is the only album of hers
that I have in the data set you can open
a pull request to fix that if you want
to correct that massive injustice but
anyway Katy Perry is a circle in the
middle and each circle the surrounding
ring is someone who is one step away
from Katy Perry because they recorded
with her on their album notably absent
in that ring of people Kevin Bacon now
imagine we take each of the circles in
the ring around Katy Perry and we find
out everyone who recorded with each of
those people and we take all those
people and make an outer ring with
circles for each of those people now I
didn't do that but I did scroll this
blue riot line around things to show
where the outer ring of circles would be
and the number of circles the number of
circles in that ring is going to grow
exponentially or at least exponentially
ish it's gonna grow very very quickly
which is part of why I didn't do it so
you don't want to see all those circles
anyway but I'm here to tell you
something exciting about that outer ring
it totally has Kevin Bacon in it and
that's basically breadth-first search
now we can take a look at the results
instruct our paths so here's what the
path looks like if you don't believe me
it's Katy Perry the David Stuart Dave
Stewart Jon Bon Jovi - Kevin Bacon okay
so that's breadth-first search now let's
implement it no no just kidding four
verses of this presentation it's an
implementation detail and there are
trade-offs and various ways to implement
it that we don't really have time to go
into you can check out the repository
for how I implemented it as well as to
other algorithms we'll talk about in a
bit but the important thing is that our
approach will keep the CPU busy rather
than do a bunch of work up front this is
so that we can see how cool worker
threads are but it's also a legitimate
trade-off one might make in the real
world it's not always worth it to spend
a bunch of time upfront pre-processing
if it's too time-consuming or takes up
too many too much storage or if there's
too much unpredictability about what
you're going to get etc so here's what
it looks like let's step through this
okay the first line gets all the track's
for the start person let's say it's a
Reetha Franklin and puts all those
tracks at the element at index zero
that's index zero and the array of
tracks for the start person now the
index indicates how many steps we've
gone from the start individual so um
this next line populates the
corresponding array of individuals that
are in that are the source of the tracks
above again in index zero in this case
it's an array of just one individual
knee namely Aretha Franklin for the two
lines starting here we're going to do
the exact same thing for the target
person let's say it's Carrie Brownstein
this line checks to see if we have a
match by seeing if there is one or more
tracks
that are in both lists of tracks lastly
this wild loop runs until we find a
match so this line adds all the
individuals and tracks that result from
going out one more step from the start
individual then we've gone this far so
all the people on tracks with Aretha
Franklin then the next time it runs it's
all the people on tracks but they're in
people's tracking let's see out our blue
line and so on and so forth and this
line updates the matches list so the
while loop will stop if we found a match
each time through the that last while
loop like I said grows exponentially ish
gets slower and slower and slower with
longer and longer paths so here's a run
with the results it took more than 14
seconds just to do the breadth-first
search that's that's a lot we can do
better even without worker threads we
can do bi-directional search so uh
bi-directional search right okay now at
this point you may be feeling a bit like
the you know this dog you might be
thinking when is it gonna shut up about
this stuff and go back to worker threads
soon don't worry so but first
bi-directional search here's how it
works first Katy Perry is not Kevin
Bacon despite striking resemblance
second we look for everyone that
connected to Katy Perry and check to see
if Kevin Bacon is in there he is not now
we do something different we bounce back
to Kevin Bacon and we get everyone
connected to him we check to see if
there's an overlap and again there isn't
and then we do once you know we okay so
right I sky obviously to leave this
slide that's okay though so we do one
for Kevin Bacon and so on so forth until
they share a person and it's gonna look
like this so here's your search that
oval on the left is Katy Perry that oval
on the right is Kevin Bacon they're not
the same person there's all the people
play with Katy Perry okay they're not
Kevin Bacon there's all the people that
played with with with the people that
play with Katy Perry still no Kevin
Bacon
okay that was breadth-first search we
found Kevin Bacon now let's do it with
bi-directional search okay one step away
from Katy Perry
oh look Kevin Bacon and now well that
wasn't an expensive search because we're
not going to the outer circles yet oh
look we only have to do one expensive
search we're gonna see a lot better
performance before we get a match okay
um don't believe me about bi-directional
search or I've gone too fast hey there's
a Wikipedia article and even talks about
big o-notation prove that it's faster
and better and all that sort of stuff
here's what bi-directional search looks
like implemented
and we're just gonna look at the while
loop because that's where all the that's
where all the interesting changes
basically instead of doing just the one
side the start side we're gonna do the
start side and the target side
and holy moley we went from over 14
seconds less than three seconds that's
awesome that's probably good enough
actually to just called it today but
wait why be bound by a single thread
rather than doing one breadth-first
search from Katy Perry and then waiting
for it to finish and then checking
against Kevin Bacon and when you forgot
to finish and then bouncing back to Katy
Perry why not just sort of just let them
both run and give you data as fast as
they can and every time you get data
from one check to see if you can stop
stop both threads and go from there and
see how fast that is so to create our
worker thread to this time we are
calling new worker again and this time
we are putting the worker code in a file
called worker j/s so we'll see that in a
moment
there's also a new thing over here in
the second argument which is a worker
data property this allows us to provide
the idea of the individual just to start
with this serializes the data and sends
it to the worker which then uncie
realises it into its own copy of the
data now worker thread so that's kind of
just like passing you know basically you
know more or less JSON data over and
then you know it uncie realizes the JSON
day that's not exactly JSON data it can
handle circular references but we're
gonna threads could do this awesome
magical thing where if you do things
just right you can share memory and also
transfer memory buffers between the main
thread and the worker thread sharing
memory doesn't actually resemble sharing
Nacho's but I needed an image anyway
we're doing this in the app we're not
doing this in the app working data just
sends a copy but if your data is of a
predictable size and format and there's
a lot of it look at the docs for
information on sharing and transferring
data it's really cool in addition to the
shared memory stuff there's pooling for
this application we oh we always need
two workers and we don't care about the
cost of starting them up only when we
need them but in an application where
where your needs are more dynamic you're
trying to get the absolute best
performance you can you'll want to
investigate having a pool of workers
that you use as needed and they're NPM
modules that help you do that if you
need to anyway over in the worker we're
reading the worker data value is done
like this we import the work of data
property from the built in worker
threads module and then we read the
value of the ID key
context switching back to the main
thread we have an error listener that
simply throws any unexpected errors and
we call a callback that we use when we
receive a message from the worker the
index here is used to distinguish the
results in Katy Perry's group from the
results in Kevin Bacon's group we might
use 0 for Katy Perry and 1 for Kevin
Bacon let's head over to the worker code
again to see how the worker sends a
message so when the worker is created it
grabs all the track's the individual is
on and also makes a note of the
individual ID and uses post message to
send the message and that's it that will
cause the message event to be emitted in
the main thread resulting in execution
of the callback so let's check out what
the callback does
again the index is a value that lets us
know if we're dealing with Katy Perry or
Kevin Bacon is it start or the target we
also get all the individuals for whom
the track is derived tracks are derived
rather and we check to see if there are
any tracks that are on both lists thus
indicating our expanding circles are
overlapping if we have a match we call a
function called done we'll check that on
in a moment and if we're not done we
send a message to the worker to go get
us another expanding ring of tracks and
individuals I'm not going to show the
worker code that listens for the message
is pretty similar to what we've already
seen if it gets a string value next it
gets the next set of search results and
sends them back to the main thread this
is way too much for 25 minutes but just
know that to receive the message the
workers listen to the message event on
the parent port object so I do want to
talk about that done function really
quickly though it removes the listener
we have for both workers and then it
calls this method that's on the worker
called Turman or terminate does it ends
the worker thread and returns a promise
that resolves to the return code of the
worker code if we have cleanup code or
whatever we want to make sure it runs we
can put in an async function and await
the value rather than just calling
terminate like we're doing here but in
this case you know we don't have any
cleanup I don't care it connects it with
an error code I just want it to go away
so do that and lastly we've print our
results so let's see how it performs
remember it took 14 seconds with
breadth-first search it took it took
just under three seconds with
bi-directional search oh my gosh it's
less than 700 milliseconds now I can't
believe it it's unbelievable by the way
all of these scripts are in the
repository at posted earlier I showed
earlier and that's it pal spent mistakes
commlink anyway um now with my 53
seconds remaining I have to admit that
the main motivation here wasn't really
to talk about worker threads awesome as
they are it was to find out how far I
was from little Nass X the answer by the
way is 6 degrees
it starts with little mass X he of
course you know recorded with Billy Ray
Cyrus on you know I have him come on old
town road the second degree is country
star Mary Chapin carpenter who along
with Billy Ray Cyrus was on that Dolly
Parton song called Romeo Dolly Parton
gets her own slide the Afro mentioned
Romeo was her thirty second studio album
she wrote it she produced the record
people who aren't country fans don't
realize the extent to achieved in
control over sound in her career I'm not
a country fan but I
recognises she's a legend and a force to
be reckoned with do not mess with dolly
and also you know since we're talking
about Old Town Road but the analogous
legend unfortunately reckoned with a
node is on a Henningsen she's the one
most responsible for implementing worker
threads and as far as all things node go
is extremely difficult to give on the
too much credit
so I'm I'm up here talking about worker
threads but like she did 99.999% of the
hard work get this done and the other
point zero one percent was done by
people aren't me anyway back to this
nonsense after Dolly Parton's track Mary
Chapin carpenter goes through Saturday
Night Live bandleader G Smith and Tom
Waits trumpet player before getting to
me but why should I restrict fun Benny
exercises like this to me
I put this up at a glitch URL which is
you know works so if you want to you
know try to connect it's retic know I
mean let's just great but I mean you
know it's like you know like I you can
just also get the repository and just
run the Express app on your local
machine they'll be faster oh let's just
awesome I love it but you can go over
here and try to you know see if you can
connect you know I don't know
Miles Davis to Billy Ray Cyrus yeah so
like I said everything's a palace my
mistake house calm thanks I'm out of
time and yeah thank you
sorry also I like this