github.com/ergo-services/ergo@v1.999.224/gen/types.go (about)

     1  package gen
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"time"
     7  
     8  	"github.com/ergo-services/ergo/etf"
     9  )
    10  
    11  // EnvKey
    12  type EnvKey string
    13  
    14  // Process
    15  type Process interface {
    16  	Core
    17  
    18  	// Spawn create a new process with parent
    19  	Spawn(name string, opts ProcessOptions, object ProcessBehavior, args ...etf.Term) (Process, error)
    20  
    21  	// RemoteSpawn creates a new process at a remote node. The object name is a regitered
    22  	// behavior on a remote name using RegisterBehavior(...). The given options will stored
    23  	// in the process environment using node.EnvKeyRemoteSpawn as a key
    24  	RemoteSpawn(node string, object string, opts RemoteSpawnOptions, args ...etf.Term) (etf.Pid, error)
    25  	RemoteSpawnWithTimeout(timeout int, node string, object string, opts RemoteSpawnOptions, args ...etf.Term) (etf.Pid, error)
    26  
    27  	// Name returns process name used on starting.
    28  	Name() string
    29  
    30  	// RegisterName register associates the name with pid (not overrides registered name on starting)
    31  	RegisterName(name string) error
    32  
    33  	// UnregisterName unregister named process. Unregistering name is allowed to the owner only
    34  	UnregisterName(name string) error
    35  
    36  	// NodeName returns node name
    37  	NodeName() string
    38  
    39  	// NodeStop stops the node
    40  	NodeStop()
    41  
    42  	// NodeUptime returns node lifespan
    43  	NodeUptime() int64
    44  
    45  	// Info returns process details
    46  	Info() ProcessInfo
    47  
    48  	// Self returns registered process identificator belongs to the process
    49  	Self() etf.Pid
    50  
    51  	// Direct make a direct request to the actor (gen.Application, gen.Supervisor, gen.Server or
    52  	// inherited from gen.Server actor) with default timeout 5 seconds
    53  	Direct(request interface{}) (interface{}, error)
    54  
    55  	// DirectWithTimeout make a direct request to the actor with the given timeout (in seconds)
    56  	DirectWithTimeout(request interface{}, timeout int) (interface{}, error)
    57  
    58  	// Send sends a message in fashion of 'erlang:send'. The value of 'to' can be a Pid, registered local name
    59  	// or gen.ProcessID{RegisteredName, NodeName}
    60  	Send(to interface{}, message etf.Term) error
    61  
    62  	// SendAfter starts a timer. When the timer expires, the message sends to the process
    63  	// identified by 'to'.  'to' can be a Pid, registered local name or
    64  	// gen.ProcessID{RegisteredName, NodeName}. Returns cancel function in order to discard
    65  	// sending a message. CancelFunc returns bool value. If it returns false, than the timer has
    66  	// already expired and the message has been sent.
    67  	SendAfter(to interface{}, message etf.Term, after time.Duration) CancelFunc
    68  
    69  	// Exit initiate a graceful stopping process
    70  	Exit(reason string) error
    71  
    72  	// Kill immediately stops process
    73  	Kill()
    74  
    75  	// CreateAlias creates a new alias for the Process
    76  	CreateAlias() (etf.Alias, error)
    77  
    78  	// DeleteAlias deletes the given alias
    79  	DeleteAlias(alias etf.Alias) error
    80  
    81  	// ListEnv returns a map of configured environment variables.
    82  	// It also includes environment variables from the GroupLeader, Parent and Node.
    83  	// which are overlapped by priority: Process(Parent(GroupLeader(Node)))
    84  	ListEnv() map[EnvKey]interface{}
    85  
    86  	// SetEnv set environment variable with given name. Use nil value to remove variable with given name.
    87  	SetEnv(name EnvKey, value interface{})
    88  
    89  	// Env returns value associated with given environment name.
    90  	Env(name EnvKey) interface{}
    91  
    92  	// Wait waits until process stopped
    93  	Wait()
    94  
    95  	// WaitWithTimeout waits until process stopped. Return ErrTimeout
    96  	// if given timeout is exceeded
    97  	WaitWithTimeout(d time.Duration) error
    98  
    99  	// Link creates a link between the calling process and another process.
   100  	// Links are bidirectional and there can only be one link between two processes.
   101  	// Repeated calls to Process.Link(Pid) have no effect. If one of the participants
   102  	// of a link terminates, it will send an exit signal to the other participant and caused
   103  	// termination of the last one. If process set a trap using Process.SetTrapExit(true) the exit signal transorms into the MessageExit and delivers as a regular message.
   104  	Link(with etf.Pid) error
   105  
   106  	// Unlink removes the link, if there is one, between the calling process and
   107  	// the process referred to by Pid.
   108  	Unlink(with etf.Pid) error
   109  
   110  	// IsAlive returns whether the process is alive
   111  	IsAlive() bool
   112  
   113  	// SetTrapExit enables/disables the trap on terminate process. When a process is trapping exits,
   114  	// it will not terminate when an exit signal is received. Instead, the signal is transformed
   115  	// into a 'gen.MessageExit' which is put into the mailbox of the process just like a regular message.
   116  	SetTrapExit(trap bool)
   117  
   118  	// TrapExit returns whether the trap was enabled on this process
   119  	TrapExit() bool
   120  
   121  	// Compression returns true if compression is enabled for this process
   122  	Compression() bool
   123  
   124  	// SetCompression enables/disables compression for the messages sent outside of this node
   125  	SetCompression(enabled bool)
   126  
   127  	// CompressionLevel returns comression level for the process
   128  	CompressionLevel() int
   129  
   130  	// SetCompressionLevel defines compression level. Value must be in range:
   131  	// 1 (best speed) ... 9 (best compression), or -1 for the default compression level
   132  	SetCompressionLevel(level int) bool
   133  
   134  	// CompressionThreshold returns compression threshold for the process
   135  	CompressionThreshold() int
   136  
   137  	// SetCompressionThreshold defines the minimal size for the message that must be compressed
   138  	// Value must be greater than DefaultCompressionThreshold (1024)
   139  	SetCompressionThreshold(threshold int) bool
   140  
   141  	// MonitorNode creates monitor between the current process and node. If Node fails or does not exist,
   142  	// the message MessageNodeDown is delivered to the process.
   143  	MonitorNode(name string) etf.Ref
   144  
   145  	// DemonitorNode removes monitor. Returns false if the given reference wasn't found
   146  	DemonitorNode(ref etf.Ref) bool
   147  
   148  	// MonitorProcess creates monitor between the processes.
   149  	// Allowed types for the 'process' value: etf.Pid, gen.ProcessID
   150  	// When a process monitor is triggered, a MessageDown sends to the caller.
   151  	// Note: The monitor request is an asynchronous signal. That is, it takes
   152  	// time before the signal reaches its destination.
   153  	MonitorProcess(process interface{}) etf.Ref
   154  
   155  	// DemonitorProcess removes monitor. Returns false if the given reference wasn't found
   156  	DemonitorProcess(ref etf.Ref) bool
   157  
   158  	// Behavior returns the object this process runs on.
   159  	Behavior() ProcessBehavior
   160  	// GroupLeader returns group leader process. Usually it points to the application process.
   161  	GroupLeader() Process
   162  	// Parent returns parent process. It returns nil if this process was spawned using Node.Spawn.
   163  	Parent() Process
   164  	// Context returns process context.
   165  	Context() context.Context
   166  
   167  	// Children returns list of children pid (Application, Supervisor)
   168  	Children() ([]etf.Pid, error)
   169  
   170  	// Links returns list of the process pids this process has linked to.
   171  	Links() []etf.Pid
   172  	// Monitors returns list of monitors created this process by pid.
   173  	Monitors() []etf.Pid
   174  	// Monitors returns list of monitors created this process by name.
   175  	MonitorsByName() []ProcessID
   176  	// MonitoredBy returns list of process pids monitored this process.
   177  	MonitoredBy() []etf.Pid
   178  	// Aliases returns list of aliases of this process.
   179  	Aliases() []etf.Alias
   180  
   181  	// RegisterEvent
   182  	RegisterEvent(event Event, messages ...EventMessage) error
   183  	UnregisterEvent(event Event) error
   184  	MonitorEvent(event Event) error
   185  	DemonitorEvent(event Event) error
   186  	SendEventMessage(event Event, message EventMessage) error
   187  
   188  	PutSyncRequest(ref etf.Ref) error
   189  	CancelSyncRequest(ref etf.Ref)
   190  	WaitSyncReply(ref etf.Ref, timeout int) (etf.Term, error)
   191  	PutSyncReply(ref etf.Ref, term etf.Term, err error) error
   192  	ProcessChannels() ProcessChannels
   193  }
   194  
   195  // ProcessInfo struct with process details
   196  type ProcessInfo struct {
   197  	PID             etf.Pid
   198  	Name            string
   199  	CurrentFunction string
   200  	Status          string
   201  	MessageQueueLen int
   202  	Links           []etf.Pid
   203  	Monitors        []etf.Pid
   204  	MonitorsByName  []ProcessID
   205  	MonitoredBy     []etf.Pid
   206  	Aliases         []etf.Alias
   207  	Dictionary      etf.Map
   208  	TrapExit        bool
   209  	GroupLeader     etf.Pid
   210  	Compression     bool
   211  }
   212  
   213  // ProcessOptions
   214  type ProcessOptions struct {
   215  	// Context allows mixing the system context with the custom one. E.g., to limit
   216  	// the lifespan using context.WithTimeout. This context MUST be based on the
   217  	// other Process' context. Otherwise, you get the error lib.ErrProcessContext
   218  	Context context.Context
   219  	// MailboxSize defines the length of message queue for the process
   220  	MailboxSize uint16
   221  	// DirectboxSize defines the length of message queue for the direct requests
   222  	DirectboxSize uint16
   223  	// GroupLeader
   224  	GroupLeader Process
   225  	// Env set the process environment variables
   226  	Env map[EnvKey]interface{}
   227  
   228  	// Fallback defines the process to where messages will be forwarded
   229  	// if the mailbox is overflowed. The tag value could be used to
   230  	// differentiate the source processes. Forwarded messages are wrapped
   231  	// into the MessageFallback struct.
   232  	Fallback ProcessFallback
   233  }
   234  
   235  // ProcessFallback
   236  type ProcessFallback struct {
   237  	Name string
   238  	Tag  string
   239  }
   240  
   241  // RemoteSpawnRequest
   242  type RemoteSpawnRequest struct {
   243  	From    etf.Pid
   244  	Ref     etf.Ref
   245  	Options RemoteSpawnOptions
   246  }
   247  
   248  // RemoteSpawnOptions defines options for RemoteSpawn method
   249  type RemoteSpawnOptions struct {
   250  	// Name register associated name with spawned process
   251  	Name string
   252  	// Monitor enables monitor on the spawned process using provided reference
   253  	Monitor etf.Ref
   254  	// Link enables link between the calling and spawned processes
   255  	Link bool
   256  	// Function in order to support {M,F,A} request to the Erlang node
   257  	Function string
   258  }
   259  
   260  // ProcessChannels
   261  type ProcessChannels struct {
   262  	Mailbox      <-chan ProcessMailboxMessage
   263  	Direct       <-chan ProcessDirectMessage
   264  	GracefulExit <-chan ProcessGracefulExitRequest
   265  }
   266  
   267  // ProcessMailboxMessage
   268  type ProcessMailboxMessage struct {
   269  	From    etf.Pid
   270  	Message interface{}
   271  }
   272  
   273  // ProcessDirectMessage
   274  type ProcessDirectMessage struct {
   275  	Ref     etf.Ref
   276  	Message interface{}
   277  	Err     error
   278  }
   279  
   280  // ProcessGracefulExitRequest
   281  type ProcessGracefulExitRequest struct {
   282  	From   etf.Pid
   283  	Reason string
   284  }
   285  
   286  // ProcessState
   287  type ProcessState struct {
   288  	Process
   289  	State interface{}
   290  }
   291  
   292  // ProcessBehavior interface contains methods you should implement to make your own process behavior
   293  type ProcessBehavior interface {
   294  	ProcessInit(Process, ...etf.Term) (ProcessState, error)
   295  	ProcessLoop(ProcessState, chan<- bool) string // method which implements control flow of process
   296  }
   297  
   298  // Core the common set of methods provided by Process and node.Node interfaces
   299  type Core interface {
   300  
   301  	// ProcessByName returns Process for the given name.
   302  	// Returns nil if it doesn't exist (not found) or terminated.
   303  	ProcessByName(name string) Process
   304  
   305  	// ProcessByPid returns Process for the given Pid.
   306  	// Returns nil if it doesn't exist (not found) or terminated.
   307  	ProcessByPid(pid etf.Pid) Process
   308  
   309  	// ProcessByAlias returns Process for the given alias.
   310  	// Returns nil if it doesn't exist (not found) or terminated
   311  	ProcessByAlias(alias etf.Alias) Process
   312  
   313  	// ProcessInfo returns the details about given Pid
   314  	ProcessInfo(pid etf.Pid) (ProcessInfo, error)
   315  
   316  	// ProcessList returns the list of running processes
   317  	ProcessList() []Process
   318  
   319  	// MakeRef creates an unique reference within this node
   320  	MakeRef() etf.Ref
   321  
   322  	// IsAlias checks whether the given alias is belongs to the alive process on this node.
   323  	// If the process died all aliases are cleaned up and this function returns
   324  	// false for the given alias. For alias from the remote node always returns false.
   325  	IsAlias(etf.Alias) bool
   326  
   327  	// IsMonitor returns true if the given references is a monitor
   328  	IsMonitor(ref etf.Ref) bool
   329  
   330  	// RegisterBehavior
   331  	RegisterBehavior(group, name string, behavior ProcessBehavior, data interface{}) error
   332  	// RegisteredBehavior
   333  	RegisteredBehavior(group, name string) (RegisteredBehavior, error)
   334  	// RegisteredBehaviorGroup
   335  	RegisteredBehaviorGroup(group string) []RegisteredBehavior
   336  	// UnregisterBehavior
   337  	UnregisterBehavior(group, name string) error
   338  }
   339  
   340  // RegisteredBehavior
   341  type RegisteredBehavior struct {
   342  	Behavior ProcessBehavior
   343  	Data     interface{}
   344  }
   345  
   346  // ProcessID long notation of registered process {process_name, node_name}
   347  type ProcessID struct {
   348  	Name string
   349  	Node string
   350  }
   351  
   352  // String string representaion of ProcessID value
   353  func (p ProcessID) String() string {
   354  	return fmt.Sprintf("<%s:%s>", p.Name, p.Node)
   355  }
   356  
   357  // MessageDown delivers as a message to Server's HandleInfo callback of the process
   358  // that created monitor using MonitorProcess.
   359  // Reason values:
   360  //   - the exit reason of the process
   361  //   - 'noproc' (process did not exist at the time of monitor creation)
   362  //   - 'noconnection' (no connection to the node where the monitored process resides)
   363  //   - 'noproxy' (no connection to the proxy this node had has a connection through. monitored process could be still alive)
   364  type MessageDown struct {
   365  	Ref       etf.Ref   // a monitor reference
   366  	ProcessID ProcessID // if monitor was created by name
   367  	Pid       etf.Pid
   368  	Reason    string
   369  }
   370  
   371  // MessageNodeDown delivers as a message to Server's HandleInfo callback of the process
   372  // that created monitor using MonitorNode
   373  type MessageNodeDown struct {
   374  	Ref  etf.Ref
   375  	Name string
   376  }
   377  
   378  // MessageProxyDown delivers as a message to Server's HandleInfo callback of the process
   379  // that created monitor using MonitorNode if the connection to the node was through the proxy
   380  // nodes and one of them went down.
   381  type MessageProxyDown struct {
   382  	Ref    etf.Ref
   383  	Node   string
   384  	Proxy  string
   385  	Reason string
   386  }
   387  
   388  // MessageExit delievers to Server's HandleInfo callback on enabled trap exit using SetTrapExit(true)
   389  // Reason values:
   390  //   - the exit reason of the process
   391  //   - 'noproc' (process did not exist at the time of link creation)
   392  //   - 'noconnection' (no connection to the node where the linked process resides)
   393  //   - 'noproxy' (no connection to the proxy this node had has a connection through. linked process could be still alive)
   394  type MessageExit struct {
   395  	Pid    etf.Pid
   396  	Reason string
   397  }
   398  
   399  // MessageFallback delivers to the process specified as a fallback process in ProcessOptions.Fallback.Name if the mailbox has been overflowed
   400  type MessageFallback struct {
   401  	Process etf.Pid
   402  	Tag     string
   403  	Message etf.Term
   404  }
   405  
   406  // MessageDirectChildren type intended to be used in Process.Children which returns []etf.Pid
   407  // You can handle this type of message in your HandleDirect callback to enable Process.Children
   408  // support for your gen.Server actor.
   409  type MessageDirectChildren struct{}
   410  
   411  // IsMessageDown
   412  func IsMessageDown(message etf.Term) (MessageDown, bool) {
   413  	var md MessageDown
   414  	switch m := message.(type) {
   415  	case MessageDown:
   416  		return m, true
   417  	}
   418  	return md, false
   419  }
   420  
   421  // IsMessageExit
   422  func IsMessageExit(message etf.Term) (MessageExit, bool) {
   423  	var me MessageExit
   424  	switch m := message.(type) {
   425  	case MessageExit:
   426  		return m, true
   427  	}
   428  	return me, false
   429  }
   430  
   431  // IsMessageProxyDown
   432  func IsMessageProxyDown(message etf.Term) (MessageProxyDown, bool) {
   433  	var mpd MessageProxyDown
   434  	switch m := message.(type) {
   435  	case MessageProxyDown:
   436  		return m, true
   437  	}
   438  	return mpd, false
   439  }
   440  
   441  // IsMessageFallback
   442  func IsMessageFallback(message etf.Term) (MessageFallback, bool) {
   443  	var mf MessageFallback
   444  	switch m := message.(type) {
   445  	case MessageFallback:
   446  		return m, true
   447  	}
   448  	return mf, false
   449  }
   450  
   451  type CancelFunc func() bool
   452  
   453  type EventMessage interface{}
   454  type Event string
   455  
   456  // MessageEventDown delivers to the process which monitored EventType if the owner
   457  // of this EventType has terminated
   458  type MessageEventDown struct {
   459  	Event  Event
   460  	Reason string
   461  }