// Copyright 2017 Twitter. All rights reserved.
//
// Licensed 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 com.twitter.heron.common.config;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalUnit;
import java.util.HashMap;
import java.util.Map;
import com.twitter.heron.common.basics.ByteAmount;
/**
* Keys to be used in the SystemConfigs
*/
// TODO(mfu): Provide default values for all configs uniformly
// TODO(mfu): https://github.com/twitter/heron/issues/970
public enum SystemConfigKey {
/**
* The relative path to the logging directory
*/
HERON_LOGGING_DIRECTORY("heron.logging.directory", Type.STRING),
/**
* The maximum log file size in MB
*/
HERON_LOGGING_MAXIMUM_SIZE_MB("heron.logging.maximum.size.mb", Type.INTEGER),
/**
* The maximum number of log files
*/
HERON_LOGGING_MAXIMUM_FILES("heron.logging.maximum.files", Type.INTEGER),
/**
* The threshold level to log error
*/
HERON_LOGGING_ERR_THRESHOLD("heron.logging.err.threshold", Type.INTEGER),
/**
* The interval in seconds to get and reset the system metrics.
* The metrics collected will be sent to metrics manager
*/
HERON_METRICS_EXPORT_INTERVAL("heron.metrics.export.interval.sec", ChronoUnit.SECONDS),
/**
* The maximum number of exceptions in one MetricPublisherPublishMessage protobuf
*/
HERON_METRICS_MAX_EXCEPTIONS_PER_MESSAGE_COUNT(
"heron.metrics.max.exceptions.per.message.count", Integer.MAX_VALUE),
/**
* The queue capacity (num of items) in bolt for buffer packets to read from stream manager
*/
INSTANCE_INTERNAL_BOLT_READ_QUEUE_CAPACITY(
"heron.instance.internal.bolt.read.queue.capacity", Type.INTEGER),
/**
* The queue capacity (num of items) in bolt for buffer packets to write to stream manager
*/
INSTANCE_INTERNAL_BOLT_WRITE_QUEUE_CAPACITY(
"heron.instance.internal.bolt.write.queue.capacity", Type.INTEGER),
/**
* The queue capacity (num of items) in spout for buffer packets to read from stream manager
*/
INSTANCE_INTERNAL_SPOUT_READ_QUEUE_CAPACITY(
"heron.instance.internal.spout.read.queue.capacity", Type.INTEGER),
/**
* The queue capacity (num of items) in spout for buffer packets to write to stream manager
*/
INSTANCE_INTERNAL_SPOUT_WRITE_QUEUE_CAPACITY(
"heron.instance.internal.spout.write.queue.capacity", Type.INTEGER),
/**
* The queue capacity (num of items) for metrics packets to write to metrics manager
*/
INSTANCE_INTERNAL_METRICS_WRITE_QUEUE_CAPACITY(
"heron.instance.internal.metrics.write.queue.capacity", Type.INTEGER),
/**
* Time based, the maximum batch time in ms for instance to read from stream manager per attempt
*/
INSTANCE_NETWORK_READ_BATCH_TIME("heron.instance.network.read.batch.time.ms", ChronoUnit.MILLIS),
/**
* Size based,the maximum batch size in bytes to read from stream manager
*/
INSTANCE_NETWORK_READ_BATCH_SIZE(
"heron.instance.network.read.batch.size.bytes", Type.BYTE_AMOUNT),
/**
* Time based, the maximum batch time in ms for instance to read from stream manager per attempt
*/
INSTANCE_NETWORK_WRITE_BATCH_TIME(
"heron.instance.network.write.batch.time.ms", ChronoUnit.MILLIS),
/**
* Size based, the maximum batch size in bytes to write to stream manager
*/
INSTANCE_NETWORK_WRITE_BATCH_SIZE(
"heron.instance.network.write.batch.size.bytes", Type.BYTE_AMOUNT),
/**
* # The maximum socket's received buffer size in bytes of instance's network options
*/
INSTANCE_NETWORK_OPTIONS_SOCKET_RECEIVED_BUFFER_SIZE(
"heron.instance.network.options.socket.received.buffer.size.bytes", Type.BYTE_AMOUNT),
/**
* The maximum socket's send buffer size in bytes
*/
INSTANCE_NETWORK_OPTIONS_SOCKET_SEND_BUFFER_SIZE(
"heron.instance.network.options.socket.send.buffer.size.bytes", Type.BYTE_AMOUNT),
/**
* The maximum # of data tuple to batch in a HeronDataTupleSet protobuf
*/
INSTANCE_SET_DATA_TUPLE_CAPACITY("heron.instance.set.data.tuple.capacity", Type.INTEGER),
/**
* The maximum size in bytes of data tuple to batch in a HeronDataTupleSet protobuf
*/
INSTANCE_SET_DATA_TUPLE_SIZE(
"heron.instance.set.data.tuple.size.bytes", ByteAmount.fromBytes(Long.MAX_VALUE)),
/**
* The size of packets read from stream manager will be determined by the minimal of
* (a) time based (b) size based
*/
/**
* The maximum # of control tuple to batch in a HeronControlTupleSet protobuf
*/
INSTANCE_SET_CONTROL_TUPLE_CAPACITY("heron.instance.set.control.tuple.capacity", Type.INTEGER),
/**
* The maximum time in ms for an spout to do acknowledgement per attempt
*/
INSTANCE_ACK_BATCH_TIME("heron.instance.ack.batch.time.ms", ChronoUnit.MILLIS),
/**
* The size of packets written to stream manager will be determined by the minimal of
* (a) time based (b) size based
*/
/**
* The maximum time in ms for an spout instance to emit tuples per attempt
*/
INSTANCE_EMIT_BATCH_TIME("heron.instance.emit.batch.time.ms", ChronoUnit.MILLIS),
/**
* The maximum batch size in bytes for an spout instance to emit tuples per attempt
*/
INSTANCE_EMIT_BATCH_SIZE("heron.instance.emit.batch.size.bytes", Type.BYTE_AMOUNT),
/**
* The maximum time in ms for an bolt instance to execute tuples per attempt
*/
INSTANCE_EXECUTE_BATCH_TIME("heron.instance.execute.batch.time.ms", ChronoUnit.MILLIS),
/**
* The maximum batch size in bytes for an bolt instance to execute tuples per attempt
*/
INSTANCE_EXECUTE_BATCH_SIZE("heron.instance.execute.batch.size.bytes", Type.BYTE_AMOUNT),
/**
* The time interval for an instance to check the state change, for instance,
* the interval a spout using to check whether activate/deactivate is invoked
* Slated for removal, see https://github.com/twitter/heron/issues/1712
*/
INSTANCE_STATE_CHECK_INTERVAL("heron.instance.state.check.interval.sec", ChronoUnit.SECONDS),
/**
* The time to wait before the instance exits forcibly when uncaught exception happens
*/
INSTANCE_FORCE_EXIT_TIMEOUT("heron.instance.force.exit.timeout.ms", ChronoUnit.MILLIS),
/**
* Interval in seconds to reconnect to the stream manager
*/
INSTANCE_RECONNECT_STREAMMGR_INTERVAL(
"heron.instance.reconnect.streammgr.interval.sec", ChronoUnit.SECONDS),
/**
* Interval in seconds to reconnect to the metrics manager
*/
INSTANCE_RECONNECT_METRICSMGR_INTERVAL(
"heron.instance.reconnect.metricsmgr.interval.sec", ChronoUnit.SECONDS),
/**
* The interval in seconds to sample a system metric, for instance, jvm used memory.
*/
INSTANCE_METRICS_SYSTEM_SAMPLE_INTERVAL(
"heron.instance.metrics.system.sample.interval.sec", ChronoUnit.SECONDS),
/**
* The lookForTimeout Interval in spout instance will be timeoutInSeconds / NBUCKETS
* For instance, if a tuple's timeout is 30s, and NBUCKETS is 10
* The spout instance will check whether there are timeout tuples every 3 seconds
*/
INSTANCE_ACKNOWLEDGEMENT_NBUCKETS("heron.instance.acknowledgement.nbuckets", Type.INTEGER),
/**
* The interval for different threads to attempt to fetch physical plan from SingletonRegistry
*/
INSTANCE_SLAVE_FETCH_PPLAN_INTERVAL(
"heron.instance.slave.fetch.pplan.interval.sec", ChronoUnit.SECONDS),
/**
* The expected size on read queue in bolt
*/
INSTANCE_TUNING_EXPECTED_BOLT_READ_QUEUE_SIZE(
"heron.instance.tuning.expected.bolt.read.queue.size", Type.INTEGER),
/**
* The expected size on write queue in bolt
*/
INSTANCE_TUNING_EXPECTED_BOLT_WRITE_QUEUE_SIZE(
"heron.instance.tuning.expected.bolt.write.queue.size", Type.INTEGER),
/**
* The expected size on read queue in spout
*/
INSTANCE_TUNING_EXPECTED_SPOUT_READ_QUEUE_SIZE(
"heron.instance.tuning.expected.spout.read.queue.size", Type.INTEGER),
/**
* The exepected size on write queue in spout
*/
INSTANCE_TUNING_EXPECTED_SPOUT_WRITE_QUEUE_SIZE(
"heron.instance.tuning.expected.spout.write.queue.size", Type.INTEGER),
/**
* The expected size on metrics write queue
*/
INSTANCE_TUNING_EXPECTED_METRICS_WRITE_QUEUE_SIZE(
"heron.instance.tuning.expected.metrics.write.queue.size", Type.INTEGER),
/**
* During dynamically tuning, the weight of new sample size to calculate
* the available capacity of queue.
* We use Exponential moving average: En = (1-w) * En-1 + w * An
* http://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average
*/
INSTANCE_TUNING_CURRENT_SAMPLE_WEIGHT("heron.instance.tuning.current.sample.weight", Type.DOUBLE),
/**
* Interval in ms to tune the size of in & out data queue in instance
*/
INSTANCE_TUNING_INTERVAL("heron.instance.tuning.interval.ms", ChronoUnit.MILLIS),
/**
* The size of packets read from socket will be determined by the minimal of:
* (a) time based (b) size based
* <p>
* Time based, the maximum batch time in ms for instance to read from socket per attempt
*/
METRICSMGR_NETWORK_READ_BATCH_TIME(
"heron.metricsmgr.network.read.batch.time.ms", ChronoUnit.MILLIS),
/**
* Size based,the maximum batch size in bytes to read from socket
*/
METRICSMGR_NETWORK_READ_BATCH_SIZE(
"heron.metricsmgr.network.read.batch.size.bytes", Type.BYTE_AMOUNT),
/**
* The size of packets written to socket will be determined by the minimal of
* (a) time based (b) size based
* <p>
* Time based, the maximum batch time in ms to write to socket
*/
METRICSMGR_NETWORK_WRITE_BATCH_TIME(
"heron.metricsmgr.network.write.batch.time.ms", ChronoUnit.MILLIS),
/**
* Size based, the maximum batch size in bytes to write to socket
*/
METRICSMGR_NETWORK_WRITE_BATCH_SIZE(
"heron.metricsmgr.network.write.batch.size.bytes", Type.BYTE_AMOUNT),
/**
* The maximum socket's received buffer size in bytes
*/
METRICSMGR_NETWORK_OPTIONS_SOCKET_RECEIVED_BUFFER_SIZE(
"heron.metricsmgr.network.options.socket.received.buffer.size.bytes", Type.BYTE_AMOUNT),
/**
* The maximum socket's send buffer size in bytes
*/
METRICSMGR_NETWORK_OPTIONS_SOCKET_SEND_BUFFER_SIZE(
"heron.metricsmgr.network.options.socket.send.buffer.size.bytes", Type.BYTE_AMOUNT),
/**
*The maximum exception count be kept in tmaster
*/
TMASTER_METRICS_COLLECTOR_MAXIMUM_EXCEPTION(
"heron.tmaster.metrics.collector.maximum.exception", Type.LONG),
/**
* The maximum interval in minutes of metrics to be kept in tmaster
*/
TMASTER_METRICS_COLLECTOR_MAXIMUM_INTERVAL(
"heron.tmaster.metrics.collector.maximum.interval.min",
ChronoUnit.MINUTES, Duration.ofHours(3)),
/**
* The interval for tmaster to purge metrics from socket
*/
TMASTER_METRICS_COLLECTOR_PURGE_INTERVAL(
"heron.tmaster.metrics.collector.purge.interval.sec",
ChronoUnit.SECONDS, Duration.ofMinutes(1));
private final String value;
private final Object defaultValue;
private final Type type;
private final TemporalUnit temporalUnit; // only used for Duration types
public enum Type {
BOOLEAN,
BYTE_AMOUNT,
DOUBLE,
DURATION,
INTEGER,
LONG,
STRING
}
// Map of value -> enum
private static final Map<String, SystemConfigKey> VALUE_MAP;
static {
VALUE_MAP = new HashMap<>();
for (SystemConfigKey key : SystemConfigKey.values()) {
VALUE_MAP.put(key.value(), key);
}
}
SystemConfigKey(String value, Type type) {
if (type == Type.DURATION) {
throw new IllegalArgumentException("DURATION types are created by passing a temporalUnit");
}
this.value = value;
this.type = type;
this.defaultValue = null;
this.temporalUnit = null;
}
SystemConfigKey(String value, TemporalUnit temporalUnit) {
this(value, temporalUnit, null);
}
SystemConfigKey(String value, String defaultValue) {
this.value = value;
this.type = Type.STRING;
this.defaultValue = defaultValue;
this.temporalUnit = null;
}
SystemConfigKey(String value, Integer defaultValue) {
this.value = value;
this.type = Type.INTEGER;
this.defaultValue = defaultValue;
this.temporalUnit = null;
}
SystemConfigKey(String value, Long defaultValue) {
this.value = value;
this.type = Type.LONG;
this.defaultValue = defaultValue;
this.temporalUnit = null;
}
SystemConfigKey(String value, Double defaultValue) {
this.value = value;
this.type = Type.DOUBLE;
this.defaultValue = defaultValue;
this.temporalUnit = null;
}
SystemConfigKey(String value, TemporalUnit temporalUnit, Duration defaultValue) {
this.value = value;
this.type = Type.DURATION;
this.defaultValue = defaultValue;
this.temporalUnit = temporalUnit;
}
SystemConfigKey(String value, Boolean defaultValue) {
this.value = value;
this.type = Type.BOOLEAN;
this.defaultValue = defaultValue;
this.temporalUnit = null;
}
SystemConfigKey(String value, ByteAmount defaultValue) {
this.value = value;
this.type = Type.BYTE_AMOUNT;
this.defaultValue = defaultValue;
this.temporalUnit = null;
}
static SystemConfigKey toSystemConfigKey(String value) {
return VALUE_MAP.get(value);
}
/**
* Get the key value for this enum (i.e., heron.directory.home)
*
* @return key value
*/
String value() {
return value;
}
Type getType() {
return type;
}
TemporalUnit getTemporalUnit() {
return temporalUnit;
}
/**
* Return the default value
*/
Object getDefault() {
return this.defaultValue;
}
public String getDefaultString() {
if (type != Type.STRING) {
throw new IllegalAccessError(String.format(
"Config Key %s is type %s, getDefaultString() not supported", this.name(), this.type));
}
return (String) this.defaultValue;
}
}