diff --git a/docs/changelog/7.x.x.txt b/docs/changelog/7.x.x.txt index 428711e47..a98175d29 100644 --- a/docs/changelog/7.x.x.txt +++ b/docs/changelog/7.x.x.txt @@ -7,6 +7,7 @@ - added: Group Manager form control - fixed #12050: Thing query caching #1 - added: Let CHI cache request $dbh via an "args" : [ "dbh" ] cache conf + - added: lineage increment_step and increment_offset for multi-master DB clusters 7.10.11 - fixed #12057: WebGUI::Search, assetIds search clause diff --git a/etc/WebGUI.conf.original b/etc/WebGUI.conf.original index 22bae7443..721372ed4 100644 --- a/etc/WebGUI.conf.original +++ b/etc/WebGUI.conf.original @@ -154,6 +154,24 @@ # "password" : "password" # }, +# If you have a multi-master set up, you must define increment_step and increment_offset +# to prevent merge conflicts between the different masters. increment_step should be set +# to the number of masters, and offset should be unique to each master, starting at 0. +# +# So, a 2-master cluster would define: +# Master 1: +# increment_step: 2 +# increment_offset: 0 +# Master 2: +# increment_step: 2 +# increment_offset: 1 +# +# "db" : { +# "increment_step" : 1, +# "increment_offset" : 0 +# }, + + # Set this value if you wish to override all outbound emails to a specific # user for testing purposes. diff --git a/lib/WebGUI/AssetLineage.pm b/lib/WebGUI/AssetLineage.pm index edbc434c3..04ef89291 100644 --- a/lib/WebGUI/AssetLineage.pm +++ b/lib/WebGUI/AssetLineage.pm @@ -763,19 +763,25 @@ Returns a 6 digit number with leading zeros of the next rank a child will get. =cut sub getNextChildRank { - my $self = shift; - my ($lineage) = $self->session->db->quickArray("select max(lineage) from asset where parentId=?",[$self->getId]); - my $rank; - if (defined $lineage) { - $rank = $self->getRank($lineage); - $self->session->errorHandler->fatal("Asset ".$self->getId." has too many children.") if ($rank >= 999998); - $rank++; - } else { - $rank = 1; - } - return $self->formatRank($rank); -} + my $self = shift; + # Increment by steps for servers in multi-master DB setups + my $inc_step = $self->session->config->get('db/increment_step') || 1; + my $inc_offset = $self->session->config->get('db/increment_offset') || 0; + + my ($lineage) = $self->session->db->quickArray("select max(lineage) from asset where parentId=?",[$self->getId]); + my $rank; + if (defined $lineage) { + $rank = $self->getRank($lineage); + # Increase rank to next step then add offset + $rank += ( $inc_step - $rank % $inc_step ) + $inc_offset; + $self->session->errorHandler->fatal("Asset ".$self->getId." has too many children.") if ($rank >= 999999); # Each lineage area is only 6 digits + } + else { + $rank = 1; + } + return $self->formatRank($rank); +} #------------------------------------------------------------------- diff --git a/t/Asset/AssetLineage.t b/t/Asset/AssetLineage.t index e13a818b0..d32a0d1b7 100644 --- a/t/Asset/AssetLineage.t +++ b/t/Asset/AssetLineage.t @@ -17,7 +17,7 @@ use WebGUI::Session; use WebGUI::User; use WebGUI::Asset; -use Test::More tests => 96; # increment this value for each test you create +use Test::More tests => 98; # increment this value for each test you create use Test::Deep; # Test the methods in WebGUI::AssetLineage @@ -234,6 +234,12 @@ is($root->getRank('100001'), '100001', "getRank: arbitrary lineage"); is($folder->getNextChildRank, '000008', "getNextChildRank: folder with 8 snippets"); is($folder2->getNextChildRank, '000002', "getNextChildRank: empty folder"); +# Change the step and offset +$session->config->set( 'db', { increment_step => 5, increment_offset => 3 } ); +is( $folder->getNextChildRank, '000013', "getNextChildRank: step 5, offset 3, folder with 8 snippets" ); +is( $folder2->getNextChildRank, '000008', "getNextChildRank: step 5, offset 3, empty folder" ); +$session->config->delete( 'db' ); + #################################################### # # swapRank