-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add ability to mark instances as absent #1731
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jamie-suse Looking better.
Some work still to be done yet hehe
@@ -0,0 +1,15 @@ | |||
defmodule Trento.Domain.Commands.MarkApplicationInstanceAbsent do | |||
@moduledoc """ | |||
Mark an application instance as absent from the monitoring system. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't really like this from the monitoring system
. It is kind of implicit, isn't it?
@@ -17,5 +17,6 @@ defmodule Trento.Domain.SapSystem.Instance do | |||
field :health, Ecto.Enum, values: Health.values() | |||
field :system_replication, :string | |||
field :system_replication_status, :string | |||
field :absent_at, :utc_datetime_usec, default: nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nil
is the default value by default XD
You don't need to add it
}, | ||
%RegisterDatabaseInstance{sap_system_id: sap_system_id} | ||
) | ||
when not is_nil(absent_at) do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we maybe revert the logic to use a better pattern matching:
defp maybe_emit_database_instance_marked_present_event(
%Instance{absent_at: nil}, %RegisterDatabaseInstance{}), do: nil
defp maybe_emit_database_instance_marked_present_event(
%Instance{}, %RegisterDatabaseInstance{sap_system_id: sap_system_id, ....} do
%DatabaseInstanceMarkedPresent{
instance_number: instance_number,
host_id: host_id,
sap_system_id: sap_system_id
}
end
The same goes for the application part.
Besides that, have a look on where this function should go checking the order of usage please.
I didn't have a proper look myself
absent_at: absent_at | ||
} | ||
) do | ||
%DatabaseInstanceMarkedAbsent{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here we need to check if the instance was already absent.
We don't want to emit the event if it was already that way.
I guess simply get the instance and with a case
check if the current value of absent. You don't need a new maybe
function. Just do it here.
The same for the app
application: %Application{instances: instances}, | ||
deregistered_at: deregistered_at | ||
} = sap_system, | ||
%RegisterApplicationInstance{host_id: host_id, instance_number: instance_number} = command |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wouldn't rename this to command
. It was ok as instance
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought to rename it as I need to use instance = get_instance(...)
further down
sap_system | ||
|> Multi.new() | ||
|> Multi.execute(fn _ -> | ||
maybe_emit_application_instance_marked_present_event(instance, command) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's put this after the maybe_emit_application_instance_registered_or_moved_event
event.
Besides that, and to follow with the already existing logic, I would pass sap_system/instance
to the function, and run the get_instance
within that one.
It looks cleaner and you reduce a duplicated code a bit (as you do it twice now)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was trying to make this in-line with the existing logic in execute(%SapSystem{}, %RegisterDatabaseInstance{})
. But I've changed it 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Referring to the logic seen here:
def execute( |
) do | ||
%Instance{absent_at: instance_absent_at} = get_instance(instances, host_id, instance_number) | ||
|
||
case instance_absent_at do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
case get_instance(instances, host_id, instance_number) do
%Instance{absent_at: nil} ->
%DatabaseInstanceMarkedAbsent{
instance_number: instance_number,
host_id: host_id,
sap_system_id: sap_system_id,
absent_at: absent_at
}
_ ->
nil
end
acf9125
to
2b76bce
Compare
FYI I had to rebase, so I squashed most commits down |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okey! Much better!
I think we need to work a bit more in the tests.
I would split the tests in smaller pieces and separate the databases and application flows, after all they have a totally independent flow
@@ -4202,6 +4208,361 @@ defmodule Trento.SapSystemTest do | |||
end | |||
end | |||
|
|||
describe "delta deregistration" do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wouldn't call this delta deregistration
.
Maybe instance marked absent/present
or similar?
@@ -4202,6 +4208,361 @@ defmodule Trento.SapSystemTest do | |||
end | |||
end | |||
|
|||
describe "delta deregistration" do | |||
test "newly registered instances should be marked as present" do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need this 1st test?
We have plenty of tests where we have a regular registration. We could add the absent_at
pattern matching in any of them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you still want to keep it, i think we should still split the database and application parts.
But the test must be fixed in any case.
The database_instance_registered
must not go in the initial events, as this is the event which triggers the change, so I would suggest to use the command in the 2nd param of assert_events_and_state
) | ||
end | ||
|
||
test "absent instances receiving 'mark as absent' command should mark as absent" do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would put this test before the others.
The tests can tell the story of the flow as well, so we would set to absent before setting it back to present, right?
) | ||
end | ||
|
||
test "absent instances receiving 'mark as absent' command should mark as absent" do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would rename this to should mark as absent a previously registered instance
Enum.map( | ||
instances, | ||
fn instance -> | ||
if instance.instance_number == instance_number and instance.host_id == host_id do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we pattern match instead of this if
?
@@ -1199,4 +1385,17 @@ defmodule Trento.Domain.SapSystem do | |||
false | |||
end) | |||
end | |||
|
|||
defp update_instance(instances, instance_number, host_id, key, value) do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't really like this key/value
thing.
Could we send the whole new update and use maybe Map.merge
?
https://hexdocs.pm/elixir/1.12/Map.html#merge/2
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some tiny things.
Ready to merge after them
|
||
embeds_one :database, Database | ||
embeds_one :application, Application | ||
field(:sap_system_id, Ecto.UUID) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Formatting error. Remove parenthesis please
instances, | ||
fn | ||
%Instance{instance_number: ^instance_number, host_id: ^host_id} = instance -> | ||
struct(instance, fields) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe I would put Kernel.struct
to exactly know the module. Up to you
@@ -4202,6 +4210,365 @@ defmodule Trento.SapSystemTest do | |||
end | |||
end | |||
|
|||
describe "instance marked absent/present" do | |||
test "should mark as absent a previously registered database instance" do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if mixing 2 different flows is a good idea, as it "hides" them.
I'm talking about the scenario where you test here that an already marked instance is not re-marked.
No need for a change, the test is totally correct.
For the future
sap_system_id: sap_system_id, | ||
sid: sid, | ||
host_id: host_id, | ||
instance_number: absent_app_instance_number, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not an app
instance in reallity, as it is a MESSAGESERVER
) | ||
end | ||
|
||
test "receiving a 'register instance' command for an already-registered database instance sets instance as present if absent" do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would rephrase this to:
should mark as present and already registered absent database instance
We use the should
wording at the beginning of each test by default
], | ||
fn state -> | ||
assert %SapSystem{ | ||
database: %SapSystem.Database{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SapSystem.Database
to Database
(already aliased in top).
The same for Instance
and Application
in all tests
sap_system_id: sap_system_id, | ||
host_id: host_id, | ||
instance_number: absent_app_instance_number, | ||
absent_at: DateTime.utc_now() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this absent_at
be created by the factory?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alright!
Green light from my side.
@rtorrero would you like to give a second look if I missed something?
Description
When an instance is no longer responding, the corresponding
MarkDatabaseInstanceAbsent
/MarkApplicationInstanceAbsent
command is dispatched (instead ofDeregister*Instance
). This even then applies anabsent
marker on the corresponding read/write models.When an instance is registered, the
absent
field should be cleared.How was this tested?
Updated unit tests to suit behaviour.