Skip to content

Sync dependencies #889

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

Merged
merged 18 commits into from
Apr 4, 2025
Merged

Sync dependencies #889

merged 18 commits into from
Apr 4, 2025

Conversation

yhabteab
Copy link
Member

@yhabteab yhabteab force-pushed the init-dependency-sync branch 2 times, most recently from 0a91368 to 8fdf0a2 Compare February 17, 2025 16:24
Copy link
Contributor

@julianbrost julianbrost left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So now I have two places things that I suggest to rename in the schema:

  1. affected_children -> total_children, see Sync dependencies #889 (comment)
  2. redundancy_group -> redundancygroup in all table and column names, see Sync dependencies #889 (comment)

Both affect web, so that should be coordinated. @nilmerg Are you fine with both of these changes? And if so, shall we just update this PR and Icinga/icinga2#10290 and ping you once done?

@@ -1334,6 +1342,61 @@ CREATE TABLE sla_history_downtime (
INDEX idx_sla_history_downtime_env_downtime_end (environment_id, downtime_end) COMMENT 'Filter for sla history retention'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin ROW_FORMAT=DYNAMIC;

CREATE TABLE redundancy_group (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rename this table to redundancygroup (and redundancygroup_state respectively) for two reasons:

Footnotes

  1. I presume that's currently necessary due to the inconsistency between Redis (icinga:redundancygroup, i.e. no separator in redundancygroup) and SQL (redundancy_group, i.e. with a separator), otherwise the Go type could also be named RedundancyGroup.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. otherwise the Go type could also be named RedundancyGroup.

No, it cannot! The Redis keys are generated dynamically based on the Go type name and that would result in icinga:redundancy:group which does not exist in Icinga 2.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Otherwise" as in "if it actually was icinga:redundancy:group and redundancy_group"

@yhabteab
Copy link
Member Author

2. redundancy_group -> redundancygroup in all table and column names, see Sync dependencies #889 (comment)

I initially asked Johannes about this and both agreed to keep it as it is, as the effort for renaming on the web side is not worth it compared to a one-line solution on the Go side, i.e. implementing the TableName() method.

@nilmerg
Copy link
Member

nilmerg commented Feb 24, 2025

I'm totally fine with total_children. But redundancygroup because consistency? Web would like to keep naming the respective model RedundancyGroup. I'd also liked to name the Hostgroup model HostGroup, but I was not involved in its naming. I don't see why we should continue this typo here on this new table.

@julianbrost
Copy link
Contributor

Why is it a typo?

@nilmerg
Copy link
Member

nilmerg commented Feb 24, 2025

@julianbrost
Copy link
Contributor

I would consider it a typo if it was was named "hostgruop" or something like that. In that case, naming new things like this for consistency would be truely insane. However, nothing is misspelled here, it's just a question of convention how things are mapped to SQL identifiers.

but I was not involved in its naming

Neither was I, so I don't know the exact motivation for the current names, but the general pattern seems to be that tables are named like the corresponding Icinga 2 object types converted to lowercase with sub-tables (like group members) being named with some _-separated suffix.

So for me, that looks perfectly fine as well, that is, considered in isolation, hostgroup and host_group would be equally valid for me, my preference towards naming the new table redundancygroup only exists because hostgroup was chosen over host_group in the past.

Web would like to keep naming the respective model RedundancyGroup. I'd also liked to name the Hostgroup model HostGroup

I mean that might be nice, but do you really expect that we'd go through the pain of renaming many existing tables any time soon just for cosmetic reasons? And were would you stop? "checkcommand" and "customvar" aren't English words either.

If you insist on the naming for this individual table, I predict that there will be inconsistencies in both the table names (hostgroup + redundancy_group) and the PHP class names (Hostgroup + RedundancyGroup) for the foreseeable future.

In case the PHP class names are that important to you and they are indeed directly tied to the table names, I'd consider relaxing the latter and adding a mechanism similar to that TableName() function in Go on the PHP more constructive: that would introduce no inconsistencies and you could name all your PHP classes just the way you like.

(I really didn't expect that to be such a controversial suggestion...)

@yhabteab yhabteab force-pushed the init-dependency-sync branch from 8fdf0a2 to dd191ef Compare February 24, 2025 15:46
@nilmerg
Copy link
Member

nilmerg commented Feb 25, 2025

the general pattern seems to be that tables are named like the corresponding Icinga 2 object types converted to lowercase

Indeed. That's where things went wrong. Icinga 2's class is also camel case. For some reason, someone decided against transforming this to snake case.

I'd consider relaxing the latter and adding a mechanism similar to that TableName() function in Go on the PHP more constructive

There is such a mechanism, but that wasn't implemented for the purpose of having a different naming syntax for class names. I'd have to verify whether this mechanism reliably works this way, where as what you have does already reliably work.

(I really didn't expect that to be such a controversial suggestion...)

I'm actually somewhat annoyed that this even comes up, half a year after I put up the schema suggestion.

@julianbrost
Copy link
Contributor

the general pattern seems to be that tables are named like the corresponding Icinga 2 object types converted to lowercase

Indeed. That's where things went wrong. Icinga 2's class is also camel case. For some reason, someone decided against transforming this to snake case.

I don't see that there's anything inherently wrong with that choice.

(I really didn't expect that to be such a controversial suggestion...)

I'm actually somewhat annoyed that this even comes up, half a year after I put up the schema suggestion.

That's simply something I didn't notice when looking at the schema diff as there's no inconsistency within the diff but only with other parts of the same file. So I actually only noticed the inconsistency when seeing that TableName() implementation and looking into the naming in more detail.

I expected the suggested change to be trivial and I still believe it would be a bad idea to introduce that inconsistency, but it really doesn't feel like that discussion is worth my time. So if you believe this is actually a good idea, I won't stop you, just be prepared for some "told you so" in the future.

@nilmerg
Copy link
Member

nilmerg commented Feb 26, 2025

just be prepared for some "told you so" in the future.

I'll gladly take that risk :)

@yhabteab yhabteab force-pushed the init-dependency-sync branch 2 times, most recently from 2736a9a to 277bb7b Compare February 28, 2025 08:23
@yhabteab yhabteab force-pushed the init-dependency-sync branch from 277bb7b to d5c8af4 Compare March 7, 2025 08:24
Copy link
Contributor

@julianbrost julianbrost left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs a rebase due to newly introduced merge conflicts. Apart from that, the first three inline comments are probably the most important ones.

Comment on lines 1290 to 1357
// TODO: Icinga 2 does send runtime delete event for those two tables, but Icinga DB does not handle them well yet.
// This is because the runtime sync pipeline is set to process upsert/delete events concurrently, which can sometimes
// lead to race conditions where the two events are processed in the wrong order.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wait, do you actually still send them?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So what exactly is the effect of the race condition mentioned in this comment? Like if it's too broken to be tested, why should it be fine for production?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have already talked about this in person, and I have even created a draft PR on your request #894, so there is no point in repeating all of it here again.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we had a discussion about that and I don't want to repeat the full discussion here, just write down the relevant parts why we're doing it that way now. I remember that we agreed that it doesn't make sense to solve that fundamental runtime update limitation in this PR, but did we really say that we want to send the updates nonetheless and ignore the problem? If so, I need a refresher on the reasons (hence my surprise in the initial comment).

From the PR you linked:

It seems that when the allowParallel parameter is set to true, the RuntimeUpdates#Sync() method does not honor the exact order of delete and upsert events from Redis, resulting in some rare and difficult to manually trigger race conditions where a subsequent runtime delete event from Icinga 2 might actually surpass the previously sent upsert event.

What exactly does "difficult to manually trigger" mean? If the tests can trigger it, why can't it happen to a user? I mean you don't need to trigger it manually for it to be a problem, if some user's automation script could trigger it, it wouldn't be good either.

So what makes it safe enough to ignore the problem here, when for regular state updates, it's worked around by not sending runtime deletes?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but did we really say that we want to send the updates nonetheless and ignore the problem?

Well, not exactly, but I definitely remember you saying to not send a runtime delete event for the regular tables, as you saw that I had already added that code in the Icinga 2 PR, so I only removed that part of the code, but not for the dependency states.

So what makes it safe enough to ignore the problem here, when for regular state updates, it's worked around by not sending runtime deletes?

Safe? I don't think it can be described as safe or not safe, if you delete some hosts or services at runtime, you will have dead state entries in the database until the next reload, that's all, nothing more. By the way, the discussion about sending or not sending delete events is not the right place here, as this PR only receives, but never sends 😅.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Safe? I don't think it can be described as safe or not safe, if you delete some hosts or services at runtime, you will have dead state entries in the database until the next reload, that's all, nothing more.

Well it's not perfect but from my understanding, not sending runtime state deletions is the safer option in the sense that all that can happen is that there are a few obsolete state rows in the database, which won't cause any user-facing problems (there's just a row in the database that will never be used). In contrast, if you send deletions, that problem can happen the other way around as well, so that would be state rows missing in the database which will be visible to the user in Icinga Web.

By the way, the discussion about sending or not sending delete events is not the right place here, as this PR only receives, but never sends 😅.

The fun of multi-project changes. The problem is in this project, the workaround in the other.

@yhabteab yhabteab force-pushed the init-dependency-sync branch 4 times, most recently from 44cc118 to 67a1d0c Compare March 24, 2025 15:42
@julianbrost julianbrost requested a review from oxzi March 25, 2025 15:51
@yhabteab yhabteab force-pushed the init-dependency-sync branch 3 times, most recently from 66159c7 to 2e806bf Compare March 26, 2025 08:43
@yhabteab yhabteab force-pushed the init-dependency-sync branch from d6f756f to 24ca91e Compare March 26, 2025 16:21
@yhabteab yhabteab requested a review from julianbrost March 26, 2025 16:21
Copy link
Contributor

@julianbrost julianbrost left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fine for me now. Can't be merged immediately for two reasons:

  1. This is not supposed to become part of the imminent release (https://github.com/Icinga/icingadb/milestone/9).
  2. Requires coordination with Sync dependencies to Redis icinga2#10290 (see Sync dependencies to Redis icinga2#10290 (comment)), in particular, both releases of Icinga 2 and Icinga DB will be necessary due to the incompatibility in Redis.

Copy link
Contributor

@julianbrost julianbrost left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given yesterday's release, the schema upgrade files have to be renamed. Also found a minor problem with the issue with the PostgreSQL schema upgrade (actually forgot to do my standard "does the migration match the full schema" check before :o)

@yhabteab yhabteab force-pushed the init-dependency-sync branch from 24ca91e to 2356ffb Compare April 4, 2025 10:16
@yhabteab yhabteab requested a review from julianbrost April 4, 2025 10:19
@julianbrost julianbrost merged commit a9badf8 into main Apr 4, 2025
31 of 33 checks passed
@julianbrost julianbrost deleted the init-dependency-sync branch April 4, 2025 15:34
@yhabteab yhabteab linked an issue Apr 4, 2025 that may be closed by this pull request
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Sync dependencies
4 participants