I use the spring-boot-data-cassandra to connect to my cassandra cluster. my application configuration is so:

spring.data.cassandra.pool.heartbeat-interval=30s

as above, I set the heartbeat-interval to 30 seconds. but after application started, I cann't see any debug information about heartbeat actions by datastax driver. my log4j configuration was set to :

 <Logger name="org.springframework.data.cassandra" level="debug" additivity="true">
        </Logger>
        <Logger name="com.datastax" level="debug" additivity="true">
</Logger>

Then I turn on the code, found it may be a bug by CassandraAutoConfiguration, the snippets as so:

private void mapPoolingOptions(CassandraProperties properties, CassandraDriverOptions options) {
        PropertyMapper map = PropertyMapper.get();
        CassandraProperties.Pool poolProperties = properties.getPool();
        map.from(poolProperties::getIdleTimeout).whenNonNull().asInt(Duration::getSeconds)
                .to((idleTimeout) -> options.add(DefaultDriverOption.HEARTBEAT_TIMEOUT, idleTimeout));
        map.from(poolProperties::getHeartbeatInterval).whenNonNull().asInt(Duration::getSeconds)
                .to((heartBeatInterval) -> options.add(DefaultDriverOption.HEARTBEAT_INTERVAL, heartBeatInterval));
    }

as above, it set DefaultDriverOption.HEARTBEAT_INTERVAL to an integer value(seconds),but datastax driver treat it as mills default, just like this: com.typesafe.config.impl.SimpleConfig.java

    public static long parseDuration(String input,
            ConfigOrigin originForException, String pathForException) {
        String s = ConfigImplUtil.unicodeTrim(input);
        String originalUnitString = getUnits(s);
        String unitString = originalUnitString;
        String numberString = ConfigImplUtil.unicodeTrim(s.substring(0, s.length()
                - unitString.length()));
        TimeUnit units = null;

        // this would be caught later anyway, but the error message
        // is more helpful if we check it here.
        if (numberString.length() == 0)
            throw new ConfigException.BadValue(originForException,
                    pathForException, "No number in duration value '" + input
                            + "'");

        if (unitString.length() > 2 && !unitString.endsWith("s"))
            unitString = unitString + "s";

        // note that this is deliberately case-sensitive
        if (unitString.equals("") || unitString.equals("ms") || unitString.equals("millis")
                || unitString.equals("milliseconds")) {
            units = TimeUnit.MILLISECONDS;

so, because 30 millis was too short, and HeartbeatHandler cast it to 0 seconds com.datastax.oss.driver.internal.core.channel.HeartbeatHandler:

  HeartbeatHandler(DriverExecutionProfile config) {
    super((int) config.getDuration(DefaultDriverOption.HEARTBEAT_INTERVAL).getSeconds(), 0, 0);
    this.config = config;
  }

so, there may be some thing to change about CassandraAutoConfiguration ?

Comment From: snicoll

@littleatp thanks for the report. You are right, it is using the wrong unit. I got tricked by the fact that the driver itself was requesting seconds from the configuration. The Heartbeat timeout is most probably affected as well.

Comment From: snicoll

Given SimpleConfig#parseDuration contract, we should be indeed using ms for all keys. This also means that the default unit for the heartbeat properties is wrong.