writesched.go 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. // Copyright 2014 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. // See https://code.google.com/p/go/source/browse/CONTRIBUTORS
  5. // Licensed under the same terms as Go itself:
  6. // https://code.google.com/p/go/source/browse/LICENSE
  7. package http2
  8. // writeScheduler tracks pending frames to write, priorities, and decides
  9. // the next one to use. It is not thread-safe.
  10. type writeScheduler struct {
  11. slice []frameWriteMsg
  12. }
  13. func (ws *writeScheduler) empty() bool { return len(ws.slice) == 0 }
  14. func (ws *writeScheduler) add(wm frameWriteMsg) {
  15. ws.slice = append(ws.slice, wm)
  16. }
  17. // take returns
  18. func (ws *writeScheduler) take() frameWriteMsg {
  19. if ws.empty() {
  20. panic("internal error: writeScheduler.take called when empty")
  21. }
  22. // TODO:
  23. // -- prioritize all non-DATA frames first. they're not flow controlled anyway and
  24. // they're generally more important.
  25. // -- for all DATA frames that are enqueued (and we should enqueue []byte instead of FRAMES),
  26. // go over each (in priority order, as determined by the whole priority tree chaos),
  27. // and decide which we have tokens for, and how many tokens.
  28. // Writing on stream X requires that we have tokens on the
  29. // stream 0 (the conn-as-a-whole stream) as well as stream X.
  30. // So: find the highest priority stream X, then see: do we
  31. // have tokens for X? Let's say we have N_X tokens. Then we should
  32. // write MIN(N_X, TOKENS(conn-wide-tokens)).
  33. //
  34. // Any tokens left over? Repeat. Well, not really... the
  35. // repeat will happen via the next call to
  36. // scheduleFrameWrite. So keep a HEAP (priqueue) of which
  37. // streams to write to.
  38. // TODO: proper scheduler
  39. wm := ws.slice[0]
  40. // shift it all down. kinda lame. will be removed later anyway.
  41. copy(ws.slice, ws.slice[1:])
  42. ws.slice[len(ws.slice)-1] = frameWriteMsg{}
  43. ws.slice = ws.slice[:len(ws.slice)-1]
  44. return wm
  45. }