- [Instructor] In our speakers class down there,
we have this callService method
and right now it does not use the circuit breaker,
so we have to create a way to call a service
via a circuit breaker.
We could now build this into the Speakers.js class
but I decided to implement a callService method directly
in the CircuitBreaker.
For that I change in my CircuitBreaker class
and there I first simply copy, paste this call Service in.
Now we have to extend it a little bit.
Of course, to use the CircuitBreaker,
so add const endpoint
equals because I want to create some unique identifier
for the endpoint so that I can store this dates then
in this.states map with it,
so I add requestOptions
and there I take the method.
This is GET POST, it's the HTTP verb
and then I want to use the requestOptions.
I copy that URL because the method
and the endpoint pretty much uniquely
identifies an endpoint.
Let's remember that we have to call initState somewhere
to actually initiate the state for this endpoint
and we could just do here now in callService
but I decided to add these two canRequest,
so I will now add here if not this.states endpoint,
we do a this.initState
for the given endpoint.
So, we can make sure that every time we call canRequest,
the endpoint is initialized.
Now back in our callService method,
we can now simply call if not this.canRequest
for this given endpoint,
we can simply return false
because the circuit is currently open.
If we end up the line after that,
the circuit is half open or closed
and we can now extend the request options a little bit
because we want to change the timeout value on it
so that it fails after this requestTimeout
and we have to multiply it with 1,000
because it's to be set in milliseconds
and we see that ESLint is now complaining
because we are reassigning on a argument
and we disable that for this line
because we know what we are doing.
Next, we now will create a try catch block
because axios will fail or throw an error
when it's called by await
if anything goes wrong,
so we have try catch block to it now
to actually catch that
and if we end up after this call to axios,
this set request went well,
so we have a success and I will add onSuccess,
so I register a successful request.
If we end up in the catch state,
I now do a this.onFailure
because the request went wrong.
And in this case, we will return false.
Now we have to use the CircuitBreaker
in the Speakers class
and there I simply now add const
CircuitBreaker
equals require two levels up lib/CircuitBreaker
as if service class like speaker-service maps directly
to one service,
I decided to create one circuit breaker
per such class and not use a global one
to share the state here
for all services that we are using,
so we will instantiate it now here directly,
Breaker equals new CircuitBreaker,
so we have a module global instance
of the CircuitBreaker
and now for using this CircuitBreaker,
we can simply go down to callService
and there we will just return circuitBreaker.callService
with the requestOptions and that's it already.
And now just for testing my circuit breaker,
I change the request timeout to two seconds
so that we can distinguish
if the CircuitBreaker was open or not.
I do an npm start
and I open the conference app on port 3080.
This works, we know that
but the problem is when we go
into All Speakers and we see now
that it takes a little bit
but it also returns pretty soon
because we set the request timeout
and the page does not show an error
but it's just empty
because we are missing the data obviously
but that looks already way better than before.
If I reloaded this, you see that it always takes
a little bit because we are waiting those to seconds
to see that the request failed.
After some times now,
the circuit should switch to open
and that's now, you see that it's now returning immediately
until it gets back to half open,
we will see that in the request time after some seconds.
Now we have half open,
so it's retrying to reach the service.
Did not work and now it's back to open.
So, this works exactly as intended.
Let's switch back the requestTimeout to one second
and you also see here those log lines
that we created before those alerts,
so if such a problem happens,
you look into the log, you see okay,
/list has a problem here obviously,
so I can go into my speaker-service,
look for the problem and fix it easily and quickly.