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.

59 lines
1.5 KiB

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