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

     1  package actor
     2  
     3  import (
     4  	"sync/atomic"
     5  	"unsafe"
     6  )
     7  
     8  /*
     9  ensure the generated pid file contains the p *Process
    10  TODO: make some sed command to inject this somehow
    11  
    12  type PID struct {
    13  	state         protoimpl.MessageState
    14  	sizeCache     protoimpl.SizeCache
    15  	unknownFields protoimpl.UnknownFields
    16  
    17  	Address   string `protobuf:"bytes,1,opt,name=Address,proto3" json:"Address,omitempty"`
    18  	Id        string `protobuf:"bytes,2,opt,name=Id,proto3" json:"Id,omitempty"`
    19  	RequestId uint32 `protobuf:"varint,3,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
    20  
    21  	//manually added
    22  	p *Process
    23  }
    24  */
    25  
    26  //goland:noinspection GoReceiverNames
    27  func (pid *PID) ref(actorSystem *ActorSystem) Process {
    28  	p := (*Process)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&pid.p))))
    29  	if p != nil {
    30  		if l, ok := (*p).(*ActorProcess); ok && atomic.LoadInt32(&l.dead) == 1 {
    31  			atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&pid.p)), nil)
    32  		} else {
    33  			return *p
    34  		}
    35  	}
    36  
    37  	ref, exists := actorSystem.ProcessRegistry.Get(pid)
    38  	if exists {
    39  		atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&pid.p)), unsafe.Pointer(&ref))
    40  	}
    41  
    42  	return ref
    43  }
    44  
    45  // sendUserMessage sends a messages asynchronously to the PID.
    46  //
    47  //goland:noinspection GoReceiverNames
    48  func (pid *PID) sendUserMessage(actorSystem *ActorSystem, message interface{}) {
    49  	pid.ref(actorSystem).SendUserMessage(pid, message)
    50  }
    51  
    52  //goland:noinspection GoReceiverNames.
    53  func (pid *PID) sendSystemMessage(actorSystem *ActorSystem, message interface{}) {
    54  	pid.ref(actorSystem).SendSystemMessage(pid, message)
    55  }
    56  
    57  //goland:noinspection GoReceiverNames.
    58  func (pid *PID) Equal(other *PID) bool {
    59  	if pid != nil && other == nil {
    60  		return false
    61  	}
    62  
    63  	return pid.Id == other.Id && pid.Address == other.Address && pid.RequestId == other.RequestId
    64  }
    65  
    66  // NewPID returns a new instance of the PID struct.
    67  func NewPID(address, id string) *PID {
    68  	return &PID{
    69  		Address: address,
    70  		Id:      id,
    71  	}
    72  }