Hi.
This is the last video of the section.
Pipeline design pattern.
Previously we learned about future design pattern in this video we're going to take a look at the concept
working and implementation of the pipeline design pattern.
The third and final pattern we'll see in this section is the pipeline pattern.
You'll see this pattern heavily in your concurrent structures.
And we can consider it one of the most useful too.
We already know what a pipeline is.
Every time that we write any function that performs some logic we're writing a pipeline.
If This Then That or else something else pipeline patents can be made more complex by using a few functions
that call to each other they can even get looped in their out execution.
The pipeline patterning go works in a similar fashion but each step in the pipeline will be in a different
go routine and communication and synchronizing will be done using channels.
What will we gain by creating a pipeline.
We're mainly looking for these benefits.
We can create a concurrent structure of a multi-step algorithm we can exploit the parallelism of multiple
machines by decomposing an algorithm in different go routines.
However just because we can decompose an algorithm in different go routines doesn't necessarily mean
the execute the fastest.
We're constantly talking about CPE use.
So ideally the algorithm must be CPO intensive to take advantage of a concurrent structure.
The overhead of creating go routines and channels could make an algorithm smaller.
Here we'll create a concurrent multi operation.
We're going to do some math for our example.
We're going to generate a list of numbers starting with 1 and ending at some arbitrary number and then
we'll take each number.
Power it to 2 and sum the resulting numbers to unique result.
So if n equals 3 our list will be 1 2 3.
After powering them to 2 our list becomes 1 4 9.
If we sum the resulting list the resulting value is 14.
Let's look at the acceptance criteria.
Functionally speaking our pipeline pattern needs to raise to the power of to every number and then some
more.
It will be divided into a number generator and two operations so one generates a list from one to N
where N can be any integer number to take each number.
This generated list and raise it to the power of 2 3 some each resulting number into a final result
and return it.
Let's begin with tests will create only one function that will manage everything.
We'll call this function launch pipeline to simplify things.
It will take an integer as an argument which will be our N number the number of items in our list.
Let's start create two documents.
Pipeline Dok Go and pipeline test or go
at the function launch pipeline in our test file we'll create a table of tests by using a slice of slices.
This is our table when passing 3 it must return 14 when passing five it must return 55.
Then we have to iterate over the table and pass the first index of each right to the launch pipeline
function.
Let's do that using range we get every row in the matrix each row is contained in a temporary variable
called.
Test test 0 represents n and test 1.
The expected result.
We compare the expected result with the returning value of the launch pipeline function.
If they aren't the same.
The test files say this file and test in the terminal
time for implementation.
The key for implementation is to separate every operation in different go routines and connect them
with channels.
The launch pipeline function is the one that orchestrates them all as shown in the diagram.
The operation consists of three steps generate a list of numbers raise them to the power of two and
add the resulting numbers.
Now we'll see the structure each step in this pipeline pattern will have.
This is the syntax let's look at the flow chart of the process.
This function represents a common step.
Let's dissect it in the same order that go scheduler will probably take to execute it.
The function name function will commonly receive a channel to take values from we call it the end function
as in the word incoming.
We cannot same value through it within the scope of this function.
That's why the arrow points out of the keyword Chan the function name function returns a channel that
the function caller will only be allowed to take values from again represented by the arrow pointing
out of the keyword channel.
This also means that any value that goes through that channel must be generated within the scope of
the function in the first line of the function we create a channel called out that will be the return
of the function.
Then we'll launch a new go routine.
Its scope will enter into play after returning this function.
So let's continue.
We return the previously created out channel.
Eventually after finishing the execution of the function and returning the channel out the go routine
executes it will take values from the inn channel until it's closed.
So the core of this function is responsible for closing this channel.
Otherwise the go routine will never end when the in channel is closed the for loop finishes and we closed
the out channel any go routine making use of this channel will not receive any new values since the
last century the only step that doesn't completely fit this approach is the first step that receives
a number representing the upper threshold on the list instead of a channel of incoming values.
Although the idea is exactly the same.
Now we can see that it's the function launch pipeline that is the one that's going to be receiving channels
and sending them back to the next step in the pipeline.
Using this diagram we can clearly see the flow of the pipeline creation by following the numbers of
the arrows a solid arrow represents a function call and the dashed arrow a channel let's look a little
more closely at the code.
Open pipeline don't go first.
We have the list generator the first step in the operation is this generation.
The list starts at 1 and will receive an integer representing the higher threshold.
We have to pass each number in the list to the next step.
So here you can see that done in the for loop as we mentioned earlier.
This is the pattern that we will follow in each step created channel launched the go routine that will
send the data through the channel and immediately return the channel this go routine will iterate from
one to the max argument which is the higher threshold for our list and said each number through the
channel.
After sending every number the channel is closed so that no more data can be sent through it but the
data already buffered can be retrieved.
Next we'll raise numbers to the power of two.
This step will take every incoming number from the first steps channel that is taken from the arguments
and raise it to the power of two.
Every result must be sent to the third step using a new channel.
This is the code for that.
We use the same pattern again.
Create a channel and launch the go routine while we return the create a channel the full range loop
keeps taking values from a channel indefinitely until the channel is closed the next part is final.
Reduce operation.
Third and final step receives every number from the second step and keeps adding them to a local value
until the connection channel is closed.
This is the function some the functions some also takes a channel as an argument.
The one return from step 2.
It also follows the same pattern of creating channel launching the go routine and returning a channel
go routine keeps adding values to a variable called Sum until the in channel is closed when the channel
is closed.
The value of some is sent to the out channel and it's immediately closed.
Now we launch the pipeline pattern.
Finally we can implement the launch pipeline function.
For that we need to add the function launch pipeline the function generator first returns the channel
that is part of the power function.
The power function returns a second channel as part of the sum function.
The function sum finally returns the first channel that receives unique value the result.
Let's try to test is now save the file open terminal and test it awesome.
It's worth mentioning that the launch pipelines function doesn't need to allocate every channel and
can be rewritten like this.
The result of the generator function is passed directly to the power function and the result of power
to some functions with the pipeline patterns we can create really complex concurrent workflows in a
very easy way.
In our case we created a linear workflow but it could also have conditionals pools and fan in and fan
out behavior.
In this video we worked with the pipeline design pattern.
Great.
This brings us to the end of this section and course this section cover the three important concurrent
patterns in go concurrency barrier future and pipeline design patterns.
We use them in different applications according to the need.
With this we conclude the course.
I hope you're now confident to use go concurrently.
Keep practicing.
Keep learning.