github.com/asynkron/protoactor-go@v0.0.0-20240308120642-ef91a6abee75/actor/bounded.go (about)

     1  package actor
     2  
     3  import (
     4  	rbqueue "github.com/Workiva/go-datastructures/queue"
     5  	"github.com/asynkron/protoactor-go/internal/queue/mpsc"
     6  )
     7  
     8  type boundedMailboxQueue struct {
     9  	userMailbox *rbqueue.RingBuffer
    10  	dropping    bool
    11  }
    12  
    13  func (q *boundedMailboxQueue) Push(m interface{}) {
    14  	if q.dropping {
    15  		if q.userMailbox.Len() > 0 && q.userMailbox.Cap()-1 == q.userMailbox.Len() {
    16  			_, _ = q.userMailbox.Get()
    17  		}
    18  	}
    19  
    20  	_ = q.userMailbox.Put(m)
    21  }
    22  
    23  func (q *boundedMailboxQueue) Pop() interface{} {
    24  	if q.userMailbox.Len() > 0 {
    25  		m, _ := q.userMailbox.Get()
    26  
    27  		return m
    28  	}
    29  
    30  	return nil
    31  }
    32  
    33  // Bounded returns a producer which creates a bounded mailbox of the specified size.
    34  func Bounded(size int, mailboxStats ...MailboxMiddleware) MailboxProducer {
    35  	return bounded(size, false, mailboxStats...)
    36  }
    37  
    38  // BoundedDropping returns a producer which creates a bounded mailbox of the specified size that drops front element on push.
    39  func BoundedDropping(size int, mailboxStats ...MailboxMiddleware) MailboxProducer {
    40  	return bounded(size, true, mailboxStats...)
    41  }
    42  
    43  func bounded(size int, dropping bool, mailboxStats ...MailboxMiddleware) MailboxProducer {
    44  	return func() Mailbox {
    45  		q := &boundedMailboxQueue{
    46  			userMailbox: rbqueue.NewRingBuffer(uint64(size)),
    47  			dropping:    dropping,
    48  		}
    49  
    50  		return &defaultMailbox{
    51  			systemMailbox: mpsc.New(),
    52  			userMailbox:   q,
    53  			middlewares:   mailboxStats,
    54  		}
    55  	}
    56  }