Skip to content
This repository was archived by the owner on Mar 3, 2026. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import scala.sys.process._

val gatlingVersion = "2.3.0"
val gatlingVersion = "2.3.1"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be part of a separate issue / PR?


scalacOptions += "-target:jvm-1.8"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,18 +61,10 @@ class CqlRequestAction(val name: String,
}

def sendQuery(session: Session): Unit = {
val enableCO = Boolean.getBoolean("gatling.dse.plugin.measure_service_time")
val responseTimeBuilder: ResponseTimeBuilder = if (enableCO) {
// The throughput checker is useless in CO affected scenarios since throughput is not known in advance
COAffectedResponseTime.startingAt(System.nanoTime())
} else {
ThroughputVerifier.checkForGatlingOverloading(session, gatlingTimingSource)
GatlingResponseTime.startedByGatling(session, gatlingTimingSource)
}
val stmt = dseAttributes.statement.buildFromSession(session)

stmt.onFailure(err => {
val responseTime: ResponseTime = responseTimeBuilder.build()
val responseTime = new ServiceTime(0, 0)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be clearer to name this serviceTime instead of responseTime?

This would also require a change to line 71:

statsEngine.logResponse(session, name, serviceTime.toGatlingResponseTimings, KO, None,
         Some(s"$tagString - Preparing: ${err.take(50)}"), List(responseTime.latencyIn(MICROSECONDS), "PRE", logUuid))		         Some(s"$tagString - Preparing: ${err.take(50)}")

but to me that seems a bit clearer. We are converting a ServiceTime to a ResponseTime. Thoughts?

val logUuid = UUID.randomUUID.toString
val tagString = if (session.groupHierarchy.nonEmpty) session.groupHierarchy.mkString("/") + "/" + dseAttributes.tag else dseAttributes.tag

Expand All @@ -84,6 +76,8 @@ class CqlRequestAction(val name: String,
})

stmt.onSuccess({ stmt =>
val responseTimeBuilder = ResponseTimeBuilder.newResponseTimeBuilder(session, gatlingTimingSource)

// global options
dseAttributes.cl.map(stmt.setConsistencyLevel)
dseAttributes.userOrRole.map(stmt.executingAs)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,18 +61,10 @@ class GraphRequestAction(val name: String,


def sendQuery(session: Session): Unit = {
val enableCO = Boolean.getBoolean("gatling.dse.plugin.measure_service_time")
val responseTimeBuilder: ResponseTimeBuilder = if (enableCO) {
// The throughput checker is useless in CO affected scenarios since throughput is not known in advance
COAffectedResponseTime.startingAt(System.nanoTime())
} else {
ThroughputVerifier.checkForGatlingOverloading(session, gatlingTimingSource)
GatlingResponseTime.startedByGatling(session, gatlingTimingSource)
}
val stmt = dseAttributes.statement.buildFromSession(session)

stmt.onFailure(err => {
val responseTime = responseTimeBuilder.build()
val responseTime = new ServiceTime(0, 0)
Copy link
Collaborator

@bradfordcp bradfordcp Oct 29, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comments as CqlRequestAction regarding responseTime vs serviceTime.

val logUuid = UUID.randomUUID.toString
val tagString = if (session.groupHierarchy.nonEmpty) session.groupHierarchy.mkString("/") + "/" + dseAttributes.tag else dseAttributes.tag

Expand All @@ -84,6 +76,8 @@ class GraphRequestAction(val name: String,
})

stmt.onSuccess({ gStmt =>
val responseTimeBuilder = ResponseTimeBuilder.newResponseTimeBuilder(session, gatlingTimingSource)

// global options
dseAttributes.cl.map(gStmt.setConsistencyLevel)
dseAttributes.defaultTimestamp.map(gStmt.setDefaultTimestamp)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ package com.datastax.gatling.plugin.utils
import java.util.concurrent.TimeUnit
import java.util.concurrent.TimeUnit.{MILLISECONDS, NANOSECONDS}

import com.datastax.gatling.plugin.request.ThroughputVerifier
import com.typesafe.scalalogging.StrictLogging
import io.gatling.commons.util.ClockSingleton
import io.gatling.core.Predef.Session
import io.gatling.core.stats.message.ResponseTimings
Expand All @@ -21,6 +23,32 @@ trait ResponseTime {
def startTimeIn(targetTimeUnit: TimeUnit): Long
}

object ResponseTimeBuilder extends StrictLogging {
val measureServiceTime: Boolean = {
if (java.lang.Boolean.getBoolean("gatling.dse.plugin.measure_service_time")) {
logger.info("Gatling DSE plugin is configured to measure service time")
true
} else {
logger.info("Gatling DSE plugin is configured to measure response time")
false
}
}

def newResponseTimeBuilder(session: Session, gatlingTimingSource: GatlingTimingSource): ResponseTimeBuilder = {
if (measureServiceTime) {
// The throughput checker is useless in CO affected scenarios since throughput is not known in advance
// Also, measuring service time MUST exclude the time spent in the feeder.
// So it makes sense to take the "start" measurement from `nanoTime()` here.
ServiceTime.startingAt(System.nanoTime())
} else {
// We trust Gatling for the user creation time when we measure response time.
// Therefore, the response time builder can be built anywhere.
ThroughputVerifier.checkForGatlingOverloading(session, gatlingTimingSource)
GatlingResponseTime.startedByGatling(session, gatlingTimingSource)
}
}
}

trait ResponseTimeBuilder {
def build(): ResponseTime
}
Expand Down Expand Up @@ -63,12 +91,12 @@ case class GatlingResponseTime(session: Session, timingSource: TimingSource)
session.startDate + NANOSECONDS.toMillis(latencyInNanos))
}

object COAffectedResponseTime {
object ServiceTime {
def startingAt(startNanos: Long): ResponseTimeBuilder =
() => COAffectedResponseTime(startNanos, System.nanoTime())
() => ServiceTime(startNanos, System.nanoTime())
}

case class COAffectedResponseTime(startNanos: Long, endNanos: Long)
case class ServiceTime(startNanos: Long, endNanos: Long)
extends ResponseTime {
override def latencyIn(targetTimeUnit: TimeUnit): Long =
targetTimeUnit.convert(endNanos - startNanos, NANOSECONDS)
Expand Down