Skip to content

Commit 756f699

Browse files
committed
Async the group de-index during upload in content-index service
Recent performance problem we met for uploading & promotion is all caused by the getAffectedBy operation, which is a time-consumed one for a full scan on store data. After checking, I found that it is mainly used for de-index or re-index content-index entries for the uploading repo. I think this de-index will not be a block factor during the upload or promotion process, which means we could make it async. In this commit, I switched back to use a normal executor service to async the de-index of the affected group. One potential problem for this solution is the executor queue size, which could cause OOM if there are bunch of uploading happened in a short time period. We need to monitor if this can happen.
1 parent 7b0bc2d commit 756f699

File tree

1 file changed

+40
-26
lines changed

1 file changed

+40
-26
lines changed

addons/content-index/src/main/java/org/commonjava/indy/content/index/IndexingContentManagerDecorator.java

+40-26
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,15 @@
1515
*/
1616
package org.commonjava.indy.content.index;
1717

18+
import org.commonjava.cdi.util.weft.ExecutorConfig;
19+
import org.commonjava.cdi.util.weft.WeftManaged;
1820
import org.commonjava.indy.IndyWorkflowException;
1921
import org.commonjava.indy.content.ContentManager;
2022
import org.commonjava.indy.content.index.conf.ContentIndexConfig;
2123
import org.commonjava.indy.core.content.PathMaskChecker;
2224
import org.commonjava.indy.data.IndyDataException;
2325
import org.commonjava.indy.data.StoreDataManager;
2426
import org.commonjava.indy.measure.annotation.Measure;
25-
import org.commonjava.indy.measure.annotation.MetricNamed;
2627
import org.commonjava.indy.model.core.ArtifactStore;
2728
import org.commonjava.indy.model.core.Group;
2829
import org.commonjava.indy.model.core.HostedRepository;
@@ -51,10 +52,10 @@
5152
import java.util.List;
5253
import java.util.Objects;
5354
import java.util.Set;
55+
import java.util.concurrent.Executor;
5456

5557
import static org.commonjava.indy.core.content.group.GroupMergeHelper.GROUP_METADATA_EXISTS;
5658
import static org.commonjava.indy.core.content.group.GroupMergeHelper.GROUP_METADATA_GENERATED;
57-
import static org.commonjava.indy.measure.annotation.MetricNamed.DEFAULT;
5859

5960
/**
6061
* Decorator for ContentManager which uses Infinispan to index content to avoid having to iterate all members of large
@@ -88,6 +89,11 @@ public abstract class IndexingContentManagerDecorator
8889
@Inject
8990
private ContentIndexConfig indexCfg;
9091

92+
@Inject
93+
@WeftManaged
94+
@ExecutorConfig( named="content-index-store-deindex", priority = 4, threads = 10)
95+
private Executor deIndexExecutor;
96+
9197
protected IndexingContentManagerDecorator()
9298
{
9399
}
@@ -112,6 +118,15 @@ protected IndexingContentManagerDecorator( final ContentManager delegate, final
112118
this.indexCfg = indexCfg;
113119
}
114120

121+
protected IndexingContentManagerDecorator( final ContentManager delegate, final StoreDataManager storeDataManager,
122+
final SpecialPathManager specialPathManager,
123+
final ContentIndexManager indexManager, final NotFoundCache nfc,
124+
final ContentIndexConfig indexCfg, final Executor deIndexExecutor)
125+
{
126+
this(delegate, storeDataManager, specialPathManager, indexManager, nfc, indexCfg);
127+
this.deIndexExecutor = deIndexExecutor;
128+
}
129+
115130
@Override
116131
public Transfer retrieveFirst( final List<? extends ArtifactStore> stores, final String path )
117132
throws IndyWorkflowException
@@ -163,12 +178,7 @@ public List<Transfer> retrieveAll( final List<? extends ArtifactStore> stores, f
163178
}
164179

165180
return null;
166-
} ).filter( Objects::nonNull ).forEachOrdered( ( transfer ) -> {
167-
if ( transfer != null )
168-
{
169-
results.add( transfer );
170-
}
171-
} );
181+
} ).filter( Objects::nonNull ).forEachOrdered( results::add );
172182

173183
return results;
174184
}
@@ -200,7 +210,7 @@ public Transfer retrieve( final ArtifactStore store, final String path, final Ev
200210
else if ( isAuthoritativelyMissing( store ) )
201211
{
202212
logger.debug(
203-
"Not found indexed transfer: {} and authoritative index switched on. Considering not found and return null." );
213+
"Not found indexed transfer: {} and authoritative index switched on. Considering not found and return null.", transfer );
204214
return null;
205215
}
206216

@@ -286,7 +296,7 @@ else if ( isAuthoritativelyMissing( store ) )
286296
{
287297
; // metadata generated/exists but missing due to membership change, not add to nfc so next req can retry
288298
}
289-
else if ( StoreType.hosted != type ) // don't track NFC for hosted repos
299+
else // don't track NFC for hosted repos
290300
{
291301
nfc.addMissing( resource );
292302
}
@@ -458,7 +468,7 @@ public Transfer getTransfer( final ArtifactStore store, final String path, final
458468
else if ( isAuthoritativelyMissing( store ) )
459469
{
460470
logger.info(
461-
"Not found indexed transfer: {} and authoritative index switched on. Considering not found and return null." );
471+
"Not found indexed transfer: {} and authoritative index switched on. Considering not found and return null.", transfer );
462472
return null;
463473
}
464474

@@ -510,7 +520,7 @@ else if ( isAuthoritativelyMissing( store ) )
510520
return transfer;
511521
}
512522

513-
@Measure( timers = @MetricNamed( DEFAULT ), exceptions = @MetricNamed( DEFAULT ) )
523+
@Measure
514524
@Deprecated
515525
public Transfer getIndexedMemberTransfer( final Group group, final String path, TransferOperation op,
516526
ContentManagementFunction func, final EventMetadata metadata )
@@ -602,7 +612,7 @@ public Transfer getTransfer( final StoreKey storeKey, final String path, final T
602612

603613
if ( isAuthoritativelyMissing( store ) )
604614
{
605-
logger.debug( "Not found indexed transfer: {} and authoritative index switched on. Return null." );
615+
logger.debug( "Not found indexed transfer: {} and authoritative index switched on. Return null.", transfer );
606616
return null;
607617
}
608618

@@ -713,21 +723,25 @@ public Transfer store( final ArtifactStore store, final String path, final Input
713723
// may change the content index sequence based on the constituents sequence in parent groups
714724
if ( store.getType() == StoreType.hosted )
715725
{
716-
try
717-
{
718-
Set<Group> groups = storeDataManager.query().getGroupsAffectedBy( store.getKey() );
719-
if ( groups != null && !groups.isEmpty() && indexCfg.isEnabled() )
726+
//FIXME: One potential problem here: The fixed thread pool is using a blocking queue to
727+
// cache runnables, which could cause OOM if there are bunch of uploading happened in
728+
// a short time period. We need to monitor if this could happen.
729+
deIndexExecutor.execute( () -> {
730+
try
720731
{
721-
groups.forEach( g -> indexManager.deIndexStorePath( g.getKey(), path ) );
732+
Set<Group> groups = storeDataManager.query().getGroupsAffectedBy( store.getKey() );
733+
if ( groups != null && !groups.isEmpty() && indexCfg.isEnabled() )
734+
{
735+
groups.forEach( g -> indexManager.deIndexStorePath( g.getKey(), path ) );
736+
}
722737
}
723-
}
724-
catch ( IndyDataException e )
725-
{
726-
throw new IndyWorkflowException(
727-
"Failed to get groups which contains: %s for NFC handling. Reason: %s", e, store.getKey(),
728-
e.getMessage() );
729-
}
730-
738+
catch ( IndyDataException e )
739+
{
740+
logger.error(
741+
String.format( "Failed to get groups which contains: %s for NFC handling. Reason: %s",
742+
store.getKey(), e.getMessage() ), e );
743+
}
744+
} );
731745
}
732746
}
733747
// nfcClearByContaining( store, path );

0 commit comments

Comments
 (0)