-
Notifications
You must be signed in to change notification settings - Fork 28.1k
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
[SPARK-529] [core] [yarn] Add type-safe config keys to SparkConf. #10205
Closed
Closed
Changes from all commits
Commits
Show all changes
36 commits
Select commit
Hold shift + click to select a range
8b00d76
[RFC] Add type-safe config keys to SparkConf.
85ab5f1
Silence mima.
bda7e2b
Fix HiveContext.
93736c2
Add entry for spark.executor.instances.
c858fa8
Move code around, create object for core config keys.
c1de25f
Implement Andrew's suggestion (`import foo.config._`).
c07293f
Merge branch 'master' into conf-opts
6b6eb27
Reorder / regroup YARN configs.
86296fd
Move mima excludes to new, correct place.
d378ced
Merge branch 'master' into conf-opts
e91c91a
Fix typo.
db4a8ae
Merge branch 'master' into conf-opts
9878c39
Merge branch 'master' into conf-opts
c3d1b4a
Merge branch 'master' into conf-opts
d8ca3e1
Allow negative values in bytesConf.
e7f775a
Fix scalastyle.
b3a3b18
Fix broken merge.
3fd9c5e
Merge branch 'master' into conf-opts
d96d92d
Merge branch 'master' into conf-opts
6f7a6d7
Revert unneeded changes.
e5604d3
Merge branch 'master' into conf-opts
e2ec60e
Feedback.
0bbee02
Use a builder to construct config options.
69142ab
Merge branch 'master' into conf-opts
0d96e3a
Fix borked merge.
03dc641
Allow transformation of config data.
0f0147c
Fix a NPE.
885d4a6
Change the way seq configs are defined.
34fed1c
Merge branch 'master' into conf-opts
3a3968d
Merge branch 'master' into conf-opts
3d15e54
Use orNull.
b6928ea
Merge branch 'master' into conf-opts
fc48cf0
Revert sql changes (to be submitted separately).
be1daed
Move new classes to an "internal" package.
dbfed7d
Merge branch 'master' into conf-opts
31156aa
Add some more javadocs.
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
184 changes: 184 additions & 0 deletions
184
core/src/main/scala/org/apache/spark/internal/config/ConfigBuilder.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,184 @@ | ||
/* | ||
* Licensed to the Apache Software Foundation (ASF) under one or more | ||
* contributor license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright ownership. | ||
* The ASF licenses this file to You under the Apache License, Version 2.0 | ||
* (the "License"); you may not use this file except in compliance with | ||
* the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package org.apache.spark.internal.config | ||
|
||
import java.util.concurrent.TimeUnit | ||
|
||
import org.apache.spark.network.util.{ByteUnit, JavaUtils} | ||
|
||
private object ConfigHelpers { | ||
|
||
def toNumber[T](s: String, converter: String => T, key: String, configType: String): T = { | ||
try { | ||
converter(s) | ||
} catch { | ||
case _: NumberFormatException => | ||
throw new IllegalArgumentException(s"$key should be $configType, but was $s") | ||
} | ||
} | ||
|
||
def toBoolean(s: String, key: String): Boolean = { | ||
try { | ||
s.toBoolean | ||
} catch { | ||
case _: IllegalArgumentException => | ||
throw new IllegalArgumentException(s"$key should be boolean, but was $s") | ||
} | ||
} | ||
|
||
def stringToSeq[T](str: String, converter: String => T): Seq[T] = { | ||
str.split(",").map(_.trim()).filter(_.nonEmpty).map(converter) | ||
} | ||
|
||
def seqToString[T](v: Seq[T], stringConverter: T => String): String = { | ||
v.map(stringConverter).mkString(",") | ||
} | ||
|
||
def timeFromString(str: String, unit: TimeUnit): Long = JavaUtils.timeStringAs(str, unit) | ||
|
||
def timeToString(v: Long, unit: TimeUnit): String = TimeUnit.MILLISECONDS.convert(v, unit) + "ms" | ||
|
||
def byteFromString(str: String, unit: ByteUnit): Long = { | ||
val (input, multiplier) = | ||
if (str.length() > 0 && str.charAt(0) == '-') { | ||
(str.substring(1), -1) | ||
} else { | ||
(str, 1) | ||
} | ||
multiplier * JavaUtils.byteStringAs(input, unit) | ||
} | ||
|
||
def byteToString(v: Long, unit: ByteUnit): String = unit.convertTo(v, ByteUnit.BYTE) + "b" | ||
|
||
} | ||
|
||
/** | ||
* A type-safe config builder. Provides methods for transforming the input data (which can be | ||
* used, e.g., for validation) and creating the final config entry. | ||
* | ||
* One of the methods that return a [[ConfigEntry]] must be called to create a config entry that | ||
* can be used with [[SparkConf]]. | ||
*/ | ||
private[spark] class TypedConfigBuilder[T]( | ||
val parent: ConfigBuilder, | ||
val converter: String => T, | ||
val stringConverter: T => String) { | ||
|
||
import ConfigHelpers._ | ||
|
||
def this(parent: ConfigBuilder, converter: String => T) = { | ||
this(parent, converter, Option(_).map(_.toString).orNull) | ||
} | ||
|
||
def transform(fn: T => T): TypedConfigBuilder[T] = { | ||
new TypedConfigBuilder(parent, s => fn(converter(s)), stringConverter) | ||
} | ||
|
||
def checkValues(validValues: Set[T]): TypedConfigBuilder[T] = { | ||
transform { v => | ||
if (!validValues.contains(v)) { | ||
throw new IllegalArgumentException( | ||
s"The value of ${parent.key} should be one of ${validValues.mkString(", ")}, but was $v") | ||
} | ||
v | ||
} | ||
} | ||
|
||
def toSequence: TypedConfigBuilder[Seq[T]] = { | ||
new TypedConfigBuilder(parent, stringToSeq(_, converter), seqToString(_, stringConverter)) | ||
} | ||
|
||
/** Creates a [[ConfigEntry]] that does not require a default value. */ | ||
def optional: OptionalConfigEntry[T] = { | ||
new OptionalConfigEntry[T](parent.key, converter, stringConverter, parent._doc, parent._public) | ||
} | ||
|
||
/** Creates a [[ConfigEntry]] that has a default value. */ | ||
def withDefault(default: T): ConfigEntry[T] = { | ||
val transformedDefault = converter(stringConverter(default)) | ||
new ConfigEntryWithDefault[T](parent.key, transformedDefault, converter, stringConverter, | ||
parent._doc, parent._public) | ||
} | ||
|
||
/** | ||
* Creates a [[ConfigEntry]] that has a default value. The default value is provided as a | ||
* [[String]] and must be a valid value for the entry. | ||
*/ | ||
def withDefaultString(default: String): ConfigEntry[T] = { | ||
val typedDefault = converter(default) | ||
new ConfigEntryWithDefault[T](parent.key, typedDefault, converter, stringConverter, parent._doc, | ||
parent._public) | ||
} | ||
|
||
} | ||
|
||
/** | ||
* Basic builder for Spark configurations. Provides methods for creating type-specific builders. | ||
* | ||
* @see TypedConfigBuilder | ||
*/ | ||
private[spark] case class ConfigBuilder(key: String) { | ||
|
||
import ConfigHelpers._ | ||
|
||
var _public = true | ||
var _doc = "" | ||
|
||
def internal: ConfigBuilder = { | ||
_public = false | ||
this | ||
} | ||
|
||
def doc(s: String): ConfigBuilder = { | ||
_doc = s | ||
this | ||
} | ||
|
||
def intConf: TypedConfigBuilder[Int] = { | ||
new TypedConfigBuilder(this, toNumber(_, _.toInt, key, "int")) | ||
} | ||
|
||
def longConf: TypedConfigBuilder[Long] = { | ||
new TypedConfigBuilder(this, toNumber(_, _.toLong, key, "long")) | ||
} | ||
|
||
def doubleConf: TypedConfigBuilder[Double] = { | ||
new TypedConfigBuilder(this, toNumber(_, _.toDouble, key, "double")) | ||
} | ||
|
||
def booleanConf: TypedConfigBuilder[Boolean] = { | ||
new TypedConfigBuilder(this, toBoolean(_, key)) | ||
} | ||
|
||
def stringConf: TypedConfigBuilder[String] = { | ||
new TypedConfigBuilder(this, v => v) | ||
} | ||
|
||
def timeConf(unit: TimeUnit): TypedConfigBuilder[Long] = { | ||
new TypedConfigBuilder(this, timeFromString(_, unit), timeToString(_, unit)) | ||
} | ||
|
||
def bytesConf(unit: ByteUnit): TypedConfigBuilder[Long] = { | ||
new TypedConfigBuilder(this, byteFromString(_, unit), byteToString(_, unit)) | ||
} | ||
|
||
def fallbackConf[T](fallback: ConfigEntry[T]): ConfigEntry[T] = { | ||
new FallbackConfigEntry(key, _doc, _public, fallback) | ||
} | ||
|
||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
can you add java doc, mention something like: