You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

53 lines
1.6 KiB

  1. package p2p
  2. import (
  3. "sync"
  4. )
  5. // default capacity for the size of a queue
  6. const defaultCapacity uint = 16e6 // ~16MB
  7. // queue does QoS scheduling for Envelopes, enqueueing and dequeueing according
  8. // to some policy. Queues are used at contention points, i.e.:
  9. //
  10. // - Receiving inbound messages to a single channel from all peers.
  11. // - Sending outbound messages to a single peer from all channels.
  12. type queue interface {
  13. // enqueue returns a channel for submitting envelopes.
  14. enqueue() chan<- Envelope
  15. // dequeue returns a channel ordered according to some queueing policy.
  16. dequeue() <-chan Envelope
  17. // close closes the queue. After this call enqueue() will block, so the
  18. // caller must select on closed() as well to avoid blocking forever. The
  19. // enqueue() and dequeue() channels will not be closed.
  20. close()
  21. // closed returns a channel that's closed when the scheduler is closed.
  22. closed() <-chan struct{}
  23. }
  24. // fifoQueue is a simple unbuffered lossless queue that passes messages through
  25. // in the order they were received, and blocks until message is received.
  26. type fifoQueue struct {
  27. queueCh chan Envelope
  28. closeFn func()
  29. closeCh <-chan struct{}
  30. }
  31. func newFIFOQueue(size int) queue {
  32. closeCh := make(chan struct{})
  33. once := &sync.Once{}
  34. return &fifoQueue{
  35. queueCh: make(chan Envelope, size),
  36. closeFn: func() { once.Do(func() { close(closeCh) }) },
  37. closeCh: closeCh,
  38. }
  39. }
  40. func (q *fifoQueue) enqueue() chan<- Envelope { return q.queueCh }
  41. func (q *fifoQueue) dequeue() <-chan Envelope { return q.queueCh }
  42. func (q *fifoQueue) close() { q.closeFn() }
  43. func (q *fifoQueue) closed() <-chan struct{} { return q.closeCh }