github.com/ergo-services/ergo@v1.999.224/apps/erlang/erlang.go (about)

     1  package erlang
     2  
     3  // TODO: https://github.com/erlang/otp/blob/master/lib/runtime_tools-1.13.1/src/erlang_info.erl
     4  
     5  import (
     6  	"github.com/ergo-services/ergo/etf"
     7  	"github.com/ergo-services/ergo/gen"
     8  	"github.com/ergo-services/ergo/lib"
     9  )
    10  
    11  type erlang struct {
    12  	gen.Server
    13  }
    14  
    15  // Init
    16  func (e *erlang) Init(process *gen.ServerProcess, args ...etf.Term) error {
    17  	lib.Log("ERLANG: Init: %#v", args)
    18  	return nil
    19  }
    20  
    21  // HandleCall
    22  func (e *erlang) HandleCall(process *gen.ServerProcess, from gen.ServerFrom, message etf.Term) (etf.Term, gen.ServerStatus) {
    23  	lib.Log("ERLANG: HandleCall: %#v, From: %#v", message, from)
    24  
    25  	switch m := message.(type) {
    26  	case etf.Tuple:
    27  		switch m.Element(1) {
    28  		case etf.Atom("process_info"):
    29  			args := m.Element(2).(etf.List)
    30  			reply := processInfo(process, args[0].(etf.Pid), args[1])
    31  			return reply, gen.ServerStatusOK
    32  		case etf.Atom("system_info"):
    33  			args := m.Element(2).(etf.List)
    34  			reply := systemInfo(process, args[0].(etf.Atom))
    35  			return reply, gen.ServerStatusOK
    36  
    37  		case etf.Atom("function_exported"):
    38  			return true, gen.ServerStatusOK
    39  		}
    40  
    41  	}
    42  	return etf.Atom("ok"), gen.ServerStatusOK
    43  }
    44  
    45  func processInfo(p gen.Process, pid etf.Pid, property etf.Term) etf.Term {
    46  	process := p.ProcessByPid(pid)
    47  	if process == nil {
    48  		return etf.Atom("undefined")
    49  	}
    50  
    51  	switch property {
    52  	case etf.Atom("registered_name"):
    53  		name := process.Name()
    54  		if name == "" {
    55  			return etf.List{}
    56  		}
    57  
    58  		return etf.Tuple{property, etf.Atom(name)}
    59  	case etf.Atom("messages"):
    60  		return etf.Tuple{property, etf.List{}}
    61  	case etf.Atom("dictionary"):
    62  		return etf.Tuple{property, etf.List{}}
    63  	case etf.Atom("current_stacktrace"):
    64  		return etf.Tuple{property, etf.List{}}
    65  	}
    66  
    67  	switch p := property.(type) {
    68  	case etf.List:
    69  		values := etf.List{}
    70  		info := process.Info()
    71  		for i := range p {
    72  			switch p[i] {
    73  			case etf.Atom("binary"):
    74  				values = append(values, etf.Tuple{p[i], etf.List{}})
    75  			case etf.Atom("catchlevel"):
    76  				// values = append(values, etf.Tuple{p[i], 0})
    77  			case etf.Atom("current_function"):
    78  				values = append(values, etf.Tuple{p[i], info.CurrentFunction})
    79  			case etf.Atom("error_handler"):
    80  				// values = append(values, etf.Tuple{p[i], })
    81  			case etf.Atom("garbage_collection"):
    82  				values = append(values, etf.Tuple{p[i], etf.List{}})
    83  			case etf.Atom("group_leader"):
    84  				values = append(values, etf.Tuple{p[i], info.GroupLeader})
    85  			case etf.Atom("heap_size"):
    86  				// values = append(values, etf.Tuple{p[i], etf.Tuple{etf.Atom("words"), 0}})
    87  			case etf.Atom("initial_call"):
    88  				values = append(values, etf.Tuple{p[i], "object:loop"})
    89  			case etf.Atom("last_calls"):
    90  				// values = append(values, etf.Tuple{p[i], })
    91  			case etf.Atom("links"):
    92  				values = append(values, etf.Tuple{p[i], info.Links})
    93  			case etf.Atom("memory"):
    94  				values = append(values, etf.Tuple{p[i], 0})
    95  			case etf.Atom("message_queue_len"):
    96  				values = append(values, etf.Tuple{p[i], info.MessageQueueLen})
    97  			case etf.Atom("monitored_by"):
    98  				values = append(values, etf.Tuple{p[i], info.MonitoredBy})
    99  			case etf.Atom("monitors"):
   100  				values = append(values, etf.Tuple{p[i], info.Monitors})
   101  			case etf.Atom("priority"):
   102  				// values = append(values, etf.Tuple{p[i], 0})
   103  			case etf.Atom("reductions"):
   104  				values = append(values, etf.Tuple{p[i], 0})
   105  			case etf.Atom("registered_name"):
   106  				values = append(values, etf.Tuple{p[i], process.Name()})
   107  			case etf.Atom("sequential_trace_token"):
   108  				// values = append(values, etf.Tuple{p[i], })
   109  			case etf.Atom("stack_size"):
   110  				// values = append(values, etf.Tuple{p[i], etf.Tuple{etf.Atom("words"), 0}})
   111  			case etf.Atom("status"):
   112  				values = append(values, etf.Tuple{p[i], info.Status})
   113  			case etf.Atom("suspending"):
   114  				// values = append(values, etf.Tuple{p[i], })
   115  			case etf.Atom("total_heap_size"):
   116  				// values = append(values, etf.Tuple{p[i], etf.Tuple{etf.Atom("words"), 0}})
   117  			case etf.Atom("trace"):
   118  				// values = append(values, etf.Tuple{p[i], 0})
   119  			case etf.Atom("trap_exit"):
   120  				values = append(values, etf.Tuple{p[i], info.TrapExit})
   121  
   122  			}
   123  
   124  		}
   125  		return values
   126  	}
   127  	return nil
   128  }
   129  
   130  func systemInfo(p gen.Process, name etf.Atom) etf.Term {
   131  	switch name {
   132  	case etf.Atom("dirty_cpu_schedulers"):
   133  		return 1
   134  	}
   135  	return etf.Atom("unknown")
   136  }