# Demonstrate the effects of a slow stream (that's causing a build up of
# waiting requests) being disconnected. This test is similar to the one in
# handle_single_slow_stream, except the slow stream is eventually disconnected.

init
handle=h
----

# Set up a triply connected handle (to s1, s2, s3) and start issuing writes at
# 1MiB/s. For two of the streams, return tokens at exactly the rate its being
# deducted (1MiB/s). For the third stream (s3), we return flow tokens at only
# 0.5MiB/s. At t=35s, disconnect the slow stream.
timeline
t=0s       handle=h op=connect    stream=t1/s1     log-position=4/0
t=0s       handle=h op=connect    stream=t1/s2     log-position=4/0
t=0s       handle=h op=connect    stream=t1/s3     log-position=4/0
t=[0s,50s) handle=h class=regular adjust=-1MiB/s   rate=10/s
t=[0s,50s) handle=h class=regular adjust=+1MiB/s   rate=10/s stream=t1/s1
t=[0s,50s) handle=h class=regular adjust=+1MiB/s   rate=10/s stream=t1/s2
t=[0s,35s) handle=h class=regular adjust=+0.5MiB/s rate=10/s stream=t1/s3
t=35s      handle=h op=disconnect stream=t1/s3
----

simulate
----

# Zoom in near the point where writes are being shaped by the slowest stream
# (s3, at 0.5MiB/s). We see the blocked stream count bouncing between 0 and 1
# as tokens get depleted and replenished (demand here is higher than the
# replenishment rate).
#
# As soon as s3 is disconnected, we see a release of 16MiB of held tokens back
# into the node-level controller (32MiB -> 48MiB). We see a burst in the number
# of stream-specific/controller-level requests bypassing Admit() due to the
# stream disconnecting. At the handle-level this just appears as a burst in
# admitted requests. After s3 disconnects, the handle-level admission rate goes
# back to what it was before traffic was shaped by s3.
#
# TODO(irfansharif): The post-stream disconnection burst might lead to
# severe over-admission since it may have been long since we observed available
# tokens for the still connected streams. In fact, many requests that started
# waiting on the soon-to-be-disconnected-stream are in the same boat, all of
# which will now get admitted. One thing we could do is to try and observe
# available tokens again for still-connected streams.
plot t=[30s,40s)
kvadmission.flow_controller.regular_blocked_stream_count    unit=streams
kvadmission.flow_controller.regular_tokens_available        unit=MiB
kvadmission.flow_controller.regular_requests_bypassed       unit=reqs/s rate=true
kvadmission.flow_handle.regular_requests_{admitted,waiting} unit=reqs/s rate=true
----
----
 1.0 ┤            ╭╮
 0.9 ┤            ││
 0.9 ┤        ╭╮  ││  ╭╮
 0.8 ┤        ││  ││  ││
 0.7 ┤        ││  ││  ││
 0.7 ┤        ││  ││  ││
 0.6 ┤        │╰╮ ││ ╭╯│
 0.5 ┤        │ │ ││ │ │
 0.5 ┤        │ │╭╯╰╮│ │
 0.4 ┤        │ ││  ││ │
 0.3 ┤       ╭╯ ││  ││ ╰╮
 0.3 ┤       │  ││  ││  │
 0.2 ┤       │  ││  ││  ╰╮
 0.1 ┤       │  ││  ││   │
 0.1 ┤       │  ╰╯  ╰╯   │
 0.0 ┼───────╯           ╰───────────────────
       regular_blocked_stream_count (streams)


 48.0 ┤                   ╭───────────────────
 46.9 ┤                   │
 45.9 ┤                   │
 44.8 ┤                   │
 43.7 ┤                   │
 42.6 ┤                   │
 41.6 ┤                   │
 40.5 ┤                   │
 39.4 ┤                   │
 38.3 ┤                   │
 37.3 ┤                   │
 36.2 ┤                   │
 35.1 ┤                   │
 34.0 ┤                   │
 33.0 ┼─╮                 │
 31.9 ┤ ╰─────────────────╯
            regular_tokens_available (MiB)


 16.0 ┤                    ╭──╮
 14.9 ┤                    │  │
 13.9 ┤                    │  │
 12.8 ┤                   ╭╯  │
 11.7 ┤                   │   │
 10.7 ┤                   │   │
  9.6 ┤                   │   │
  8.5 ┤                   │   │
  7.5 ┤                   │   │
  6.4 ┤                   │   │
  5.3 ┤                   │   │
  4.3 ┤                   │   │
  3.2 ┤                   │   │
  2.1 ┤                   │   │
  1.1 ┤                   │   ╰╮
  0.0 ┼───────────────────╯    ╰──────────────
       rate(regular_requests_bypassed) (reqs/s)


  25.0 ┤                     ╭─╮
  22.3 ┤                    ╭╯ │
  19.7 ┤                    │  │
  17.0 ┤                   ╭╯  │
  14.3 ┤                   │   │
  11.7 ┼───────╮           │   ╰───────────────
   9.0 ┤       ╰─╮         │
   6.3 ┤         ╰╭────────╮
   3.7 ┤        ╭─╯        │
   1.0 ┼────────╯          │   ╭───────────────
  -1.7 ┤                   │   │
  -4.3 ┤                   │   │
  -7.0 ┤                   ╰╮  │
  -9.7 ┤                    │  │
 -12.3 ┤                    ╰─╮│
 -15.0 ┤                      ╰╯
        rate(flow_handle.regular_requests_{admitted,waiting}) (reqs/s)
----
----

# vim:ft=conf
