All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
io.gatling.http.action.sse.fsm.SseFsm.scala Maven / Gradle / Ivy
/*
* Copyright 2011-2024 GatlingCorp (https://gatling.io)
*
* 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 io.gatling.http.action.sse.fsm
import java.util.concurrent.{ ScheduledFuture, TimeUnit }
import scala.concurrent.duration.FiniteDuration
import io.gatling.commons.util.Clock
import io.gatling.core.action.Action
import io.gatling.core.session.Session
import io.gatling.core.stats.StatsEngine
import io.gatling.http.action.sse.SseInboundMessage
import io.gatling.http.cache.SslContextSupport
import io.gatling.http.check.sse.SseMessageCheckSequence
import io.gatling.http.client.Request
import io.gatling.http.engine.HttpEngine
import io.gatling.http.protocol.HttpProtocol
import io.gatling.http.util.BoundedMutableDequeue
import com.typesafe.scalalogging.StrictLogging
import io.netty.channel.EventLoop
object SseFsm {
def apply(
session: Session,
sseName: String,
connectActionName: String,
connectRequest: Request,
connectCheckSequence: List[SseMessageCheckSequence],
statsEngine: StatsEngine,
httpEngine: HttpEngine,
httpProtocol: HttpProtocol,
clock: Clock
): SseFsm = {
val stream = new SseStream(
session,
connectRequest,
connectActionName,
SslContextSupport.sslContexts(session),
httpProtocol.enginePart.shareConnections,
httpEngine: HttpEngine,
statsEngine: StatsEngine,
clock: Clock
)
val fsm = new SseFsm(
sseName,
connectActionName,
connectCheckSequence,
statsEngine,
httpProtocol,
session.eventLoop,
clock,
stream
)
stream.fsm = fsm
fsm
}
}
final class SseFsm(
private[fsm] val sseName: String,
private[fsm] val connectActionName: String,
private[fsm] val connectCheckSequence: List[SseMessageCheckSequence],
private[fsm] val statsEngine: StatsEngine,
httpProtocol: HttpProtocol,
eventLoop: EventLoop,
private[fsm] val clock: Clock,
private[fsm] val stream: SseStream
) extends StrictLogging {
private var currentState: SseState = _
private var currentTimeout: ScheduledFuture[Unit] = _
private[fsm] val unmatchedInboundMessageBuffer = new BoundedMutableDequeue[SseInboundMessage](httpProtocol.ssePart.unmatchedInboundMessageBufferSize)
private[fsm] def scheduleTimeout(dur: FiniteDuration): Unit = {
currentTimeout = eventLoop.schedule(
() => {
logger.debug(s"Timeout ${currentTimeout.hashCode} triggered")
currentTimeout = null
execute(currentState.onTimeout())
},
dur.toMillis,
TimeUnit.MILLISECONDS
)
logger.debug(s"Timeout ${currentTimeout.hashCode} scheduled")
}
private[fsm] def cancelTimeout(): Unit =
if (currentTimeout == null) {
logger.debug("Couldn't cancel timeout because it wasn't set")
} else {
if (currentTimeout.cancel(true)) {
logger.debug(s"Timeout ${currentTimeout.hashCode} cancelled")
} else {
logger.debug(s"Failed to cancel timeout ${currentTimeout.hashCode}")
}
currentTimeout = null
}
private def execute(f: => NextSseState): Unit = {
val NextSseState(nextState, afterStateUpdate) = f
currentState = nextState
afterStateUpdate()
}
def onPerformInitialConnect(session: Session, initialConnectNext: Action): Unit =
execute(SseConnectingState.gotoConnecting(this, session, initialConnectNext))
def onSseStreamConnected(): Unit =
execute(currentState.onSseStreamConnected(clock.nowMillis))
def onSetCheck(actionName: String, checkSequences: List[SseMessageCheckSequence], session: Session, next: Action): Unit = {
unmatchedInboundMessageBuffer.clear()
execute(currentState.onSetCheck(actionName, checkSequences, session: Session, next))
}
def onSseReceived(message: String): Unit =
execute(currentState.onSseReceived(message, clock.nowMillis))
def onSseEndOfStream(): Unit =
execute(currentState.onSseStreamClosed(clock.nowMillis))
def onSseStreamClosed(): Unit =
execute(currentState.onSseStreamClosed(clock.nowMillis))
def onSseStreamCrashed(t: Throwable): Unit =
execute(currentState.onSseStreamCrashed(t, clock.nowMillis))
def onClientCloseRequest(actionName: String, session: Session, next: Action): Unit =
execute(currentState.onClientCloseRequest(actionName, session, next))
def collectUnmatchedInboundMessages(): List[SseInboundMessage] =
unmatchedInboundMessageBuffer.removeAll()
}