-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
MapperService has to be passed in as null for EnginePlugins CodecService constructor #2177
Changes from 4 commits
45665db
17c0abb
5c136be
eeeab29
5379899
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
/* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
* The OpenSearch Contributors require contributions made to | ||
* this file be licensed under the Apache-2.0 license or a | ||
* compatible open source license. | ||
*/ | ||
|
||
package org.opensearch.index.codec; | ||
|
||
import org.apache.logging.log4j.Logger; | ||
import org.opensearch.common.Nullable; | ||
import org.opensearch.index.IndexSettings; | ||
import org.opensearch.index.mapper.MapperService; | ||
|
||
import java.util.Objects; | ||
|
||
/** | ||
* The configuration parameters necessary for the {@link CodecService} instance construction. | ||
*/ | ||
public final class CodecServiceConfig { | ||
private final IndexSettings indexSettings; | ||
private final MapperService mapperService; | ||
private final Logger logger; | ||
|
||
public CodecServiceConfig(IndexSettings indexSettings, @Nullable MapperService mapperService, Logger logger) { | ||
this.indexSettings = Objects.requireNonNull(indexSettings); | ||
this.mapperService = mapperService; | ||
this.logger = logger; | ||
} | ||
|
||
public IndexSettings getIndexSettings() { | ||
return indexSettings; | ||
} | ||
|
||
@Nullable | ||
public MapperService getMapperService() { | ||
return mapperService; | ||
} | ||
|
||
public Logger getLogger() { | ||
return logger; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
/* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
* The OpenSearch Contributors require contributions made to | ||
* this file be licensed under the Apache-2.0 license or a | ||
* compatible open source license. | ||
*/ | ||
|
||
package org.opensearch.index.codec; | ||
|
||
/** | ||
* A factory for creating new {@link CodecService} instance | ||
*/ | ||
@FunctionalInterface | ||
public interface CodecServiceFactory { | ||
/** | ||
* Create new {@link CodecService} instance | ||
* @param config code service configuration | ||
* @return new {@link CodecService} instance | ||
*/ | ||
CodecService createCodecService(CodecServiceConfig config); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,6 +8,7 @@ | |
|
||
package org.opensearch.index.engine; | ||
|
||
import org.apache.logging.log4j.Logger; | ||
import org.apache.lucene.analysis.Analyzer; | ||
import org.apache.lucene.index.MergePolicy; | ||
import org.apache.lucene.search.QueryCache; | ||
|
@@ -18,6 +19,9 @@ | |
import org.opensearch.common.unit.TimeValue; | ||
import org.opensearch.index.IndexSettings; | ||
import org.opensearch.index.codec.CodecService; | ||
import org.opensearch.index.codec.CodecServiceConfig; | ||
import org.opensearch.index.codec.CodecServiceFactory; | ||
import org.opensearch.index.mapper.MapperService; | ||
import org.opensearch.index.seqno.RetentionLeases; | ||
import org.opensearch.index.shard.ShardId; | ||
import org.opensearch.index.store.Store; | ||
|
@@ -39,7 +43,7 @@ | |
* A factory to create an EngineConfig based on custom plugin overrides | ||
*/ | ||
public class EngineConfigFactory { | ||
private final CodecService codecService; | ||
private final CodecServiceFactory codecServiceFactory; | ||
private final TranslogDeletionPolicyFactory translogDeletionPolicyFactory; | ||
|
||
/** default ctor primarily used for tests without plugins */ | ||
|
@@ -58,14 +62,16 @@ public EngineConfigFactory(PluginsService pluginsService, IndexSettings idxSetti | |
EngineConfigFactory(Collection<EnginePlugin> enginePlugins, IndexSettings idxSettings) { | ||
Optional<CodecService> codecService = Optional.empty(); | ||
String codecServiceOverridingPlugin = null; | ||
Optional<CodecServiceFactory> codecServiceFactory = Optional.empty(); | ||
String codecServiceFactoryOverridingPlugin = null; | ||
Optional<TranslogDeletionPolicyFactory> translogDeletionPolicyFactory = Optional.empty(); | ||
String translogDeletionPolicyOverridingPlugin = null; | ||
for (EnginePlugin enginePlugin : enginePlugins) { | ||
// get overriding codec service from EnginePlugin | ||
if (codecService.isPresent() == false) { | ||
codecService = enginePlugin.getCustomCodecService(idxSettings); | ||
codecServiceOverridingPlugin = enginePlugin.getClass().getName(); | ||
} else { | ||
} else if (enginePlugin.getCustomCodecService(idxSettings).isPresent()) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems to be a bug: the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems bad. Has this case just never been hit because in practice there is only ever 1 engine plugin or because the last plugin in the list is the one to override the codec service? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hard to say, but I would guess that only handful of engine plugins do provide codec service (and probably there is usually only 1 as you mentioned). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right, and I believe this change was introduced in 1.2 as well |
||
throw new IllegalStateException( | ||
"existing codec service already overridden in: " | ||
+ codecServiceOverridingPlugin | ||
|
@@ -76,20 +82,47 @@ public EngineConfigFactory(PluginsService pluginsService, IndexSettings idxSetti | |
if (translogDeletionPolicyFactory.isPresent() == false) { | ||
translogDeletionPolicyFactory = enginePlugin.getCustomTranslogDeletionPolicyFactory(); | ||
translogDeletionPolicyOverridingPlugin = enginePlugin.getClass().getName(); | ||
} else { | ||
} else if (enginePlugin.getCustomTranslogDeletionPolicyFactory().isPresent()) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here |
||
throw new IllegalStateException( | ||
"existing TranslogDeletionPolicyFactory is already overridden in: " | ||
+ translogDeletionPolicyOverridingPlugin | ||
+ " attempting to override again by: " | ||
+ enginePlugin.getClass().getName() | ||
); | ||
} | ||
// get overriding CodecServiceFactory from EnginePlugin | ||
if (codecServiceFactory.isPresent() == false) { | ||
codecServiceFactory = enginePlugin.getCustomCodecServiceFactory(idxSettings); | ||
codecServiceFactoryOverridingPlugin = enginePlugin.getClass().getName(); | ||
} else if (enginePlugin.getCustomCodecServiceFactory(idxSettings).isPresent()) { | ||
throw new IllegalStateException( | ||
"existing codec service factory already overridden in: " | ||
+ codecServiceFactoryOverridingPlugin | ||
+ " attempting to override again by: " | ||
+ enginePlugin.getClass().getName() | ||
); | ||
} | ||
} | ||
|
||
if (codecService.isPresent() && codecServiceFactory.isPresent()) { | ||
throw new IllegalStateException( | ||
"both codec service and codec service factory are present, codec service provided by: " | ||
+ codecServiceOverridingPlugin | ||
+ " conflicts with codec service factory provided by: " | ||
+ codecServiceFactoryOverridingPlugin | ||
); | ||
} | ||
this.codecService = codecService.orElse(null); | ||
|
||
final CodecService instance = codecService.orElse(null); | ||
this.codecServiceFactory = (instance != null) ? (config) -> instance : codecServiceFactory.orElse(null); | ||
this.translogDeletionPolicyFactory = translogDeletionPolicyFactory.orElse((idxs, rtls) -> null); | ||
} | ||
|
||
/** Instantiates a new EngineConfig from the provided custom overrides */ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why cant we just delete this method and go with 179? This method looks to only be used IndexShard. Is it possible for plugin developers to access EngineConfigFactory.java? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a public method which could be used (by plugins fe) so we should not break them |
||
/** | ||
* Instantiates a new EngineConfig from the provided custom overrides | ||
* @deprecated please use overloaded {@code newEngineConfig} with {@link MapperService} | ||
*/ | ||
@Deprecated | ||
public EngineConfig newEngineConfig( | ||
ShardId shardId, | ||
ThreadPool threadPool, | ||
|
@@ -114,6 +147,61 @@ public EngineConfig newEngineConfig( | |
LongSupplier primaryTermSupplier, | ||
EngineConfig.TombstoneDocSupplier tombstoneDocSupplier | ||
) { | ||
return newEngineConfig( | ||
shardId, | ||
threadPool, | ||
indexSettings, | ||
warmer, | ||
store, | ||
mergePolicy, | ||
analyzer, | ||
similarity, | ||
codecService, | ||
eventListener, | ||
queryCache, | ||
queryCachingPolicy, | ||
translogConfig, | ||
flushMergesAfter, | ||
externalRefreshListener, | ||
internalRefreshListener, | ||
indexSort, | ||
circuitBreakerService, | ||
globalCheckpointSupplier, | ||
retentionLeasesSupplier, | ||
primaryTermSupplier, | ||
tombstoneDocSupplier, | ||
null, /* mapperService */ | ||
null /* logger */ | ||
); | ||
} | ||
|
||
/** Instantiates a new EngineConfig from the provided custom overrides */ | ||
public EngineConfig newEngineConfig( | ||
ShardId shardId, | ||
ThreadPool threadPool, | ||
IndexSettings indexSettings, | ||
Engine.Warmer warmer, | ||
Store store, | ||
MergePolicy mergePolicy, | ||
Analyzer analyzer, | ||
Similarity similarity, | ||
CodecService codecService, | ||
Engine.EventListener eventListener, | ||
QueryCache queryCache, | ||
QueryCachingPolicy queryCachingPolicy, | ||
TranslogConfig translogConfig, | ||
TimeValue flushMergesAfter, | ||
List<ReferenceManager.RefreshListener> externalRefreshListener, | ||
List<ReferenceManager.RefreshListener> internalRefreshListener, | ||
Sort indexSort, | ||
CircuitBreakerService circuitBreakerService, | ||
LongSupplier globalCheckpointSupplier, | ||
Supplier<RetentionLeases> retentionLeasesSupplier, | ||
LongSupplier primaryTermSupplier, | ||
EngineConfig.TombstoneDocSupplier tombstoneDocSupplier, | ||
MapperService mapperService, | ||
Logger logger | ||
) { | ||
|
||
return new EngineConfig( | ||
shardId, | ||
|
@@ -124,7 +212,9 @@ public EngineConfig newEngineConfig( | |
mergePolicy, | ||
analyzer, | ||
similarity, | ||
this.codecService != null ? this.codecService : codecService, | ||
this.codecServiceFactory != null | ||
? this.codecServiceFactory.createCodecService(new CodecServiceConfig(indexSettings, mapperService, logger)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should only build CodecService in one place and always use the factory. That way, we can avoid ternary statements like the above. For default CodecServiceFactory, we can set it like I did here. Im somewhat conflicted on where to build CodecService. I think there are 2 options: 1. Call
|
||
: codecService, | ||
eventListener, | ||
queryCache, | ||
queryCachingPolicy, | ||
|
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 we are passing index settings to the getCustomCodecServiceFactory, do we need to include them in CodecServiceConfig?
Im just wondering if we should steer plugin developers to make decisions based on index settings in getCustomCodecServiceFactory instead of in createCodecService. Would this limit functionality? Does it really matter where decisions on index settings are being made?
I think I am leaning towards limiting it to getCustomCodecServiceFactory. What are your thoughts @nknize @reta?
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.
We could, I believe the presence of the index settings could be beneficial, otherwise would leave that up to implementors to pass the index settings from
EnginePlugin
toCodecService
instance if needed