Modeling the Circuit Breaker: The Property
Start off with the test module and take a look at the property and the generators of the FSM tests.
We'll cover the following...
The property
Let’s start by looking at the property.
Press + to interact
property "FSM property for circuit breakers", [:verbose] doApplication.stop(:circuit_breaker) # we take over thatforall cmds <- commands(__MODULE__) do{:ok, pid} = :circuit_breaker.start_link(){history, state, result} = run_commands(__MODULE__, cmds)GenServer.stop(pid, :normal, 5000) #(1)(result == :ok)|> aggregate(:proper_statem.zip(state_names(history), command_names(cmds)))|> when_fail(IO.puts("""History: #{inspect(history)}State: #{inspect(state)}Result: #{inspect(result)}"""))endend
There will be four generators:
ok/1
tripped/1
blocked/1
unregistered/1
- This fourth generator is added because manual calls aren’t available until the circuit breaker’s service id is registered, which occurs automatically on the first use. This peculiarity will be encoded into the state machine itself.
Here we are starting the circuit breaker process by hand, which is paired with a call to gen_server:stop/3
at line 6. The circuit breaker module doesn’t expose a callback to terminate the breaker, usually preferring to let a supervision tree do that work. However, the gen_server
behavior ...