Skip to content
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

Service for database domain management #3052

Merged
merged 44 commits into from
Mar 17, 2021

Conversation

arcusfelis
Copy link
Contributor

@arcusfelis arcusfelis commented Mar 8, 2021

Proposed changes include:

  • Service
  • Core
  • DB queries
  • Docs

DONE:

  • We need to write a gen_server, which removes old records from the domain_events table.
  • Pagination tests - many records inserted. Maybe proper tests.
  • Other DB backends, not just Postgres.
  • Distributed tests - more than one node (though do we really need it? Other nodes would read events from the domain_events table in exactly the same way, as one node does).
    - Need to add tests to check what is happening when service goes down.

@chrzaszcz
Copy link
Member

chrzaszcz commented Mar 8, 2021

Please describe the architecture, e.g. why two database tables are needed. One commit with 1000 lines of code and no description of the changes makes it difficult to figure out the reasoning behind all the changes.

For PR's still in progress (not intended for review and merging yet) please use the 'Draft' option on GitHub.

@codecov
Copy link

codecov bot commented Mar 8, 2021

Codecov Report

Merging #3052 (874999d) into multi-tenancy-phase-1 (135fec2) will increase coverage by 0.06%.
The diff coverage is 84.32%.

Impacted file tree graph

@@                    Coverage Diff                    @@
##           multi-tenancy-phase-1    #3052      +/-   ##
=========================================================
+ Coverage                  78.53%   78.60%   +0.06%     
=========================================================
  Files                        378      385       +7     
  Lines                      31119    31438     +319     
=========================================================
+ Hits                       24440    24712     +272     
- Misses                      6679     6726      +47     
Impacted Files Coverage Δ
src/config/mongoose_config_spec.erl 98.80% <ø> (ø)
src/domain/mongoose_domain_utils.erl 0.00% <0.00%> (ø)
src/domain/mongoose_domain_db_cleaner.erl 76.47% <76.47%> (ø)
src/domain/service_domain_db.erl 80.70% <80.70%> (ø)
src/domain/mongoose_domain_core.erl 82.85% <82.85%> (ø)
src/domain/mongoose_domain_loader.erl 82.85% <82.85%> (ø)
src/domain/mongoose_domain_api.erl 90.32% <90.32%> (ø)
src/domain/mongoose_domain_sql.erl 91.01% <91.01%> (ø)
src/ejabberd_app.erl 93.75% <100.00%> (+0.06%) ⬆️
src/elasticsearch/mongoose_elasticsearch.erl 76.92% <0.00%> (-7.70%) ⬇️
... and 18 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 135fec2...874999d. Read the comment docs.

@arcusfelis arcusfelis marked this pull request as draft March 8, 2021 10:27
Two new DB tables: domain_settings and domain_events.
Added service service_domain_db.
Added prepared queries in mongoose_domain_sql.
The entry point for logic is in mongoose_domain_api.
The module mongoose_domain_core should be always started.
service_domain_db needs to be specified in the TOML config.
service_domain_db_SUITE contains tests.
@arcusfelis arcusfelis marked this pull request as ready for review March 9, 2021 15:40
false
end.

remove_all_unlocked() ->
Copy link
Collaborator

Choose a reason for hiding this comment

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

What is the purpose of such interface? There must be per domain operations, group removal should not be possible. Otherwise, it's impossible to implement domain add/remove hooks.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is the simplest way to recover if gen_server of a DB service crashes.

Copy link
Collaborator

@DenysGonchar DenysGonchar Mar 11, 2021

Choose a reason for hiding this comment

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

we must rework this. if this ETS is a source of truth for other components, it cannot spontaneously lose all the domains.

Copy link
Collaborator

Choose a reason for hiding this comment

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

putting here some notes after today's discussion:

there are 2 different cases when domains DB service can potentially crash:

  • During the MIM startup. before the initial filling of the ETS table (from DB) is done.
  • after initial ETS filling.

for the first case it's acceptable to completely drop the core's ETS table, because we cannot use events DB table to perform an update of the ETS table with the latest changes.

for the second case, we must use events DB table.

implementation notes:

  • core's gen_server must store the last applied event id.
  • at the beginning, before the initial ETS filling, this event id is undefined.
  • once initial ETS filling is done, event id is set for the first time.
  • after that event id is updated with each and every change of the ETS.
  • it must be possible to drop ETS data only if event id is not set yet.
  • after initialization of the event id, DB service (on restart) must use that stored event id to apply the latest changes to the ETS.
  • also we may want to extend the cleaning interval and max age parameters for the events DB table to some higher value, e.g. 1 day

@arcusfelis please add some implementation note in the source code.

%% must be added to the core MIM component described above.
%% Domains should be nameprepped using `jid:nameprep'
-spec init([pair()]) -> ok | {error, term()}.
init(Pairs) ->
Copy link
Collaborator

@DenysGonchar DenysGonchar Mar 10, 2021

Choose a reason for hiding this comment

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

It must accept as a second parameter the list of allowed host types.
Only operation with the specified host types are allowed! if an invalid host type is used, the corresponding error must be returned.

Also host types are just strings. So every correct domain name is a correct host type identifier, but not every host type is a correct domain name

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Also host types are just strings. So every correct domain name is a correct host type identifier, but not every host type is a correct domain name

so, it would not make it interchangeable with any code, which does nameprepping for the Host argument. Or requires host-type in the specification (hook api-s, pool api-s).

Copy link
Collaborator

@DenysGonchar DenysGonchar Mar 11, 2021

Choose a reason for hiding this comment

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

the host types automatically created for hosts declaration in config file will be interchangeable.

but the final goal is to ensure that MIM supports any string id for the host_type. that is one of the sanity checks.

Add db_reinserted_from_one_node_while_service_disabled_on_another testcase
Copy link
Member

@chrzaszcz chrzaszcz left a comment

Choose a reason for hiding this comment

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

Lots of good work! I have some comments, but with such a big change it is inevitable.

big_tests/tests/service_domain_db_SUITE.erl Outdated Show resolved Hide resolved
big_tests/tests/service_domain_db_SUITE.erl Outdated Show resolved Hide resolved
src/domain/mongoose_domain_core.erl Outdated Show resolved Hide resolved
src/domain/mongoose_domain_core.erl Outdated Show resolved Hide resolved
big_tests/tests/service_domain_db_SUITE.erl Outdated Show resolved Hide resolved
src/domain/service_domain_db.erl Outdated Show resolved Hide resolved
src/domain/service_domain_db.erl Show resolved Hide resolved
src/domain/mongoose_domain_sql.erl Show resolved Hide resolved
src/domain/mongoose_domain_api.erl Show resolved Hide resolved
src/domain/service_domain_db.erl Outdated Show resolved Hide resolved
-module(mongoose_domain_utils).
-export([halt_node/1]).

halt_node(ExitText) ->
Copy link
Collaborator

Choose a reason for hiding this comment

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

Just a side note, no need to change anything:

we should think about one common MIM helper module for such functionality

Copy link
Collaborator

@DenysGonchar DenysGonchar left a comment

Choose a reason for hiding this comment

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

just a side note, no need to change anything in this PR:

in the future we should split service_domain_db_SUITE.erl into 2 separate suites:

  • one for the domains core module testing (MB even make it a unit test)
  • another for service testing

and of course we will have to extend (and rework if required) dynamic domain documentation as we progress with implementation.

Copy link
Member

@chrzaszcz chrzaszcz left a comment

Choose a reason for hiding this comment

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

Minor comments that should be addressed in subsequent PR's.

Comment on lines +36 to +37
db_reanabled_domain_is_in_db,
db_reanabled_domain_is_in_core,
Copy link
Member

Choose a reason for hiding this comment

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

Minor typo: reenabled

src/domain/mongoose_domain_api.erl Show resolved Hide resolved
get_all_static() ->
mongoose_domain_core:get_all_static().

%% Get the list of the host\_types provided during initialisation
Copy link
Member

Choose a reason for hiding this comment

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

Minor:

Suggested change
%% Get the list of the host\_types provided during initialisation
%% Get the list of the host_types provided during initialisation

end.

check_for_updates(FromId, PageSize) ->
check_if_from_num_still_relevant(FromId),
Copy link
Member

Choose a reason for hiding this comment

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

Minor:

Suggested change
check_if_from_num_still_relevant(FromId),
check_if_from_id_still_relevant(FromId),


check_for_updates(FromId, PageSize) ->
check_if_from_num_still_relevant(FromId),
%% Ordered by the earlist events first
Copy link
Member

Choose a reason for hiding this comment

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

Minor:

Suggested change
%% Ordered by the earlist events first
%% Ordered by the earliest events first

src/domain/mongoose_domain_loader.erl Show resolved Hide resolved
Comment on lines +50 to +51
check_if_from_num_still_relevant(0) ->
ok;
Copy link
Member

Choose a reason for hiding this comment

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

This returns ok but what if some records were added in the meantime (while there was no connection to the DB) and then cleanup happened? I think that we should still check that Min = 1 or something like that to make sure no cleanup was done.

@chrzaszcz chrzaszcz merged commit 3626394 into multi-tenancy-phase-1 Mar 17, 2021
@chrzaszcz chrzaszcz deleted the mu-multi-tenancy-phase-1-db branch March 17, 2021 07:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants