Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an option to control sleep interval between calls to read_poll #9

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

tomjridge
Copy link
Contributor

The default is as before: 0.1 s sleep between calls to read_poll. A value of 0.0 skips sleeping altogether. This is possibly useful if events are being lost - a lower sleep may result in fewer events being lost.

The default is as before: 0.1 s sleep between calls to read_poll. A
value of 0.0 skips sleeping altogether. This is possibly useful if
events are being lost - a lower sleep may result in fewer events being
lost.
@sadiqj
Copy link
Collaborator

sadiqj commented Jan 5, 2023

I think being able to control the sleep is a good idea but could we go further and have a simple control loop that tunes it adaptively?

@tomjridge
Copy link
Contributor Author

I'm not familiar with adaptive tuning, but I assume it is something like:

  1. Check the number of events read from the most recent poll (n, say)
  2. With two bounds (hi and lo): If n>= hi, assume the rate of production is high, and don't sleep (ie sleep for 0s); if n<= lo, sleep for 0.1s, say; if lo < n < hi, sleep proportionately between 0 and 0.1s

Something like this?

@sadiqj
Copy link
Collaborator

sadiqj commented Jan 5, 2023

Yes. Another way to think about it is that we're aiming to sleep for some amount of time that means we expect to read N events when we do poll.

If we poll and we read fewer than N events then increase our interval (up to hi), if we read fewer then decrease (down to lo).

Events are a little bursty because they tend to all happen during GCs, so N probably wants to be reasonably big (hundreds, maybe thousand?).

@tomjridge
Copy link
Contributor Author

tomjridge commented Jan 6, 2023

Some sample code. There's lots of possible choices here. I've guessed at what might be good choices. But I'm worried that the approach feels very ad hoc. What do you think?

let clamp lo hi (x:float) =
  match () with
  | _ when x < lo -> lo
  | _ when x > hi -> hi
  | _ -> x

let next_sleep_dur ~n_target ~lo_dur ~hi_dur () = 
  assert(lo_dur < hi_dur);
  (* delta is the amount we increment or decrement the duration; currently 10% of the
     target range *)
  let delta = (hi_dur -. lo_dur) *. 0.1 in 
  fun current_sleep_dur (n_read:int) ->
    if n_read > n_target then
      (* we want to decrease sleep duration if possible; we are worried about losing events
         so we immediately drop to the lowest possible duration *)
      lo_dur
    else if n_read < n_target / 2 then
      (* if we are reading substantially less events than our target, gradually increase
         sleep, clamped between lo_dur and hi_dur *)
      clamp lo_dur hi_dur (current_sleep_dur +. delta)
    else current_sleep_dur

@sadiqj
Copy link
Collaborator

sadiqj commented Jan 10, 2023

That looks like it could work. Have you tested it on a couple of examples?

@Sudha247 Sudha247 added the stale label Sep 11, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants